Loading multiple rows with mysql question
#1

I'm trying to create group system, where a player is able to create his own group.
When player tries to create group it should check if group name is not already taken so I figured that I should load data of all groups there are on OnGameModeInit and once player is trying to create his own group I would just run a for cycle to check if the name is taken

So let's say I want to load all these groups into "GroupInfo" on OnGameModeInit


Код:
enum Data
{
ID,
Name
};
new GroupInfo[Amount_of_groups][Data];
How should I do that?
Im using mysql R39-6
Reply
#2

You could either take the approach you described above, or query the database once a user tries to create a group. I wrote a small example with comments for the approach you described above.
It's just a quick and basic example, so copy/pasting may not work (nor was it intended to be a copy pasting example). Hope this gives you a basic picture on a way to do what you want. If anything's still unclear, I'll be happy to help and explain.

PHP код:
public OnGameModeInit()
{
    
//Start the group loading. It's in another function to keep it clean.
    
LoadGroups();
}
forward LoadGroups();
public 
LoadGroups()
{
    
//Execute a SQL query to get all records from the groups table
    //We tell the function to pass data onto OnGroupsRetrieved.
    
mysql_tquery(sqlHandle"SELECT * FROM `groups_table`;""OnGroupsRetrieved"); 
}
//Called on completion of LoadGroups query
forward OnGroupsRetrieved();
public 
OnGroupsRetrieved()
{
    
//First check if there are any entries. If not, print that to console.
    
if(cache_get_row_count() == 0) print("[INFO]: No groups found in database.");
    else
    {
        
//Now that we know we have data, execute a for loop for the amount of entries in the database.
        //Same as above, we use cache_get_row_count to get the amount of result rows we have from the query
        
for(new 0cache_get_row_count(); i++)
        {
            
//cache_get_field_content_int wants a result number and the name of the field to get the value from.
            //We use 'i' as result number because we loop through the results
            
GroupInfo[i][ID] = cache_get_field_content_int(i"ID");
            
            
//cache_get_field_content is a little different. It too wants the result number and field name, but I always
            //compare it with the 'format' function. This because it also wants the variable to put the value into in the function
            //and it wants the length of the variable. In addition to that, it also wants the sqlHandle variable.
            //cache_get_field_content(resultnumber, fieldname, variable to store into, sqlhandle, length of variable to store into);
            
cache_get_field_content(i"Name"GroupInfo[i][Name], sqlHandleGROUP_NAME_LENGTH);
        }
        
//Once we loaded everything we print the amount of rows of our result, just for information.
        
printf("[INFO]: Loaded %d groups from the database."cache_get_row_count()); 
        
    }
    return 
true//I believe you should return true to 'free result'; empty the cache.

Reply
#3

Quote:
Originally Posted by Jstylezzz
Посмотреть сообщение
You could either take the approach you described above, or query the database once a user tries to create a group. I wrote a small example with comments for the approach you described above.
It's just a quick and basic example, so copy/pasting may not work (nor was it intended to be a copy pasting example). Hope this gives you a basic picture on a way to do what you want. If anything's still unclear, I'll be happy to help and explain.

PHP код:
public OnGameModeInit()
{
    
//Start the group loading. It's in another function to keep it clean.
    
LoadGroups();
}
forward LoadGroups();
public 
LoadGroups()
{
    
//Execute a SQL query to get all records from the groups table
    //We tell the function to pass data onto OnGroupsRetrieved.
    
mysql_tquery(sqlHandle"SELECT * FROM `groups_table`;""OnGroupsRetrieved"); 
}
//Called on completion of LoadGroups query
forward OnGroupsRetrieved();
public 
OnGroupsRetrieved()
{
    
//First check if there are any entries. If not, print that to console.
    
if(cache_get_row_count() == 0) print("[INFO]: No groups found in database.");
    else
    {
        
//Now that we know we have data, execute a for loop for the amount of entries in the database.
        //Same as above, we use cache_get_row_count to get the amount of result rows we have from the query
        
for(new 0cache_get_row_count(); i++)
        {
            
//cache_get_field_content_int wants a result number and the name of the field to get the value from.
            //We use 'i' as result number because we loop through the results
            
GroupInfo[i][ID] = cache_get_field_content_int(i"ID");
            
            
//cache_get_field_content is a little different. It too wants the result number and field name, but I always
            //compare it with the 'format' function. This because it also wants the variable to put the value into in the function
            //and it wants the length of the variable. In addition to that, it also wants the sqlHandle variable.
            //cache_get_field_content(resultnumber, fieldname, variable to store into, sqlhandle, length of variable to store into);
            
cache_get_field_content(i"Name"GroupInfo[i][Name], sqlHandleGROUP_NAME_LENGTH);
        }
        
//Once we loaded everything we print the amount of rows of our result, just for information.
        
printf("[INFO]: Loaded %d groups from the database."cache_get_row_count()); 
        
    }
    return 
true//I believe you should return true to 'free result'; empty the cache.

Thank you for you detailed answer, it was very helpful. Perhaps you also know how to get the amount of rows for enum? There can be different amount of groups everytime OnGameModeInit gets called so I tried doing this

Код:
new groups; 

public OnGameModeInit()
{
	 mysql_tquery(mysql, "SELECT * FROM `groups`", "GetLines");
	return 1;
}

forward GetLines();
public GetLines()
{
groups=cache_get_row_count();
}

enum Data
{
ID,
Name
};
new GroupInfo[groups][Data];
but I get an error
Код:
error 008: must be a constant expression; assumed zero
it isn't much of a problem as I can just give that array a big value like new GroupInfo[1000][Data], I'm just curious if it's possible to do it
Reply
#4

Why not just use INSERT IGNORE INTO syntax and set Name as UNIQUE index? This way, it will check if rows were affected (a successful row was inserted) or otherwise (nothing affected) returned an error for duplicate and ignored (skipped) the query.
Reply
#5

new problem

Код:
groups=cache_get_row_count();
    if(groups == 0) print("[INFO]: No groups found in database.");
    else
    {
    print("----------------------------------------------------------------");
            print(" ");
            print("\tLOADING GROUPS");
            print(" ");
        for(new i = 0; i < groups; i++)
        {
            GroupInfo[i][ID] = cache_get_field_content_int(i, "ID");
            cache_get_field_content(i, "Name", GroupInfo[i][Name], mysql, 12);
            printf("NAME : %s",GroupInfo[i][Name]);
        }
        printf("[LOADING GROUPS] : Loaded %d groups from the database.", groups);
        print(" ");
        print("----------------------------------------------------------------");
    }
    for(new i=0; i<groups; i++) printf("NAME : %s",GroupInfo[i][Name]);
this is what gets printed into console

[18:46:31] ----------------------------------------------------------------
[18:46:31]
[18:46:31] LOADING GROUPS
[18:46:31]
[18:46:31] NAME : dadac
[18:46:31] NAME : cvcvvvsvsa
[18:46:31] NAME : dqdaaacxzc
[18:46:31] NAME : xccsa
[18:46:31] NAME : yyyya
[18:46:31] [LOADING GROUPS] : Loaded 5 groups from the database.
[18:46:31]
[18:46:31] ----------------------------------------------------------------
[18:46:31] NAME : dcd xyyyya
[18:46:31] NAME : cd xyyyya
[18:46:31] NAME : d xyyyya
[18:46:31] NAME : xyyyya
[18:46:31] NAME : yyyya

I dont do anything to GroupInfo[i][Name] after storing group name into it, but it gets all messed up outside the for cycle.
Reply
#6

Quote:
Originally Posted by ax1
Посмотреть сообщение
new problem

Код:
groups=cache_get_row_count();
    if(groups == 0) print("[INFO]: No groups found in database.");
    else
    {
    print("----------------------------------------------------------------");
            print(" ");
            print("\tLOADING GROUPS");
            print(" ");
        for(new i = 0; i < groups; i++)
        {
            GroupInfo[i][ID] = cache_get_field_content_int(i, "ID");
            cache_get_field_content(i, "Name", GroupInfo[i][Name], mysql, 12);
            printf("NAME : %s",GroupInfo[i][Name]);
        }
        printf("[LOADING GROUPS] : Loaded %d groups from the database.", groups);
        print(" ");
        print("----------------------------------------------------------------");
    }
    for(new i=0; i<groups; i++) printf("NAME : %s",GroupInfo[i][Name]);
this is what gets printed into console

[18:46:31] ----------------------------------------------------------------
[18:46:31]
[18:46:31] LOADING GROUPS
[18:46:31]
[18:46:31] NAME : dadac
[18:46:31] NAME : cvcvvvsvsa
[18:46:31] NAME : dqdaaacxzc
[18:46:31] NAME : xccsa
[18:46:31] NAME : yyyya
[18:46:31] [LOADING GROUPS] : Loaded 5 groups from the database.
[18:46:31]
[18:46:31] ----------------------------------------------------------------
[18:46:31] NAME : dcd xyyyya
[18:46:31] NAME : cd xyyyya
[18:46:31] NAME : d xyyyya
[18:46:31] NAME : xyyyya
[18:46:31] NAME : yyyya

I dont do anything to GroupInfo[i][Name] after storing group name into it, but it gets all messed up outside the for cycle.
bump
Reply
#7

Quote:
Originally Posted by ax1
Посмотреть сообщение
bump
Name is a string variable, which contains characters, you have to set it's lenght.
Код:
enum Data
{
ID,
Name[32]
};
new GroupInfo[Amount_of_groups][Data];
Make sure that you change the "Name" lenght (12) in the loading query.
Код:
cache_get_field_content(i, "Name", GroupInfo[i][Name], mysql, 32);
Reply
#8

Apologies for the late reply, I didn't notice the question.

Quote:
Originally Posted by ax1
Посмотреть сообщение
Thank you for you detailed answer, it was very helpful. Perhaps you also know how to get the amount of rows for enum? There can be different amount of groups everytime OnGameModeInit gets called so I tried doing this
-- code --
it isn't much of a problem as I can just give that array a big value like new GroupInfo[1000][Data], I'm just curious if it's possible to do it
The size of the variable has to be constant. This means you have to define in advance how big this array can be at most, so you can't set it to the amount of groups that are in the database at the moment of loading. Similar to the MAX_PLAYERS definition we all know, you can make one for your group so that you can easily change it later on, and improve your readability throughout the script. Let's say you want a maximum amount of 20 groups to be created, you could just say:
PHP код:
#define MAX_GROUPS 20 
Then, just declare your variable as
PHP код:
new GroupInfo[MAX_GROUPS][Data]; 
Alternatively, if you really want to have unlimited groups without using massive array sizes, you could go for an approach that doesn't store group info locally. This would mean that each time you want to get info/create/delete a group, you'd need to query the database. I use this approach for a few things, but it completely depends on the situation for me. If you would do it that way, you could use the way Konstantinos described a few replies earlier.
Also:

Quote:
Originally Posted by whadez
Посмотреть сообщение
Name is a string variable, which contains characters, you have to set it's lenght.
Код:
enum Data
{
ID,
Name[32]
};
new GroupInfo[Amount_of_groups][Data];
Make sure that you change the "Name" lenght (12) in the loading query.
Код:
cache_get_field_content(i, "Name", GroupInfo[i][Name], mysql, 32);
This is correct, I didn't notice the 'Name' missing the length when I gave my answer. It's something easy to overlook, and it produces weird results :')
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)