bool CRegistry::Query ( std::string strQuery, CLuaArguments *pArgs, CRegistryResult* pResult ) { std::string strParsedQuery = ""; if ( m_bOpened == false ) { m_strLastError = "SQLite3 was not opened, cannot perform query!"; return false; } // Walk through the query and replace the variable placeholders with the actual variables unsigned int uiLen = strQuery.length (); unsigned int a = 0, type = 0; const char *szContent = NULL; char szBuffer[32] = {0}; for ( unsigned int i = 0; i < uiLen; i++ ) { if ( strQuery.at(i) == SQL_VARIABLE_PLACEHOLDER ) { // If the placeholder is found, replace it with the variable CLuaArgument *pArgument = (*pArgs)[a++]; // Check the type of the argument and convert it to a string we can process if ( pArgument ) { type = pArgument->GetType (); if ( type == LUA_TBOOLEAN ) { szContent = ( pArgument->GetBoolean() ) ? "true" : "false"; } else if ( type == LUA_TNUMBER ) { _snprintf ( szBuffer, 31, "%f", pArgument->GetNumber () ); szContent = szBuffer; } else if ( type == LUA_TSTRING ) { szContent = pArgument->GetString ().c_str (); // If we have a string, add a quote at the beginning too strParsedQuery += '\''; } } // Copy the string into the query, and escape the single quotes as well if ( szContent ) { for ( unsigned int k = 0; k < strlen ( szContent ); k++ ) { if ( szContent[k] == '\'' ) strParsedQuery += '\''; strParsedQuery += szContent[k]; } // If we have a string, add a quote at the end too if ( type == LUA_TSTRING ) strParsedQuery += '\''; } else { // If we don't have any content, put just output 2 quotes to indicate an empty variable strParsedQuery += "\'\'"; } } else { // If we found a normal character, copy it into the destination buffer strParsedQuery += strQuery[i]; } } return QueryInternal ( strParsedQuery.c_str (), pResult ); }
/////////////////////////////////////////////////////////////// // // CDatabaseConnectionSqlite::Query // // // /////////////////////////////////////////////////////////////// bool CDatabaseConnectionSqlite::Query ( const SString& strQuery, CRegistryResult& registryResult ) { // VACUUM query does not work with transactions if ( strQuery.BeginsWithI( "VACUUM" ) ) EndAutomaticTransaction (); else BeginAutomaticTransaction (); return QueryInternal ( strQuery, registryResult ); }
/////////////////////////////////////////////////////////////// // // CDatabaseConnectionSqlite::EndAutomaticTransaction // // // /////////////////////////////////////////////////////////////// void CDatabaseConnectionSqlite::EndAutomaticTransaction ( void ) { if ( m_bInAutomaticTransaction ) { m_bInAutomaticTransaction = false; CRegistryResult dummy; QueryInternal ( "END TRANSACTION", dummy ); } }
void CRegistry::EndAutomaticTransaction ( void ) { if ( m_bInAutomaticTransaction ) { m_bInAutomaticTransaction = false; CRegistryResult dummy; QueryInternal ( "END TRANSACTION", &dummy ); } }
/////////////////////////////////////////////////////////////// // // CDatabaseConnectionSqlite::BeginAutomaticTransaction // // // /////////////////////////////////////////////////////////////// void CDatabaseConnectionSqlite::BeginAutomaticTransaction ( void ) { if ( m_bInAutomaticTransaction ) { // If it's been a little while since this transaction was started, consider renewing it if ( ( CTickCount::Now () - m_AutomaticTransactionStartTime ).ToLongLong () > 1500 ) EndAutomaticTransaction (); } if ( !m_bInAutomaticTransaction && m_bAutomaticTransactionsEnabled ) { m_bInAutomaticTransaction = true; m_AutomaticTransactionStartTime = CTickCount::Now (); CRegistryResult dummy; QueryInternal ( "BEGIN TRANSACTION", dummy ); } }
void CRegistry::BeginAutomaticTransaction ( void ) { if ( !m_bInAutomaticTransaction ) { if ( m_llSuspendBatchingEndTime ) { if ( m_llSuspendBatchingEndTime > GetTickCount64_ () ) return; m_llSuspendBatchingEndTime = 0; } m_bInAutomaticTransaction = true; CRegistryResult dummy; QueryInternal ( "BEGIN TRANSACTION", &dummy ); } }
bool CRegistry::Select ( std::string strColumns, std::string strTable, std::string strWhere, unsigned int uiLimit, CRegistryResult* pResult ) { char szBuffer[32] = {0}; if ( m_bOpened == false ) { m_strLastError = "SQLite3 was not opened, cannot get value!"; return false; } std::string strQuery = "SELECT " + strColumns + " FROM " + strTable; if ( !strWhere.empty () ) strQuery += " WHERE " + strWhere; if ( uiLimit > 0 ) strQuery += " LIMIT " + std::string ( itoa ( uiLimit, szBuffer, 10 ) ); // Execute the query return QueryInternal ( strQuery.c_str (), pResult ); }
bool CRegistry::Query ( CRegistryResult* pResult, const char* szQuery, va_list vl ) { // Clear result if ( pResult ) *pResult = CRegistryResult (); if ( m_bOpened == false ) { SetLastErrorMessage ( "SQLite3 was not opened, cannot perform query!", szQuery ); return false; } SString strParsedQuery; for ( unsigned int i = 0; szQuery[i] != '\0'; i++ ) { if ( szQuery[i] != SQL_VARIABLE_PLACEHOLDER ) { strParsedQuery += szQuery[i]; } else { switch ( va_arg( vl, int ) ) { case SQLITE_INTEGER: { int iValue = va_arg( vl, int ); strParsedQuery += SString ( "%d", iValue ); } break; case SQLITE_FLOAT: { double fValue = va_arg( vl, double ); strParsedQuery += SString ( "%f", fValue ); } break; case SQLITE_TEXT: { const char* szValue = va_arg( vl, const char* ); assert ( szValue ); strParsedQuery += SString ( "'%s'", SQLEscape ( szValue, true, false ).c_str () ); } break; case SQLITE_BLOB: { strParsedQuery += "CANT_DO_BLOBS_M8"; } break; case SQLITE_NULL: { strParsedQuery += "NULL"; } break; default: // someone passed a value without specifying its type assert ( 0 ); break; } } } va_end ( vl ); // VACUUM query does not work with transactions if ( strParsedQuery.BeginsWithI( "VACUUM" ) ) EndAutomaticTransaction (); else BeginAutomaticTransaction (); return QueryInternal ( strParsedQuery.c_str (), pResult ); }
bool CRegistry::Query ( const std::string& strQuery, CLuaArguments *pArgs, CRegistryResult* pResult ) { std::string strParsedQuery = ""; if ( m_bOpened == false ) { SetLastErrorMessage ( "SQLite3 was not opened, cannot perform query!", strQuery ); return false; } // Walk through the query and replace the variable placeholders with the actual variables unsigned int uiLen = strQuery.length (); unsigned int a = 0, type = 0; const char *szContent = NULL; char szBuffer[32] = {0}; for ( unsigned int i = 0; i < uiLen; i++ ) { if ( strQuery.at(i) == SQL_VARIABLE_PLACEHOLDER ) { // If the placeholder is found, replace it with the variable CLuaArgument *pArgument = (*pArgs)[a++]; // Check the type of the argument and convert it to a string we can process if ( pArgument ) { type = pArgument->GetType (); if ( type == LUA_TBOOLEAN ) { szContent = ( pArgument->GetBoolean() ) ? "true" : "false"; } else if ( type == LUA_TNUMBER ) { snprintf ( szBuffer, 31, "%f", pArgument->GetNumber () ); szContent = szBuffer; } else if ( type == LUA_TSTRING ) { szContent = pArgument->GetString ().c_str (); // If we have a string, add a quote at the beginning too strParsedQuery += '\''; } } // Copy the string into the query, and escape the single quotes as well if ( szContent ) { for ( unsigned int k = 0; szContent[k] != '\0'; k++ ) { if ( szContent[k] == '\'' ) strParsedQuery += '\''; strParsedQuery += szContent[k]; } // If we have a string, add a quote at the end too if ( type == LUA_TSTRING ) strParsedQuery += '\''; } else { // If we don't have any content, put just output 2 quotes to indicate an empty variable strParsedQuery += "\'\'"; } } else { // If we found a normal character, copy it into the destination buffer strParsedQuery += strQuery[i]; } } // Catch BEGIN/END/COMMIT TRANSACTION and ignore SString strTest = SString ( strParsedQuery ).ToUpper (); if ( strTest.find ( "TRANSACTION" ) != std::string::npos ) { strTest = strTest.Replace ( "\t", " " ).Replace ( " ", " ", true ).TrimStart ( " " ).TrimEnd ( " " ); if ( strTest.find ( "BEGIN" ) == 0 || strTest.find ( "END" ) == 0 || strTest.find ( "COMMIT" ) == 0 ) { return true; } } BeginAutomaticTransaction (); return QueryInternal ( strParsedQuery.c_str (), pResult ); }