[Tutorial] Updating BlueG's MySQL plugin R33+ scripts to R40
#1

This small guide will list all code-breaking changes introduced in R40 and how to fix them in your script. I will also provide regular expressions in some places (search-and-replace regex) which will easily fix the corresponding change for you. All regular expressions were tested in Notepad++, however I do NOT guarantee that they will replace always everything correctly. Make sure to backup your script before you apply the regular expressions, and always review all changes made by them.

Follow the guide step by step. Don't skip anything, or you'll quickly end up with confusing instructions and results.

  1. new "MySQL" tag for connection handles:
    Code:
    new g_SQL;
    
    public OnGameModeInit()
    {
    	g_SQL = mysql_connect(/* credentials */);
    }
    becomes
    Code:
    new MySQL:g_SQL;
    
    public OnGameModeInit()
    {
    	g_SQL = mysql_connect(/* credentials */);
    }
    Simply prepend "MySQL:" before your global MySQL variable.
  2. redundant prefixes from log level enum removed:
    Code:
    mysql_log(LOG_ERROR | LOG_DEBUG);
    becomes
    Code:
    mysql_log(ERROR | DEBUG);
    Just remove the "LOG_" part before any log level
  3. connection handle parameter moved to last position in mysql_escape_string, mysql_stat and mysql_get_charset:
    Code:
    mysql_get_charset(destination, g_SQL, sizeof(destination));
    becomes
    Code:
    mysql_get_charset(destination, sizeof(destination), g_SQL);
    Pass the global MySQL handle variable as the last parameter.
    RegEx:
    Search:
    Code:
    (mysql_escape_string|mysql_stat|mysql_get_charset)\((.+?), ?g_SQL(.*?)\);
    Replace:
    Code:
    \1\(\2\3, g_SQL\);
  4. password and database parameters swapped in mysql_connect:
    Code:
    mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_DATABASE, MYSQL_PASSWORD);
    becomes
    Code:
    mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE);
    As the title says, simply swap the password and database values.
  5. all connection options in mysql_connect moved into an own small system:
    Code:
    mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, .autoreconnect = false, .pool_size = 0);
    becomes
    Code:
    new MySQLOpt:options = mysql_init_options();
    mysql_set_option(options, AUTO_RECONNECT, false);
    mysql_set_option(options, POOL_SIZE, 0);
    mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, options);
    You now have to create an extra MySQL connection options instance, set
    the options you need and pass it to mysql_connect.
  6. mysql_option renamed into mysql_global_options:
    Code:
    mysql_option(DUPLICATE_CONNECTIONS, true);
    becomes
    Code:
    mysql_global_options(DUPLICATE_CONNECTIONS, true);
    Simply search-and-replace it.
  7. log type parameter in mysql_log removed:
    Code:
    mysql_log(ALL, LOG_TYPE_HTML);
    becomes
    Code:
    mysql_log(ALL);
  8. mysql_reconnect removed:
    Code:
    mysql_reconnect(g_SQL);
    becomes
    Code:
    mysql_close(g_SQL);
    g_SQL = mysql_connect(/* credentials */);
    Just close the handle and create a new one to the same database.
  9. mysql_current_handle removed:
    Yep. Just removed. No replacement.

  10. connection handle parameter from all cache function removed:
    Code:
    cache_get_row(0, 0, g_SQL);
    simply becomes
    Code:
    cache_get_row(0, 0);
    Same thing goes for every other cache native.
    RegEx:
    Search: (replace "g_SQL" in the regular expression below with your used global MySQL variable)
    Code:
    (cache_.+?\(.+?), ?g_SQL\);
    Replace:
    Code:
    \1\);
  11. cache_get_row renamed into cache_get_value_index:
    Code:
    cache_get_row(0, 0, dest);
    new value = cache_get_row_int(0, 1);
    becomes
    Code:
    cache_get_value_index(0, 0, dest);
    new value = cache_get_value_index_int(0, 1);
    Simply search-and-replace it.
  12. cache_get_field_content renamed into cache_get_value_name:
    Code:
    cache_get_field_content(0, "string", dest);
    new value = cache_get_field_content_int(0, "integer");
    becomes
    Code:
    cache_get_value_name(0, "string", dest);
    new value = cache_get_value_name(0, "integer");
    Simply search-and-replace it.
  13. all cache_get_ functions now return their value through a reference parameter instead of returning it directly:
    Code:
    new bool:value = cache_get_value_index_bool(0, 2);
    
    new row_count = cache_get_row_count();
    becomes
    Code:
    new bool:value;
    cache_get_value_index_bool(0, 2, value);
    
    new row_count;
    cache_get_row_count(row_count);
    All cache_get_ functions that returned data through their return value before now return it through a reference parameter. Instead they now return an status code, indicating if the function successfully executed or not.
    RegEx (will correct all "cache_get_value_" natives which are in the style "variable = cache_get_value_*(*);":
    Search:
    Code:
    (.+?) ?= ?(cache_get_value_.+?\(.*?)\);
    Replace:
    Code:
    \2, \1\);
  14. "cache_set_active(Cache:0);" doesn't unset the active cache anymore:
    Code:
    cache_set_active(Cache:0);
    becomes
    Code:
    cache_unset_active();
    Easy, huh?
  15. cache_get_data removed (use `cache_get_*_count`):
    Code:
    new rows, fields;
    cache_get_data(rows, fields);
    becomes
    Code:
    new rows, fields;
    cache_get_row_count(rows);
    cache_get_field_count(fields);
  16. parameter "clearvars" in orm_delete removed:
    Code:
    orm_delete(orm_id);
    becomes
    Code:
    orm_delete(orm_id);
    orm_clear_vars(orm_id);
  17. all y_inline support code has been outsourced, see samp-mysql-yinline-include.
Reply
#2

Can't wait for it, don't forget to implement example-script login/register as always, it's really useful
Reply
#3

Already done (thanks to Konstantinos)!
Reply
#4

Thanks!
Reply
#5

Awesome. Can't wait to check it
Reply
#6

Awesome, now I can instantly update to R40 when it comes out.
Btw is there any specific reason behind those change names?
Reply
#7

Quote:
Originally Posted by PrO.GameR
View Post
Awesome, now I can instantly update to R40 when it comes out.
Btw is there any specific reason behind those change names?
I guess you're talking about cache_get_field_content and cache_get_row.
  1. Those two natives do basically the same (retrieve values from the active cache), yet they have completely unrelated names.
  2. When you first use cache_get_row, you might think it retrieves a whole row out of the result set, but it doesn't.
  3. cache_get_field_content has the word "field" in it, which refers to a column in MySQL terminology. Again, you don't retrieve the "content of a column".
Those two natives retrieve values from the cache, specified by an row index. One uses a column index, while the other one uses a column name to get the desired value. That's why they're named "cache_get_value_index" and "cache_get_value_name" now.

Oh, and thanks to some preprocessor magic, you can omit the "_index" and "_value" part, e.g.
Code:
cache_get_value(0, 0, string); //will resolve to cache_get_value_index
cache_get_value_float(0, "health", health); //will resolve to cache_get_value_name_float
Reply
#8

Nice tutorial!
Reply
#9

A really helpful tutorial.

Thanks for this.
Reply
#10

RegEx don't work in pawno!!
Reply
#11

When I replace cache_get_row_int with cache_get_value_index_int, I get warning that number of parameters doesn't match definition.
Here's my code

Code:
_dan = cache_get_row_int(0, 0) + 1;
becomes

Code:
_dan = cache_get_value_index_int(0, 0) + 1;
I like new plugin, and major changes, but you fucked up little bit with changing functions names.
Reply
#12

Quote:
Originally Posted by vannesenn
View Post
When I replace cache_get_row_int with cache_get_value_index_int, I get warning that number of parameters doesn't match definition.
Here's my code

Code:
_dan = cache_get_row_int(0, 0) + 1;
becomes

Code:
_dan = cache_get_value_index_int(0, 0) + 1;
I like new plugin, and major changes, but you fucked up little bit with changing functions names.
Quote:

all cache_get_ functions now return their value through a reference parameter instead of returning it directly

So you have to do it like this:
Code:
cache_get_value_index_int(0, 0, _dan);
_dan += 1;
I think that he made a bad decision for getting a column's value through a reference parameter. I get his idea of making every function return a status value, but still.

One important downside: we have to transform all our lines using SetGVar* or SetPVar* to use a temporary variable, which I don't like to.
Reply
#13

Then author should edit topic. Wiki says one, topic says second. Also, some parts of code explanation are weird.
Reply
#14

Well, why I can't use char array?

Code:
	cache_get_value_index_int(0, 20, _HRP_kVisina{_playerid});
	cache_get_value_index_int(0, 21, _HRP_kOMasa{_playerid});
	cache_get_value_index_int(0, 22, _HRP_kMMasa{_playerid});
	cache_get_value_index_int(0, 23, _HRP_kMSala{_playerid});
Code:
error 035: argument type mismatch (argument 3)
I think I'll roll back on R39. I understand why he changed functions names, but why functions don't return value like before R40?
Reply
#15

The same problem with using gvar and pvar... i don't want to store the result in some temporary var and then into the gvar. I think i will stay on R39 till this R40 will return values.
Reply
#16

Nice Work Man
but i saved MySQL R33+ in my memory
its hard to transfer it but i will try i like it so Good Job man
Thank you .
Reply
#17

Quote:
Originally Posted by IstuntmanI
View Post
So you have to do it like this:
Code:
cache_get_value_index_int(0, 0, _dan);
_dan += 1;
I think that he made a bad decision for getting a column's value through a reference parameter. I get his idea of making every function return a status value, but still.

One important downside: we have to transform all our lines using SetGVar* or SetPVar* to use a temporary variable, which I don't like to.
Well, just add wrapper functions for those affected:

Code:
stock cache_get_row_int(row, field_idx, connectionHandle = 1)
{
    #pragma unused connectionHandle

    new retval = cellmin; // so this wrapper function will return cellmin in case of fail
    cache_get_value_index_int(row, field_idx, retval);
    return retval;
}
// and so on for cache_get_row_float, etc
Reply
#18

Quote:
Originally Posted by vannesenn
View Post
Then author should edit topic. Wiki says one, topic says second. Also, some parts of code explanation are weird.
If you'd actually read the tutorial, you would have seen that directly after changing the names of the cache_get_value functions there's the "cache_get_value return their values through a reference parameter" point. The wiki is also correctly describing the new functions, and even provides small examples along them.

Quote:
Originally Posted by nGen.SoNNy
View Post
The same problem with using gvar and pvar... i don't want to store the result in some temporary var and then into the gvar. I think i will stay on R39 till this R40 will return values.
Then you're going to stay on R39 forever. I don't intend to change these functions again in the next update.
Reply
#19

Good job
Reply
#20

Integer is wrong;

cache_get_value_name(0, "string", dest);
new value = cache_get_value_name(0, "integer");

New;

new value;
cache_get_value_name_int(0, "integer", value);
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)