Как определить, является ли файл базы данных sqlite действительным или нет - PullRequest
12 голосов
/ 08 октября 2010

В приведенном ниже коде pathToNonDatabase - это путь к простому текстовому файлу, а не к реальной базе данных sqlite. Я надеялся, что sqlite3_open обнаружит это, но это не так (db не NULL, а result - SQLITE_OK). Итак, как определить, что файл не является допустимой базой данных sqlite?

sqlite3 *db = NULL;
int result = sqlite3_open(pathToNonDatabase, &db);

if((NULL==db) || (result!=SQLITE_OK)) { 
   // invalid database
}

Ответы [ 3 ]

15 голосов
/ 15 января 2014

sqlite открывает лениво базы данных. Просто сделайте что-нибудь сразу после открытия, которое требует, чтобы это была база данных.

Лучше всего наверное pragma schema_version;.

  • Это сообщит 0, если база данных не была создана (например, пустой файл). В этом случае это безопасно работать (и запустить CREATE TABLE, и т. Д.)
  • Если база данных была создана, она вернет, сколько ревизий прошла схема. Это значение может быть неинтересным, но это не ноль.
  • Если файл существует и не является базой данных (или пустым), вы получите ошибку.

Если вы хотите провести более тщательную проверку, вы можете использовать pragma quick_check;. Это облегченная проверка целостности, которая пропускает проверку соответствия содержимого таблиц индексам. Это все еще может быть очень медленным.

Избегайте integrity_check. Он не только проверяет каждую страницу, но затем проверяет содержимое таблиц по индексам. Это положительно сказывается на большой базе данных.

6 голосов
/ 19 марта 2014

Для тех, кому нужно сделать это в C # с System.Data.SQLite, вы можете начать транзакцию, а затем сразу же откатить ее следующим образом: -

    private bool DatabaseIsValid(string filename)
    {
        using (SQLiteConnection db = new SQLiteConnection(@"Data Source=" + filename + ";FailIfMissing=True;"))
        {
            try
            {
                db.Open();
                using (var transaction = db.BeginTransaction())
                {
                    transaction.Rollback();
                }
            }
            catch (Exception ex)
            {
                log.Debug(ex.Message, ex);
                return false;
            }
        }
        return true;
    }

Если файл не является действительной базой данныхвыдается следующее SQLiteException - файл зашифрован или не является базой данных (System.Data.SQLite.SQLiteErrorCode.NotADb).Если вы не используете зашифрованные базы данных, этого решения должно быть достаточно.(Для версии 1.0.81.0 System.Data.SQLite требовался только db.Open (), но когда я обновился до версии 1.0.91.0, мне пришлось вставить внутренний блок using, чтобы заставить его работать).

2 голосов
/ 08 октября 2010

Я думаю, что прагматическая проверка целостности могла бы сделать это.

...