OvidiuS icon

Untitled

OvidiuS | PRO | 06/15/16 03:21:36 PM UTC | 0 ⭐ | 300 👁️ | Never ⏰ | []
C++ |

3.68 KB

|

None

|

0 👍

/

0 👎

// The C Plus Plus headers.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <stdarg.h>
 
// The other further headers.
#include "Header.h"
#include "amxxmodule.h"
#include "sqlite3.h"
 
// The definitions.
#define MAXIMUM_CHARACTERS_FOR_STRING   4096U
#define MAXIMUM_CHARACTERS_FOR_COLUMN   128U
#define MAXIMUM_ROWS_TO_SELECT          2048U
#define MAXIMUM_COLUMNS_TO_HAVE         64U
 
// The Database_Row class. Each row will contain 64 columns as long as 128 maximum characters.
class Database_Row
{
public:
    char Column[MAXIMUM_COLUMNS_TO_HAVE][MAXIMUM_CHARACTERS_FOR_COLUMN];
};
 
// The data used into the extension.
Database_Row g_Row[MAXIMUM_ROWS_TO_SELECT];
 
sqlite3 * g_Handle = NULL;
 
char g_String[MAXIMUM_CHARACTERS_FOR_STRING];
 
int g_Rows = 0U;
int g_Iterator = 0U;
int g_Length = 0U;
 
// The SQLite handlers.
int SQLite_SelectQueryHandler(void *, int Count, char ** Data, char **)
{
    if (g_Rows < MAXIMUM_ROWS_TO_SELECT)
    {
        for (g_Iterator = 0; g_Iterator < Count && g_Iterator < MAXIMUM_COLUMNS_TO_HAVE; g_Iterator++)
        {
            _snprintf(g_Row[g_Rows].Column[g_Iterator], MAXIMUM_CHARACTERS_FOR_COLUMN, "%s", \
                Data[g_Iterator] ? Data[g_Iterator] : "NULL");
        }
    }
 
    // Let this one to increment everytime. It will be usefull for getting the rows count from any table.
    g_Rows++;
 
    return 0U;
}
 
int SQLite_UpdateQueryHandler(void *, int, char **, char **)
{
    // Do nothing.
    return 0U;
}
 
// The AMX Mod X functions.
static cell AMX_NATIVE_CALL Query(AMX * Handle, cell * Parameters)
{
    g_Rows = 0U;
 
    sqlite3_exec(g_Handle, MF_GetAmxString(Handle, Parameters[1U], 0U, 0U), Parameters[2U] ? \
        SQLite_SelectQueryHandler : SQLite_UpdateQueryHandler, NULL, NULL);
 
    return g_Rows;
}
 
static cell AMX_NATIVE_CALL Get(AMX * Handle, cell * Parameters)
{
    // If the coder will fail, this won't log any error. Will just set the buffer as "NULL" and will return zero.
    if (Parameters[1U] >= 0U && Parameters[1U] < MAXIMUM_ROWS_TO_SELECT && Parameters[2U] >= 0U && \
        Parameters[2U] < MAXIMUM_COLUMNS_TO_HAVE)
    {
        MF_SetAmxString(Handle, Parameters[3U], g_Row[Parameters[1U]].Column[Parameters[2U]], Parameters[4U]);
 
        return (cell)atoi(g_Row[Parameters[1U]].Column[Parameters[2U]]);
    }
 
    MF_SetAmxString(Handle, Parameters[3U], "NULL", Parameters[4U]);
 
    return 0U;
}
 
static cell AMX_NATIVE_CALL Safe(AMX * Handle, cell * Parameters)
{
    // Run into an error whether coder wants to replace a bad character with another bad character.
    if (Parameters[2] == '\'' || Parameters[2] == '"' || Parameters[2] == '\\' || Parameters[2] == '`')
    {
        MF_LogError(Handle, AMX_ERR_NATIVE, \
            "Unable to replace a bad character with another bad character. Bad characters are \\, ', \" and `.");
 
        return 0U;
    }
 
    g_Length = _snprintf(g_String, MAXIMUM_CHARACTERS_FOR_STRING, "%s", MF_GetAmxString(Handle, Parameters[1U], 0U, 0U));
 
    // Check for each character.
    for (g_Iterator = 0; g_Iterator < g_Length; g_Iterator++)
    {
        if (g_String[g_Iterator] == '\'' || g_String[g_Iterator] == '"' || g_String[g_Iterator] == '\\' \
            || g_String[g_Iterator] == '`')
        {
            // Replace bad character with the given one.
            g_String[g_Iterator] = Parameters[2U];
        }
    }
 
    MF_SetAmxString(Handle, Parameters[1U], g_String, g_Length);
 
    return 1U;
}
 
// Functions bundle.
const AMX_NATIVE_INFO g_Functions[] =
{
    { "Database_Query", Query },
    { "Database_Get", Get },
    { "Database_Safe", Safe },
 
    { NULL, NULL }
};
 
// AMX Mod X forwards.
void OnAmxxAttach(void)
{
    MF_AddNatives(g_Functions);
 
    sqlite3_open("Database.SQ3", &g_Handle);
}
 
void OnAmxxDetach(void)
{
    sqlite3_close(g_Handle);
}

Comments