miraks
21st April 2010, 21:21
Hi,
My application is working with a document file implemented in a sqlite database.
So, the function "Open" is copying a file base sqlite database in memory (This is very fast).
The function "Save" is copying a memory database into a file (This is very slow due to file access).
For you information, here is the code to do this copy:
SKGError SKGServices::copySqliteDatabase(QSqlDatabase* iFileDb, QSqlDatabase* iMemoryDb, bool iFromFileToMemory)
{
SKGError err;
SKGTRACEINRC(10, "SKGServices::copySqliteDatabase", err);
if (iFileDb && iMemoryDb) {
SKGTRACEL(20) << "Input parameter [iFileDb]=[" << iFileDb->databaseName() << ']' << endl;
SKGTRACEL(20) << "Input parameter [iMemoryDb]=[" << iMemoryDb->databaseName() << ']' << endl;
SKGTRACEL(10) << "Input parameter [iFromFileToMemory]=[" << (iFromFileToMemory ? "FILE->MEMORY" : "MEMORY->FILE") << ']' << endl;
QString dbFileName=iFileDb->databaseName();
// Copy the schema
SKGTRACEL(20) << "Coping the schema..." << endl;
SKGStringListList listSqlOrder;
err=SKGServices::executeSelectSqliteOrder((iFromFi leToMemory ? iFileDb: iMemoryDb),
"SELECT sql FROM sqlite_master WHERE sql NOT NULL and name NOT IN ('sqlite_stat1', 'sqlite_sequence')",
listSqlOrder);
int nb=listSqlOrder.count();
for (int i=1; err.isSucceeded() && i<nb; ++i) { //Forget header
QString val=listSqlOrder.at(i).at(0);
err=SKGServices::executeSqliteOrder((iFromFileToMe mory ? iMemoryDb: iFileDb), val);
}
// Attach the file dbFileName to the target
if (err.isSucceeded()) {
SKGTRACEL(20) << "Attaching the file..." << endl;
err = SKGServices::executeSqliteOrder(iMemoryDb, "ATTACH DATABASE '" + dbFileName + "' as source");
if (err.isSucceeded()) {
// Copy the DATA from the source to the target
SKGTRACEL(20) << "Coping data..." << endl;
err = SKGServices::executeSqliteOrder(iMemoryDb, "BEGIN");
if (err.isSucceeded()) {
SKGStringListList listSqlOrder;
err=SKGServices::executeSelectSqliteOrder(iMemoryD b,
"SELECT name FROM source.sqlite_master WHERE type='table' and name NOT IN ('sqlite_stat1', 'sqlite_sequence')",
listSqlOrder);
int nb=listSqlOrder.count();
for (int i=1; err.isSucceeded() && i<nb; ++i) { //Forget header
QString val=listSqlOrder.at(i).at(0);
if (iFromFileToMemory) err=SKGServices::executeSqliteOrder(iMemoryDb, "insert into main."+val+" select * from source."+val);
else err=SKGServices::executeSqliteOrder(iMemoryDb, "insert into source."+val+" select * from main."+val);
}
}
if (err.isSucceeded()) err = SKGServices::executeSqliteOrder(iMemoryDb, "COMMIT");
//Detach
SKGError err2=SKGServices::executeSqliteOrder(iMemoryDb, "DETACH DATABASE source");
if (err.isSucceeded() && err2.isFailed()) err=err2;
//Check if created file exists
if (err.isSucceeded() && !iFromFileToMemory && !QFile(dbFileName).exists()) {
//Set error message
err.setReturnCode(ERR_FAIL);
err.setMessage(i18nc("An error message", "Creation file [%1] failed",dbFileName));
}
}
}
if (err.isFailed()) err.addError(SQLLITEERROR + ERR_FAIL, i18nc("Error message", "%1 failed", QString("copySqliteDatabase::copySqliteDatabase()")));
}
return err;
}
I saw in this page http://www.sqlite.org/backup.html that new APIs are existing to do that.
Do you know how we can use it with QT ?
My application is working with a document file implemented in a sqlite database.
So, the function "Open" is copying a file base sqlite database in memory (This is very fast).
The function "Save" is copying a memory database into a file (This is very slow due to file access).
For you information, here is the code to do this copy:
SKGError SKGServices::copySqliteDatabase(QSqlDatabase* iFileDb, QSqlDatabase* iMemoryDb, bool iFromFileToMemory)
{
SKGError err;
SKGTRACEINRC(10, "SKGServices::copySqliteDatabase", err);
if (iFileDb && iMemoryDb) {
SKGTRACEL(20) << "Input parameter [iFileDb]=[" << iFileDb->databaseName() << ']' << endl;
SKGTRACEL(20) << "Input parameter [iMemoryDb]=[" << iMemoryDb->databaseName() << ']' << endl;
SKGTRACEL(10) << "Input parameter [iFromFileToMemory]=[" << (iFromFileToMemory ? "FILE->MEMORY" : "MEMORY->FILE") << ']' << endl;
QString dbFileName=iFileDb->databaseName();
// Copy the schema
SKGTRACEL(20) << "Coping the schema..." << endl;
SKGStringListList listSqlOrder;
err=SKGServices::executeSelectSqliteOrder((iFromFi leToMemory ? iFileDb: iMemoryDb),
"SELECT sql FROM sqlite_master WHERE sql NOT NULL and name NOT IN ('sqlite_stat1', 'sqlite_sequence')",
listSqlOrder);
int nb=listSqlOrder.count();
for (int i=1; err.isSucceeded() && i<nb; ++i) { //Forget header
QString val=listSqlOrder.at(i).at(0);
err=SKGServices::executeSqliteOrder((iFromFileToMe mory ? iMemoryDb: iFileDb), val);
}
// Attach the file dbFileName to the target
if (err.isSucceeded()) {
SKGTRACEL(20) << "Attaching the file..." << endl;
err = SKGServices::executeSqliteOrder(iMemoryDb, "ATTACH DATABASE '" + dbFileName + "' as source");
if (err.isSucceeded()) {
// Copy the DATA from the source to the target
SKGTRACEL(20) << "Coping data..." << endl;
err = SKGServices::executeSqliteOrder(iMemoryDb, "BEGIN");
if (err.isSucceeded()) {
SKGStringListList listSqlOrder;
err=SKGServices::executeSelectSqliteOrder(iMemoryD b,
"SELECT name FROM source.sqlite_master WHERE type='table' and name NOT IN ('sqlite_stat1', 'sqlite_sequence')",
listSqlOrder);
int nb=listSqlOrder.count();
for (int i=1; err.isSucceeded() && i<nb; ++i) { //Forget header
QString val=listSqlOrder.at(i).at(0);
if (iFromFileToMemory) err=SKGServices::executeSqliteOrder(iMemoryDb, "insert into main."+val+" select * from source."+val);
else err=SKGServices::executeSqliteOrder(iMemoryDb, "insert into source."+val+" select * from main."+val);
}
}
if (err.isSucceeded()) err = SKGServices::executeSqliteOrder(iMemoryDb, "COMMIT");
//Detach
SKGError err2=SKGServices::executeSqliteOrder(iMemoryDb, "DETACH DATABASE source");
if (err.isSucceeded() && err2.isFailed()) err=err2;
//Check if created file exists
if (err.isSucceeded() && !iFromFileToMemory && !QFile(dbFileName).exists()) {
//Set error message
err.setReturnCode(ERR_FAIL);
err.setMessage(i18nc("An error message", "Creation file [%1] failed",dbFileName));
}
}
}
if (err.isFailed()) err.addError(SQLLITEERROR + ERR_FAIL, i18nc("Error message", "%1 failed", QString("copySqliteDatabase::copySqliteDatabase()")));
}
return err;
}
I saw in this page http://www.sqlite.org/backup.html that new APIs are existing to do that.
Do you know how we can use it with QT ?