Raised This Month: $51 Target: $400
 12% 

Saving Player Info to SQL


Post New Thread Reply   
 
Thread Tools Display Modes
PRoSToTeM@
Veteran Member
Join Date: Jan 2010
Location: Russia, Ivanovo
Old 08-23-2017 , 15:34   Re: Saving Player Info to SQL
Reply With Quote #11

With threaded queries you need to handle situations when you need player data, but it is not loaded yet.
__________________
PRoSToTeM@ is offline
Send a message via ICQ to PRoSToTeM@ Send a message via Skype™ to PRoSToTeM@
siriusmd99
Veteran Member
Join Date: Oct 2013
Location: Republic of Moldova
Old 08-24-2017 , 05:28   Re: Saving Player Info to SQL
Reply With Quote #12

So can i use previous code by Hawk from my last post as an example to build it in my plugin?
I saw that is has both write and read SQL data with threaded queries.
siriusmd99 is offline
siriusmd99
Veteran Member
Join Date: Oct 2013
Location: Republic of Moldova
Old 08-26-2017 , 13:14   Re: Saving Player Info to SQL
Reply With Quote #13

Ok, i tested. Everything works ok.But as i said something is not ok in my case.

I save items in array for every player like :

g_items[33][100]

So every item has it's id. If i want to add a item to player i do:
g_items[id][ItemID]++

Now the problem is that i can't save this to sql because:

"UPDATE `Table_Name` SET `password` = '%s' WHERE `steamid` = '%s'"

In pawn scripting there is no "array" thing like %Array. So if i use %s string to save g_items array i will fail, because it's checking for end of string null value. So if i a player has for example third item "g_items[id][3] = 1"
but doesnt have first item "g_items[id][0] = 0" then it will be checking for end of string and item g_items[id][3] won't be saved to sql.
It will work only if player would have all items in consecutive mode starting from first cell.
It's really annoying. Is there a method to save as array and pass null cells?

Last edited by siriusmd99; 08-26-2017 at 13:16.
siriusmd99 is offline
KiLLeR.
Senior Member
Join Date: Jul 2014
Location: Bulgaria
Old 08-26-2017 , 13:37   Re: Saving Player Info to SQL
Reply With Quote #14

Pseudocode:
Code:
new str, i; for i=0 i<sizeof array i++     str[i] = array[i]; string[i++] = NULL;
Then save your array like a string in sql.
KiLLeR. is offline
siriusmd99
Veteran Member
Join Date: Oct 2013
Location: Republic of Moldova
Old 08-26-2017 , 16:43   Re: Saving Player Info to SQL
Reply With Quote #15

I think your code is wrong or maybe I didn't understand what do you mean.
There are still zero values in your array.
I managed how to deal with this. I just replace all 0 with -1 and it works.
As i see negative values are not considered null even if they are out of ASCII table.
I don't really understand why that happens. I see symbols like novergian "y" with two points above after i replace with -1 but ascii table doesnt have negative characters. I know about extended ascii but they go over 255. Maybe in sql negative numbers are given special symbols as offsets, idk.
Anyway, I created a function that converts all null values to -1 and back.

Here is function, maybe someone needs it too:

PHP Code:
set_signed_nullsstr[], signmax_val 0)
{
    new 
itmp;
    if(
sign//Switching between signing and reseting nulls
    
{
        
//Checking last valid number found in string
        //Example: 1 2 0 0 5 0 0 0
        //We need to get possition of number 5
        
        
for(max_val>= 0i--)
        {
            if(
str[i] != EOS)
            {
               
tmp i;
               break;
            }  
        }     
      
        
//Now we check and replace all nulls (number 0) with -1
        //Will stop checking when number 5 is found.
        //No need to replace all zeroes until the last cell is reached because there is no data after number 5
        
if(tmp)
        {
            for(
0tmpi++)
            {
                if(
str[i] == EOS)
                {
                   
str[i] = -1;
                }   
            }
        }
        
        
//So the final result will be:
        //Before ---> 1 2  0  0 5 0 0 0
        //After  ---> 1 2 -1 -1 5 0 0 0
    
}
    else
    {
        
//Here is the reverse operation. Replacing all -1 with zeroes back.
        //In previous case: 1 2 -1 -1 5 0 0 0
        //Loop will start from first cell and end to string length
        
        
tmp strlen(str)
        for(
0tmpi++)
        {
            if(
str[i] == -1)
            {
                
str[i] = EOS;
            }   
        }
        
        
//Before ---> 1 2 -1 -1 5 0 0 0
        //After  ---> 1 2  0  0 5 0 0 0
    
}

I using set_signed_nulls( myArray, 1, charsmax(MyArray)) before saving to sql

And then: set_signed_nulls( myArray, 0) setting back -1 to 0.

Also i optimized code so that it doesnt replace all 0 numbers until the last cell of array is reached, only until there is no valid number bigger than 0. It will save space wherever you add resulting string.
siriusmd99 is offline
KiLLeR.
Senior Member
Join Date: Jul 2014
Location: Bulgaria
Old 08-26-2017 , 17:01   Re: Saving Player Info to SQL
Reply With Quote #16

I don't understand why you have to replace 0 with -1?!?!
Let's say we have the following array (g_items): 0 1 0 0 1 1 0, when you are going to save just save it as string: "0100110"?!?
And when you want to load the data, read the string from the db and iterate over it, adding its value to your items for corresponding cell.

Look at this:
Code:
#define MAX_ITEMS 10 new g_items[33][MAX_ITEMS]; // your array save_sql(id) {     new authid[24], str_items[MAX_ITEMS+1]. i;     get_user_authid(id, authid, charsmax(authid));         for(i=0; i<MAX_ITEMS; i++)         str_items[i] = g_items[id[[i];     str_items[i++] = NULL;         new tmp[256];     formatex(tmp, charsmax(tmp), "UPDATE `items` SET `data` = '%i' WHERE `items`.`steamid` = '%s';", str_items, authid)     SQL_ThreadQuery(g_SqlTuple, "UpdateHandle", tmp) } load_sql(id) {     new authid[24]     get_user_authid(id, authid, charsmax(authid));         new data[1]     data[0] = id;         new tmp[256];     formatex(tmp, charsmax(tmp), "SELECT * FROM `items` WHERE (`items`.`steamid` = '%s')", authid)     SQL_ThreadQuery(g_SqlTuple,"SelectHandle", tmp, Data, 1) } public SelectHandle(FailState, Handle:Query, Error[], Errcode, Data[], DataSize) {     if(FailState == TQUERY_CONNECT_FAILED)         return set_fail_state("Could not connect to SQL database.")     else if(FailState == TQUERY_QUERY_FAILED)         return set_fail_state("Query failed.")         if(Errcode)         return log_amx("Error on query: %s",Error)         new id     id = Data[0];         if(SQL_NumResults(Query) < 1)     {         // no results     }     else     {         new str_items[MAX_ITEMS+1];         SQL_ReadResult(Query, str_items, charsmax(str_items));                 for(new i=0; i<MAX_ITEMS; i++);         {             g_items[id][i] = str_items[i]; // not sure how to convert char to int (not the ascii int representing this char)         }     }         return PLUGIN_CONTINUE; }

Last edited by KiLLeR.; 08-26-2017 at 17:28.
KiLLeR. is offline
siriusmd99
Veteran Member
Join Date: Oct 2013
Location: Republic of Moldova
Old 08-27-2017 , 02:56   Re: Saving Player Info to SQL
Reply With Quote #17

No. Your case will work only with digits like 0,1,2 to 9. But if I have number 1000 for example? I can't save it into one cell because it has length 4 and uses 4 cells.
siriusmd99 is offline
klippy
AlliedModders Donor
Join Date: May 2013
Location: Serbia
Old 08-27-2017 , 03:51   Re: Saving Player Info to SQL
Reply With Quote #18

Please provide your database structure.
klippy is offline
siriusmd99
Veteran Member
Join Date: Oct 2013
Location: Republic of Moldova
Old 08-27-2017 , 05:03   Re: Saving Player Info to SQL
Reply With Quote #19

It doesn't matter database. The fact is that I send and read SQL query as string. And I cannot place null values inside a string, there will be end of string.

For example if I had something like query_send_array(handle, column, array) it would work because it will replace all values from SQL string with values from my array.
But in my case I format a string query. I don't think that it's even possible with Amxx to do that.

Last edited by siriusmd99; 08-27-2017 at 05:04.
siriusmd99 is offline
klippy
AlliedModders Donor
Join Date: May 2013
Location: Serbia
Old 08-27-2017 , 06:13   Re: Saving Player Info to SQL
Reply With Quote #20

Quote:
It doesn't matter database.
It does. What you currently have is not how a database should be designed. MySQL isn't supposed to handle arrays of values, you should use relationships between entities.

Quote:
I see symbols like novergian "y" with two points above after i replace with -1 but ascii table doesnt have negative characters.
You see 'ÿ' because you are inputting character 255 actually ('ÿ' = 255 or 0xFF). That's because -1 is 0xFFFFFFFF and natives working with strings only copy the least significant byte (the rightmost two F's).
Because of this you can't have higher values than 255 anyway, unless you "spread" a cell into 4 characters in a string.

Last edited by klippy; 08-27-2017 at 07:52.
klippy is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 13:23.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode