Bloqueio de arquivos sqlite e dropbox
Pergunta
Estou desenvolvendo um aplicativo no Visual C ++ que usa um sqlite3 dB para armazenar dados. Geralmente fica na bandeja na maioria das vezes.
Eu também gostaria de ativar colocar meu aplicativo em uma pasta Dropbox para compartilhá -lo em vários PCs. Funcionou muito bem até o Dropbox se atualizar recentemente. E agora diz que "não pode sincronizar o arquivo em uso". O arquivo SQLite está aberto no meu aplicativo, mas o bloqueio é compartilhado. Existem algumas declarações preparadas, mas todas são redefinidas imediatamente após o uso step
.
Existe alguma maneira de permitir a sincronização de um arquivo de banco de dados SQLite aberto? Obrigado!
Aqui está o invólucro simples que eu uso apenas para teste (sem tratamento de erros), caso isso ajude:
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;
};
Up: Tentei comentar todas as chamadas para LockFile e LockFileEx no SQLITE3.C - O mesmo resultado.
UPD2: Tentei ligar para o SQLITE3_CLOSE quando ocioso (exatamente como prova de conceito) - ainda o mesmo resultado! Filemon diz que o arquivo ainda não está fechado, apenas desbloqueado.
UPD3: O modo Autocomit está ativado. Os números de inicia e começos correspondem (transações de classe e Raii cuidam disso). O SQLitemanager é capaz de se conectar ao banco de dados enquanto meu aplicativo está em execução e faz modificações.
Solução
Verificando o resultado de sqlite3_close (). Talvez não esteja funcionando porque você não finalizou todas as suas declarações preparadas.
Outras dicas
Qual sistema de arquivos você está usando?
Tem certeza de que a AutoCommit está ligada e/ou que está cometendo suas declarações? Lembro -me de ter um problema em não cometer e a fechadura permaneceria.
Alex Pechnikov tem um programa de replicação de banco de dados SQLite com vários mestres SQLITE3-RDIFF. Provavelmente é um exagero pelo que você está tentando realizar, mas pode ser mais fácil do que a replicação do arquivo.
Sqlite também tem um API de backup online; Há um exemplo nessa página: Exemplo 2: Backup online de um banco de dados em execução.