Je développe une application dans Visual C++ qui utilise une base de données SQLite3 pour stocker des données. Habituellement, il se trouve dans le bac la plupart du temps.Verrouillage de fichiers SQLite et DropBox
Je voudrais également activer l'application de mon application dans un dossier DropBox pour la partager sur plusieurs ordinateurs. Cela a très bien fonctionné jusqu'à ce que DropBox se soit récemment mis à jour. Et maintenant, il dit qu'il "ne peut pas synchroniser le fichier en cours d'utilisation". Le fichier SQLite est ouvert dans mon application, mais le verrou est partagé. Il existe des instructions préparées, mais toutes sont réinitialisées immédiatement après l'utilisation de step
.
Est-il possible d'activer la synchronisation d'un fichier de base de données SQLite ouvert? Merci!
Voici l'emballage simple que je viens d'utiliser pour les tests (pas de gestion des erreurs), dans le cas où cette aide:
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: a essayé de commenter tous les appels à LockFile et LockFileEx à sqlite3.c - même résultat.
UPD2: Essayé d'appeler sqlite3_close au repos (comme preuve de concept) - toujours le même résultat! Filemon dit que le fichier n'est toujours pas fermé, seulement déverrouillé.
UPD3: Le mode Autocommit est activé. Les nombres de BEGINs et COMMITs correspondent (la classe Transaction et RAII s'en occupent). SQliteManager est capable de se connecter à la base de données pendant que mon application est en cours d'exécution et y apporter des modifications.
Vérifiez-vous le résultat de sqlite3_close()? Peut-être que cela ne fonctionne pas parce que vous n'avez pas finalisé toutes vos déclarations préparées. –
C'était ça! Cela ne fonctionnait pas à cause d'une sauvegarde en arrière-plan en cours d'exécution. Erreur muette .. Merci! Mettez-le comme une réponse et je vais l'accepter. –