Как определить, действителен ли файл базы данных sqlite или нет.

В приведенном ниже коде 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
}

Ответ 1

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

Лучшим может быть pragma schema_version;.

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

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

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

Ответ 2

Для всех, кто должен это сделать на С# с помощью 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, мне пришлось вставить внутренний блок использования, чтобы заставить его работать).

Ответ 3

Я думаю, что pragma integrity_check может это сделать.