Как определить, действителен ли файл базы данных 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 может это сделать.