2010-03-12 20 views
5

Visual C++ uygulamasında veri depolamak için bir SQLite3 DB kullanan bir uygulama geliştiriyorum. Genellikle çoğu zaman tepsiye oturur.SQLite dosya kilitleme ve DropBox

Ayrıca, uygulamanızı birkaç PC'den paylaşmak üzere bir DropBox klasörüne koyma özelliğini de etkinleştirmek istiyorum. DropBox kendini yeni güncellemeye başlayana kadar çok iyi çalıştı. Ve şimdi "dosyayı kullanımda senkronize edemiyor" diyor. Uygulamamda SQLite dosyası açık, ancak kilit paylaşılıyor. Bazı hazır ifadeler vardır, ancak hepsi step kullandıktan sonra hemen sıfırlanır.

Açık bir SQLite veritabanı dosyasının eşitlenmesini etkinleştirmenin bir yolu var mı? Teşekkürler! İşte

durumda bu yardımcı olur, sadece test (hayır hata işleme) için kullanmak basit bir sarıcı geçerli:

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: sqlite3.c içinde lockfile ve LockFileEx için tüm çağrıları dışında yorum, denedim - aynı sonuç.

UPD2: Boşta iken sqlite3_close'u çağırmayı denedi (tıpkı kavramın kanıtı olarak) - yine de aynı sonuç! Filemon, dosyanın hala kapalı olmadığını, sadece kilidin açıldığını söyler.

UPD3: Autocommit modu açık. BEGIN ve COMMIT'lerin sayıları eşleşir (İşlem ve RAII sınıfı bununla ilgilenir). Uygulamam çalışırken SQliteManager, DB'ye bağlanabiliyor ve değişiklik yapabiliyor.

+1

Sonuç sqlite3_close()? Belki de işe yaramıyor çünkü hazırlamış olduğunuz bütün ifadeleri bitirmediniz. –

+0

Bu o oldu! Çalışan bir arka plan yedekleme nedeniyle çalışmıyordu. Aptal hata .. Teşekkürler! Bir cevap olarak koyun ve kabul edeceğim. –

cevap

4

Sonuç sqlite3_close() 'dan kontrol ediliyor. Belki de işe yaramıyor çünkü hazırlamış olduğunuz bütün ifadeleri bitirmediniz.

2

Hangi dosya sistemini kullanıyorsunuz?

Otomatik denetimin açık olduğundan ve/veya beyanlarınızı yaptığınızdan emin misiniz? Taahhüt etmememle ilgili bir sorun olduğunu hatırlıyorum ve kilit devam edecek.

+0

NTFS. İşlem hakkında iyi bir fikir, teşekkürler, durumun böyle olup olmadığını kontrol edeceğim. –

+0

Otomatik kabul modu açık. BEGIN ve COMMIT'lerin sayıları eşleşir (İşlem ve RAII sınıfı bununla ilgilenir). Bunun nedeni değil gibi görünüyor. Uygulamam çalışırken SQliteManager, DB'ye bağlanabiliyor ve değişiklik yapabiliyor. –

2

Alex Pechnikov bir çoklu ana SQLite veritabanı çoğaltma programı sqlite3-rdiff sahiptir. Muhtemelen başarmaya çalıştığınız şey için çok fazladır, ancak dosya çoğaltmasından daha kolay olabilir. SQLite ayrıca bir Online Backup API;

SQLite; Bu sayfada bir örnek var: Örnek 2: Çalışan Veritabanının Çevrimiçi Yedeklemesi.

+0

Bunu otomatik olarak nasıl kullanabileceğimi düşünemiyorum. sqlite3-rdiff, Tcl gerektirir ve yedekleme API'sini kullanmak, her değişiklikten sonra tüm DB'nin bir kopyasını oluşturmak anlamına gelir. –

+0

DropBox, her değişiklikten sonra DB'nin bir kopyasını (veya bir rdiff'ini) oluşturmuyor mu? Eğer öyleyse, yerel bir kopya fazla mesai değildir. Değilse, sadece yerel kopyasını DropBox'ın ihtiyacı olduğu gibi yapın. –

İlgili konular