Блокировка файлов SQLite и DropBox - PullRequest
5 голосов
/ 12 марта 2010

Я разрабатываю приложение на Visual C ++, которое использует БД SQLite3 для хранения данных. Обычно он сидит в лотке большую часть времени.

Я также хотел бы включить мое приложение в папку DropBox, чтобы делиться им с несколькими компьютерами. Это работало очень хорошо до тех пор, пока DropBox не обновился. И теперь он говорит, что «не может синхронизировать используемый файл». Файл SQLite открыт в моем приложении, но блокировка является общей. Есть некоторые подготовленные операторы, но все сбрасываются сразу после использования step.

Есть ли способ включить синхронизацию открытого файла базы данных SQLite? Спасибо!

Вот простая оболочка, которую я использую только для тестирования (без обработки ошибок), на случай, если это поможет:

 class Statement
 {
 private:
  Statement(sqlite3* db, const std::wstring& sql) : db(db)
  {
   sqlite3_prepare16_v2(db, sql.c_str(), sql.length() * sizeof(wchar_t), &stmt, NULL);
  }

 public:
  ~Statement() { sqlite3_finalize(stmt); }

 public:
  void reset() { sqlite3_reset(stmt); }
  int step() { return sqlite3_step(stmt); }
  int getInt(int i) const { return sqlite3_column_int(stmt, i); }

  std::wstring getText(int i) const
  {
   const wchar_t* v = (const wchar_t*)sqlite3_column_text16(stmt, i);
   int sz = sqlite3_column_bytes16(stmt, i) / sizeof(wchar_t);
   return std::wstring(v, v + sz);
  }

 private:
  friend class Database;

  sqlite3* db;
  sqlite3_stmt* stmt;
 };


 class Database
 {
 public:
  Database(const std::wstring& filename = L"")) : db(NULL)
  {
   sqlite3_open16(filename.c_str(), &db);
  }

  ~Database() { sqlite3_close(db); } 

  void exec(const std::wstring& sql)
  {
   auto_ptr<Statement> st(prepare(sql));
   st->step();   
  }

  auto_ptr<Statement> prepare(const std::wstring& sql) const
  {
   return auto_ptr<Statement>(new Statement(db, sql));
  }

 private:
  sqlite3* db;
 };

UPD: Попытка закомментировать все вызовы LockFile и LockFileEx в sqlite3.c - тот же результат.

UPD2: Попытка вызова sqlite3_close в режиме ожидания (как подтверждение концепции) - все тот же результат! Filemon сообщает, что файл все еще не закрыт, только разблокирован.

UPD3: Включен режим автоматической фиксации. Номера BEGIN и COMMIT совпадают (класс Transaction и RAII позаботятся об этом). SQliteManager может подключаться к БД во время работы моего приложения и вносить в него изменения.

Ответы [ 3 ]

4 голосов
/ 18 марта 2010

Проверка результата из sqlite3_close (). Возможно, это не работает, потому что вы не завершили все свои подготовленные заявления.

2 голосов
/ 15 марта 2010

У Алекса Печникова есть многопользовательская программа репликации базы данных SQLite sqlite3-rdiff .Это, вероятно, излишне для того, что вы пытаетесь выполнить, но это может быть проще, чем репликация файлов.

SQLite также имеет Online Backup API ;на этой странице есть пример: Пример 2. Резервное копирование работающей базы данных в режиме онлайн.

2 голосов
/ 14 марта 2010

Какую файловую систему вы используете?

Вы уверены, что автокоммит включен и / или вы делаете свои заявления? Я помню, что у меня были проблемы с фиксацией, и блокировка осталась.

...