mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-18 17:10:05 +02:00
AUP3: Adds connection configuration and ...
Optimizes a couple of sample block copy loops by only preparing the statement once outside the loop. The connection configuration ensure that all connections use the same settings...assuming you remember to configure it after opening. :-) The possibly controversial setting is the "PRAGMA synchronous = off"
This commit is contained in:
parent
e2f9090723
commit
6ffced4881
@ -54,9 +54,9 @@ static const char *ProjectFileSchema =
|
|||||||
//
|
//
|
||||||
// See the CMakeList.txt for the SQLite lib for more
|
// See the CMakeList.txt for the SQLite lib for more
|
||||||
// settings.
|
// settings.
|
||||||
"PRAGMA <dbname>.application_id = %d;"
|
"PRAGMA <schema>.application_id = %d;"
|
||||||
"PRAGMA <dbname>.user_version = %d;"
|
"PRAGMA <schema>.user_version = %d;"
|
||||||
"PRAGMA <dbname>.journal_mode = WAL;"
|
"PRAGMA <schema>.journal_mode = WAL;"
|
||||||
""
|
""
|
||||||
// project is a binary representation of an XML file.
|
// project is a binary representation of an XML file.
|
||||||
// it's in binary for speed.
|
// it's in binary for speed.
|
||||||
@ -70,7 +70,7 @@ static const char *ProjectFileSchema =
|
|||||||
// There is no limit to document blob size.
|
// There is no limit to document blob size.
|
||||||
// dict will be smallish, with an entry for each
|
// dict will be smallish, with an entry for each
|
||||||
// kind of field.
|
// kind of field.
|
||||||
"CREATE TABLE IF NOT EXISTS <dbname>.project"
|
"CREATE TABLE IF NOT EXISTS <schema>.project"
|
||||||
"("
|
"("
|
||||||
" id INTEGER PRIMARY KEY,"
|
" id INTEGER PRIMARY KEY,"
|
||||||
" dict BLOB,"
|
" dict BLOB,"
|
||||||
@ -90,7 +90,7 @@ static const char *ProjectFileSchema =
|
|||||||
// There is no limit to document blob size.
|
// There is no limit to document blob size.
|
||||||
// dict will be smallish, with an entry for each
|
// dict will be smallish, with an entry for each
|
||||||
// kind of field.
|
// kind of field.
|
||||||
"CREATE TABLE IF NOT EXISTS <dbname>.autosave"
|
"CREATE TABLE IF NOT EXISTS <schema>.autosave"
|
||||||
"("
|
"("
|
||||||
" id INTEGER PRIMARY KEY,"
|
" id INTEGER PRIMARY KEY,"
|
||||||
" dict BLOB,"
|
" dict BLOB,"
|
||||||
@ -99,7 +99,7 @@ static const char *ProjectFileSchema =
|
|||||||
""
|
""
|
||||||
// CREATE SQL tags
|
// CREATE SQL tags
|
||||||
// tags is not used (yet)
|
// tags is not used (yet)
|
||||||
"CREATE TABLE IF NOT EXISTS <dbname>.tags"
|
"CREATE TABLE IF NOT EXISTS <schema>.tags"
|
||||||
"("
|
"("
|
||||||
" name TEXT,"
|
" name TEXT,"
|
||||||
" value BLOB"
|
" value BLOB"
|
||||||
@ -116,7 +116,7 @@ static const char *ProjectFileSchema =
|
|||||||
// blockID is a 64 bit number.
|
// blockID is a 64 bit number.
|
||||||
//
|
//
|
||||||
// summin to summary64K are summaries at 3 distance scales.
|
// summin to summary64K are summaries at 3 distance scales.
|
||||||
"CREATE TABLE IF NOT EXISTS <dbname>.sampleblocks"
|
"CREATE TABLE IF NOT EXISTS <schema>.sampleblocks"
|
||||||
"("
|
"("
|
||||||
" blockid INTEGER PRIMARY KEY AUTOINCREMENT,"
|
" blockid INTEGER PRIMARY KEY AUTOINCREMENT,"
|
||||||
" sampleformat INTEGER,"
|
" sampleformat INTEGER,"
|
||||||
@ -128,6 +128,12 @@ static const char *ProjectFileSchema =
|
|||||||
" samples BLOB"
|
" samples BLOB"
|
||||||
");";
|
");";
|
||||||
|
|
||||||
|
// Settings applied to each database connection
|
||||||
|
static const char *ConnectionConfiguration =
|
||||||
|
"PRAGMA <schema>.synchronous = OFF;"
|
||||||
|
"PRAGMA <schema>.locking_mode = EXCLUSIVE;"
|
||||||
|
"PRAGMA <schema>.wal_autocheckpoint = 1000;";
|
||||||
|
|
||||||
// This singleton handles initialization/shutdown of the SQLite library.
|
// This singleton handles initialization/shutdown of the SQLite library.
|
||||||
// It is needed because our local SQLite is built with SQLITE_OMIT_AUTOINIT
|
// It is needed because our local SQLite is built with SQLITE_OMIT_AUTOINIT
|
||||||
// defined.
|
// defined.
|
||||||
@ -145,7 +151,7 @@ public:
|
|||||||
if (mRc == SQLITE_OK)
|
if (mRc == SQLITE_OK)
|
||||||
{
|
{
|
||||||
// Use the "unix-excl" VFS to make access to the DB exclusive. This gets
|
// Use the "unix-excl" VFS to make access to the DB exclusive. This gets
|
||||||
// rid of the "<dbname>-shm" shared memory file.
|
// rid of the "<database name>-shm" shared memory file.
|
||||||
//
|
//
|
||||||
// Though it shouldn't, it doesn't matter if this fails.
|
// Though it shouldn't, it doesn't matter if this fails.
|
||||||
auto vfs = sqlite3_vfs_find("unix-excl");
|
auto vfs = sqlite3_vfs_find("unix-excl");
|
||||||
@ -352,6 +358,31 @@ void ProjectFileIO::UseConnection( sqlite3 *db, const FilePath &filePath )
|
|||||||
SetFileName( filePath );
|
SetFileName( filePath );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectFileIO::ConfigConnection(sqlite3 *db, const wxString &schema)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
wxString sql = ConnectionConfiguration;
|
||||||
|
|
||||||
|
if (schema.empty())
|
||||||
|
{
|
||||||
|
sql.Replace(wxT("<schema>."), wxT(""));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sql.Replace(wxT("<schema>"), schema);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sqlite3_exec(db, sql, nullptr, nullptr, nullptr);
|
||||||
|
if (rc != SQLITE_OK)
|
||||||
|
{
|
||||||
|
// This non-fatal...for now
|
||||||
|
SetDBError(XO("Failed to set connection configuration"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sqlite3 *ProjectFileIO::OpenDB(FilePath fileName)
|
sqlite3 *ProjectFileIO::OpenDB(FilePath fileName)
|
||||||
{
|
{
|
||||||
wxASSERT(mDB == nullptr);
|
wxASSERT(mDB == nullptr);
|
||||||
@ -381,6 +412,9 @@ sqlite3 *ProjectFileIO::OpenDB(FilePath fileName)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure attached DB connection gets configured
|
||||||
|
ConfigConnection(mDB);
|
||||||
|
|
||||||
if (!CheckVersion())
|
if (!CheckVersion())
|
||||||
{
|
{
|
||||||
CloseDB();
|
CloseDB();
|
||||||
@ -674,13 +708,13 @@ bool ProjectFileIO::CheckVersion()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProjectFileIO::InstallSchema(sqlite3 *db, const char *dbname /* = "main" */)
|
bool ProjectFileIO::InstallSchema(sqlite3 *db, const char *schema /* = "main" */)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
wxString sql;
|
wxString sql;
|
||||||
sql.Printf(ProjectFileSchema, ProjectFileID, ProjectFileVersion);
|
sql.Printf(ProjectFileSchema, ProjectFileID, ProjectFileVersion);
|
||||||
sql.Replace("<dbname>", dbname);
|
sql.Replace("<schema>", schema);
|
||||||
|
|
||||||
rc = sqlite3_exec(db, sql.mb_str().data(), nullptr, nullptr, nullptr);
|
rc = sqlite3_exec(db, sql.mb_str().data(), nullptr, nullptr, nullptr);
|
||||||
if (rc != SQLITE_OK)
|
if (rc != SQLITE_OK)
|
||||||
@ -751,13 +785,6 @@ bool ProjectFileIO::CheckForOrphans(BlockIDs &blockids)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
|
||||||
void ProjectFileIO::UpdateCallback(void *data, int operation, char const *dbname, char const *table, long long rowid)
|
|
||||||
{
|
|
||||||
UpdateCB cb = *static_cast<UpdateCB *>(data);
|
|
||||||
cb(operation, dbname, table, rowid);
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3 *ProjectFileIO::CopyTo(const FilePath &destpath,
|
sqlite3 *ProjectFileIO::CopyTo(const FilePath &destpath,
|
||||||
const TranslatableString &msg,
|
const TranslatableString &msg,
|
||||||
bool prune /* = false */)
|
bool prune /* = false */)
|
||||||
@ -816,20 +843,19 @@ sqlite3 *ProjectFileIO::CopyTo(const FilePath &destpath,
|
|||||||
// Cleanup in case things go awry
|
// Cleanup in case things go awry
|
||||||
auto cleanup = finally([&]
|
auto cleanup = finally([&]
|
||||||
{
|
{
|
||||||
// Detach the destination database, whether it was successfully attached or not
|
|
||||||
sqlite3_exec(db, "DETACH DATABASE dest;", nullptr, nullptr, nullptr);
|
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
sqlite3_close(destdb);
|
sqlite3_close(destdb);
|
||||||
|
|
||||||
|
sqlite3_exec(db, "DETACH DATABASE outbound;", nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
wxRemoveFile(destpath);
|
wxRemoveFile(destpath);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Attach the destination database
|
// Attach the destination database
|
||||||
wxString sql;
|
wxString sql;
|
||||||
sql.Printf("ATTACH DATABASE '%s' AS dest;", destpath);
|
sql.Printf("ATTACH DATABASE '%s' AS outbound;", destpath);
|
||||||
|
|
||||||
rc = sqlite3_exec(db, sql.mb_str().data(), nullptr, nullptr, nullptr);
|
rc = sqlite3_exec(db, sql.mb_str().data(), nullptr, nullptr, nullptr);
|
||||||
if (rc != SQLITE_OK)
|
if (rc != SQLITE_OK)
|
||||||
@ -840,15 +866,18 @@ sqlite3 *ProjectFileIO::CopyTo(const FilePath &destpath,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure attached DB connection gets configured
|
||||||
|
ConfigConnection(db, "outbound");
|
||||||
|
|
||||||
// Install our schema into the new database
|
// Install our schema into the new database
|
||||||
if (!InstallSchema(db, "dest"))
|
if (!InstallSchema(db, "outbound"))
|
||||||
{
|
{
|
||||||
// Message already set
|
// Message already set
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = sqlite3_exec(db,
|
rc = sqlite3_exec(db,
|
||||||
"INSERT INTO dest.tags SELECT * FROM main.tags;",
|
"INSERT INTO outbound.tags SELECT * FROM main.tags;",
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr);
|
nullptr);
|
||||||
@ -862,6 +891,30 @@ sqlite3 *ProjectFileIO::CopyTo(const FilePath &destpath,
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
// Ensure statement gets cleaned up
|
||||||
|
sqlite3_stmt *stmt = nullptr;
|
||||||
|
auto cleanup = finally([&]
|
||||||
|
{
|
||||||
|
if (stmt)
|
||||||
|
{
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Prepare the statement only once
|
||||||
|
rc = sqlite3_prepare_v2(db,
|
||||||
|
"INSERT INTO outbound.sampleblocks"
|
||||||
|
" SELECT * FROM main.sampleblocks"
|
||||||
|
" WHERE blockid = ?;",
|
||||||
|
-1, &stmt, 0);
|
||||||
|
if (rc != SQLITE_OK)
|
||||||
|
{
|
||||||
|
SetDBError(
|
||||||
|
XO("Unable to prepare project file command:\n\n%s").Format(sql)
|
||||||
|
);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/* i18n-hint: This title appears on a dialog that indicates the progress
|
/* i18n-hint: This title appears on a dialog that indicates the progress
|
||||||
in doing something.*/
|
in doing something.*/
|
||||||
ProgressDialog progress(XO("Progress"), msg, pdlgHideStopButton);
|
ProgressDialog progress(XO("Progress"), msg, pdlgHideStopButton);
|
||||||
@ -872,32 +925,28 @@ sqlite3 *ProjectFileIO::CopyTo(const FilePath &destpath,
|
|||||||
|
|
||||||
for (auto blockid : blockids)
|
for (auto blockid : blockids)
|
||||||
{
|
{
|
||||||
wxString sql;
|
// BIND blockid parameter
|
||||||
sql.Printf("INSERT INTO dest.sampleblocks"
|
if (sqlite3_bind_int64(stmt, 1, blockid) != SQLITE_OK)
|
||||||
" SELECT * FROM main.sampleblocks"
|
{
|
||||||
" WHERE blockid = %lld",
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
blockid);
|
}
|
||||||
|
|
||||||
rc = sqlite3_exec(db, sql.mb_str().data(), nullptr, nullptr, nullptr);
|
// Process it
|
||||||
if (rc != SQLITE_OK)
|
rc = sqlite3_step(stmt);
|
||||||
|
if (rc != SQLITE_DONE)
|
||||||
{
|
{
|
||||||
SetDBError(
|
SetDBError(
|
||||||
XO("Failed to copy project file")
|
XO("Failed to update the project file.\nThe following command failed:\n\n%s").Format(sql)
|
||||||
);
|
);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
rc = sqlite3_wal_checkpoint_v2(db, "dest", SQLITE_CHECKPOINT_FULL, nullptr, nullptr);
|
// BIND blockid parameter
|
||||||
if (rc != SQLITE_OK)
|
if (sqlite3_reset(stmt) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
SetDBError(
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
XO("Failed to copy project file")
|
|
||||||
);
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
result = progress.Update(++count, total);
|
result = progress.Update(++count, total);
|
||||||
if (result != ProgressResult::Success)
|
if (result != ProgressResult::Success)
|
||||||
{
|
{
|
||||||
@ -909,7 +958,7 @@ sqlite3 *ProjectFileIO::CopyTo(const FilePath &destpath,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copy failed
|
// Copy failed
|
||||||
if (rc != SQLITE_OK)
|
if (rc != SQLITE_DONE)
|
||||||
{
|
{
|
||||||
SetDBError(
|
SetDBError(
|
||||||
XO("Failed to copy project file")
|
XO("Failed to copy project file")
|
||||||
@ -918,6 +967,9 @@ sqlite3 *ProjectFileIO::CopyTo(const FilePath &destpath,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Detach the destination database
|
||||||
|
sqlite3_exec(db, "DETACH DATABASE outbound;", nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
// Open the newly created database
|
// Open the newly created database
|
||||||
rc = sqlite3_open(destpath, &destdb);
|
rc = sqlite3_open(destpath, &destdb);
|
||||||
if (rc != SQLITE_OK)
|
if (rc != SQLITE_OK)
|
||||||
@ -929,6 +981,9 @@ sqlite3 *ProjectFileIO::CopyTo(const FilePath &destpath,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure connection gets configured
|
||||||
|
ConfigConnection(destdb);
|
||||||
|
|
||||||
// Tell cleanup everything is good to go
|
// Tell cleanup everything is good to go
|
||||||
success = true;
|
success = true;
|
||||||
|
|
||||||
@ -1038,6 +1093,9 @@ bool ProjectFileIO::Vacuum()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure connection gets configured
|
||||||
|
ConfigConnection(mDB);
|
||||||
|
|
||||||
// Copy the original database to a new database while pruning unused sample blocks
|
// Copy the original database to a new database while pruning unused sample blocks
|
||||||
auto newDB = CopyTo(origName, XO("Compacting project"), true);
|
auto newDB = CopyTo(origName, XO("Compacting project"), true);
|
||||||
|
|
||||||
@ -1495,7 +1553,7 @@ bool ProjectFileIO::ImportProject(const FilePath &fileName)
|
|||||||
{
|
{
|
||||||
if (indb)
|
if (indb)
|
||||||
{
|
{
|
||||||
sqlite3_close(indb);
|
DiscardConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
RestoreConnection();
|
RestoreConnection();
|
||||||
@ -1514,6 +1572,9 @@ bool ProjectFileIO::ImportProject(const FilePath &fileName)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure connection gets configured
|
||||||
|
ConfigConnection(indb);
|
||||||
|
|
||||||
// The inbound project file becomes the active project file
|
// The inbound project file becomes the active project file
|
||||||
UseConnection(indb, fileName);
|
UseConnection(indb, fileName);
|
||||||
|
|
||||||
@ -1635,11 +1696,18 @@ bool ProjectFileIO::ImportProject(const FilePath &fileName)
|
|||||||
// Get access to the current project file
|
// Get access to the current project file
|
||||||
auto db = DB();
|
auto db = DB();
|
||||||
|
|
||||||
// Make sure the inbound project file gets detached
|
// Cleanup...
|
||||||
|
sqlite3_stmt *stmt = nullptr;
|
||||||
auto cleanup = finally([&]
|
auto cleanup = finally([&]
|
||||||
{
|
{
|
||||||
|
// Ensure the prepared statement gets cleaned up
|
||||||
|
if (stmt)
|
||||||
|
{
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
// Detach the inbound project file, whether it was successfully attached or not
|
// Detach the inbound project file, whether it was successfully attached or not
|
||||||
sqlite3_exec(db, "DETACH DATABASE dest;", nullptr, nullptr, nullptr);
|
sqlite3_exec(db, "DETACH DATABASE inbound;", nullptr, nullptr, nullptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Attach the inbound project file
|
// Attach the inbound project file
|
||||||
@ -1656,9 +1724,31 @@ bool ProjectFileIO::ImportProject(const FilePath &fileName)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure attached DB connection gets configured
|
||||||
|
ConfigConnection(db, "inbound");
|
||||||
|
|
||||||
|
// Prepare the statement to copy the sample block from the inbound project to the
|
||||||
|
// active project. All columns other than the blockid column gets copied.
|
||||||
|
wxString columns(wxT("sampleformat, summin, summax, sumrms, summary256, summary64k, samples"));
|
||||||
|
sql.Printf("INSERT INTO main.sampleblocks (%s)"
|
||||||
|
" SELECT %s"
|
||||||
|
" FROM inbound.sampleblocks"
|
||||||
|
" WHERE blockid = ?;",
|
||||||
|
columns,
|
||||||
|
columns);
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
|
||||||
|
if (rc != SQLITE_OK)
|
||||||
|
{
|
||||||
|
SetDBError(
|
||||||
|
XO("Unable to prepare project file command:\n\n%s").Format(sql)
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* i18n-hint: This title appears on a dialog that indicates the progress
|
/* i18n-hint: This title appears on a dialog that indicates the progress
|
||||||
in doing something.*/
|
in doing something.*/
|
||||||
ProgressDialog progress(XO("Progress"), XO("Importing project"));
|
ProgressDialog progress(XO("Progress"), XO("Importing project"), pdlgHideStopButton);
|
||||||
ProgressResult result = ProgressResult::Success;
|
ProgressResult result = ProgressResult::Success;
|
||||||
|
|
||||||
wxLongLong_t count = 0;
|
wxLongLong_t count = 0;
|
||||||
@ -1705,32 +1795,31 @@ bool ProjectFileIO::ImportProject(const FilePath &fileName)
|
|||||||
SampleBlockID blockid;
|
SampleBlockID blockid;
|
||||||
attr->GetValue().ToLongLong(&blockid);
|
attr->GetValue().ToLongLong(&blockid);
|
||||||
|
|
||||||
// Copy the sample block from the inbound project to the active project.
|
// BIND blockid parameter
|
||||||
// All columns other than the blockid column gets copied.
|
if (sqlite3_bind_int64(stmt, 1, blockid) != SQLITE_OK)
|
||||||
wxString columns(wxT("sampleformat, summin, summax, sumrms, summary256, summary64k, samples"));
|
{
|
||||||
wxString sql;
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
sql.Printf("INSERT INTO main.sampleblocks (%s)"
|
}
|
||||||
" SELECT %s"
|
|
||||||
" FROM inbound.sampleblocks"
|
// Process it
|
||||||
" WHERE blockid = %lld",
|
rc = sqlite3_step(stmt);
|
||||||
columns,
|
if (rc != SQLITE_DONE)
|
||||||
columns,
|
|
||||||
blockid);
|
|
||||||
rc = sqlite3_exec(db, sql.mb_str().data(), nullptr, nullptr, nullptr);
|
|
||||||
if (rc != SQLITE_OK)
|
|
||||||
{
|
{
|
||||||
SetDBError(
|
SetDBError(
|
||||||
XO("Failed to import sample block")
|
XO("Failed to import sample block.\nThe following command failed:\n\n%s").Format(sql)
|
||||||
);
|
);
|
||||||
|
return false;
|
||||||
result = ProgressResult::Failed;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace the original blockid with the new one
|
// Replace the original blockid with the new one
|
||||||
attr->SetValue(wxString::Format(wxT("%lld"), sqlite3_last_insert_rowid(db)));
|
attr->SetValue(wxString::Format(wxT("%lld"), sqlite3_last_insert_rowid(db)));
|
||||||
|
|
||||||
|
// BIND blockid parameter
|
||||||
|
if (sqlite3_reset(stmt) != SQLITE_OK)
|
||||||
|
{
|
||||||
|
THROW_INCONSISTENCY_EXCEPTION;
|
||||||
|
}
|
||||||
|
|
||||||
// Remember that we copied this node in case the user cancels
|
// Remember that we copied this node in case the user cancels
|
||||||
result = progress.Update(++count, total);
|
result = progress.Update(++count, total);
|
||||||
if (result != ProgressResult::Success)
|
if (result != ProgressResult::Success)
|
||||||
|
@ -138,7 +138,10 @@ private:
|
|||||||
void RestoreConnection();
|
void RestoreConnection();
|
||||||
|
|
||||||
// Use a connection that is already open rather than invoke OpenDB
|
// Use a connection that is already open rather than invoke OpenDB
|
||||||
void UseConnection( sqlite3 *db, const FilePath &filePath );
|
void UseConnection(sqlite3 *db, const FilePath &filePath);
|
||||||
|
|
||||||
|
// Make sure the connection/schema combo is configured the way we want
|
||||||
|
void ConfigConnection(sqlite3 *db, const wxString &schema = wxT("main"));
|
||||||
|
|
||||||
sqlite3 *OpenDB(FilePath fileName = {});
|
sqlite3 *OpenDB(FilePath fileName = {});
|
||||||
bool CloseDB();
|
bool CloseDB();
|
||||||
@ -153,7 +156,7 @@ private:
|
|||||||
bool GetBlob(const char *sql, wxMemoryBuffer &buffer);
|
bool GetBlob(const char *sql, wxMemoryBuffer &buffer);
|
||||||
|
|
||||||
bool CheckVersion();
|
bool CheckVersion();
|
||||||
bool InstallSchema(sqlite3 *db, const char *dbname = "main");
|
bool InstallSchema(sqlite3 *db, const char *schema = "main");
|
||||||
bool UpgradeSchema();
|
bool UpgradeSchema();
|
||||||
|
|
||||||
// Write project or autosave XML (binary) documents
|
// Write project or autosave XML (binary) documents
|
||||||
@ -174,9 +177,6 @@ private:
|
|||||||
void SetError(const TranslatableString & msg);
|
void SetError(const TranslatableString & msg);
|
||||||
void SetDBError(const TranslatableString & msg);
|
void SetDBError(const TranslatableString & msg);
|
||||||
|
|
||||||
using UpdateCB = std::function<void(int operation, char const *dbname, char const *table, long long rowid)>;
|
|
||||||
static void UpdateCallback(void *data, int operation, char const *dbname, char const *table, long long rowid);
|
|
||||||
|
|
||||||
unsigned long long CalculateUsage();
|
unsigned long long CalculateUsage();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user