[Plugin] [REL] MySQL Plugin (Now on github!)

Sometimes this error is in mysql_log without reason:
Код:
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
I was checked all mysql_tqueries but there isn't any problem, is it my problem or plugin's?
+
PLEASE COMPILE THE PLUGIN FOR NEW FIX IN OnQueryError !!!
Reply

Quote:
Originally Posted by Aliassassin123456
Посмотреть сообщение
Sometimes this error is in mysql_log without reason:
Код:
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
.....
I was checked all mysql_tqueries but there isn't any problem, is it my problem or plugin's?
+
PLEASE COMPILE THE PLUGIN FOR NEW FIX IN OnQueryError !!!
It is fine here, must be something with your script. I'm also using ID 1 connection handle.
Reply

Quote:
Originally Posted by georJik
Посмотреть сообщение
On Windows - good.
Linux - bad.
Well, this isn't really an answer to my question.

Quote:
Originally Posted by Misiur
Посмотреть сообщение
It seems that sometimes threaded queries lose data (no idea what causes it, can't isolate test case).

http://pastebin.com/V6J8T1NQ
Also there is ~400 cache_get_row calls earlier in the same second.


This one has two records in database, but cache_get_row_count returns 0. Reverting to R34 solves the problem. I'm not sure, but I had reports of that only on linux (didn't get anyone to check on windows).
Quote:
Originally Posted by Aliassassin123456
Посмотреть сообщение
Sometimes this error is in mysql_log without reason:
Код:
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[21:58:46] [ERROR] "mysql_tquery" - invalid connection handle (id: 1)
[...]
I was checked all mysql_tqueries but there isn't any problem, is it my problem or plugin's?
+
PLEASE COMPILE THE PLUGIN FOR NEW FIX IN OnQueryError !!!
I'll lock myself up in the basement and test everything the plugin has to offer. I won't release a new version until I'm absolutely sure that there are no bugs (kinda getting sick of those bugs). I'll also take my time (no ETA till R38), but you can always check progress through the commits.
Reply

Ok, seems like issue is back on R34 as well, so get out of basement for now. Still no idea what causes it, so either the cache is overwritten when it shouldn't be, or it's somewhere deeper - on libmysql, or db level. I'll investigate further.
Reply

orm_save and orm_update sometimes stores the data in the wrong charset.

Код:
тест -> ????
Reply

Quote:

strcat(cVar, "reg_id,autoLogin,pass,IP,adminlevel,hours,minutes ,seconds,kills,deaths,money,score,premium,saveskin ,spawnplace,seepms,cookies,events_won,races_won,MB _found,keyflip,savedvehicle,speedboost,wheels,reg_ time,last_time,color,goto,autofix,god,bmoney,rtest s,arrests,plate,bounce,");
strcat(cVar, "speedo,autotune,superman,killstreak,description,d uels_won,hidden,weapon_set,fallouts,country,group_ id,group_rank,derby_wins,time,weather,v_expired,ch at_color,hideMSGs,duels_off,cookiejars,Muted,Jaile d,report_points,id_color,house_id");

format(cQuery, sizeof(cQuery), "SELECT %s FROM players WHERE name='%s' LIMIT 1", cVar, PlayerName);
mysql_function_query(g_SQL_handle, cQuery, true, "OnUserDataLoad", "i", playerid);

Just converted to the latest version of this plugin today, for some reason OnUserDataLoad doesnt get executed, am I doing something wrong?
Reply

Quote:
Originally Posted by ReV.
Посмотреть сообщение
Just converted to the latest version of this plugin today, for some reason OnUserDataLoad doesnt get executed, am I doing something wrong?
It looks fine, can you check the debug information.

Quote:
Originally Posted by CKA3KuH
Посмотреть сообщение
orm_save and orm_update sometimes stores the data in the wrong charset.

Код:
тест -> ????
Which character set you're using? i.e. usc2, utf16, utf32, utf8mb4...
Reply

Oh, Rev. I thought your uber sfse plugin is better than this one, did my speed tests convince you?
Reply

Quote:
Originally Posted by iZN
Посмотреть сообщение
It looks fine, can you check the debug information.



Which character set you're using? i.e. usc2, utf16, utf32, utf8mb4...
utf8 and cp1251
Reply

Quote:

Using non-threaded queries that let your script wait until data is loaded, or intentionally block the rest of OnFilterScriptInit to be executed by adding a loop that checks for flags to be set from within the callbacks of those queries?
Either way, the server will be held back to be started until data has been loaded, which is exactly what I need.

Compare this:
pawn Code:
new
    Cache:players = mysql_query(MySQL, "SELECT COUNT(`id`) FROM `players`")
;
printf("There are %d players", cache_get_row_int(0, 0, MySQL));
cache_delete(players, MySQL);

new
    Cache:vehicles = mysql_query(MySQL, "SELECT COUNT(`id`) FROM `vehicles`")
;
printf("There are %d vehicles", cache_get_row_int(0, 0, MySQL));
cache_delete(vehicles, MySQL);

printf("Everything done!");
with this:
pawn Code:
new
    loadQueriesStatus = 0,
;

//(...)
public OnGameModeInit()
{
    inline PHandle() {
        printf("There are %d players", cache_get_row_int(0, 0, MySQL));
        loadQueriesStatus |= 1;
        StartupSequence();
    }
    mysql_tquery_inline(MySQL, "SELECT 2 + 2 FROM dual", using inline PHandle, "");

    inline VHandle() {
        printf("There are %d vehicles", cache_get_row_int(0, 0, MySQL));    
        loadQueriesStatus |= 2;
        StartupSequence();
    }
    mysql_tquery_inline(MySQL, "SELECT 3 + 3 FROM dual", using inline VHandle, "");

   
    printf("Everything done!");
    return 1;
}

stock StartupSequence()
{
    if(loadQueriesStatus != (1 | 2)) return 0;
    printf("Let's do it!");

    return 1;
}
(y_inline optional). Now, with first version, query #2 has to wait until query #1 is finished. If query #1 is big, this will create a big startup delay, with every new query piling up queries in "queue" (let's say O(n), but n isn't constant). Now, using magic of threading (and multiple cores if you can), this doesn't have to happen. All queries are fired at the same time, and your script has to wait only for the one running the longest (O(x) where x is the longest taking query. I think).

So, assuming you have 4 queries taking 1.6s each (gigantic stuff, yeah) it will take:
Unthreaded - 4x1.6 = 6.4s
Threaded - 1.6s

And still you have an option to wait until everything is done before allowing players to join.

#e: note to self, use less word "query"
Reply

Quote:
Originally Posted by Misiur
View Post
Compare this:
pawn Code:
new
    Cache:players = mysql_query(MySQL, "SELECT COUNT(`id`) FROM `players`")
;
printf("There are %d players", cache_get_row_int(0, 0, MySQL));
cache_delete(players, MySQL);

new
    Cache:vehicles = mysql_query(MySQL, "SELECT COUNT(`id`) FROM `vehicles`")
;
printf("There are %d vehicles", cache_get_row_int(0, 0, MySQL));
cache_delete(vehicles, MySQL);

printf("Everything done!");
with this:
pawn Code:
new
    loadQueriesStatus = 0,
;

//(...)
public OnGameModeInit()
{
    inline PHandle() {
        printf("There are %d players", cache_get_row_int(0, 0, MySQL));
        loadQueriesStatus |= 1;
        StartupSequence();
    }
    mysql_tquery_inline(MySQL, "SELECT 2 + 2 FROM dual", using inline PHandle, "");

    inline VHandle() {
        printf("There are %d vehicles", cache_get_row_int(0, 0, MySQL));    
        loadQueriesStatus |= 2;
        StartupSequence();
    }
    mysql_tquery_inline(MySQL, "SELECT 3 + 3 FROM dual", using inline VHandle, "");

   
    printf("Everything done!");
    return 1;
}

stock StartupSequence()
{
    if(loadQueriesStatus != (1 | 2)) return 0;
    printf("Let's do it!");

    return 1;
}
(y_inline optional). Now, with first version, query #2 has to wait until query #1 is finished. If query #1 is big, this will create a big startup delay, with every new query piling up queries in "queue" (let's say O(n), but n isn't constant). Now, using magic of threading (and multiple cores if you can), this doesn't have to happen. All queries are fired at the same time, and your script has to wait only for the one running the longest (O(x) where x is the longest taking query. I think).

So, assuming you have 4 queries taking 1.6s each (gigantic stuff, yeah) it will take:
Unthreaded - 4x1.6 = 6.4s
Threaded - 1.6s

And still you have an option to wait until everything is done before allowing players to join.

#e: note to self, use less word "query"
I need YSI to use the "inline" stuff?
It looks quite complex for me.
Reply

You don't need to use inline functions, I just used them to keep example small. Normal mysql_(t/p)query is enough. And nobody said it won't be complex, it just massively improves your server boot time.
Reply

pawn Code:
new string[1024];
mysql_format(db, string, sizeof(string), "SELECT * FROM smsid WHERE saaja = %i AND kustutatudsaajal = 0 ORDER BY id DESC LIMIT 50", KasutajaInfo[playerid][mTelefon]);
new Cache:r = mysql_query(db, string);
strcpy(telefoniquery[playerid], string);
new rows = mysql_num_rows(), result[48], varv[12];
if (rows)
{
    strcpy(string, "");
    for (new i; i < rows; i++)
    {
        cache_get_field_content(i, "sisu", result);
                if (cache_get_field_content_int(i, "loetud")) strcpy(varv, COL_WHITE);
        else strcpy(varv, COL_RED);
        format(result, sizeof(result), "%s%s - %s", varv, NumberKontakt(playerid, cache_get_field_content_int(i, "saatja")), result);
        format(string, sizeof(string), "%s%s\n", string, result);
    }
    ShowPlayerDialog(playerid, DIALOG_SMSID, DIALOG_STYLE_LIST, COL_WHITE"Telefon", string, "Vali", "Tagasi");
}
else ShowPlayerDialog(playerid, DIALOG_SMSINFO, DIALOG_STYLE_MSGBOX, COL_WHITE"Telefon", COL_WHITE"Vastuvхetud sхnumid puuduvad!", "Tagasi", "");
cache_delete(r);
Why am I getting this result?



Edit:

Code:
19:57:08	mysql_format	OK	connection: 1, len: 1024, format: "SELECT * FROM smsid WHERE saaja = %i AND kustutatudsaajal = 0 ORDER BY id DESC LIMIT 50"
19:57:08	mysql_query	OK	connection: 1, query: "SELECT * FROM smsid WHERE saaja = 1337 AND kustutatudsaajal = 0 ", use_cache: true
19:57:08	CMySQLQuery::Execute	OK	starting query execution
19:57:08	CMySQLQuery::Execute	OK	query was successfully executed within 0.383 milliseconds
19:57:08	CMySQLResult::CMySQLResult()	OK	constructor called
19:57:08	CMySQLHandle::SaveActiveResult	OK	cache saved (id: 18)
19:57:08	cache_get_row_count	OK	connection: 1
19:57:08	cache_get_field_content	OK	row: 0, field_name: "sisu", connection: 1, max_len: 48
19:57:08	CMySQLResult::GetRowDataByName	OK	row: '0', field: "sisu", data: "tere"
19:57:08	cache_get_field_content_int	OK	row: 0, field_name: "loetud", connection: 1
19:57:08	CMySQLResult::GetRowDataByName	OK	row: '0', field: "loetud", data: "1"
19:57:08	cache_get_field_content_int	OK	row: 0, field_name: "saatja", connection: 1
19:57:08	CMySQLResult::GetRowDataByName	OK	row: '0', field: "saatja", data: "1337"
19:57:08	mysql_format	OK	connection: 1, len: 128, format: "SELECT * FROM kontaktid WHERE lisaja = %i AND telefon = %i"
19:57:08	mysql_query	OK	connection: 1, query: "SELECT * FROM kontaktid WHERE lisaja = 1337 AND telefon = 1337", use_cache: true
19:57:08	CMySQLQuery::Execute	OK	starting query execution
19:57:08	CMySQLQuery::Execute	OK	query was successfully executed within 0.122 milliseconds
19:57:08	CMySQLResult::CMySQLResult()	OK	constructor called
19:57:08	CMySQLHandle::SaveActiveResult	OK	cache saved (id: 13)
19:57:08	cache_get_row_count	OK	connection: 1
19:57:08	cache_get_field_content	OK	row: 0, field_name: "nimi", connection: 1, max_len: 128
19:57:08	CMySQLResult::GetRowDataByName	OK	row: '0', field: "nimi", data: "mina ise"
19:57:08	cache_get_field_content	OK	row: 1, field_name: "sisu", connection: 1, max_len: 48
19:57:08	CMySQLResult::GetRowDataByName()	ERROR	invalid row index ('1')
19:57:08	cache_get_field_content_int	OK	row: 1, field_name: "loetud", connection: 1
19:57:08	CMySQLResult::GetRowDataByName()	ERROR	invalid row index ('1')
19:57:08	cache_get_field_content_int	ERROR	invalid datatype
19:57:08	cache_get_field_content_int	OK	row: 1, field_name: "saatja", connection: 1
19:57:08	CMySQLResult::GetRowDataByName()	ERROR	invalid row index ('1')
19:57:08	cache_get_field_content_int	ERROR	invalid datatype
19:57:08	mysql_format	OK	connection: 1, len: 128, format: "SELECT * FROM kontaktid WHERE lisaja = %i AND telefon = %i"
19:57:08	mysql_query	OK	connection: 1, query: "SELECT * FROM kontaktid WHERE lisaja = 1337 AND telefon = 0", use_cache: true
19:57:08	CMySQLQuery::Execute	OK	starting query execution
19:57:08	CMySQLQuery::Execute	OK	query was successfully executed within 0.101 milliseconds
19:57:08	CMySQLResult::CMySQLResult()	OK	constructor called
19:57:08	CMySQLHandle::SaveActiveResult	OK	cache saved (id: 8)
19:57:08	cache_get_row_count	OK	connection: 1
19:57:08	cache_get_field_content	OK	row: 2, field_name: "sisu", connection: 1, max_len: 48
19:57:08	CMySQLResult::GetRowDataByName()	ERROR	invalid row index ('2')
19:57:08	cache_get_field_content_int	OK	row: 2, field_name: "loetud", connection: 1
19:57:08	CMySQLResult::GetRowDataByName()	ERROR	invalid row index ('2')
19:57:08	cache_get_field_content_int	ERROR	invalid datatype
19:57:08	cache_get_field_content_int	OK	row: 2, field_name: "saatja", connection: 1
19:57:08	CMySQLResult::GetRowDataByName()	ERROR	invalid row index ('2')
19:57:08	cache_get_field_content_int	ERROR	invalid datatype
19:57:08	mysql_format	OK	connection: 1, len: 128, format: "SELECT * FROM kontaktid WHERE lisaja = %i AND telefon = %i"
19:57:08	mysql_query	OK	connection: 1, query: "SELECT * FROM kontaktid WHERE lisaja = 1337 AND telefon = 0", use_cache: true
19:57:08	CMySQLQuery::Execute	OK	starting query execution
19:57:08	CMySQLQuery::Execute	OK	query was successfully executed within 0.89 milliseconds
19:57:08	CMySQLResult::CMySQLResult()	OK	constructor called
19:57:08	CMySQLHandle::SaveActiveResult	OK	cache saved (id: 19)
19:57:08	cache_get_row_count	OK	connection: 1
19:57:08	cache_get_field_content	OK	row: 3, field_name: "sisu", connection: 1, max_len: 48
19:57:08	CMySQLResult::GetRowDataByName()	ERROR	invalid row index ('3')
19:57:08	cache_get_field_content_int	OK	row: 3, field_name: "loetud", connection: 1
19:57:08	CMySQLResult::GetRowDataByName()	ERROR	invalid row index ('3')
19:57:08	cache_get_field_content_int	ERROR	invalid datatype
19:57:08	cache_get_field_content_int	OK	row: 3, field_name: "saatja", connection: 1
19:57:08	CMySQLResult::GetRowDataByName()	ERROR	invalid row index ('3')
19:57:08	cache_get_field_content_int	ERROR	invalid datatype
19:57:08	mysql_format	OK	connection: 1, len: 128, format: "SELECT * FROM kontaktid WHERE lisaja = %i AND telefon = %i"
19:57:08	mysql_query	OK	connection: 1, query: "SELECT * FROM kontaktid WHERE lisaja = 1337 AND telefon = 0", use_cache: true
19:57:08	CMySQLQuery::Execute	OK	starting query execution
19:57:08	CMySQLQuery::Execute	OK	query was successfully executed within 0.84 milliseconds
19:57:08	CMySQLResult::CMySQLResult()	OK	constructor called
19:57:08	CMySQLHandle::SaveActiveResult	OK	cache saved (id: 20)
19:57:08	cache_get_row_count	OK	connection: 1
19:57:08	cache_delete	OK	cache_id: 18, connection: 1
19:57:08	CMySQLResult::~CMySQLResult()	OK	deconstructor called
19:57:08	CMySQLHandle::DeleteSavedResult	OK	result deleted
Reply

Quote:
Originally Posted by Misiur
View Post
You don't need to use inline functions, I just used them to keep example small. Normal mysql_(t/p)query is enough. And nobody said it won't be complex, it just massively improves your server boot time.
I'm using mysql_tqueries already.
But they use callbacks and OnFilterScriptInit is finished before any of the queries are processed.
The callbacks are called after the server is online already.

I guess I'll just go for the mysql_query example you provided, to load data sequentially.
Some data must be loaded sequentially after all.

I'm loading vehicle-info, this holds all data related to maxfuel settings, fuel consumption and refuel times per vehicle-model.
This must be loaded before any vehicle is loaded, otherwise the fuel settings are messed up, causing the fuel textdraw to stay hidden (empty text).

I don't really care if the server needs only 5 seconds to boot, or 20 seconds.

My MMORPG server I had years ago took about 2 minutes to boot.

After all, a server is normally started once and should stay online for days or weeks, or even months.
Those 20 seconds won't matter that much.
Reply

@kvann:
You are sending another query in your custom function "NumberKontakt", which overwrites the active cache. You have to re-set the cache as active.

@PowerPC603:
I haven't read the whole conversation, but I think your first question was if the unthreaded query feature will stay in future revisions (correct me if I'm wrong). Yes, it will stay for sure, since sometimes it is just impossible to avoid them.
Reply

Quote:
Originally Posted by maddinat0r
View Post
@kvann:
You are sending another query in your custom function "NumberKontakt", which overwrites the active cache. You have to re-set the cache as active.
Ahh... I never had this problem with Dan's plugin. Can I use multiple caches at the same time somehow?

Edit: Found cache_set_active, thanks.

Edit2: When i'm using a function like this, do I have to free the result/delete the cache?

pawn Code:
stock bool:CheckForUser(sqlid)
{
    new bool:olemas;
    if (sqlid > 0)
    {
        new string[128];
        mysql_format(db, string, sizeof(string), "SELECT * FROM kasutajad WHERE id = %i", sqlid);
        mysql_query(db, string);
        if (mysql_num_rows()) olemas = true;
    }
    return olemas;
}
Reply

Quote:
Originally Posted by kvann
View Post
[...]Can I use multiple caches at the same time somehow?
You always have to switch the active cache to the correctly saved one.
pawn Code:
new Cache:a, Cache:b, Cache:c;
a = mysql_query(sql, "SELECT 2+2");
b = mysql_query(sql, "SELECT 3+3");
c = mysql_query(sql, "SELECT 4+4");

cache_set_active(b);
printf("3+3: %d", cache_get_row_int(0,0));
cache_set_active(a);
printf("2+2: %d", cache_get_row_int(0,0));
cache_set_active(c);
printf("4+4: %d", cache_get_row_int(0,0));

cache_delete(a);
cache_delete(b);
cache_delete(c);
Quote:
Originally Posted by kvann
View Post
[...]When i'm using a function like this, do I have to free the result/delete the cache?
Yes, you have to free it manually (there isn't even a way to free it automatically).
Reply

nice
Reply

Quote:
Originally Posted by maddinat0r
View Post
@kvann:
You are sending another query in your custom function "NumberKontakt", which overwrites the active cache. You have to re-set the cache as active.

@PowerPC603:
I haven't read the whole conversation, but I think your first question was if the unthreaded query feature will stay in future revisions (correct me if I'm wrong). Yes, it will stay for sure, since sometimes it is just impossible to avoid them.
Yes, that was the question.
I edited my script to use non-threaded queries using mysql_query to load my data now, using the cache.

I thought the loading was slow when it got to my 212 vehicles, but it was slow because mysql_debug was enabled.
Logfile was 275Kb after starting the server once.

Disabling logging loads the data as if I was using plain textfiles.

pawn Code:
// This function is used to load all speedcameras, gas-stations from MySQL when starting the server (called only during OnFilterscriptInit)
SQL_Data_Load()
{
    // Setup local variables
    new Query[128], Cache:result;

    printf("********************************************************************************");

    // Send a query to load all speedcameras from MySQL
    format(Query, sizeof(Query), "SELECT * FROM %s", table_speedcams);
    result = mysql_query(SQL_db, Query, true);
    // Print some debug info to the server console
    printf("*** Loading speed-cameras from MySQL using \"%s\"", Query);
    CamerasLoad();
    cache_delete(result, SQL_db);

    printf(" ");

    // Send a query to load all gas-stations from MySQL
    format(Query, sizeof(Query), "SELECT * FROM %s", table_gasstations);
    result = mysql_query(SQL_db, Query, true);
    // Print some debug info to the server console
    printf("*** Loading gas-stations from MySQL using \"%s\"", Query);
    GasStationsLoad();
    cache_delete(result, SQL_db);

    printf(" ");

    // Send a query to load all police-stations from MySQL
    format(Query, sizeof(Query), "SELECT * FROM %s", table_policestations);
    result = mysql_query(SQL_db, Query, true);
    // Print some debug info to the server console
    printf("*** Loading police-stations from MySQL using \"%s\"", Query);
    PoliceStationsLoad();
    cache_delete(result, SQL_db);

    printf(" ");

    // Send a query to load all vehicle-info from MySQL
    format(Query, sizeof(Query), "SELECT * FROM %s", table_vehicleinfo);
    result = mysql_query(SQL_db, Query, true);
    // Print some debug info to the server console
    printf("*** Loading vehicle-info from MySQL using \"%s\"", Query);
    VehicleInfoLoad();
    cache_delete(result, SQL_db);

    printf("********************************************************************************");

    return 1;
}

// This function is called to load the speedcameras
CamerasLoad()
{
    // Setup local variables
    new Rows, CamID, CameraName[50], MaxSpeed, Float:x, Float:y, Float:z, Float:rot, CountSuccess, CountFailed, Query[128];

    // Get the amount of rows (cameras)
    Rows = cache_get_row_count(SQL_db);

    // If there are any rows (cameras) loaded, load data and create them
    if (Rows >= 1)
    {
        // Loop through all rows
        for (new Row; Row < Rows; Row++)
        {
            // Load the data
            CamID = cache_get_field_content_int(Row, "ID", SQL_db);
            cache_get_field_content(Row, "Name", CameraName, SQL_db, sizeof(CameraName));
            MaxSpeed = cache_get_field_content_int(Row, "CamSpeed", SQL_db);
            x = cache_get_field_content_float(Row, "X", SQL_db);
            y = cache_get_field_content_float(Row, "Y", SQL_db);
            z = cache_get_field_content_float(Row, "Z", SQL_db);
            rot = cache_get_field_content_float(Row, "Angle", SQL_db);

            // Check if the CamID is invalid (out of range)
            if ((CamID < 0) || (CamID >= MAX_CAMERAS))
            {
                // Count the amount of failed cameras (invalid CamID's)
                CountFailed++;
                printf("*** ERROR: Invalid CamID found in table %s: %i (entry deleted)", table_speedcams, CamID);
                mysql_format(SQL_db, Query, sizeof(Query), "DELETE FROM %s WHERE ID = '%i'", table_speedcams, CamID);
                mysql_tquery(SQL_db, Query, "", "");
                // Continue with the next speedcamera from the MySQL query
                continue;
            }

            // Check if the CamSpeed is invalid (0 or lower)
            if (MaxSpeed <= 0)
            {
                // Count the amount of failed cameras (invalid MaxSpeed)
                CountFailed++;
                printf("*** ERROR: Invalid CamSpeed found in table %s: CamID %i, MaxSpeed %i (entry deleted)", table_speedcams, CamID, MaxSpeed);
                mysql_format(SQL_db, Query, sizeof(Query), "DELETE FROM %s WHERE ID = '%i'", table_speedcams, CamID);
                mysql_tquery(SQL_db, Query, "", "");
                // Continue with the next speedcamera from the MySQL query
                continue;
            }

            // Create the camera at the given CamID (there should be no duplicate cameras with the same ID as the table-structure doesn't allow it, ID = primary key)
            SetupSpeedCamera(x, y, z, rot, MaxSpeed, CameraName, CamID);
            // Count the succesfully created cameras
            CountSuccess++;
        }
    }

    // Print the amount of speedcams loaded for debugging
    printf("*** Speed-cameras loaded: %i (successful: %i, failed: %i)", Rows, CountSuccess, CountFailed);

    return 1;
}

// This function is called to load the gas-stations
GasStationsLoad()
{
    // Setup local variables
    new Rows, GasID, Name[50], Float:x, Float:y, Float:z, CountSuccess, CountFailed, Query[128];

    // Get the amount of rows (gas-stations)
    Rows = cache_get_row_count(SQL_db);

    // If there are any rows (gas-stations) loaded, load data and create them
    if (Rows >= 1)
    {
        // Loop through all rows
        for (new Row; Row < Rows; Row++)
        {
            // Load the data
            GasID = cache_get_field_content_int(Row, "ID", SQL_db);
            cache_get_field_content(Row, "Name", Name, SQL_db, sizeof(Name));
            x = cache_get_field_content_float(Row, "X", SQL_db);
            y = cache_get_field_content_float(Row, "Y", SQL_db);
            z = cache_get_field_content_float(Row, "Z", SQL_db);

            // Check if the GasID is invalid (out of range)
            if ((GasID < 0) || (GasID >= MAX_GASSTATIONS))
            {
                // Count the amount of failed gas-stations (invalid GasID's)
                CountFailed++;
                printf("*** ERROR: Invalid GasID found in table %s: %i (entry deleted)", table_gasstations, GasID);
                mysql_format(SQL_db, Query, sizeof(Query), "DELETE FROM %s WHERE ID = '%i'", table_gasstations, GasID);
                mysql_tquery(SQL_db, Query, "", "");
                // Continue with the next gas-station from the MySQL query
                continue;
            }

            // Create the gas-station at the given GasID (there should be no duplicate gas-stations with the same ID as the table-structure doesn't allow it, ID = primary key)
            SetupGasStation(x, y, z, Name, GasID);
            // Count the succesfully created gas-stations
            CountSuccess++;
        }
    }

    // Print the amount of gas-stations loaded for debugging
    printf("*** Gas-stations loaded: %i (successful: %i, failed: %i)", Rows, CountSuccess, CountFailed);

    return 1;
}

// This function is called to load the police-stations
PoliceStationsLoad()
{
    // Setup local variables
    new Rows, PoliceID, Name[50], Float:x, Float:y, Float:z, CountSuccess, CountFailed, Query[128];

    // Get the amount of rows (police-stations)
    Rows = cache_get_row_count(SQL_db);

    // If there are any rows (police-stations) loaded, load data and create them
    if (Rows >= 1)
    {
        // Loop through all rows
        for (new Row; Row < Rows; Row++)
        {
            // Load the data
            PoliceID = cache_get_field_content_int(Row, "ID", SQL_db);
            cache_get_field_content(Row, "Name", Name, SQL_db, sizeof(Name));
            x = cache_get_field_content_float(Row, "X", SQL_db);
            y = cache_get_field_content_float(Row, "Y", SQL_db);
            z = cache_get_field_content_float(Row, "Z", SQL_db);

            // Check if the PoliceID is invalid (out of range)
            if ((PoliceID < 0) || (PoliceID >= MAX_POLICESTATIONS))
            {
                // Count the amount of failed police-stations (invalid PoliceID's)
                CountFailed++;
                printf("*** ERROR: Invalid PoliceID found in table %s: %i (entry deleted)", table_policestations, PoliceID);
                mysql_format(SQL_db, Query, sizeof(Query), "DELETE FROM %s WHERE ID = '%i'", table_policestations, PoliceID);
                mysql_tquery(SQL_db, Query, "", "");
                // Continue with the next police-station from the MySQL query
                continue;
            }

            // Create the police-station at the given PoliceID (there should be no duplicate police-stations with the same ID as the table-structure doesn't allow it, ID = primary key)
            SetupPoliceStation(x, y, z, Name, PoliceID);
            // Count the succesfully created police-stations
            CountSuccess++;
        }
    }

    // Print the amount of police-stations loaded for debugging
    printf("*** Police-stations loaded: %i (successful: %i, failed: %i)", Rows, CountSuccess, CountFailed);

    return 1;
}

// This function is called to load the vehicle-info
VehicleInfoLoad()
{
    // Setup local variables
    new Rows, ID, Price, Float:MaxFuel, Float:Consump, RefuelT, Disabled, CountSuccess, CountFailed, Query[128], vModel;

    // Get the amount of rows (vehicle-info)
    Rows = cache_get_row_count(SQL_db);

    // If there are any rows (vehicle-info) loaded, load data and overwrite default script-values
    if (Rows >= 1)
    {
        // Loop through all rows
        for (new Row; Row < Rows; Row++)
        {
            // Load the data
            ID = cache_get_field_content_int(Row, "ID", SQL_db);
            Price = cache_get_field_content_int(Row, "Price", SQL_db);
            MaxFuel = cache_get_field_content_float(Row, "MaxFuel", SQL_db);
            Consump = cache_get_field_content_float(Row, "Consumption", SQL_db);
            RefuelT = cache_get_field_content_int(Row, "RefuelTime", SQL_db);
            Disabled = cache_get_field_content_int(Row, "Disabled", SQL_db);

            // Check if the ID is invalid (out of range)
            if ((ID < 0) || (ID >= sizeof(AVehicleInfo)))
            {
                // Count the amount of failed vehicle-info entries (invalid ID's)
                CountFailed++;
                printf("*** ERROR: Invalid ID found in table %s: %i (entry deleted)", table_vehicleinfo, ID);
                mysql_format(SQL_db, Query, sizeof(Query), "DELETE FROM %s WHERE ID = '%i'", table_vehicleinfo, ID);
                mysql_tquery(SQL_db, Query, "", "");
                // Continue with the next vehicle-info entry from the MySQL query
                continue;
            }

            // Store all the data
            AVehicleInfo[ID][VehiclePrice] = Price;
            AVehicleInfo[ID][VehicleMaxFuel] = MaxFuel;
            AVehicleInfo[ID][FuelConsumption] = Consump;
            AVehicleInfo[ID][RefuelTime] = RefuelT;
            if (Disabled == 1)
                AVehicleInfo[ID][VehicleDisabled] = true;
            else
                AVehicleInfo[ID][VehicleDisabled] = false;
            // Count the succesfully loaded vehicle-info entries
            CountSuccess++;
        }
    }

    // Print the amount of vehicle-info entries loaded for debugging
    printf("*** Vehicle-info loaded: %i (successful: %i, failed: %i)", Rows, CountSuccess, CountFailed);

    return 1;
}
This is my data-loading function for now.
This loads 1 speedcam, 23 gas-stations, 7 police-stations and 212 vehicle-models.
And it goes lightning fast, less than a second.

I want to keep this like it is now because now my data is loaded before the server is open to the public.

This is one such instance where it's impossible/unwanted to get mysql_query removed.
The data MUST be loaded in a certain sequence and the data must be present before any player is allowed to connect to avoid bugged players.
Reply

I optimized the hell out of the plugin. I optimized it that far, that my cached unthreaded queries are faster than uncached ("live") unthreaded queries used in other plugins (at least they are faster than the ones in StrickenKid's plugin).
Difference cached <--> uncached: uncached unthreaded queries only fetch the result you actually need, while cached ones fetch and save the complete result set (even rows and fields you won't use).
And since everything has its price, that optimization created some (a ton IMO) bugs which I've been fixing since R35 (and there are still some in R37 regarding mysql_unprocessed_queries and mysql_errno).
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)