SA-MP Forums

Go Back   SA-MP Forums > SA-MP Scripting and Plugins > Plugin Development

Reply
 
Thread Tools Display Modes
Old 01/02/2010, 07:09 PM   #111
Misiek
Big Clucker
 
Join Date: May 2006
Posts: 113
Reputation: 16
Default Re: [REL] SA:MP MySQL Plugin 1.1

Hi there again, Ethan
Simply a great update, it's a huge progress from 1.0.x. Nice to see you using C++'s operators now, but I still could find a few mistakes

There's one thing I mentioned after G-Stylezz's R3 release. You both decided to return a constant number in mysql_query. Your version at least returns 1 instead of 0.
I've modified this function. First of all, you still didn't make it free the allocated *query after an error from mysql_real_query(). I also allowed myself to adjust returned values a little. I hope you're okay with that
I don't like going through all 20 possible mysql connections (even in a separate thread), while most of plugin's uses won't require more than just one connetion open at a time. I actually think you could reduce it to just three - if anyone needs a bigger one, they can simply modify and recompile the plugin. You didn't choose std::vector to store them - was it because of it's overhead?
And there's also the thing Mike has already mentioned - use ProcessTick() and another queue to call OnMysqlQuery().
Quote:
// native mysql_query(const query[]);
PLUGIN_FUNCTION
n_mysql_query( AMX* amx, cell* params )
{
int
h = MY_HANDLE(3);
if (!PARAM_COUNT(3))
{
GenerateError(h, "'mysql_query' called with incorrect param count", P_ERROR_INCPARAMCNT);
return 0;
}
if (!my[h].connected)
{
GenerateError(h, "'mysql_reload' called when not connected to any database", P_ERROR_DBNOCONN);
return 0;
}
if (my[h].result)
{
mysql_free_result(my[h].result);
my[h].result = NULL;
}
if (params[2] != -1)
{
queryInfo
mysqlQueue;
mysqlQueue.query = GetParam(amx, params[1]);
mysqlQueue.resultId = params[2];
my[h].queueInfo.push(mysqlQueue);
return -1;
}
else
{
const char
*query = GetParam(amx, params[1]);
my[h].state = mysql_real_query(my[h].mysql, query, strlen(query)+1);
if (my[h].state != NULL)
{
GenerateError(h, "Could not execute query", mysql_errno(my[h].mysql));
delete query;
return 0;

}

if (my[h].logging == LOG_ALL)
mysql_log("'mysql_query' executed: \"%s\" with result: \"%d\".", query, my[h].state);

delete query;
return 1;
}
//no constant return here
}
__________________
Ex-SA-MP beta tester 😉
net4game.com
Misiek is offline   Reply With Quote
Old 01/02/2010, 08:52 PM   #112
StrickenKid
Gangsta
 
Join Date: Feb 2009
Posts: 762
Reputation: 44
Default Re: [REL] SA:MP MySQL Plugin 1.1

Quote:
Originally Posted by Wicko
Hi there again, Ethan
Simply a great update, it's a huge progress from 1.0.x. Nice to see you using C++'s operators now, but I still could find a few mistakes

There's one thing I mentioned after G-Stylezz's R3 release. You both decided to return a constant number in mysql_query. Your version at least returns 1 instead of 0.
I've modified this function. First of all, you still didn't make it free the allocated *query after an error from mysql_real_query(). I also allowed myself to adjust returned values a little. I hope you're okay with that
I don't like going through all 20 possible mysql connections (even in a separate thread), while most of plugin's uses won't require more than just one connetion open at a time. I actually think you could reduce it to just three - if anyone needs a bigger one, they can simply modify and recompile the plugin. You didn't choose std::vector to store them - was it because of it's overhead?
And there's also the thing Mike has already mentioned - use PricessTick() and another queue to call OnMysqlQuery().
Quote:
// native mysql_query(const query[]);
PLUGIN_FUNCTION
n_mysql_query( AMX* amx, cell* params )
{
int
h = MY_HANDLE(3);
if (!PARAM_COUNT(3))
{
GenerateError(h, "'mysql_query' called with incorrect param count", P_ERROR_INCPARAMCNT);
return 0;
}
if (!my[h].connected)
{
GenerateError(h, "'mysql_reload' called when not connected to any database", P_ERROR_DBNOCONN);
return 0;
}
if (my[h].result)
{
mysql_free_result(my[h].result);
my[h].result = NULL;
}
if (params[2] != -1)
{
queryInfo
mysqlQueue;
mysqlQueue.query = GetParam(amx, params[1]);
mysqlQueue.resultId = params[2];
my[h].queueInfo.push(mysqlQueue);
return -1;
}
else
{
const char
*query = GetParam(amx, params[1]);
my[h].state = mysql_real_query(my[h].mysql, query, strlen(query)+1);
if (my[h].state != NULL)
{
GenerateError(h, "Could not execute query", mysql_errno(my[h].mysql));
delete query;
return 0;

}

if (my[h].logging == LOG_ALL)
mysql_log("'mysql_query' executed: \"%s\" with result: \"%d\".", query, my[h].state);

delete query;
return 1;
}
//no constant return here
}
Thanks allot

I never knew about the ProcessTick() callback and I'll use that, Thanks for the other heads up, I will work on it in a little while. Just got home from school and I'm going to get some lunch.

EDIT: Oh, also, it doesn't loop through all 20 connections, it will loop until it hits a null'd mysql variable, so if theirs only one connection, it will stop the loop at the next check because it will be null. But I could also lower it to maybe 5.
StrickenKid is offline   Reply With Quote
Old 02/02/2010, 10:15 AM   #113
Maniek
Big Clucker
 
Maniek's Avatar
 
Join Date: Apr 2007
Posts: 192
Reputation: 2
Default Re: [REL] SA:MP MySQL Plugin 1.1

What I do wrong?

Code:
mysql_log(1);
	mysql_connect("", "", "", "", 0);
 	new string[256], data[256];
 	format(string, sizeof(string), "SELECT `user_pass` FROM `map_users` WHERE `user_nick`=%s", PN(playerid));
 	mysql_query(string);
 	mysql_store_result();
 	if(mysql_fetch_field("user_pass", data))
 	{
 	  new string2[64];
 	  format(string2, sizeof(string2), "%s", mysql_store_result());
		SendClientMessage(playerid, ZOLTY, string2);
 	}
 	else
 	{
 	  SendClientMessage(playerid, ZOLTY, "B");
 	}
Maniek is offline   Reply With Quote
Old 02/02/2010, 12:51 PM   #114
Misiek
Big Clucker
 
Join Date: May 2006
Posts: 113
Reputation: 16
Default Re: [REL] SA:MP MySQL Plugin 1.1

What does the log say?
I assume it's because you don't enclose the nickname in the query.
Code:
format(string, sizeof(string), "SELECT `user_pass` FROM `map_users` WHERE `user_nick`='%s'", PN(playerid));
Is what you're looking for.

__________________
Ex-SA-MP beta tester 😉
net4game.com
Misiek is offline   Reply With Quote
Old 02/02/2010, 12:59 PM   #115
StrickenKid
Gangsta
 
Join Date: Feb 2009
Posts: 762
Reputation: 44
Default Re: [REL] SA:MP MySQL Plugin 1.1

Code:
format(string2, sizeof(string2), "%s", mysql_store_result());
What Wicko posted and that ^ is the problem. You're trying to get a string from mysql_store_result ?

Try this:

Code:
mysql_log(1);
	mysql_connect("", "", "", "", 0);
 	new string[256], data[256];
 	format(string, sizeof(string), "SELECT `user_pass` FROM `map_users` WHERE `user_nick`='%s'", PN(playerid));
 	mysql_query(string);
 	mysql_store_result();
 	if(mysql_fetch_field("user_pass", data))
 	{
	  SendClientMessage(playerid, ZOLTY, data);
 	}
 	else
 	{
 	  SendClientMessage(playerid, ZOLTY, "B");
 	}
StrickenKid is offline   Reply With Quote
Old 03/02/2010, 09:35 AM   #116
MenaceX^
High-roller
 
Join Date: Aug 2008
Posts: 3,262
Reputation: 13
Default Re: [REL] SA:MP MySQL Plugin 1.1.1

Awesome, good to see you keep updating it!
MenaceX^ is offline   Reply With Quote
Old 03/02/2010, 10:42 AM   #117
Misiek
Big Clucker
 
Join Date: May 2006
Posts: 113
Reputation: 16
Default Re: [REL] SA:MP MySQL Plugin 1.1.1

mysql_fetch_field()
Code:
	delete cfield;
	char
		*err = new char[128];
	sprintf((char *)err, "'mysql_fetch_field' could not find field: '%s'.", cfield);
	GenerateError(h, (const char *)err, P_ERROR_NOFIELD);
	delete [] err;
	return 0;
You free *cfield and then use it for logging. There's also a typo in, afair, mysql_connect, being "verson" instead of "version".
I'll test the plugin soon
__________________
Ex-SA-MP beta tester 😉
net4game.com
Misiek is offline   Reply With Quote
Old 03/02/2010, 04:23 PM   #118
Misiek
Big Clucker
 
Join Date: May 2006
Posts: 113
Reputation: 16
Default Re: [REL] SA:MP MySQL Plugin 1.1.1

Hi again! I've got another request.
As we know, the plugin doesn't require mysql_fetch_row() before fetching separate fields. It's obviously a proper behaviour, but you do a little thing, which makes the plugin less compatible and may cause problems for people trying to switch to it.
What I mean is my[h].row = NULL in n_mysql_fetch_row(). As you know, there are people using while(mysql_fetch_row(..)) to fetch their data, but even though they use this function, they also use fetching single fields, so their code looks like:
Code:
while(mysql_fetch_row(..))
{
mysql_fetch_field("blah",dest);
mysql_fetch_field("blah",dest);
mysql_fetch_field("blah",dest);
}
This code, however, will not work properly and it will retrieve only half of actual rows, because mysql_fetch_row() fetches one row and "frees" it, and then the first mysql_fetch_field() fetches another row.

To fix that, you can simply remove my[h].row = NULL from n_mysql_fetch_row(). You do it anyway in mysql_free_result(), so it definitely won't cause any problems.
And if there's something, which can make users want to switch, then why not?

Actually, you could also provide a native which they could put in a while() instead of b_mysql_fetch_row(), which would simply call the mysql_fetch_row() in order to fill my[h].row without returning any PAWN string. It would make users to be able to switch really easily, it would be a mix of efficiency and compatibility.
__________________
Ex-SA-MP beta tester 😉
net4game.com
Misiek is offline   Reply With Quote
Old 03/02/2010, 10:10 PM   #119
StrickenKid
Gangsta
 
Join Date: Feb 2009
Posts: 762
Reputation: 44
Default Re: [REL] SA:MP MySQL Plugin 1.1.1

Thanks for the mysql_fetch_field catch and the idea, I've fixed mysql_fetch_field, and added mysql_fetch_row_data, which will be able to work with mysql_fetch_field. I want to test it a little more, I'll be uploading it soon.

EDIT:

Updated.

[anchor=mysql_fetch_row_data]_________________________________________________

How to use mysql_fetch_row_data

Example usage:

(Although I suggest you to use mysql_fetch_row with split or sscanf)

Here is an example of loading all the houses from a table:
Code:
mysql_query("SELECT * FROM `houses`");
mysql_store_result();
new buffer[64];
new int i = 0;
while(mysql_fetch_row_data())
{
	mysql_fetch_field("X", buffer);
	// Here you would set the house X coord to: floatstr(buffer);
	mysql_fetch_field("Y", buffer);
	// Here you would set the house Y coord to: floatstr(buffer);
	mysql_fetch_field("Z", buffer);
	// Here you would set the house Z coord to: floatstr(buffer);


	mysql_fetch_field("owner", buffer);
	// Here you would set the house owner to: strval(buffer);
	mysql_fetch_field("price", buffer);
	// Here you would set the house price to: strval(buffer);

	i++;
}
printf("%d total houses loaded.", i);
mysql_free_result();
Here is an example on loading a players info for login:

Code:
mysql_query("SELECT * FROM `accounts` where `name` = 'PLAYERNAME'");
mysql_store_result();
new buffer[64];
if(mysql_fetch_row_data())
{
	mysql_fetch_field("money", buffer);
	// Here you would set the players money to: strval(buffer);

	mysql_fetch_field("kills", buffer);
	// Here you would set the players kills to: strval(buffer);

	mysql_fetch_field("deaths", buffer);
	// Here you would set the players deaths to: strval(buffer);

	// Set variable that the player is logged in.

	mysql_free_result();
}
else
{
	// No rows could be fetched thus the account does not exist.
}
StrickenKid is offline   Reply With Quote
Old 04/02/2010, 12:36 AM   #120
Cr0ssFir3
Big Clucker
 
Cr0ssFir3's Avatar
 
Join Date: Oct 2007
Posts: 95
Reputation: 0
Default Re: [REL] SA:MP MySQL Plugin 1.1.2

Great

Damn i love this plugin
Cr0ssFir3 is offline   Reply With Quote
Reply

Thread Tools
Display Modes

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


Similar Threads
Thread Thread Starter Forum Replies Last Post
[Plugin] [REL] MySQL Plugin (Now on github!) BlueG Plugin Development 6158 11/04/2020 08:51 AM
Best MySQL Plugin? Antonio [G-RP] Help Archive 3 10/01/2011 01:31 AM
Best MySQL plugin? DRIFT_HUNTER Help Archive 2 07/12/2010 03:43 PM
Which MySQL plugin? Whois. Help Archive 0 07/04/2010 11:55 AM
Mysql Plugin Help Jbosh123 Help Archive 0 04/09/2009 11:35 AM


All times are GMT. The time now is 11:56 AM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.