mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 08:47:17 +01:00
Remove the SQLite methods that could be used to copy the database to and from memory because it they could crash easilly and didn't make much sense.
This commit is contained in:
parent
41f5cfe663
commit
9657905586
@ -164,86 +164,6 @@ Int32 Connection::GetInfo(Int32 operation, bool highwater, bool reset)
|
||||
return cur_value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Connection Connection::CopyToMemory()
|
||||
{
|
||||
// Validate the handle
|
||||
Validate();
|
||||
// Is the database already in memory?
|
||||
if (m_Handle->mMemory)
|
||||
STHROWF("The database is already in memory");
|
||||
// Destination database
|
||||
ConnHnd db(_SC(""));
|
||||
// Attempt to open the in-memory database
|
||||
db->Create(_SC(":memory:"), SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
|
||||
// Clear the temporary buffer
|
||||
GetTempBuff()[0] = 0;
|
||||
// Begin a transaction to replicate the schema of origin database
|
||||
if ((m_Handle = sqlite3_exec(m_Handle, "BEGIN", NULL, NULL, NULL)) != SQLITE_OK)
|
||||
STHROWF("Unable to begin schema replication [%s]", m_Handle.ErrMsg());
|
||||
// Attempt to replicate the schema of origin database to the in-memory one
|
||||
else if ((m_Handle = sqlite3_exec(m_Handle,
|
||||
"SELECT [sql] FROM [sqlite_master] WHERE [sql] NOT NULL AND [tbl_name] != 'sqlite_sequence'",
|
||||
&Connection::ProcessDDLRow, db->mPtr, NULL)) != SQLITE_OK)
|
||||
{
|
||||
// Did the error occurred from the DDL process function?
|
||||
if (GetTempBuff()[0] != 0)
|
||||
// Throw the resulted message but also include the point where it failed
|
||||
STHROWF("Unable to replicate schema [%s]", GetTempBuff());
|
||||
// Obtain the message from the connection handle if possible
|
||||
else
|
||||
STHROWF("Unable to replicate schema [%s]", m_Handle.ErrMsg());
|
||||
}
|
||||
// Attempt to commit the changes to the database schema replication
|
||||
else if ((m_Handle = sqlite3_exec(m_Handle, "COMMIT", NULL, NULL, NULL)) != SQLITE_OK)
|
||||
STHROWF("Unable to commit schema replication [%s]", m_Handle.ErrMsg());
|
||||
// Attempt to attach the origin database to the in-memory one
|
||||
else if ((db = sqlite3_exec(db, QFmtStr("ATTACH DATABASE '%q' as origin", m_Handle->mName.c_str()),
|
||||
NULL, NULL, NULL)) != SQLITE_OK)
|
||||
STHROWF("Unable to attach origin [%s]", db.ErrMsg());
|
||||
// Begin a transaction to replicate the data of origin database
|
||||
else if ((db = sqlite3_exec(db, "BEGIN", NULL, NULL, NULL) != SQLITE_OK))
|
||||
STHROWF("Unable to begin data replication [%s]", db.ErrMsg());
|
||||
// Attempt to replicate the data of origin database to the in-memory one
|
||||
else if ((db = sqlite3_exec(db, "SELECT [name] FROM [origin.sqlite_master] WHERE [type]='table'",
|
||||
&Connection::ProcessDMLRow, db->mPtr, NULL)) != SQLITE_OK)
|
||||
{
|
||||
// Did the error occurred from the DML process function?
|
||||
if (GetTempBuff()[0] != 0)
|
||||
{
|
||||
// Throw the resulted message but also include the point where it failed
|
||||
STHROWF("Unable to replicate data [%s]", GetTempBuff());
|
||||
}
|
||||
// Obtain the message from the connection handle if possible
|
||||
else
|
||||
STHROWF("Unable to replicate data [%s]", db.ErrMsg());
|
||||
}
|
||||
// Attempt to commit the changes to the database data replication
|
||||
else if ((db = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL)) != SQLITE_OK)
|
||||
{
|
||||
// Attempt to rollback changes from the data copy operation
|
||||
if ((db = sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL)) != SQLITE_OK)
|
||||
STHROWF("Unable to rollback data replication [%s]", db.ErrMsg());
|
||||
// Attempt to detach the disk origin from in-memory database
|
||||
else if ((db = sqlite3_exec(db, "DETACH DATABASE origin", NULL, NULL, NULL)) != SQLITE_OK)
|
||||
STHROWF("Unable to detach origin [%s]", db.ErrMsg());
|
||||
// Operation failed
|
||||
STHROWF("Unable to commit data replication [%s]", db.ErrMsg());
|
||||
}
|
||||
// At this point everything went fine and the database instance should be returned
|
||||
return Connection(db);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Connection::CopyToDatabase(const Connection & db)
|
||||
{
|
||||
// Make sure that we have two valid database handles
|
||||
Validate();
|
||||
db.Validate();
|
||||
// Attempt to take the snapshot and return the result
|
||||
TakeSnapshot(db.m_Handle);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Connection::ReserveQueue(Uint32 num)
|
||||
{
|
||||
@ -285,70 +205,6 @@ void Connection::ProfileOutput(void * /*ptr*/, CCStr sql, sqlite3_uint64 time)
|
||||
_SqMod->LogInf("SQLite profile (time: %llu): %s", time, sql);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
int Connection::ProcessDDLRow(void * db, int columns_count, char ** values, char ** /*columns*/)
|
||||
{
|
||||
// Make sure that exactly one column exists in the result
|
||||
if (columns_count != 1)
|
||||
FmtStr("Error occurred during DDL: columns != 1");
|
||||
// Execute the sql statement in values[0] in the received database connection
|
||||
else if (sqlite3_exec((sqlite3 *)db, values[0], NULL, NULL, NULL) != SQLITE_OK)
|
||||
FmtStr("Error occurred during DDL execution: %s", sqlite3_errmsg((sqlite3 *)db));
|
||||
else
|
||||
// Continue processing
|
||||
return 0;
|
||||
// Operation aborted
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Connection::ProcessDMLRow(void * db, int columns_count, char ** values, char ** /*columns*/)
|
||||
{
|
||||
// Make sure that exactly one column exists in the result
|
||||
if (columns_count != 1)
|
||||
{
|
||||
FmtStr("Error occurred during DML: columns != 1");
|
||||
// Operation aborted
|
||||
return -1;
|
||||
}
|
||||
// Generate the query string with the received values
|
||||
char * sql = sqlite3_mprintf("INSERT INTO main.%q SELECT * FROM origin.%q", values[0], values[0]);
|
||||
// Attempt to execute the generated query string on the received database connection
|
||||
if (sqlite3_exec((sqlite3 *)db, sql, NULL, NULL, NULL) != SQLITE_OK)
|
||||
FmtStr("Error occurred during DML execution: %s", sqlite3_errmsg((sqlite3 *)db));
|
||||
else
|
||||
{
|
||||
// Free the generated query string
|
||||
sqlite3_free(sql);
|
||||
// Continue processing
|
||||
return 0;
|
||||
}
|
||||
// Free the generated query string
|
||||
sqlite3_free(sql);
|
||||
// Operation aborted
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Connection::TakeSnapshot(const ConnHnd & destination)
|
||||
{
|
||||
// Attempt to initialize a backup structure
|
||||
sqlite3_backup * backup = sqlite3_backup_init(destination, "main", m_Handle, "main");
|
||||
// See if the backup structure could be created
|
||||
if (!backup)
|
||||
STHROWF("Unable to initialize the backup structure [%s]", destination.ErrMsg());
|
||||
// -1 to copy the entire source database to the destination
|
||||
if ((m_Handle = sqlite3_backup_step(backup, -1)) != SQLITE_DONE)
|
||||
{
|
||||
// Finalize the backup structure first
|
||||
sqlite3_backup_finish(backup);
|
||||
// Now it's safe to throw the error
|
||||
STHROWF("Unable to copy source [%s]", m_Handle.ErrStr());
|
||||
}
|
||||
// Clean up resources allocated by sqlite3_backup_init()
|
||||
if ((m_Handle = sqlite3_backup_finish(backup)) != SQLITE_OK)
|
||||
STHROWF("Unable to finalize backup [%s]", m_Handle.ErrStr());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Connection::ExecF(HSQUIRRELVM vm)
|
||||
{
|
||||
|
@ -445,16 +445,6 @@ public:
|
||||
sqlite3_db_release_memory(m_Handle);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move the whole database into memory.
|
||||
*/
|
||||
Connection CopyToMemory();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Takes a snapshot of a database which is located in memory and saves it to a database file.
|
||||
*/
|
||||
void CopyToDatabase(const Connection & db);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Returns internal runtime status information associated with the current database connection.
|
||||
*/
|
||||
@ -584,21 +574,6 @@ protected:
|
||||
* Callback function for ActivateProfiling()
|
||||
*/
|
||||
static void ProfileOutput(void * ptr, const char * sql, sqlite3_uint64 time);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Build and modify the structure of tables and other objects in the memory database.
|
||||
*/
|
||||
static int ProcessDDLRow(void * db, int columns_count, char ** values, char ** columns);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Insert all data from the origin database into the memory database.
|
||||
*/
|
||||
static int ProcessDMLRow(void * db, int columns_count, char ** values, char ** columns);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Takes and saves a snapshot of the memory database in a file.
|
||||
*/
|
||||
void TakeSnapshot(const ConnHnd & destination);
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -212,8 +212,6 @@ void RegisterAPI(HSQUIRRELVM vm)
|
||||
.Func(_SC("TableExists"), &Connection::TableExists)
|
||||
.Func(_SC("InterruptOperation"), &Connection::InterruptOperation)
|
||||
.Func(_SC("ReleaseMemory"), &Connection::ReleaseMemory)
|
||||
.Func(_SC("CopyToMemory"), &Connection::CopyToMemory)
|
||||
.Func(_SC("CopyToDatabase"), &Connection::CopyToDatabase)
|
||||
.Overload< Int32 (Connection::*)(Int32) >(_SC("GetInfo"), &Connection::GetInfo)
|
||||
.Overload< Int32 (Connection::*)(Int32, bool) >(_SC("GetInfo"), &Connection::GetInfo)
|
||||
.Overload< Int32 (Connection::*)(Int32, bool, bool) >(_SC("GetInfo"), &Connection::GetInfo)
|
||||
|
Loading…
Reference in New Issue
Block a user