Help-me include erro
#1

Erro:
Код:
C:\Program Files\pawno\include\sqlitei.inc(969) : error 017: undefined symbol "db_get_result_mem_handle"
C:\Program Files\pawno\include\sqlitei.inc(978) : error 017: undefined symbol "db_get_result_mem_handle"
C:\Program Files\pawno\include\sqlitei.inc(2159) : error 017: undefined symbol "db_get_result_mem_handle"
Include:
PHP код:
/*
    SQLite Improved v0.9.7 by Slice
    
    Changelog:
            2015-07-13:
                * Update for 0.3.7 R2.
                * All crash issues should be solved now, including the previous one that happened only on some servers.
            2014-10-08:
                * Fix crash when using stmt_fetch_row on an empty result (only affects Linux servers).
            2013-10-07:
                * Display errors from db_query. Works only on Windows.
            
            2012-07-23:
                * Fix problem with persistent databases (hopefully).
            
            2012-07-21:
                * Fix crash happening on Linux related to NULL values in db_free_result.
            
            2012-07-15:
                * Improvements to persistent databases.
            
            2012-06-15:
                * Fix compiler crash when db_query isn't used.
            
            2012-05-27:
                * Always throw warnings when invalid results are given to SQLitei functions.
                * Even more improvements to stability!
                * GetAmxBase is now updated with a JIT compatible version (all credits to Zeex).
                * All the default DB functions (which are hooked by SQLitei) are now compatible with the JIT plugin.
                * Fixed a bug in SA-MP's SQLite implementation where strings would contain signed characters instead of unsigned.
                  Most functions work just fine with both types of strings but strcmp, for one, does not.
                * stmt_bind_value now deals with packed strings properly.
            
            2012-03-22:
                * db_query now accept extra parameters similar to those in stmt_bind_value, allowing
                  a very quick way to format and run queries!
                
            2012-03-21:
                * Fixed a rare crash that would occur if you closed a DB while having autofreed results open.
                * The deprecated db_query_autofree is now removed. Simply use db_query instead.
                * Fixed a problem where a certain integer would cause an invalid value.
                * Added DB::TYPE_UINT, which inserts an unsigned integer.
                  An unsigned integer have values between 0 and 4294967295 as opposed to -2147483648 and 2147483647.
                * Added helper function db_print_query.
                * Added db_dump_table!
            
            2012-03-01:
                * db_free_result will now completely ignore invalid results (0).
            
            2012-02-12:
                * Added db_attach_memory_db and db_detach_memory_db.
            
            2012-02-11:
                * Added DB::TYPE_ARRAY, which allows you to insert and read arrays with statements!
                * Improved error handling and increased some buffer sizes.
                * Added db_begin_transaction, db_end_transaction, and db_set_asynchronous.
                * Minor improvements here and there.
            
            2012-02-10:
                * A few bug fixes.
                * Added db_field_is_null, which returns true if the field is a true NULL value (not just an empty string).
                * Deprecated db_query_autofree.
            
            2012-02-09:
                * Defining WP_Hash prior to inclusion is no longer needed.
                * db_query now has an optional third argument - enable autorelease, which is
                  true by default.
                * Improved stability on freeing results:
                    - Freeing results twice will not crash the server anymore - it will just generate
                      a warning.
                    - Freeing a result that will be autoreleased will remove it from the autorelease pool.
                * The compiler will no longer wrongfully detect recursion inside this include.
                * Added db_query_int and db_query_float.
                * Added db_get_struct_info and db_set_struct_info; used mainly internally.
                * Added db_exec and db_insert.
                * Performance improvements!
            
            2012-02-08:
                * db_print_result will no longer go to the end of the result.
                * Added db_get_row_index, db_set_row_index, and db_rewind.
            
            2012-02-07:
                * db_get_field/db_get_field_assoc will not crash anymore with NULL values!
            
            2011-12-21:
                * Added two new types for stmt_bind_value:
                    - DB::TYPE_WP_HASH: Puts a BLOB value of a whirlpool hash from the given string into the query (ex. x'FFAA4411...').
                    - DB::TYPE_PLAYER_NAME: Puts a player name from the ID passed.
                  Note that DB_USE_WHIRLPOOL must be defined as true in order for DB::TYPE_WP_HASH to work.
                * Made some optimizations and minor bug fixes.
                * stmt_execute will now autofree the result unless the 3rd argument is false.
                * Added the preprocessor options DE_DEBUG (logs debug info) and DB_LOG_TO_CHAT (prints log messages to chat).
                * Improved the way results are dealt with internally to avoid crashes at all costs.
                * Added debug messages pretty much everywhere.
            
            2011-12-16:
                * Added db_open_persistent, db_is_persistent, db_is_valid_persistent, and db_free_persistent.
                * Added db_query_autofree.
                * Added db_get_field_int and db_get_field_float.
                * Corrected a few SQLite natives.
            
            2011-12-15:
                * Added stmt_autoclose.
                * Memory usage decreased significantly.
                * All functions now accept both packed and unpacked strings.
                * Minor bug fixes and optimizations.
            
            2011-12-14:
                * Initial release.
*/
#if !defined _samp_included
    #error Please include a_samp before sqlitei.
#endif
#if defined __fmt_funcinc && defined FormatSpecifier
    #error Please include sqlitei before formatex.
#endif
#if !defined HTTP
    #tryinclude <a_http>
#endif
#if !defined DB_MAX_PARAMS
    #define DB_MAX_PARAMS  32
#endif
#if !defined DB_MAX_STATEMENTS
    #define DB_MAX_STATEMENTS  16
#endif
#if !defined DB_MAX_STATEMENT_SIZE
    #define DB_MAX_STATEMENT_SIZE  1024
#endif
#if !defined DB_MAX_FIELDS
    #define DB_MAX_FIELDS  64
#endif
#if !defined DB_MAX_PERSISTENT_DATABASES
    #define DB_MAX_PERSISTENT_DATABASES  4
#endif
#if !defined DB_USE_WHIRLPOOL
    #define DB_USE_WHIRLPOOL  false
#endif
#if !defined DB_DEBUG
    #define DB_DEBUG  false
#endif
#if !defined DB_DEBUG_BACKTRACE_NOTICE
    #define DB_DEBUG_BACKTRACE_NOTICE  false
#endif
#if !defined DB_DEBUG_BACKTRACE_WARNING
    #define DB_DEBUG_BACKTRACE_WARNING  false
#endif
#if !defined DB_DEBUG_BACKTRACE_ERROR
    #define DB_DEBUG_BACKTRACE_ERROR  false
#endif
#if !defined DB_DEBUG_BACKTRACE_DEBUG
    #define DB_DEBUG_BACKTRACE_DEBUG  false
#endif
#if !defined DB_LOG_TO_CHAT
    #define DB_LOG_TO_CHAT  false
#endif
// "Namespace"
#define DB:: DB_
// Fix some natives ("const" keyword was missing)
native DB:db_open@(const szName[]) = db_open;
native DBResult:db_query@(DB:db, const szQuery[]) = db_query;
native db_get_field@(DBResult:dbresultfieldresult[], maxlength) = db_get_field;
native db_get_field_assoc@(DBResult:dbresult, const field[], result[], maxlength) = db_get_field_assoc;
native db_close@(DB:db) = db_close;
native db_free_result@(DBResult:dbrResult) = db_free_result;
#define db_open        db_open@
#define db_query%1(    db_query_hook(_,
#define db_close       db_close_hook
#define db_free_result db_free_result_hook
#if DB::USE_WHIRLPOOL
    
native DB::WP_Hash(buffer[], len, const str[]) = WP_Hash;
#endif
enum DB::e_SYNCHRONOUS_MODE {
    
DB::SYNCHRONOUS_OFF,
    
DB::SYNCHRONOUS_NORMAL,
    
DB::SYNCHRONOUS_FULL
};
enum DBDataType: {
    
DB::TYPE_NONE,
    
DB::TYPE_NULL,
    
DB::TYPE_INT,
    
DB::TYPE_INTEGER DB::TYPE_INT,
    
DB::TYPE_UINT,
    
DB::TYPE_UINTEGER DB::TYPE_UINT,
    
DB::TYPE_FLOAT,
    
DB::TYPE_STRING,
    
DB::TYPE_RAW_STRING,
    
DB::TYPE_IDENTIFIER,
    
    
// Special types
    
#if DB::USE_WHIRLPOOL
    
DB::TYPE_WP_HASH,
#endif
    
    
DB::TYPE_PLAYER_NAME,
    
DB::TYPE_PLAYER_IP,
    
DB::TYPE_ARRAY
};
#define INT:          DB::TYPE_INT,QQPA:
#define INTEGER:      DB::TYPE_INT,QQPA:
#define UINT:         DB::TYPE_UINT,QQPA:
#define UINTEGER:     DB::TYPE_UINT,QQPA:
#define FLOAT:        DB::TYPE_FLOAT,QQPA:
#define STRING:       DB::TYPE_STRING,QQPA:
#define RAW_STRING:   DB::TYPE_RAW_STRING,QQPA:
#define IDENTIFIER:   DB::TYPE_IDENTIFIER,QQPA:
#if DB::USE_WHIRLPOOL
    #define WP_HASH:  DB::TYPE_WP_HASH,QQPA:
#endif
#define PLAYER_NAME:  DB::TYPE_PLAYER_NAME,QQPA:
#define PLAYER_IP:    DB::TYPE_PLAYER_IP,QQPA:
enum DB::E_STATEMENT {
    
// The ready-to-run query.
    
e_szQuery[DB::MAX_STATEMENT_SIZE 1],
    
    
// Parameter count
    
e_iParams,
    
    
// The parameter types.
    
DBDataType:e_aiParamTypes[DB::MAX_PARAMS],
    
    
// Position of parameters in the query string.
    
e_aiParamPositions[DB::MAX_PARAMS],
    
    
// Length of parameters in the query string.
    
e_aiParamLengths[DB::MAX_PARAMS],
    
    
// Types of bound return fields
    
DBDataType:e_aiFieldTypes[DB::MAX_FIELDS],
    
    
// Sizes of bound result fields (used only for strings currently)
    
e_aiFieldSizes[DB::MAX_FIELDS],
    
    
// Addresses of bound result fields
    
e_aiFieldAddresses[DB::MAX_FIELDS],
    
    
// The database it was created for
    
DB:e_dbDatabase,
    
    
// The result (after executing)
    
DBResult:e_dbrResult,
    
    
// How many rows were fetched from the most recent result
    
e_iFetchedRows,
    
    
// Whether or not any leftover results should be automatically freed
    // Note that whenever a new result is put into e_dbrResult, the previous one is freed.
    
bool:e_bAutoFreeResult
};
enum {
    
SQLITE_LIMIT_LENGTH,
    
SQLITE_LIMIT_SQL_LENGTH,
    
SQLITE_LIMIT_COLUMN,
    
SQLITE_LIMIT_EXPR_DEPTH,
    
SQLITE_LIMIT_COMPOUND_SELECT,
    
SQLITE_LIMIT_VDBE_OP,
    
SQLITE_LIMIT_FUNCTION_ARG,
    
SQLITE_LIMIT_ATTACHED,
    
SQLITE_LIMIT_LIKE_PATTERN_LEN,
    
SQLITE_LIMIT_VARIABLE_NUMBER,
    
SQLITE_LIMIT_TRIGGER_DEPTH
};
// SQLite 3 C-struct offsets
enum e_SQLITE3 {
         
sqlite3_pVfs                [4],
         
sqlite3_iBackends           [4],
         
sqlite3_pBackends           [4],
         
sqlite3_iFlags              [4],
         
sqlite3_iOpenFlags          [4],
    
         
sqlite3_iErrorCode          [4],
         
sqlite3_iErrorMask          [4],
    
bool:sqlite3_bAutoCommit         [1],
         
sqlite3_iTempStore          [1],
    
bool:sqlite3_bMallocFailed       [1],
    
         
sqlite3_iDefaultLockMode    [1],
         
sqlite3_iNextAutovac        [1],
    
bool:sqlite3_bSuppressErrors     [1],
         
sqlite3_iPad                [2],
    
         
sqlite3_iNextPagesize       [4],
         
sqlite3_iNumTables          [4],
         
sqlite3_pDefaultCollation   [4],
         
sqlite3_iLastRowid          [4],
         
sqlite3_iLastRowidUpperBytes[4],
         
sqlite3_iMagic              [4],
         
sqlite3_iNumChanges         [4],
         
sqlite3_iNumTotalChanges    [4],
    
         
sqlite3_aiLimits            [SQLITE_LIMIT_TRIGGER_DEPTH 4],
    
         
sqlite3_aInitInfo           [12],
         
sqlite3_iNumExtensions      [4],
         
sqlite3_pExtensions         [4],
         
sqlite3_pVdbe               [4],
         
sqlite3_iActiveVdbeCount    [4],
         
sqlite3_iWritingVdbeCount   [4],
    
         
sqlite3_pTraceFunc          [4],
         
sqlite3_pTraceArg           [4],
         
sqlite3_pProfilingFunc      [4],
         
sqlite3_pProfilingArg       [4],
         
sqlite3_pCommitArg          [4],
         
sqlite3_pCommitCallback     [4],
         
sqlite3_pRollbackArg        [4],
         
sqlite3_pRollbackCallback   [4],
         
sqlite3_pUpdateArg          [4],
         
sqlite3_pUpdateCallback     [4],
         
sqlite3_pWalCallback        [4],
         
sqlite3_pWalArg             [4],
         
sqlite3_pCollNeeded         [4],
         
sqlite3_pCollNeeded16       [4],
         
sqlite3_pCollNeededArg      [4],
         
sqlite3_pError              [4],
         
sqlite3_pErrorMsg           [4],
         
sqlite3_pErrorMsg16         [4]
};
enum DB::E_PERSISTENT_DB {
         
e_szName[128 char],
    
bool:e_bIsUsed,
      
DB:e_dbDatabase
};
static 
stock
                gs_szBuffer
[8192],
                
gs_aiCompressBuffer[3072],
                
gs_Statements[DBStatement:DB::MAX_STATEMENTS][DB::E_STATEMENT],
                
gs_iAutoFreeTimer = -1,
                
gs_iAutoFreeResultsIndex 0,
       
DBResult:gs_adbrAutoFreeResults[1024],
                
gs_iAutoCloseStatementsIndex 0,
    
DBStatement:gs_astAutoCloseStatements[1024],
                
gs_PersistentDatabases[DB::MAX_PERSISTENT_DATABASES][DB::E_PERSISTENT_DB],
                
gs_iClosePersistentTimer = -1,
                
gs_iFreeStatementResultsTimer = -1,
                
gs_szNull[1] = {0}
;
const
    
DBStatement:DB::INVALID_STATEMENT DBStatement:-1,
       
DBResult:DB::INVALID_RESULT DBResult:0
;
#if !DB_DEBUG
    #define DB_Debug(%1)%0;
#endif
#if !DB_LOG_TO_CHAT
    #if DB_DEBUG_BACKTRACE_NOTICE
        #define DB_Notice(%1)    print(!"SQLitei Notice: " %1),PrintAmxBacktrace()
        #define DB_Noticef(%1)   printf("SQLitei Notice: " %1),PrintAmxBacktrace()
    #else
        #define DB_Notice(%1)    print(!"SQLitei Notice: " %1)
        #define DB_Noticef(%1)   printf("SQLitei Notice: " %1)
    #endif
    #if DB_DEBUG_BACKTRACE_WARNING
        #define DB_Warning(%1)   print(!"SQLitei Warning: " %1),PrintAmxBacktrace()
        #define DB_Warningf(%1)  printf("SQLitei Warning: " %1),PrintAmxBacktrace()
    #else
        #define DB_Warning(%1)   print(!"SQLitei Warning: " %1)
        #define DB_Warningf(%1)  printf("SQLitei Warning: " %1)
    #endif
    #if DB_DEBUG_BACKTRACE_ERROR
        #define DB_Error(%1)     print(!"SQLitei Error: " %1),PrintAmxBacktrace()
        #define DB_Errorf(%1)    printf("SQLitei Error: " %1),PrintAmxBacktrace()
    #else
        #define DB_Error(%1)     print(!"SQLitei Error: " %1)
        #define DB_Errorf(%1)    printf("SQLitei Error: " %1)
    #endif
    
    #if DB_DEBUG
        #if DB_DEBUG_BACKTRACE_DEBUG
            #define DB_Debug(%1)  printf("SQLitei Debug: " %1),PrintAmxBacktrace()
        #else
            #define DB_Debug(%1)  printf("SQLitei Debug: " %1)
        #endif
    #endif
#else
    
new
        
gs_szLogMessageBuffer[256]
    ;
    
    
#define DB_Notice(%1)    SendClientMessageToAll(0xFFFFFFFF, "SQLitei Notice: "  %1), print(!"SQLitei Notice: "  %1)
    #define DB_Warning(%1)   SendClientMessageToAll(0xEBBD17FF, "SQLitei Warning: " %1), print(!"SQLitei Warning: " %1)
    #define DB_Error(%1)     SendClientMessageToAll(0xCC0000FF, "SQLitei Error: "   %1), print(!"SQLitei Error: "   %1)
    #define DB_Noticef(%1)   format(gs_szLogMessageBuffer, sizeof(gs_szLogMessageBuffer), "SQLitei Notice: "  %1), print(gs_szLogMessageBuffer), SendClientMessageToAll(0xDDDDDDFF, gs_szLogMessageBuffer)
    #define DB_Warningf(%1)  format(gs_szLogMessageBuffer, sizeof(gs_szLogMessageBuffer), "SQLitei Warning: " %1), print(gs_szLogMessageBuffer), SendClientMessageToAll(0xEBBD17FF, gs_szLogMessageBuffer)
    #define DB_Errorf(%1)    format(gs_szLogMessageBuffer, sizeof(gs_szLogMessageBuffer), "SQLitei Error: "   %1), print(gs_szLogMessageBuffer), SendClientMessageToAll(0xCC0000FF, gs_szLogMessageBuffer)
    
    #if DB_DEBUG
        #define DB_Debug(%1)  format(gs_szLogMessageBuffer, sizeof(gs_szLogMessageBuffer), "SQLitei Debug: " %1), print(gs_szLogMessageBuffer), SendClientMessageToAll(0xFFFFFFFF, gs_szLogMessageBuffer)
    #endif
#endif
// Has to be defined after statement functions.
forward DBResult:db_query_hook(iTagOf3 tagof(_bAutoRelease), DB:db, const szQuery[], {boolDBDataType}:_bAutoRelease true, {DBDataTypeQQPA}:...);
// forward's
forward bool:db_set_row_index(DBResult:dbrResultiRow);
forward bool:db_free_result_hook(DBResult:dbrResult);
forward bool:db_set_synchronous(DB:dbDB::e_SYNCHRONOUS_MODE:iValue);
forward DB::funcinc();
public 
DB::funcinc() {
    
strcat(gs_szBuffer"");
    
strpack(gs_szBuffer"");
    
ispacked(gs_szBuffer);
    
db_get_field(DBResult:00gs_szBuffer0);
    
db_query(DB:0,"");
}
static 
stock DB::CompressArray(const aiArray[], iSize sizeof(aiArray), aiOutput[]) {
    new
        
iOutputIndex 4,
        
iValue,
        
iMSB,
        
iShift
    
;
    
    
// * 0b11000000 = Single byte, negative
    // * 0b10000000 = Single byte
    // * 0b01000000 = Multi-byte
    //   - 0b01000000 = More bytes
    //   - 0b11000000 = Last byte
    //   - 0b10000000 = Unused
    
    
for (new 0iSizei++) {
        
// Will the value fit in one byte?
        
        
iValue aiArray[i];
        
        if (-
0b00111111 <= iValue <= 0b00111111) {
            
// Is the value negative?
            
            
if (iValue 0x80000000) {
                
// Set the "single byte, negative" bits on and put the value without its sign
                
                
aiOutput{iOutputIndex++} = 0b11000000 | -iValue;
            } else {
                
// Just put the value in with the "single byte" bit
                
                
aiOutput{iOutputIndex++} = 0b10000000 |  iValue;
            }
        } else {
            
// Figure out how many bits we'll have to write
            
iMSB DB::FindMSB(iValue) + 1;
            
            
// Make iShift a multiple of 6 (if it isn't already)
            
if ((iShift iMSB 6))
                
aiOutput{iOutputIndex++} = 0b01000000 | (iValue >>> (iMSB iShift) & ~(0xFFFFFFFF << iShift));
            
            
iShift iMSB iShift;
            
            
// Write bits out left-right
            
while ((iShift -= 6) >= 0)
                
aiOutput{iOutputIndex++} = 0b01000000 | (iValue >>> iShift 0b00111111);
            
            
// Change the "more bytes" bits into "last byte"
            
aiOutput{iOutputIndex 1} |= 0b11000000;
        }
    }
    
    
// Put the number of bytes we just wrote into the first cell of the output
    
aiOutput[0] = 0x80808080 | ((iOutputIndex 0x1FE00000) << 3) | ((iOutputIndex 0x3FC000) << 2) | ((iOutputIndex 0x7F80) << 1) | (iOutputIndex 0x7F);
    
    
// Make sure the bytes in the last cell are 0
    
aiOutput{iOutputIndex} = 0;
    
    
iValue iOutputIndex;
    
    while (++
iOutputIndex 4)
        
aiOutput{iOutputIndex} = 0;
    
    
// Return the number of bytes written (not counting the first 4)
    
return iValue;
}
static 
stock DB::DecompressArray(const aiCompressedArray[], aiOutput[], iOutputSize sizeof(aiOutput)) {
    new
        
iBytes,
        
iOutputIndex 0
    
;
    
    
// Get the number of bytes to parse
    
iBytes aiCompressedArray[0];
    
iBytes = ((iBytes 0x7F000000) >>> 3) | ((iBytes 0x7F0000) >>> 2) | ((iBytes 0x7F00) >>> 1) | (iBytes 0x7F);
    
    for (new 
4iBytesi++) {
        
// Out of slots?
        
if (iOutputIndex >= iOutputSize) {
            
DB::Error("(DB::DecompressArray) Compressed array is larger than decompress buffer.");
        
            break;
        }
        
        
// Single byte?
        
if ((aiCompressedArray{i} & 0b10000000)) {
            
// Negative?
            
if ((aiCompressedArray{i} & 0b01000000))
                
aiOutput[iOutputIndex++] = -(aiCompressedArray{i} & 0b00111111);
            else
                
aiOutput[iOutputIndex++] =  (aiCompressedArray{i} & 0b00111111);
        } else {
            
// Multi byte; read the last bits
            
aiOutput[iOutputIndex] = aiCompressedArray{i} & 0b00111111;
            
            
// Keep reading bits while shifting the value to the left
            
do {
                
aiOutput[iOutputIndex] <<= 6;
                
aiOutput[iOutputIndex]  |= aiCompressedArray{++i} & 0b00111111;
            } while ((
aiCompressedArray{i} & 0b10000000) == 0);
            
            
iOutputIndex++;
        }
    }
    
    return 
iOutputIndex;
}
static 
stock DB::memset(aArray[], iValueiSize sizeof(aArray)) {
    new
        
iAddress
    
;
    
    
// Store the address of the array
    #emit LOAD.S.pri 12
    #emit STOR.S.pri iAddress
    
    // Convert the size from cells to bytes
    
iSize *= 4;
    
    
// Loop until there is nothing more to fill
    
while (iSize 0) {
        
// I have to do this because the FILL instruction doesn't accept a dynamic number.
        
if (iSize >= 4096) {
            
#emit LOAD.S.alt iAddress
            #emit LOAD.S.pri iValue
            #emit FILL 4096
        
            
iSize    -= 4096;
            
iAddress += 4096;
        } else if (
iSize >= 1024) {
            
#emit LOAD.S.alt iAddress
            #emit LOAD.S.pri iValue
            #emit FILL 1024
            
iSize    -= 1024;
            
iAddress += 1024;
        } else if (
iSize >= 256) {
            
#emit LOAD.S.alt iAddress
            #emit LOAD.S.pri iValue
            #emit FILL 256
            
iSize    -= 256;
            
iAddress += 256;
        } else if (
iSize >= 64) {
            
#emit LOAD.S.alt iAddress
            #emit LOAD.S.pri iValue
            #emit FILL 64
            
iSize    -= 64;
            
iAddress += 64;
        } else if (
iSize >= 16) {
            
#emit LOAD.S.alt iAddress
            #emit LOAD.S.pri iValue
            #emit FILL 16
            
iSize    -= 16;
            
iAddress += 16;
        } else {
            
#emit LOAD.S.alt iAddress
            #emit LOAD.S.pri iValue
            #emit FILL 4
            
iSize    -= 4;
            
iAddress += 4;
        }
    }
    
    
// aArray is used, just not by its symbol name
    #pragma unused aArray
    
    
return 1;
}
stock DB::LazyInitialize() {
    static
        
bool:bIsInitialized false
    
;
    
    if (
bIsInitialized)
        return;
    
    
bIsInitialized true;
    
    
#if defined HTTP
        
HTTP(0x7FEDCBA0HTTP_GET, !"spelsajten.net/sqlitei_version.php?version=097""", !"DB_VersionCheckReponse");
    
#endif
}
#if defined HTTP
    
forward DB::VersionCheckReponse(iIndexiResponseCode, const szResponse[]);
    public 
DB::VersionCheckReponse(iIndexiResponseCode, const szResponse[]) {
        if (
iResponseCode == 200) {
            if (
strval(szResponse) != 1) {
                print(!
"\n\n\n  *******************************************************************");
                print(      !
"  *   There's a new version version of SQLite Improved available!   *");
                print(      !
"  * Please visit the topic at the SA-MP forums for the latest copy. *");
                print(      !
"  *  Alternatively, get it here: http://spelsajten.net/sqlitei.inc  *");
                print(      !
"  *******************************************************************\n\n\n");
            }
        }
    }
#endif
stock db_escape_string(szString[], const szEnclosing[] = "'"iSize sizeof(szString)) {
    
DB::LazyInitialize();
    
    new
        
iPos
    
;
    
    while (-
!= (iPos strfind(szStringszEnclosing_iPos))) {
        
strins(szStringszEnclosingiPosiSize);
        
        
iPos += 2;
    }
}
stock bool:db_is_persistent(DB:db) {
    return !!(
_:db 0x80000000);
}
stock bool:db_is_valid_persistent(DB:db) {
    new
        
iIndex = (_:db 0x7FFFFFFF)
    ;
    
    if ((
<= iIndex sizeof(gs_PersistentDatabases)) && gs_PersistentDatabases[iIndex][e_bIsUsed])
        return 
true;
    
    return 
false;
}
stock bool:db_is_table_exists(DB:db, const szTable[])
{
    new
        
DBResult:dbrResult
    
;
    
    
format(gs_szBuffersizeof(gs_szBuffer), "SELECT name FROM sqlite_master WHERE type = 'table' AND tbl_name = '%s'"szTable);
    
    
dbrResult db_query(dbgs_szBufferfalse);
    
    if (
db_num_fields(dbrResult)) {
        
db_free_result(dbrResult);
        
        return 
true;
    }
    
    
db_free_result(dbrResult);
    
    return 
false;
}
stock bool:db_rewind(DBResult:dbrResult) {
    if (
dbrResult == DB::INVALID_RESULT) {
        
DB::Notice("(db_rewind) Invalid result given.");
        
        return 
false;
    }
    
    return 
db_set_row_index(dbrResult0);
}
stock bool:db_exec(DB:db, const szQuery[]) {
    new
        
DBResult:dbrResult db_query(dbszQueryfalse)
    ;
    
    if (
dbrResult) {
        
db_free_result(dbrResult);
        
        return 
true;
    }
    
    return 
false;
}
stock db_insert(DB:db, const szQuery[]) {
    new
        
DBResult:dbrResult db_query(dbszQueryfalse)
    ;
    
    if (
dbrResult) {
        
db_free_result(dbrResult);
        
        return 
db_last_insert_rowid(db);
    }
    
    return 
0;
}
stock db_get_struct_info(DB:db, {_e_SQLITE3}:iOffset) {
    if (
db_is_persistent(db)) {
        if (!
db_is_valid_persistent(db)) {
            
DB::Errorf("(db_get_struct_info) Invalid persistent database given (%04x%04x)."_:db >>> 16_:db 0xFFFF);
            
            return 
0;
        }
        
        new 
iIndex = (_:db 0x7FFFFFFF);
        
        
db gs_PersistentDatabases[iIndex][e_dbDatabase];
        
        if (!
db) {
            
DB::Errorf("(db_get_struct_info) Closed persistent database given (%04x%04x)."_:db >>> 16_:db 0xFFFF);
            
            return 
0;
        }
    }
    
    new
        
iAddress db_get_mem_handle(db DB:0x7FFFFFFF) - DB::GetAmxBaseRelative() + iOffset,
        
iValue
    
;
    
    
#emit LREF.S.pri  iAddress
    #emit STOR.S.pri  iValue
    
    
return iValue;
}
stock db_set_struct_info(DB:db, {_e_SQLITE3}:iOffsetiValue) {
    if (
db_is_persistent(db)) {
        if (!
db_is_valid_persistent(db)) {
            
DB::Errorf("(db_set_struct_info) Invalid persistent database given (%04x%04x)."_:db >>> 16_:db 0xFFFF);
            
            return 
0;
        }
        
        new 
iIndex = (_:db 0x7FFFFFFF);
        
        
db gs_PersistentDatabases[iIndex][e_dbDatabase];
        
        if (!
db) {
            
DB::Errorf("(db_set_struct_info) Closed persistent database given (%04x%04x)."_:db >>> 16_:db 0xFFFF);
            
            return 
0;
        }
    }
    
    new
        
iAddress db_get_mem_handle(db DB:0x7FFFFFFF) - DB::GetAmxBaseRelative() + iOffset
    
;
    
    
#emit LOAD.S.pri  iValue
    #emit SREF.S.pri  iAddress
}
stock bool:db_set_row_index(DBResult:dbrResultiRow) {
    if (
dbrResult == DB::INVALID_RESULT) {
        
DB::Notice("(db_set_row_index) Invalid result given.");
        
        return 
false;
    }
    
    if (
iRow || iRow >= db_num_rows(dbrResult))
        return 
false;
    
    new
        
iAddress db_get_result_mem_handle(dbrResult) - DB::GetAmxBaseRelative() + 16
    
;
    
    
#emit LOAD.S.pri  iRow
    #emit SREF.S.pri  iAddress
    
    
return true;
}
stock db_get_row_index(DBResult:dbrResult) {
    if (
dbrResult == DB::INVALID_RESULT) {
        
DB::Notice("(db_get_row_index) Invalid result given.");
        
        return 
0;
    }
    
    new
        
iAddress db_get_result_mem_handle(dbrResult) - DB::GetAmxBaseRelative() + 16
    
;
    
    
#emit LREF.S.pri  iAddress
    #emit STACK       4
    #emit RETN
    
    
return 0;
}
stock DB:db_open_persistent(const szName[]) {
    new
        
DB:db,
           
iIndex = -1
    
;
    
    for (new 
0sizeof(gs_PersistentDatabases); i++) {
        if (!
gs_PersistentDatabases[i][e_bIsUsed]) {
            
iIndex i;
            
            break;
        }
    }
    
    if (
iIndex == -1) {
        
DB::Error("(db_open_persistent) Unable to find a free slot.");
        
        return 
DB:-1;
    }
    
    if (!(
db db_open(szName))) {
        
DB::Error("(db_open_persistent) Unable to open the database.");
        
        return 
DB:-1;
    }
    
    
gs_PersistentDatabases[iIndex][e_bIsUsed]    = true;
    
gs_PersistentDatabases[iIndex][e_dbDatabase] = db;
    
gs_PersistentDatabases[iIndex][e_szName][0]  = 0;
    
    if (
gs_iClosePersistentTimer == -1)
        
gs_iClosePersistentTimer SetTimer("db_close_persistent"0false);
    
    
strpack(gs_PersistentDatabases[iIndex][e_szName], szName_:e_bIsUsed);
    
    
DB::Debug("(db_open_persistent=%d) Opened new persistent DB."iIndex);
    
    return 
DB:(iIndex 0x80000000);
}
stock db_close_hook(DB:db) {
    new
        
iIndex
    
;
    
    if (
db_is_persistent(db)) {
        if (!
db_is_valid_persistent(db)) {
            
DB::Errorf("(db_close) Invalid persistent database given (%04x%04x)."_:db >>> 16_:db 0xFFFF);
            
            return;
        }
        
        
iIndex = (_:db 0x7FFFFFFF);
        
        if (
gs_PersistentDatabases[iIndex][e_dbDatabase]) {
            
db_close@(gs_PersistentDatabases[iIndex][e_dbDatabase]);
            
            
gs_PersistentDatabases[iIndex][e_dbDatabase] = DB:0;
            
            
DB::Debug("(db_close) Closed the DB for the persistent DB with index %d."iIndex);
        } else {
            
DB::Debug("(db_close) Would close the DB for the persistent DB with index %d, but it already is."iIndex);
        }
    } else {
        
db_close@(db);
    }
}
stock db_query_int(DB:db, const szQuery[], iField 0) {
    new
        
DBResult:dbrResult db_query(dbszQueryfalse)
    ;
    if (!
dbrResult) {
        
strunpack(gs_szBufferszQuery);
        
        
DB::Warningf("(db_query_int) Query failed: \"%s\"."gs_szBuffer);
        
        return 
0;
    }
    
db_get_field(dbrResultiFieldgs_szBuffersizeof(gs_szBuffer) - 1);
    
db_free_result(dbrResult);
    return 
strval(gs_szBuffer);
}
stock Float:db_query_float(DB:db, const szQuery[], iField 0) {
    new
        
DBResult:dbrResult db_query(dbszQueryfalse)
    ;
    if (!
dbrResult) {
        
strunpack(gs_szBufferszQuery);
        
        
DB::Warningf("(db_query_float) Query failed: \"%s\"."gs_szBuffer);
        
        return 
0.0;
    }
    
db_get_field(dbrResultiFieldgs_szBuffersizeof(gs_szBuffer) - 1);
    
db_free_result(dbrResult);
    return 
floatstr(gs_szBuffer);
}
stock db_is_result_freed(DBResult:dbrResult) {
    if (
dbrResult == DB::INVALID_RESULT) {
        
DB::Notice("(db_is_result_freed) Invalid result given.");
        
        return 
true;
    }
    return 
db_get_result_mem_handle(dbrResult) == 0;
}
stock bool:db_free_result_hook(DBResult:dbrResult) {
    if (
dbrResult == DB::INVALID_RESULT) {
        
DB::Notice("(db_free_result_hook) Invalid result given.");
        
        return 
false;
    }
    
    
DB::Debug("(db_free_result) Freeing 0x%04x%04x."_:dbrResult >>> 16_:dbrResult 0xFFFF);
    
    for (new 
gs_iAutoFreeResultsIndexi--; ) {
        if (
gs_adbrAutoFreeResults[i] == dbrResult) {
            
gs_adbrAutoFreeResults[i] = DBResult:0;
            
            
DB::Debug("(db_free_result) The result being freed was inside the autorelease pool.");
        }
    }
    new
        
iFreeTestAddress db_get_result_mem_handle(dbrResult) - DB::GetAmxBaseRelative() + 16,
        
iData
    
;
    
    
#emit LREF.S.pri  iFreeTestAddress
    #emit STOR.S.pri  iData
    
    
if (iData != 0xFFFFFFFF) {
        new
            
iResultAddress db_get_result_mem_handle(dbrResult) - DB::GetAmxBaseRelative(),
            
iAddress,
            
iRows,
            
iCols,
            
iDataAddress,
            
iOffset,
            
iNullAddress
        
;
        
#emit CONST.pri   gs_szNull
        #emit STOR.S.pri  iNullAddress
        
        
iNullAddress +=  DB::GetAmxBaseRelative();
        
        
iAddress iResultAddress;
        
#emit LREF.S.pri  iAddress
        #emit STOR.S.pri  iRows
        
        
iAddress += 4;
        
#emit LREF.S.pri  iAddress
        #emit STOR.S.pri  iCols
        
        
iAddress += 4;
        
#emit LREF.S.pri  iAddress
        #emit STOR.S.pri  iDataAddress
        
        
iDataAddress -= DB::GetAmxBaseRelative();
        
        
iOffset = (iCols iRows iCols) * 4;
        
        while (
iOffset >= 0) {
            
iAddress iDataAddress iOffset;
            
            
#emit LREF.S.pri  iAddress
            #emit STOR.S.pri  iAddress
            
            
if (iAddress == iNullAddress) {
                
iAddress iDataAddress iOffset;
                
                
#emit CONST.pri   0
                #emit SREF.S.pri  iAddress
            
}
            
            
iOffset -= 4;
        }
        
        
db_free_result@(dbrResult);
        
        
#emit CONST.pri   0xFFFFFFFF
        #emit SREF.S.pri  iFreeTestAddress
        
        
return true;
    } else {
        
DB::Warning("(db_free_result) Attempted to free an already freed result; crash prevented.");
    }
    
    return 
false;
}
stock db_free_persistent(DB:db) {
    new
        
iIndex
    
;
    
    if (!
db_is_valid_persistent(db)) {
        
DB::Errorf("(db_free_persistent) Invalid persistent database given (%04x%04x)."_:db >>> 16_:db 0xFFFF);
        
        return;
    }
    
    
iIndex = (_:db 0x7FFFFFFF);
    
    if (
gs_PersistentDatabases[iIndex][e_dbDatabase]) {
        
db_close@(gs_PersistentDatabases[iIndex][e_dbDatabase]);
        
        
gs_PersistentDatabases[iIndex][e_dbDatabase] = DB:0;
        
        
DB::Debug("(db_free_persistent:%d) Closed and freed the persistent DB."iIndex);
    } else {
        
DB::Debug("(db_free_persistent:%d) Freed the already closed persistent DB."iIndex);
    }
    
    
gs_PersistentDatabases[iIndex][e_bIsUsed] = false;
}
stock db_changes(DB:db) {
    
DB::LazyInitialize();
    
    if (!
db) {
        
DB::Error("(db_changes) Invalid database handle given.");
        
        return 
0;
    }
    
    return 
db_get_struct_info(dbsqlite3_iNumChanges);
}
stock db_begin_transaction(DB:db)
    return 
db_exec(db, !"BEGIN");
stock db_end_transaction(DB:db)
    return 
db_exec(db, !"COMMIT");
stock db_set_asynchronous(DB:dbbool:bSet true) {
    
db_set_synchronous(DB:dbbSet DB::SYNCHRONOUS_OFF DB::SYNCHRONOUS_FULL);
}
stock bool:db_set_synchronous(DB:dbDB::e_SYNCHRONOUS_MODE:iValue) {
    if (
<= _:iValue <= 2) {
        
format(gs_szBuffersizeof(gs_szBuffer), "PRAGMA synchronous = %d"_:iValue);
    
        return 
db_exec(dbgs_szBuffer);
    } else
        return 
false;
}
stock bool:db_attach_memory_db(DB:db, const szName[]) {
    
strunpack(gs_szBufferszName);
    
    
db_escape_string(gs_szBuffer"\"");
    
    
format(gs_szBuffersizeof(gs_szBuffer), "ATTACH DATABASE ':memory:' AS \"%s\""gs_szBuffer);
    
    return 
db_exec(dbgs_szBuffer);
}
stock bool:db_detach_memory_db(DB:db, const szName[]) {
    
strunpack(gs_szBufferszName);
    
    
db_escape_string(gs_szBuffer"\"");
    
    
format(gs_szBuffersizeof(gs_szBuffer), "DETACH DATABASE \"%s\""gs_szBuffer);
    
    return 
db_exec(dbgs_szBuffer);
}
stock db_total_changes(DB:db) {
    
DB::LazyInitialize();
    if (!
db) {
        
DB::Error("(db_changes) Invalid database handle given.");
        return 
0;
    }
    return 
db_get_struct_info(dbsqlite3_iNumTotalChanges);
}
stock db_last_insert_rowid(DB:db) {
    
DB::LazyInitialize();
    
    if (!
db) {
        
DB::Error("(db_last_insert_rowid) Invalid database handle given.");
        
        return 
0;
    }
    
    return 
db_get_struct_info(dbsqlite3_iLastRowid);
}
stock db_field_is_null(DBResult:dbrResultiField) {
    if (
dbrResult == DB::INVALID_RESULT) {
        
DB::Notice("(db_field_is_null) Invalid result given.");
    
        return 
false;
    }
    
    new
        
iAddress db_get_result_mem_handle(dbrResult) - DB::GetAmxBaseRelative(),
        
iCols,
        
iCurrentRow
    
;
    
    
iAddress += 4;
    
#emit LREF.S.pri  iAddress
    #emit STOR.S.pri  iCols
    
    
if (iField >= iCols)
        return 
true;
    
    
iAddress += 8;
    
#emit LREF.S.pri  iAddress
    #emit STOR.S.pri  iCurrentRow
    
    
iAddress -= 4;
    
    
#emit LREF.S.pri  iAddress
    #emit STOR.S.pri  iAddress
    
    
iAddress -= DB::GetAmxBaseRelative();
    
iAddress += (iCols iCols iCurrentRow iField) * 4;
    
    
#emit LREF.S.pri  iAddress
    #emit CONST.alt   gs_szNull
    #emit SUB
    #emit STOR.S.pri  iAddress
    
    
iAddress -= DB::GetAmxBaseRelative();
    
    return !
iAddress;
}
stock db_autofree_result(DBResult:dbrResult) {
    
DB::LazyInitialize();
    
    if (
dbrResult == DB::INVALID_RESULT) {
        
DB::Notice("(db_autofree_result) Invalid result given.");
        
        return;
    }
    
    if (
gs_iAutoFreeTimer == -1)
        
gs_iAutoFreeTimer SetTimer("db_drain_autofree_pool"0false);
    
    if (
gs_iAutoFreeResultsIndex >= sizeof(gs_adbrAutoFreeResults)) {
        
DB::Warning("(db_autofree_result) The autofree pool is full!");
        
        return;
    }
    
    
gs_adbrAutoFreeResults[gs_iAutoFreeResultsIndex] = dbrResult;
    
    
DB::Debug("(db_autofree_result) Will autofree 0x%04x%04x."_:dbrResult >>> 16_:dbrResult 0xFFFF);
    
    
gs_iAutoFreeResultsIndex++;
}
stock DBStatement:db_prepare(DB:db, const szQuery[]) {
    
DB::LazyInitialize();
    
    new
        
DBStatement:stStatement DB::INVALID_STATEMENT,
        
iPos,
        
i,
        
iLength
    
;
    
    if (!
db) {
        
DB::Error("(db_prepare) Invalid database handle given.");
        
        return 
DB::INVALID_STATEMENT;
    }
    
    
// Pretty useless to prepare empty queries.
    
if (!(iLength strlen(szQuery))) {
        
DB::Error("(db_prepare) Empty query.");
        
        return 
DB::INVALID_STATEMENT;
    }
    
    if (
iLength char DB::MAX_STATEMENT_SIZE) {
        
DB::Error("(db_prepare) The query is too long. Increase DB_MAX_STATEMENT_SIZE.");
        
        return 
DB::INVALID_STATEMENT;
    }
    
    
// Find an empty slot in gs_Statements.
    
for (0sizeof(gs_Statements); i++) {
        if (!
gs_Statements[DBStatement:i][e_dbDatabase]) {
            
stStatement DBStatement:i;
            
            break;
        }
    }
    
    if (
stStatement == DB::INVALID_STATEMENT) {
        
DB::Error("(db_prepare) Unable to find an empty slot for the statement. Increase DB_MAX_STATEMENTS.");
        
        return 
DB::INVALID_STATEMENT;
    }
    
    
gs_Statements[stStatement][e_dbDatabase] = db;
    
gs_Statements[stStatement][e_dbrResult] = DB::INVALID_RESULT;
    
gs_Statements[stStatement][e_iFetchedRows] = 0;
    
    
// Make sure no parameters are initialized.
    
for (0DB::MAX_PARAMSi++)
        
gs_Statements[stStatement][e_aiParamTypes][i] = DB::TYPE_NONE;
    
    
// Make sure no return fields are initialized.
    
for (0DB::MAX_FIELDSi++)
        
gs_Statements[stStatement][e_aiFieldTypes][i] = DB::TYPE_NONE;
    
    
iPos = -1;
    
0;
    
    
// Find all parameters
    
while (-!= (iPos strfind(szQuery, !"?"_, ++iPos))) {
        
gs_Statements[stStatement][e_aiParamPositions][i] = iPos;
        
gs_Statements[stStatement][e_aiParamLengths][i] = 1;
        
        if (++
>= DB::MAX_PARAMS) {
            
DB::Error("(db_prepare) Parameter limit exceeded. Increase DB_MAX_PARAMS.");
            
            return 
DB::INVALID_STATEMENT;
        }
    }
    
    
gs_Statements[stStatement][e_iParams] = i;
    
    
gs_Statements[stStatement][e_szQuery][0] = 0;
    
    if (
ispacked(szQuery)) {
#if DB_DEBUG
        
strunpack(gs_szBufferszQuery);
        
        
DB::Debug("(db_prepare=%d) Preparing statement with %d params: %s"_:stStatementigs_szBuffer);
#endif
        
        
strcat(gs_Statements[stStatement][e_szQuery], szQueryDB::MAX_STATEMENT_SIZE);
    } else {
        
DB::Debug("(db_prepare=%d) Preparing statement with %d params: %s"_:stStatementiszQuery);
        
        
strpack(gs_Statements[stStatement][e_szQuery], szQueryDB::MAX_STATEMENT_SIZE);
    }
    
    return 
stStatement;
}
stock bool:stmt_bind_value(&DBStatement:stStatementiParamDBDataType:iType, {Float_}:...) {
    
DB::LazyInitialize();
    
    new
             
iLengthDiff,
             
iLength,
        
bool:bIsPacked,
             
iNumArgs
    
;
    
    
#emit LOAD.S.pri  8
    #emit SHR.C.pri   2
    #emit STOR.S.pri  iNumArgs
    
    
if (stStatement == DB::INVALID_STATEMENT || !(<= _:stStatement sizeof(gs_Statements))) {
        
DB::Warningf("(stmt_bind_value) Invalid statement passed (%d)."_:stStatement);
        
        return 
false;
    }
    
    if (
iParam >= gs_Statements[stStatement][e_iParams]) {
        
DB::Warningf("(stmt_bind_value) Parameter index larger than number of parameters (%d > %d)."iParamgs_Statements[stStatement][e_iParams]);
        
        return 
false;
    }
    
    
// Fill gs_szBuffer with the new contents.
    
gs_szBuffer[0] = 0;
    
    switch (
iType) {
        case 
DB::TYPE_NULL:
            goto 
default_case;
        
        case 
DB::TYPE_INT: {
            new
                
iArgValue getarg(3)
            ;
            
            if (
iArgValue == cellmin)
                
gs_szBuffer = !"-2147483648";
            else
                
format(gs_szBuffersizeof(gs_szBuffer), "%d"getarg(3));
        }
        
        case 
DB::TYPE_UINT: {
            new
                
iArgValue getarg(3)
            ;
            
            if (!
iArgValue) {
                
gs_szBuffer = !"0";
            } else {
                new
                    
11
                
;
                
                
gs_szBuffer "00000000000";
                
                while (
iArgValue) {
                    
// gs_szBuffer[--j]
                    #emit CONST.alt   gs_szBuffer // alt = *gs_szBuffer
                    #emit LOAD.S.pri  j           // pri = j
                    #emit DEC.pri                 // pri -= 1
                    #emit STOR.S.pri  j           // j = pri
                    #emit IDXADDR                 // pri = alt + j * 4
                    #emit PUSH.pri                // Store for later
                    // Now do an unsigned divide on iArgValue then use both the quotient and remainder!
                    #emit LOAD.S.pri  iArgValue // pri = iArgValue
                    #emit CONST.alt   10
                    #emit UDIV                  // pri = iArgValue / 10; alt = iArgValue % 10
                    #emit STOR.S.pri  iArgValue // iArgValue = pri
                    #emit CONST.pri   '0'
                    #emit ADD                   // pri = '0' + (iArgValue % 10)
                    #emit POP.alt               // alt = gs_szBuffer[j]
                    #emit STOR.I                // gs_szBuffer[j] = pri
                
}
            
                
strpack(gs_szBuffergs_szBuffer[j]);
            }
        }
        
        case 
DB::TYPE_FLOAT:
            
format(gs_szBuffersizeof(gs_szBuffer), "%f"getarg(3));
        
        case 
DB::TYPE_STRING: {
            new 
iSize sizeof(gs_szBuffer) - 3;
            
            
//strpack(dest[], const source[], maxlength = sizeof dest)
            #emit PUSH.S    iSize
            #emit PUSH.S    24 // arg 3
            #emit PUSH.C    gs_szBuffer
            #emit PUSH.C    12
            #emit SYSREQ.C  strpack
            #emit STACK     16
            
            
db_escape_string(gs_szBuffer"'"sizeof(gs_szBuffer) - 1);
            
            
strins(gs_szBuffer, !"'"0);
            
strcat(gs_szBuffer, !"'");
        }
        
#if DB::USE_WHIRLPOOL
        
case DB::TYPE_WP_HASH: {
            
strcat(gs_szBuffer"x'");
            
            
DB::getstringarg(gs_szBuffer[2], 3sizeof(gs_szBuffer) - 2);
            
            
DB::WP_Hash(gs_szBuffer[2], sizeof(gs_szBuffer) - 2gs_szBuffer[2]);
            
            
strcat(gs_szBuffer"'");
        }
#endif
        
        
case DB::TYPE_PLAYER_NAME: {
            new
                
iPlayer getarg(3)
            ;
            
            if (!(
<= iPlayer MAX_PLAYERS) || !IsPlayerConnected(iPlayer)) {
                
DB::Warningf("(stmt_bind_value) Invalid player ID passed for DB::TYPE_PLAYER_NAME (%d)."iPlayer);
                
                
strcat(gs_szBuffer, !"''");
            } else {
                
gs_szBuffer[0] = '\'';
                
                
GetPlayerName(iPlayergs_szBuffer[1], sizeof(gs_szBuffer) - 1);
                
                
db_escape_string(gs_szBuffer[1], "'"sizeof(gs_szBuffer) - 1);
                
                
strcat(gs_szBuffer"'");
            }
        }
        
        case 
DB::TYPE_PLAYER_IP: {
            new
                
iPlayer getarg(3)
            ;
            
            if (!(
<= iPlayer MAX_PLAYERS) || !IsPlayerConnected(iPlayer)) {
                
DB::Warningf("(stmt_bind_value) Invalid player ID passed for DB::TYPE_PLAYER_IP (%d)."iPlayer);
                
                
strcat(gs_szBuffer, !"''");
            } else {
                
gs_szBuffer[0] = '\'';
                
                
GetPlayerIp(iPlayergs_szBuffer[1], sizeof(gs_szBuffer) - 1);
                
                
db_escape_string(gs_szBuffer[1], "'"sizeof(gs_szBuffer) - 1);
                
                
strcat(gs_szBuffer"'");
            }
        }
        
        
// http://www.sqlite.org/lang_keywords.html...0.81324268
        
case DB::TYPE_IDENTIFIER: {
            
bIsPacked = !!DB::isargpacked(3);
            
            if (!
bIsPacked)
                
gs_szBuffer[0] = '"';
            
            
DB::getstringarg(gs_szBuffer[bIsPacked 1], 3sizeof(gs_szBuffer) - 3);
            
            
db_escape_string(gs_szBuffer[bIsPacked 1], "\""sizeof(gs_szBuffer) - 1);
            
            if (
bIsPacked)
                
strins(gs_szBuffer"\""0);
            
            
strcat(gs_szBuffer"\"");
        }
        
        case 
DB::TYPE_RAW_STRING:
            
DB::getstringarg(gs_szBuffer3);
        
        case 
DB::TYPE_ARRAY: {
            
// DB::CompressArray(const aiArray[], iSize = sizeof(aiArray), aiOutput[])
            
            
if (iNumArgs != 5) {
                
DB::Error("(stmt_bind_value) Invalid argument count. DB::TYPE_ARRAY requires an additional argument containing the array's length.");
                
                return 
false;
            }
            
            new
                
iCompressedSize,
                
i
            
;
            
            
// Push the output array
            #emit PUSH.C      gs_aiCompressBuffer
            
            // Push the size
            #emit LREF.S.pri  28 // 12 + 4 cells
            #emit PUSH.pri
            
            // Push the input array
            #emit PUSH.S      24
            
            // Push the argument count
            #emit PUSH.C      12
            
            // Push the return address
            #emit LCTRL       6
            #emit ADD.C       28
            #emit PUSH.pri
            
            // Call DB::CompressArray
            #emit CONST.pri   DB_CompressArray
            #emit SCTRL       6
            
            // Store the return value
            #emit STOR.S.pri  iCompressedSize
            
            
iCompressedSize = (iCompressedSize 3) / 4;
            
            
gs_szBuffer[0] = 'x';
            
gs_szBuffer[1] = '\'';
            
            if ((
iCompressedSize << 3) + sizeof(gs_szBuffer)) {
                for (
0iCompressedSizei++)
                    
format(gs_szBuffer[+ (<< 3)], sizeof(gs_szBuffer) - (+ (<< 3)), "%01x%07x"gs_aiCompressBuffer[i] >>> 28gs_aiCompressBuffer[i] & 0x0FFFFFFF);
            } else {
                
strcat(gs_szBuffer"00");
                
                
DB::Errorf("(stmt_bind_value) Unable to compress the array; out of buffer size (has %d, needs %d)."sizeof(gs_szBuffer), (iCompressedSize << 3) + 2);
                
                return 
false;
            }
            
            
strcat(gs_szBuffer"'");
        }    
        
        default: {
default_case:
            
            
strcat(gs_szBuffer"NULL");
        }
    }
    
    
iLength strlen(gs_szBuffer);
    
    
iLengthDiff iLength gs_Statements[stStatement][e_aiParamLengths][iParam];
    
    
// Adjust the position of any params after the one being modified.
    
for (new iParam 1gs_Statements[stStatement][e_iParams]; i++)
        
gs_Statements[stStatement][e_aiParamPositions][i] += iLengthDiff;
    
    
// Delete the old parameter from the query.
    
strdel(gs_Statements[stStatement][e_szQuery], gs_Statements[stStatement][e_aiParamPositions][iParam], gs_Statements[stStatement][e_aiParamPositions][iParam] + gs_Statements[stStatement][e_aiParamLengths][iParam]);
    
    
// Make sure we have enough space.
    
if ((strlen(gs_Statements[stStatement][e_szQuery]) + iLengthchar DB::MAX_STATEMENT_SIZE) {
        
DB::Error("(stmt_bind_value) Buffer overflow. Increase DB_MAX_STATEMENT_SIZE.");
        
        
stmt_close(stStatement);
        
        return 
false;
    }
    
    
// Insert the new parameter.
    
strins(gs_Statements[stStatement][e_szQuery], gs_szBuffergs_Statements[stStatement][e_aiParamPositions][iParam], DB::MAX_STATEMENT_SIZE);
    
#if DB_DEBUG
    
if (ispacked(gs_szBuffer))
        
strunpack(gs_szBuffergs_szBuffer);
    
    
DB::Debug("(stmt_bind_value:%d) Inserted new value for parameter %d at %d: %s"_:stStatementiParamgs_Statements[stStatement][e_aiParamPositions][iParam], gs_szBuffer);
#endif
    
    
gs_Statements[stStatement][e_aiParamLengths][iParam] = iLength;
    
gs_Statements[stStatement][e_aiParamTypes][iParam] = iType;
    
    return 
true;
}
stock stmt_bind_result_field(&DBStatement:stStatementiFieldDBDataType:iType, {Float_}:...) {
    
DB::LazyInitialize();
    
    new
        
iAddress,
        
iSize,
        
iNumArgs
    
;
    
    
#emit LOAD.S.pri  8
    #emit SHR.C.pri   2
    #emit STOR.S.pri  iNumArgs
    
if (stStatement == DB::INVALID_STATEMENT || !(<= _:stStatement sizeof(gs_Statements))) {
        
DB::Warningf("(stmt_bind_result_field) Invalid statement passed (%d)."_:stStatement);
        return;
    }
    if (
iField 0) {
        
DB::Errorf("(stmt_bind_result_field) Negative field index (%d)."iField);
        return;
    }
    
    switch (
iType) {
        case 
DB::TYPE_STRING,
             
DB::TYPE_RAW_STRING,
             
DB::TYPE_IDENTIFIER,
             
DB::TYPE_ARRAY: {
            if (
iNumArgs != 5) {
                
DB::Error("(stmt_bind_result_field) Invalid number of arguments passed. Strings and arrays require an additional argument containing the string size.");
                return;
            }
            
            
iSize getarg(4);
        }
        
        case 
DB::TYPE_NONE: {
            
gs_Statements[stStatement][e_aiFieldTypes][iField] = DB::TYPE_NONE;
            
            return;
        }
        
        default: {
            if (
iNumArgs != 4) {
                
DB::Error("(stmt_bind_result_field) Invalid number of arguments passed.");
                return;
            }
            
            
iSize 1;
        }
    }
    
    if (
iField >= DB::MAX_FIELDS) {
        
DB::Warningf("(stmt_bind_result_field) Field index larger than max number of fields (%d > %d). Increase DB_MAX_FIELDS."iFieldDB::MAX_FIELDS);
        
        return;
    }
    
    
// Without this, STOR.S.pri doesn't seem to do what it should.
    
iAddress 0;
    
    
#emit LOAD.S.pri 24
    #emit STOR.S.pri iAddress
    
    
gs_Statements[stStatement][e_aiFieldTypes][iField] = iType;
    
gs_Statements[stStatement][e_aiFieldAddresses][iField] = iAddress;
    
gs_Statements[stStatement][e_aiFieldSizes][iField] = iSize;
    
    
DB::Debug("(stmt_bind_result_field:%d) Bound result field %d (type %d) to variable 0x%04x%04x."_:stStatementiField_:iTypeiAddress >>> 16iAddress 0xFFFF);
}
stock bool:stmt_skip_row(&DBStatement:stStatement) {
    
DB::LazyInitialize();
    
    if (
stStatement == DB::INVALID_STATEMENT || !(<= _:stStatement sizeof(gs_Statements))) {
        
DB::Errorf("(stmt_skip_row) Invalid statement passed (%d)."_:stStatement);
        
        return 
false;
    }
    
    if (
gs_Statements[stStatement][e_dbrResult] == DB::INVALID_RESULT) {
        if (!
gs_Statements[stStatement][e_iFetchedRows])
            
DB::Warning("(stmt_skip_row) Statement has no result.");
        
        return 
false;
    }
    
    
gs_Statements[stStatement][e_iFetchedRows]++;
    
    if (!
db_next_row(gs_Statements[stStatement][e_dbrResult])) {
        
db_free_result(gs_Statements[stStatement][e_dbrResult]);
        
        
gs_Statements[stStatement][e_dbrResult] = DB::INVALID_RESULT;
        
        
DB::Debug("(stmt_skip_row:%d) Skipped row and freed result."_:stStatement);
    } else {
        
DB::Debug("(stmt_skip_row:%d) Skipped row."_:stStatement);
    }
    
    return 
true;
}
stock bool:stmt_fetch_row(&DBStatement:stStatement) {
    
DB::LazyInitialize();
    
    if (
stStatement == DB::INVALID_STATEMENT || !(<= _:stStatement sizeof(gs_Statements))) {
        
DB::Errorf("(stmt_fetch_row) Invalid statement passed (%d)."_:stStatement);
        
        return 
false;
    }
    
    if (
gs_Statements[stStatement][e_dbrResult] == DB::INVALID_RESULT) {
        if (!
gs_Statements[stStatement][e_iFetchedRows])
            
DB::Warning("(stmt_fetch_row) Statement has no result.");
        
        return 
false;
    }
    if (!
stmt_rows_left(stStatement)) {
        
DB::Debug("(stmt_fetch_row) No rows left.");
        return 
false;
    }
    
    if (!
db_num_rows(gs_Statements[stStatement][e_dbrResult])) {
        
DB::Debug("(stmt_fetch_row) Freed previous result.");
        
        
db_free_result(gs_Statements[stStatement][e_dbrResult]);
        
        
gs_Statements[stStatement][e_dbrResult] = DB::INVALID_RESULT;
    
        return 
false;
    }
    
    new
        
iFields db_num_fields(gs_Statements[stStatement][e_dbrResult]),
        
iAddress,
        
xValue,
        
iCount
    
;
    
    if (
iFields DB::MAX_FIELDS) {
        
DB::Warning("(stmt_bind_result_field) There are more fields returned than DB_MAX_FIELDS.");
        
        
iFields DB::MAX_FIELDS;
    }
    
    
gs_Statements[stStatement][e_iFetchedRows]++;
    
    for (new 
iField 0iField iFieldsiField++) {
        if (
gs_Statements[stStatement][e_aiFieldTypes][iField] == DB::TYPE_NONE)
            continue;
        
        
iCount++;
        
        switch (
gs_Statements[stStatement][e_aiFieldTypes][iField]) {
            case 
DB::TYPE_NONE,
                 
DB::TYPE_NULL:
                continue;
            
            case 
DB::TYPE_INT,
                 
DB::TYPE_UINT,
                 
DB::TYPE_FLOAT: {
                
db_get_field(gs_Statements[stStatement][e_dbrResult], iFieldgs_szBuffersizeof(gs_szBuffer) - 1);
                
                
iAddress gs_Statements[stStatement][e_aiFieldAddresses][iField];
                
xValue = (gs_Statements[stStatement][e_aiFieldTypes][iField] != DB::TYPE_FLOAT) ? strval(gs_szBuffer) : _:floatstr(gs_szBuffer);
                
#emit LOAD.S.pri xValue
                #emit SREF.S.pri iAddress
            
}
            
            
// Assumes the field is a string containing a player name.
            // Gives the ID of a connected play with that name, otherwise INVALID_PLAYER_ID.
            
case DB::TYPE_PLAYER_NAME: {
                static
                    
s_szName[MAX_PLAYER_NAME]
                ;
                
                
xValue INVALID_PLAYER_ID;
                
                for (new 
0GetMaxPlayers(); li++) {
                    if (!
IsPlayerConnected(i))
                        continue;
                    
                    
GetPlayerName(is_szNamesizeof(s_szName));
                    
db_get_field(gs_Statements[stStatement][e_dbrResult], iFieldgs_szBuffersizeof(gs_szBuffer) - 1);
                    
                    if (!
strcmp(gs_szBuffers_szNametrue)) {
                        
xValue i;
                        
                        break;
                    }
                }
                
                
iAddress gs_Statements[stStatement][e_aiFieldAddresses][iField];
                
#emit LOAD.S.pri xValue
                #emit SREF.S.pri iAddress
            
}
            
            case 
DB::TYPE_STRING,
                 
DB::TYPE_RAW_STRING,
                 
DB::TYPE_IDENTIFIER: {
                new
                    
DBResult:dbrResult,
                             
iSize
                
;
                
                static const
                    
sc_szFormatString[] = "%s"
                
;
                
                
iAddress  gs_Statements[stStatement][e_aiFieldAddresses][iField];
                
dbrResult gs_Statements[stStatement][e_dbrResult];
                
iSize     gs_Statements[stStatement][e_aiFieldSizes][iField];
                
                
#emit PUSH.S    iSize
                #emit PUSH.S    iAddress
                #emit PUSH.S    iField
                #emit PUSH.S    dbrResult
                #emit PUSH.C    16
                #emit SYSREQ.C  db_get_field
                #emit STACK     20
                
                // Fix a bug with UTF-8 characters
                // For example, 'Г¶' would become 0xFFFFFFC3 instead of 0xC3
                #emit PUSH.S     iAddress
                #emit PUSH.C     sc_szFormatString
                #emit PUSH.S     iSize
                #emit PUSH.S     iAddress
                #emit PUSH.C     16
                #emit SYSREQ.C   format
                #emit STACK      20
            
}
            
            case 
DB::TYPE_ARRAY: {
                
// DecompressArray(const aiCompressedArray[], aiOutput[], iOutputSize = sizeof(aiOutput))
                
                
db_get_field(gs_Statements[stStatement][e_dbrResult], iFieldgs_szBuffersizeof(gs_szBuffer) - 1);
                
                
format(gs_szBuffersizeof(gs_szBuffer), "%s"gs_szBuffer);
                
strpack(gs_szBuffergs_szBuffer);
                
                new
                    
iOutputSize gs_Statements[stStatement][e_aiFieldSizes][iField],
                    
iDecompressedCells
                
;
                
                
iAddress gs_Statements[stStatement][e_aiFieldAddresses][iField];
                
                
// Push the output array size
                #emit PUSH.S      iOutputSize
                // Push the output array
                #emit PUSH.S      iAddress
                // Push the input array
                #emit PUSH.C      gs_szBuffer
                // Push the argument count
                #emit PUSH.C      12
                // Push the return address
                #emit LCTRL       6
                #emit ADD.C       28
                #emit PUSH.pri
                // Call DB::DecompressArray
                #emit CONST.pri   DB_DecompressArray
                #emit SCTRL       6
                
                // Store the return address
                #emit STOR.S.pri  iDecompressedCells
                
                // If there are more cells in the array, fill them with 0
                
if (iOutputSize iDecompressedCells) {
                    
DB::Noticef("(stmt_fetch_row:%d) The array fetched from the DB is smaller than the destination array (%d > %d); the remaining slots with will be filled with 0."_:stStatementiOutputSizeiDecompressedCells);
                    
                    
iAddress += iDecompressedCells 4-4;
                    
iOutputSize iOutputSize iDecompressedCells;
                    
                    
// DB::memset(aArray[], iValue, iSize = sizeof(aArray))
                    #emit PUSH.S      iOutputSize
                    #emit PUSH.C      0
                    #emit PUSH.S      iAddress
                    #emit PUSH.C      12
                    #emit LCTRL       6
                    #emit ADD.C       28
                    #emit PUSH.pri
                    #emit CONST.pri   DB_memset
                    #emit SCTRL       6
                
}
                
                
            }
        }
    }
    
    if (!
db_next_row(gs_Statements[stStatement][e_dbrResult])) {
        
db_free_result(gs_Statements[stStatement][e_dbrResult]);
        
        
gs_Statements[stStatement][e_dbrResult] = DB::INVALID_RESULT;
        
        
DB::Debug("(stmt_fetch_row:%d) Fetched %d fields and freed the result."_:stStatementiCount);
    } else {
        
DB::Debug("(stmt_fetch_row:%d) Fetched %d fields."_:stStatementiCount);
    }
    
    return 
true;
}
stock stmt_rows_left(&DBStatement:stStatement) {
    
DB::LazyInitialize();
    
    if (
stStatement == DB::INVALID_STATEMENT || !(<= _:stStatement sizeof(gs_Statements))) {
        
DB::Errorf("(stmt_rows_left) Invalid statement passed (%d)."_:stStatement);
        
        return 
0;
    }
    
    if (
gs_Statements[stStatement][e_dbrResult] == DB::INVALID_RESULT) {
        if (!
gs_Statements[stStatement][e_iFetchedRows])
            
DB::Warning("(stmt_rows_left) Statement has no result.");
        
        return 
0;
    }
    
    return 
max(0db_num_rows(gs_Statements[stStatement][e_dbrResult]) - gs_Statements[stStatement][e_iFetchedRows]);
}
stock bool:stmt_execute(&DBStatement:stStatementbool:bStoreResult truebool:bAutoFreeResult true) {
    
DB::LazyInitialize();
    
    if (
stStatement == DB::INVALID_STATEMENT || !(<= _:stStatement sizeof(gs_Statements))) {
        
DB::Errorf("(stmt_execute) Invalid statement passed (%d)."_:stStatement);
        
        return 
false;
    }
    
    if (!
gs_Statements[stStatement][e_dbDatabase]) {
        
DB::Errorf("(stmt_execute) Uninitialized statement passed (%d)."_:stStatement);
        
        return 
false;
    }
    
    
// Make sure all parameters have been set.
    
for (new 0gs_Statements[stStatement][e_iParams]; i++) {
        if (
gs_Statements[stStatement][e_aiParamTypes][i] == DB::TYPE_NONE) {
            
DB::Errorf("(stmt_execute) Uninitialized parameter in statement (%d)."i);
            
            return 
false;
        }
    }
    
    
// If old results are left, free them.
    
if (gs_Statements[stStatement][e_dbrResult] != DB::INVALID_RESULT) {
        
db_free_result(gs_Statements[stStatement][e_dbrResult]);
        
        
gs_Statements[stStatement][e_dbrResult] = DB::INVALID_RESULT;
    }
    
    
DB::Debug("(stmt_execute:%d) Executing statement."_:stStatement);
    
    new
        
DBResult:dbrResult db_query(gs_Statements[stStatement][e_dbDatabase], gs_Statements[stStatement][e_szQuery], false)
    ;
    
    
gs_Statements[stStatement][e_iFetchedRows] = 0;
    
gs_Statements[stStatement][e_bAutoFreeResult] = bAutoFreeResult;
    
    if (
dbrResult == DB::INVALID_RESULT)
        return 
false;
    
    if (!
bStoreResult)
        
db_free_result(dbrResult);
    else {
        
gs_Statements[stStatement][e_dbrResult] = dbrResult;
        
        if (
bAutoFreeResult && gs_iFreeStatementResultsTimer == -1)
            
gs_iFreeStatementResultsTimer SetTimer("db_free_stmt_results"1false);
    }
    
    return 
true;
}
stock stmt_free_result(&DBStatement:stStatement) {
    
DB::LazyInitialize();
    
    if (
stStatement == DB::INVALID_STATEMENT || !(<= _:stStatement sizeof(gs_Statements))) {
        
DB::Noticef("(stmt_free_result) Invalid statement passed (%d)."_:stStatement);
        
        return;
    }
    
    
gs_Statements[stStatement][e_iFetchedRows] = 0;
    
    if (
gs_Statements[stStatement][e_dbrResult] != DB::INVALID_RESULT) {
        
db_free_result(gs_Statements[stStatement][e_dbrResult]);
        
        
gs_Statements[stStatement][e_dbrResult] = DB::INVALID_RESULT;
        
        
DB::Debug("(stmt_free_result:%d) Freed result."_:stStatement);
    } else {
        
DB::Debug("(stmt_free_result:%d) Nothing to free."_:stStatement);
    }
}
stock stmt_close(&DBStatement:stStatement) {
    
DB::LazyInitialize();
    
    if (
stStatement == DB::INVALID_STATEMENT || !(<= _:stStatement sizeof(gs_Statements))) {
        
DB::Noticef("(stmt_close) Invalid statement passed (%d)."_:stStatement);
        
        return;
    }
    
    if (
gs_Statements[stStatement][e_dbrResult] != DB::INVALID_RESULT)
        
db_free_result(gs_Statements[stStatement][e_dbrResult]);
    
    
gs_Statements[stStatement][e_dbDatabase] = DB:0;
    
    
DB::Debug("(stmt_close:%d) Closed statement."_:stStatement);
    
    
stStatement DB::INVALID_STATEMENT;
}
stock stmt_autoclose(&DBStatement:stStatement) {
    
DB::LazyInitialize();
    
    if (
stStatement == DB::INVALID_STATEMENT || !(<= _:stStatement sizeof(gs_Statements))) {
        
DB::Noticef("(stmt_autoclose) Invalid statement passed (%d)."_:stStatement);
        
        return;
    }
    
    if (
gs_iAutoFreeTimer == -1)
        
gs_iAutoFreeTimer SetTimer("db_drain_autofree_pool"0false);
    
    if (
gs_iAutoCloseStatementsIndex >= sizeof(gs_astAutoCloseStatements)) {
        
DB::Warning("(stmt_autoclose) The autoclose pool is full!");
        
        return;
    }
    
    
gs_astAutoCloseStatements[gs_iAutoCloseStatementsIndex] = stStatement;
    
    
gs_iAutoCloseStatementsIndex++;
    
    
DB::Debug("(stmt_autoclose:%d) Will autoclose statement."_:stStatement);
}
stock DBResult:db_query_hook(iTagOf3 tagof(_bAutoRelease), DB:db, const szQuery[], {boolDBDataType}:_bAutoRelease true, {DBDataTypeQQPA}:...) {
    new
             
iIndex,
             
iNumArgs,
             
iStaticArgs 4,
        
bool:bAutoRelease true
    
;
    
    
#emit LOAD.S.pri  8
    #emit SHR.C.pri   2
    #emit STOR.S.pri  iNumArgs
    
    
DB::LazyInitialize();
    
    if (
iTagOf3 == tagof(DBDataType:)) {
        
iStaticArgs 3;
    } else {
        
bAutoRelease _bAutoRelease;
    }
    
    if (
db_is_persistent(db)) {
        if (!
db_is_valid_persistent(db)) {
            
DB::Errorf("(db_query) Invalid persistent database given (%04x%04x)."_:db >>> 16_:db 0xFFFF);
            
            return 
DB::INVALID_RESULT;
        }
        
        
iIndex _:db 0x7FFFFFFF;
        
        if (!
gs_PersistentDatabases[iIndex][e_dbDatabase]) {
            if (!(
gs_PersistentDatabases[iIndex][e_dbDatabase] = db_open(gs_PersistentDatabases[iIndex][e_szName]))) {
                
DB::Errorf("(db_query) Failed to lazily open the database.");
                
                return 
DB::INVALID_RESULT;
            }
            
            if (
gs_iClosePersistentTimer == -1)
                
gs_iClosePersistentTimer SetTimer("db_close_persistent"0false);
        }
        
        
db gs_PersistentDatabases[iIndex][e_dbDatabase];
    }
    
#if DB_DEBUG
    
if (ispacked(szQuery)) {
        
strunpack(gs_szBufferszQuery);
        
        
DB::Debug("(db_query) Running query: %s"gs_szBuffer);
    } else {
        
DB::Debug("(db_query) Running query: %s"szQuery);
    }
#endif
    
    
new
        
DBResult:dbrResult
    
;
    
    if (
iNumArgs iStaticArgs) {
        if ((
iNumArgs iStaticArgs) & 0b1) {
            
DB::Error("(db_query) Invalid argument count. Did you forget to use the correct prefix on the arguments (e.g. STRING:somestring)?");
            
            return 
DB::INVALID_RESULT;
        }
        
        new 
DBStatement:stmt db_prepare(dbszQuery);
        
        for (new 
iStaticArgs 1iNumArgs+= 2) {
            
// Load the address of argument <i>
            #emit LCTRL       5
            #emit LOAD.S.alt  i
            #emit SHL.C.alt   2
            #emit ADD
            #emit ADD.C       12
            #emit MOVE.alt
            #emit LOAD.I
            #emit PUSH.pri
            #emit PUSH.alt
            
            
if (== 4) {
                
// Load the address of argument <i - 1>
                #emit POP.pri
                #emit ADD.C       0xFFFFFFFC
                #emit LOAD.I
                #emit PUSH.pri
            
} else {
                
// Load the address of argument <i - 1>
                #emit POP.pri
                #emit ADD.C       0xFFFFFFFC
                #emit LOAD.I
                #emit LOAD.I
                #emit PUSH.pri
            
}
            
            
// Push the param index: (i - iStaticArgs) / 2
            #emit LOAD.S.pri  i
            #emit LOAD.S.alt  iStaticArgs
            #emit SUB
            #emit SHR.C.pri   1
            #emit PUSH.pri
            #emit PUSH.ADR    stmt
            
            // Push the argument count
            #emit PUSH.C      16
            
            // Push the return address
            #emit LCTRL       6
            #emit ADD.C       28
            #emit PUSH.pri
            
            // Call stmt_bind_value
            #emit CONST.pri   stmt_bind_value
            #emit SCTRL       6
        
}
        
        
dbrResult db_query@(dbgs_Statements[stmt][e_szQuery]);
        
        
stmt_close(stmt);
    } else {
        
dbrResult db_query@(dbszQuery);
    }
    
    if (
dbrResult) {
        if (
bAutoRelease)
            
db_autofree_result(dbrResult);
        
        new
            
iResultAddress db_get_result_mem_handle(dbrResult) - DB::GetAmxBaseRelative(),
            
iAddress,
            
iRows,
            
iCols,
            
iDataAddress,
            
iOffset
        
;
        
        
iAddress iResultAddress;
        
#emit LREF.S.pri  iAddress
        #emit STOR.S.pri  iRows
        
        
iAddress += 4;
        
#emit LREF.S.pri  iAddress
        #emit STOR.S.pri  iCols
        
        
iAddress += 4;
        
#emit LREF.S.pri  iAddress
        #emit STOR.S.pri  iDataAddress
        
        
iDataAddress -= DB::GetAmxBaseRelative();
        
        
iOffset = (iCols iRows iCols) * 4;
        
        while (
iOffset >= 0) {
            
iAddress iDataAddress iOffset;
            
            
#emit LREF.S.pri  iAddress
            #emit STOR.S.pri  iAddress
            
            
if (!iAddress) {
                new
                    
iAmxBaseRelative DB::GetAmxBaseRelative()
                ;
                
                
iAddress iDataAddress iOffset;
                
                
#emit CONST.pri   gs_szNull
                #emit LOAD.S.alt  iAmxBaseRelative
                #emit ADD
                #emit SREF.S.pri  iAddress
            
}
            
            
iOffset -= 4;
        }
    }
    
    return 
dbrResult;
}
stock db_get_field_hook(DBResult:dbresultfieldresult[], maxlength sizeof(result)) {
    new 
retval db_get_field(dbresultfieldresultmaxlength);
    
    
format(resultmaxlength"%s"result);
    
    return 
retval;
}
stock db_get_field_assoc_hook(DBResult:dbresult, const field[], result[], maxlength sizeof(result)) {
    new 
retval db_get_field_assoc(dbresultfieldresultmaxlength);
    
    
format(resultmaxlength"%s"result);
    
    return 
retval;
}
stock bool:db_dump_table(DB:db, const szTable[], const szFilename[]) {
    static
        
s_szColumnName[256]
    ;
    new
        
DBResult:dbrResult,
        
File:fp
    
;
    
    if (
strfind(szTable"\"") != -|| strfind(szTable"'") != -1) {
        
DB::Error("(db_dump_table) Invalid table name given.");
        
        return 
false;
    }
    
    if (!(
fp fopen(szFilenameio_write))) {
        
DB::Error("(db_dump_table) Failed to open the file.");
        
        return 
false;
    }
    
    
format(gs_szBuffersizeof(gs_szBuffer), "SELECT sql FROM sqlite_master WHERE tbl_name = '%s'"szTable);
    
    
dbrResult db_query(dbgs_szBuffer);
    
    if (!
dbrResult) {
        
DB::Error("(db_dump_table) Failed to get the table sql.");
        
        return 
false;
    }
    
    
db_get_field(dbrResult0gs_szBuffersizeof(gs_szBuffer) - 1);
    
    if (
strlen(gs_szBuffer) >= sizeof(gs_szBuffer) - 2) {
        
DB::Error("(db_dump_table) Buffer overflow.");
        
        
fwrite(fp"\nBUFFER OVERFLOW");
        
fclose(fp);
        
        
db_free_result(dbrResult);
        
        return 
false;
    }
    
    
fwrite(fpgs_szBuffer);
    
fwrite(fp";\n\n\n");
    
    
db_free_result(dbrResult);
    
    
format(gs_szBuffersizeof(gs_szBuffer), "PRAGMA table_info(%s)"szTable);
    
    
dbrResult db_query(dbgs_szBufferfalse);
    
    if (!
dbrResult) {
        
DB::Error("(db_dump_table) Failed to get table info.");
        
        return 
false;
    }
    
    
gs_szBuffer "SELECT 'INSERT INTO ";
    
strcat(gs_szBufferszTable);
    
strcat(gs_szBuffer" VALUES('");
    
    if (
db_num_rows(dbrResult)) do {
        
db_get_field(dbrResult1s_szColumnNamesizeof(s_szColumnName) - 1);
        
        if (
db_get_row_index(dbrResult) > 0)
            
strcat(gs_szBuffer" || ', '");
        
        
strcat(gs_szBuffer" || quote(");
        
strcat(gs_szBuffers_szColumnName);
        
strcat(gs_szBuffer")");
    } while (
db_next_row(dbrResult));
    
    
strcat(gs_szBuffer" || ');' FROM ");
    
strcat(gs_szBufferszTable);
    
    
db_free_result(dbrResult);
    
    
dbrResult db_query(dbgs_szBuffer);
    
    
fwrite(fp"BEGIN;\n\n");
    
    if (
db_num_rows(dbrResult)) do {
        
db_get_field(dbrResult0gs_szBuffersizeof(gs_szBuffer) - 1);
        
        if (
strlen(gs_szBuffer) >= sizeof(gs_szBuffer) - 2) {
            
DB::Error("(db_dump_table) Buffer overflow.");
            
            
fwrite(fp"\nBUFFER OVERFLOW");
            
fclose(fp);
            
            
db_free_result(dbrResult);
            
            return 
false;
        }
        
        
fwrite(fpgs_szBuffer);
        
fwrite(fp"\n");
    } while (
db_next_row(dbrResult));
    
    
fwrite(fp"\nCOMMIT;\n");
    
    
db_free_result(dbrResult);
    
    
fclose(fp);
    
    return 
true;
}
stock DBResult:db_print_result(DBResult:dbrResultiMaxFieldLength 40) {
    
DB::LazyInitialize();
    
    const
        
MAX_ROWS         100,
        
MAX_FIELDS       20,
        
MAX_FIELD_LENGTH 88
    
;
    
    static
        
s_aaszFields[MAX_ROWS 1][MAX_FIELDS][MAX_FIELD_LENGTH char],
        
s_aiFieldMaxLength[MAX_FIELDS]
    ;
    
    static const
        
szcSpacePadding[MAX_FIELD_LENGTH] = {' ', ...},
        
szcDashPadding[MAX_FIELD_LENGTH] = {'-', ...}
    ;
    
    if (
iMaxFieldLength == -1)
        
iMaxFieldLength MAX_FIELD_LENGTH;
    
    print(!
" ");
    print(!
"Query result:");
    
    if (!
dbrResult)
        print(!
"\t- Invalid result.");
    else if (!
db_num_rows(dbrResult))
        print(!
"\t- No rows.");
    else {
        new
                 
iRow 0,
                 
iRows,
                 
iFields db_num_fields(dbrResult),
                 
iField,
                 
iLength,
            
bool:bHasMoreLines,
                 
iPos,
                 
iNextPos,
                 
iRowIndex db_get_row_index(dbrResult)
        ;
        
        
db_set_row_index(dbrResult0);
        
        if (
iMaxFieldLength MAX_FIELD_LENGTH) {
            
printf("\t- The longest possible field length is %d. Change MAX_FIELD_LENGTH for larger values."MAX_FIELD_LENGTH);
            
            
iMaxFieldLength MAX_FIELD_LENGTH;
        }
        
        if (
iFields MAX_FIELDS) {
            
printf("\t- There are %d, but only %d of them will be visible."iFieldsMAX_FIELDS);
            print(!
"\t- Increase MAX_FIELDS if you want to see all fields.");
            
            
iFields MAX_FIELDS;
        }
        
        for (
iField 0iField iFieldsiField++) {
            
db_field_name(dbrResultiFieldgs_szBufferiMaxFieldLength 1);
            
            
iPos 0;
            
            while (-
!= (iPos strfind(gs_szBuffer"\r"_iPos)))
                
gs_szBuffer[iPos] = ' ';
            
            
iPos 0;
            
            while (-
!= (iPos strfind(gs_szBuffer"\t"_iPos))) {
                
gs_szBuffer[iPos] = ' ';
                
                
strins(gs_szBuffer"   "iPosiMaxFieldLength);
                
                
iPos += 4;
            }
            
            
iPos 0;
            do {
                
iNextPos strfind(gs_szBuffer"\n"_iPos) + 1;
                if (!
iNextPos)
                    
iLength strlen(gs_szBuffer[iPos]);
                else
                    
iLength iNextPos iPos 1;
                
s_aiFieldMaxLength[iField] = min(iMaxFieldLengthmax(iLengths_aiFieldMaxLength[iField]));
            } while ((
iPos iNextPos));
            
            
strpack(s_aaszFields[0][iField], gs_szBufferiMaxFieldLength char);
        }
        
        do {
            for (
iField 0iField iFieldsiField++) {
                if (
db_field_is_null(dbrResultiField))
                    
gs_szBuffer "NULL";
                else
                    
db_get_field(dbrResultiFieldgs_szBufferiMaxFieldLength 1);
                
                
iPos 0;
                
                while (-
!= (iPos strfind(gs_szBuffer"\r"_iPos)))
                    
gs_szBuffer[iPos] = ' ';
                
                
iPos 0;
                
                while (-
!= (iPos strfind(gs_szBuffer"\t"_iPos))) {
                    
gs_szBuffer[iPos] = ' ';
                    
                    
strins(gs_szBuffer"   "iPosiMaxFieldLength);
                    
                    
iPos += 4;
                }
                
                
iPos 0;
                do {
                    
iNextPos strfind(gs_szBuffer"\n"_iPos) + 1;
                    if (!
iNextPos)
                        
iLength strlen(gs_szBuffer[iPos]);
                    else
                        
iLength iNextPos iPos 1;
                    
s_aiFieldMaxLength[iField] = min(iMaxFieldLengthmax(iLengths_aiFieldMaxLength[iField]));
                } while ((
iPos iNextPos));
                
strpack(s_aaszFields[iRow 1][iField], gs_szBufferiMaxFieldLength char);
            }
            
            if (++
iRow >= MAX_ROWS) {
                
iRows iRow;
                
                while (
db_next_row(dbrResult))
                    
iRows++;
                
                
printf("\t- Only the first %d rows are displayed; there are %d remaining."MAX_ROWSiRows);
                
                break;
            }
        } while (
db_next_row(dbrResult));
        
        print(!
" ");
        
        for (
iRows iRowiRow 0iRow <= iRowsiRow++) {
            do {
                
bHasMoreLines false;
                
                
gs_szBuffer[0] = 0;
                
                for (
iField 0iField iFieldsiField++) {
                    if (
iField)
                        
strcat(gs_szBuffer" | ");
                    
                    
iLength strlen(gs_szBuffer);
                    
                    if (-
!= (iPos strfind(s_aaszFields[iRow][iField], "\n"))) {
                        
strunpack(gs_szBuffer[iLength], s_aaszFields[iRow][iField], strlen(gs_szBuffer[iLength]) + iPos 1);
                        
                        
strdel(s_aaszFields[iRow][iField], 0iPos 1);
                        
                        
bHasMoreLines true;
                    } else {
                        if (
s_aaszFields[iRow][iField]{0}) {
                            
strunpack(gs_szBuffer[iLength], s_aaszFields[iRow][iField], sizeof(gs_szBuffer) - iLength);
                            
                            
s_aaszFields[iRow][iField]{0} = 0;
                        }
                    }
                
                    
iLength strlen(gs_szBuffer[iLength]);
                    
                    
strcat(gs_szBufferszcSpacePaddingstrlen(gs_szBuffer) + (s_aiFieldMaxLength[iField] - iLength 1));
                }
                
                if (
bHasMoreLines)
                    
printf("\t| %s |"gs_szBuffer);
                
            } while (
bHasMoreLines);
            
            if (
iRow == 0) {
                
printf("\t/ %s \\"gs_szBuffer);
            } else {
                
printf("\t| %s |"gs_szBuffer);
            }
            
            if (
iRow == iRows) {
                
gs_szBuffer[0] = 0;
                
                for (
iField 0iField iFieldsiField++) {
                    if (
iField)
                        
strcat(gs_szBuffer"---");
                    
                    
strcat(gs_szBufferszcDashPaddingstrlen(gs_szBuffer) + s_aiFieldMaxLength[iField] + 1);
                }
                
printf("\t\\-%s-/"gs_szBuffer);
            } else {
                
gs_szBuffer[0] = 0;
                
                for (
iField 0iField iFieldsiField++) {
                    if (
iField)
                        
strcat(gs_szBuffer"-|-");
                    
                    
strcat(gs_szBufferszcDashPaddingstrlen(gs_szBuffer) + s_aiFieldMaxLength[iField] + 1);
                }
                
                
printf("\t|-%s-|"gs_szBuffer);
            }
        }
        
        
db_set_row_index(dbrResultiRowIndex);
    }
    
    print(!
" ");
    
    return 
dbrResult;
}
stock db_print_query(DB:db, const szQuery[], iMaxFieldLength 40) {
    new
        
DBResult:dbrResult db_query(dbszQueryfalse)
    ;
    
    
db_print_result(dbrResultiMaxFieldLength);
    
    
db_free_result(dbrResult);
}
forward db_drain_autofree_pool();
public 
db_drain_autofree_pool() {
    
DB::LazyInitialize();
    
    
gs_iAutoFreeTimer = -1;
    
    for (new 
gs_iAutoFreeResultsIndexi--; ) {
        if (
gs_adbrAutoFreeResults[i]) {
            new 
DBResult:result gs_adbrAutoFreeResults[i];
            
            
gs_adbrAutoFreeResults[i] = DB::INVALID_RESULT;
            
            
DB::Debug("(db_drain_autofree_pool) Autofreeing 0x%04x%04x"_:result >>> 16_:result 0xFFFF);
            
            
db_free_result_hook(result);
        }
    }
    
    
gs_iAutoFreeResultsIndex 0;
    for (new 
gs_iAutoCloseStatementsIndexi--; ) {
        if (
gs_astAutoCloseStatements[i]) {
            
DB::Debug("(db_drain_autofree_pool) Autoclosing statement %d."_:gs_astAutoCloseStatements[i]);
        
            
stmt_close(gs_astAutoCloseStatements[i]);
        }
    }
    
    
gs_iAutoCloseStatementsIndex 0;
}
forward db_free_stmt_results();
public 
db_free_stmt_results() {
    
gs_iFreeStatementResultsTimer = -1;
    
    for (new 
DBStatement:DBStatement:0_:sizeof(gs_Statements); i++) {
        if (
gs_Statements[i][e_dbDatabase]
         && 
gs_Statements[i][e_bAutoFreeResult]
         && 
gs_Statements[i][e_dbrResult] != DB::INVALID_RESULT) {
            new 
DBResult:result gs_Statements[i][e_dbrResult];
            
            
gs_Statements[i][e_dbrResult] = DB::INVALID_RESULT;
            
            
DB::Debug("(db_free_stmt_results) Freeing 0x%04x%04x for %d."_:result >>> 16_:result 0xFFFF_:i);
            
            
db_free_result_hook(result);
        }
    }
}
forward db_close_persistent();
public 
db_close_persistent() {
    
gs_iClosePersistentTimer = -1;
    
    for (new 
0sizeof(gs_PersistentDatabases); i++) {
        if (
gs_PersistentDatabases[i][e_bIsUsed] && gs_PersistentDatabases[i][e_dbDatabase]) {
            
db_close@(gs_PersistentDatabases[i][e_dbDatabase]);
            
            
gs_PersistentDatabases[i][e_dbDatabase] = DB:0;
        }
    }
}
static 
stock DB::FindMSB(iInput) {
    
// http://graphics.stanford.edu/~seander/bi...0.81324268
    
    
static const
        
s_aiDeBruijnBitPositionsPacked[32 char] = {
            
0x0A010900,
            
0x1D02150D,
            
0x12100E0B,
            
0x1E031916,
            
0x1C140C08,
            
0x0718110F,
            
0x06171B13,
            
0x1F04051A
        
}
    ;
    
    if (
iInput) {
        
#emit LOAD.S.pri  iInput
        #emit MOVE.alt
        #emit SHR.C.alt   1
        #emit OR
        #emit MOVE.alt
        #emit SHR.C.alt   2
        #emit OR
        #emit MOVE.alt
        #emit SHR.C.alt   4
        #emit OR
        #emit MOVE.alt
        #emit SHR.C.alt   8
        #emit OR
        #emit MOVE.alt
        #emit SHR.C.alt   16
        #emit OR
        #emit CONST.alt   0x07C4ACDD
        #emit UMUL
        #emit SHR.C.pri   27
        #emit ADD.C       s_aiDeBruijnBitPositionsPacked
        #emit LODB.I      1
        #emit RETN
    
}
    
    return -
1;
}
static 
stock DB::getstringarg(dest[], arglen sizeof (dest)) {
    
// Get the address of the previous function's stack.  First get the index of
    // the argument required.
    #emit LOAD.S.pri arg
    // Then convert that number to bytes from cells.
    #emit SMUL.C     4
    // Get the previous function's frame.  Stored in variable 0 (in the current
    // frame).  Parameters are FRM+n+12, locals are FRM-n, previous frame is
    // FRM+0, return address is FRM+4, parameter count is FRM+8.  We could add
    // checks that "arg * 4 < *(*(FRM + 0) + 8)", for the previous frame parameter
    // count (in C pointer speak).
    #emit LOAD.S.alt 0
    // Add the frame pointer to the argument offset in bytes.
    #emit ADD
    // Add 12 to skip over the function header.
    #emit ADD.C      12
    // Load the address stored in the specified address.
    #emit LOAD.I
    // Push the length for "strcat".
    #emit PUSH.S     len
    // Push the address we just determined was the source.
    #emit PUSH.pri
    // Load the address of the destination.
    #emit LOAD.S.alt dest
    // Blank the first cell so "strcat" behaves like "strcpy".
    #emit CONST.pri  0
    // Store the loaded number 0 to the loaded address.
    #emit STOR.I
    // Push the loaded address.
    #emit PUSH.alt
    // Push the number of parameters passed (in bytes) to the function.
    #emit PUSH.C     12
    // Call the function.
    #emit SYSREQ.C   strcat
    // Restore the stack to its level before we called this native.
    #emit STACK      16
}
static 
stock DB::setstringarg(iArg, const szValue[], iLength sizeof(szValue)) {
    new
        
iAddress
    
;
    
// Get the address of the previous function's stack.  First get the index of
    // the argument required.
    #emit LOAD.S.pri iArg
    // Then convert that number to bytes from cells.
    #emit SMUL.C     4
    // Get the previous function's frame.
    #emit LOAD.S.alt 0
    // Add the frame pointer to the argument offset in bytes.
    #emit ADD
    // Add 12 to skip over the function header.
    #emit ADD.C      12
    // Load the address stored in the specified address.
    #emit LOAD.I
    #emit STOR.S.PRI iAddress
    // Push the length (last argument first)
    #emit PUSH.S     iLength
    // Push the new value (source) szValue
    #emit PUSH.S     szValue
    // Blank out the first cell of the argument
    #emit CONST.pri  0
    #emit SREF.S.pri iAddress
    
    // Push the destination
    #emit PUSH.S     iAddress
    // Push the number of parameters passed (in bytes) to the function.
    #emit PUSH.C     12
    
    // Call the function.
    #emit SYSREQ.C   strcat
    
    // Restore the stack to its level before we called this native.
    #emit STACK      16
}
// Pretty much ******'s va_strlen function
static stock DB::isargpacked(iArg) {
    
// Get the length of the string at the given position on the previous
    // function's stack (convenience function).
    // Get the address of the previous function's stack.  First get the index of
    // the argument required.
    #emit LOAD.S.pri iArg
    // Then convert that number to bytes from cells.
    #emit SMUL.C     4
    // Get the previous function's frame.  Stored in variable 0 (in the current
    // frame).  Parameters are FRM+n+12, locals are FRM-n, previous frame is
    // FRM+0, return address is FRM+4, parameter count is FRM+8.  We could add
    // checks that "arg * 4 < *(*(FRM + 0) + 8)", for the previous frame parameter
    // count (in C pointer speak).
    #emit LOAD.S.alt 0
    // Add the frame pointer to the argument offset in bytes.
    #emit ADD
    // Add 12 to skip over the function header.
    #emit ADD.C      12
    // Load the address stored in the specified address.
    #emit LOAD.I
    // Push the address we just determined was the source.
    #emit PUSH.pri
    // Push the number of parameters passed (in bytes) to the function.
    #emit PUSH.C     4
    // Call the function.
    #emit SYSREQ.C   ispacked
    // Restore the stack to its level before we called this native.
    #emit STACK      8
    #emit RETN
    // Never called.
    
return 0;
}
stock DB::GetAmxBaseRelative() {
    static
        
s_iAmxBaseRelative 0
    
;
    
    if (!
s_iAmxBaseRelative) {
        
s_iAmxBaseRelative DB::GetAmxBase();
        
#emit LCTRL     1
        #emit LOAD.alt  s_iAmxBaseRelative
        #emit ADD
        #emit STOR.pri  s_iAmxBaseRelative
    
}
    
    return 
s_iAmxBaseRelative;
}
// By Zeex!
// Returns the AMX base address i.e. amx->base.
static stock DB::dummy() {
    return 
0;
}
stock DB::GetAmxBase() {
    static 
amx_base 0// cached
    
if (amx_base == 0) {
        new 
coddat;
        
#emit lctrl 0
        #emit stor.s.pri cod
        #emit lctrl 1
        #emit stor.s.pri dat
        // Get code section start address relative to data.
        
new code_start cod dat;
        
// Get address of DB::dummy().
        
new fn_addr;
        
#emit const.pri DB_dummy
        #emit stor.s.pri fn_addr
        // Get absolute address from the CALL instruction.
        
new fn_addr_reloccall_addr;
        
DB_dummy();
        
#emit lctrl 6
        #emit stor.s.pri call_addr
        
call_addr call_addr 12 code_start;
        
#emit lref.s.pri call_addr
        #emit stor.s.pri fn_addr_reloc
        
amx_base fn_addr_reloc fn_addr cod;
    }
    return 
amx_base;
}
// phys_memory.inc
static stock AbsToRel(addr) {
    new 
dat;
    
#emit lctrl 1
    #emit stor.s.pri dat
    
return addr - (GetAmxBaseAddress() + dat);
}
// This function has a bug in older amx_assembly versions
static stock WritePhysMemoryCell_(addrwhat) {
    new 
rel_addr AbsToRel(addr);
    
#emit load.s.pri what
    #emit sref.s.pri rel_addr
    #emit stack 4
    #emit retn
    
return 0// make compiler happy
}
// Hook db_get_field
// This is done lastly because the fixed function isn't needed within SQLitei
#define db_get_field db_get_field_hook
#define db_get_field_assoc db_get_field_assoc_hook 
Reply
#2

Maybe your a_sampdb.inc is outdated.
Download samp server package, and copy the includes into your gamemode directory.
Reply
#3

You probably used the wrong include version. The script probably uses an older or newer version.
Reply
#4

Quote:
Originally Posted by BurnZ
Посмотреть сообщение
You probably used the wrong include version. The script probably uses an older or newer version.
Don't not this is version correct
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)