02.03.2013, 16:24
(
Последний раз редактировалось Misiur; 15.03.2013 в 16:21.
Причина: Wrong cache_get_row_float/int example
)
I'll assume that you are already using R7 and know how to use it ( https://sampforum.blast.hk/showthread.php?tid=337810 ).
Let's take a look at this example for R7
There should be more logic, like logging in, registration, etc, but I won't cover it in this tut.
Let's focus on this:
In some update there were added functions cache_get_row_(int/float). Let's use them!
Cool, we can even get rid of tmp! Now, there is something bad happening. The nick isn't loaded properly! Why?
Let's take a look at a_mysql.inc
max_len argument, it wasn't there in r7! How to fix this?
By default the function will assume that
This code isn't correct for our situation, because we will get size of an enum instead of string. Maybe sizeof Player[pid][nick]? Nope, won't work. We have 3 options:
Now string should get loaded properly.
That's all folks!
Let's take a look at this example for R7
pawn Код:
#include <a_samp>
#include <a_mysql>
#define DEBUG 1
#if DEBUG
#define Debug(%0) printf(%0)
#else
#define stock Debug({Float,_}:...)
#endif
enum PInfo {
dbID,
nick[65],
Float:lastPos[4],
bankMoney,
lastSeen
}
static Player[MAX_PLAYERS][PInfo];
#define DBPREFIX "myrp_"
enum {
TB_PLAYERS,
TB_SESSIONS
}
static dbhandle;
#define MAX_TABLE_LEN 32
static tables[][MAX_TABLE_LEN] = {
DBPREFIX"players",
DBPREFIX"sessions"
};
public OnGameModeInit() {
if((dbhandle = mysql_connect(...)) && dbhandle) {
Debug("Awwright");
} else {
Debug("DB Connection failed!");
}
return 1;
}
public OnGameModeExit() {
mysql_close(dbhandle);
return 1;
}
public OnPlayerConnect(playerid) {
new tmp[174 + MAX_TABLE_LEN + MAX_TABLE_LEN + MAX_PLAYER_NAME + 1];
GetPlayerName(playerid, tmp);
mysql_format(dbhandle, tmp, "SELECT t1.dbID, t1.nick, t1.posX, t1.posY, t1.posZ, t1.posR, t1.bankMoney, t2.session_end FROM `%s` t1 LEFT JOIN `%s` t2 ON t2.uid = t1.dbID WHERE t1.name = '%e' ORDER BY t2.session_end DESC LIMIT 0,1", tables[TB_PLAYERS], tables[TB_SESSIONS], tmp);
mysql_function_query(dbhandle, tmp, true, "OnPlayerLoad", "i", playerid);
return 1;
}
forward OnPlayerLoad(pid);
public OnPlayerLoad(pid) {
new rows, fields, tmp[64];
cache_get_data(rows, fields, dbhandle);
if(rows == 0) {
SendClientMessage(pid, -1, "You don't have an account here!");
return Kick(pid);
}
cache_get_row(0, 0, tmp, dbhandle);
Player[pid][dbID] = strval(tmp);
cache_get_row(0, 1, Player[pid][nick], dbhandle);
cache_get_row(0, 2, tmp, dbhandle);
Player[pid][lastPos][0] = floatstr(tmp);
cache_get_row(0, 3, tmp, dbhandle);
Player[pid][lastPos][1] = floatstr(tmp);
cache_get_row(0, 4, tmp, dbhandle);
Player[pid][lastPos][2] = floatstr(tmp);
cache_get_row(0, 5, tmp, dbhandle);
Player[pid][lastPos][3] = floatstr(tmp);
cache_get_row(0, 6, tmp, dbhandle);
Player[pid][bankMoney] = strval(tmp);
cache_get_row(0, 7, tmp, dbhandle);
Player[pid][lastSeen] = strval(tmp);
Debug("Loaded player with nick %s!", Player[pid][nick]);
return 1;
}
public OnQueryError(errorid, error[], callback[], query[], connectionHandle) {
Debug("Error while executing query!\nQ: %s\nErrno: %d\nError: %s", query, errorid, error);
return 1;
}
Let's focus on this:
pawn Код:
cache_get_row(0, 0, tmp, dbhandle);
Player[pid][dbID] = strval(tmp);
cache_get_row(0, 1, Player[pid][nick], dbhandle);
cache_get_row(0, 2, tmp, dbhandle);
Player[pid][lastPos][0] = floatstr(tmp);
cache_get_row(0, 3, tmp, dbhandle);
Player[pid][lastPos][1] = floatstr(tmp);
cache_get_row(0, 4, tmp, dbhandle);
Player[pid][lastPos][2] = floatstr(tmp);
cache_get_row(0, 5, tmp, dbhandle);
Player[pid][lastPos][3] = floatstr(tmp);
cache_get_row(0, 6, tmp, dbhandle);
Player[pid][bankMoney] = strval(tmp);
cache_get_row(0, 7, tmp, dbhandle);
Player[pid][lastSeen] = strval(tmp);
pawn Код:
cache_get_row_int(0, 0, Player[pid][dbID], dbhandle);
cache_get_row(0, 1, Player[pid][nick], dbhandle);
Player[pid][lastPos][0] = cache_get_row_float(0, 2, dbhandle);
Player[pid][lastPos][1] = cache_get_row_float(0, 3, dbhandle);
Player[pid][lastPos][2] = cache_get_row_float(0, 4, dbhandle);
Player[pid][lastPos][3] = cache_get_row_float(0, 5, dbhandle);
Player[pid][bankMoney] = cache_get_row_int(0, 6, dbhandle);
Player[pid][lastSeen] = cache_get_row_int(0, 7, dbhandle);
Let's take a look at a_mysql.inc
pawn Код:
native cache_get_row(row, idx, destination[], connectionHandle = 1, max_len=sizeof(destination));
By default the function will assume that
pawn Код:
max_len = sizeof(Player[pid]);
pawn Код:
//1. Hardcoded
cache_get_row(0, 1, Player[pid][nick], dbhandle, 65);
//2. Hardcoded as well
#define MAX_NICK_LEN 65
//(...)
nick[65] => nick[MAX_NICK_LEN]
//(...)
cache_get_row(0, 1, Player[pid][nick], dbhandle, MAX_NICK_LEN);
//3. Little trick, consuming some of the stack
new PTmp[PInfo];
cache_get_row(0, 1, Player[pid][nick], dbhandle, sizeof PTmp[nick]);
That's all folks!