Этот туториал предназначен для тех, кто хотя бы имеет образное представление о MySQL.
ORM - облегченный сценарий запросов. Доступен с версии R33 в плагине MySQL от BlueG. ( сейчас разрабатывается Pain123/maddinat0r ).
Первое, что необходимо сделать, это создать ORM экземпляр, идентификатор - id = orm_create(nametable[]) где nametable - название таблицы базы данных, которую мы будем использовать. Теперь некоторые глобальные (или static) переменные должны быть "привязаны" к ORM процессу путем вызова функции.
PHP код:
//глобальные переменные
new kills, Float:kd_ratio, name[MAX_PLAYER_NAME+1];
PHP код:
// ... структура запросов в функции
orm_addvar_int(id, kills, "kills"); // orm_addvar_int(ORM:id, переменная, поле в БД[])
orm_addvar_float(id, kd_ratio, "ratio"); // orm_addvar_float(ORM:id, переменная, поле в БД[])
orm_addvar_string(id, name, sizeof(name), "name"); // orm_addvar_string(ORM:id, массив[], максимальная длина, поле в БД[])
Эти три запроса считают наши данные. Переменная должна быть либо глобальная либо статическая - другими словами, она не может быть в стеке!
Теперь, когда вы поняли, что делает этот макрос, а, если нет, то мне придется показать вам то, что он делает - Он считывает ваши данные из таблицы. Покажу уже на более крупном примере.
PHP код:
#include <a_mysql>
enum E_PLAYER {
ORM:ORM_ID, // создаем идентификатор в енуменаторе.
ID,
Name[MAX_PLAYER_NAME+1],
Money,
Level,
Float:PosX,
Float:PosY,
Float:PosZ,
};
new Player[MAX_PLAYERS][E_PLAYER];
public OnPlayerConnect(playerid)
{
GetPlayerName(playerid, Player[playerid][Name], MAX_PLAYER_NAME);
new ORM:ormid = Player[playerid][ORM_ID] = orm_create("players"); // Создаем наше соединение!
// Считываем данные
orm_addvar_int(ormid, Player[playerid][ID], "ID");
orm_addvar_string(ormid, Player[playerid][Name], MAX_PLAYER_NAME+1, "Name");
orm_addvar_int(ormid, Player[playerid][Money], "Money");
orm_addvar_int(ormid, Player[playerid][Level], "Level");
orm_addvar_float(ormid, Player[playerid][PosX], "PosX");
orm_addvar_float(ormid, Player[playerid][PosY], "PosY");
orm_addvar_float(ormid, Player[playerid][PosZ], "PosZ");
orm_setkey(ormid, "Name"); // Устанавливаем имя для нашей дальнейшей проверки
orm_select(ormid, "OnPlayerDataLoad", "d", playerid); // Переходим к коллбеку
return 1;
}
forward OnPlayerDataLoad(playerid);
public OnPlayerDataLoad(playerid)
{
switch(orm_errno(Player[playerid][ORM_ID])) // Проверяем на ошибки
{
case ERROR_OK: {
ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Авторизация", "Введите ваш пароль", "Login", "Abort");
}
case ERROR_NO_DATA: {
ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Регистрация", "Введите ваш пароль", "Register", "Abort");
}
}
orm_setkey(Player[playerid][ORM_ID], "ID"); // Установим идентификатор игрока для будущих запросов!
return 1;
}
public OnPlayerDisconnect(playerid, reason)
{
if(Player[playerid][ID] != 0) {
orm_update(Player[playerid][ORM_ID]); // Обновляем наши данные
}
orm_destroy(Player[playerid][ORM_ID]); // Удаляем наш идентификатор который мы создали в енуменаторе
for(new E_PLAYER:e; e < E_PLAYER; ++e)
Player[playerid][e] = 0; // Обнуляем переменные игрока
return 1;
}
Теперь по-подробнее объясню об этой части:
PHP код:
orm_setkey(ormid, "Имя");
orm_select(ormid, "OnPlayerDataLoad", "d", playerid);
Что мы сделали?
1) Установили поле Name для запроса ( путем `Name` (WHERE часть запроса) )
2) Создали запрос: "SELECT `ID`,`Name`,`Money`,`Level`,`PosX`,`PozY`,`PosZ` FROM `players` WHERE `Name`='%s' LIMIT 1" (%s ник игрока)
3) Выполняем запрос ( Это делается в отдельном потоке! )
4) Обновляем данные с запрашиваемой информации.
5) Вызываем OnPlayerDataLoad с playerid в качестве единственного параметра после завершения запроса
При успешном запросе orm_error возвращает 0, при неудачном - 1.
* ERROR_OK (0)
* ERROR_NO_DATA (1)
Так ERROR_OK, для нас в данном случае обозначает, что игрок уже существует в базе данных, и мы можем продолжить нашу проверку пользователя - попросим его авторизоваться.
Но другое дело здесь в том, что для будущих запросов, мы установили новый ключ в поле для запроса:
PHP код:
orm_setkey(Player[playerid][ORM_ID], "ID");
Это понадобится нам для дальнейших запросов, например, с orm_update (как показано в OnPlayerDisconnect), orm_select или orm_delete. После того, как игрок отключается, мы удалить экземпляр с ORM orm_destroy(ORM:id). До этого, можно назвать все orm-уроженцы кроме orm_select и orm_update.
Игрок должен зарегистрироваться на сервере, нам понадобится - orm_insert. Она создает запись в таблице. Синтаксис аналогичен orm_select:
PHP код:
orm_insert(Плеер[playerid][ORM_ID], "OnPlayerRegister", "d", playerid);
Вы заметили, что значение Player[playerid][ID] обновляется. Мы послали запрос INSERT, далее мы должны использовать orm_setkey для идентификатора переменной перед вызовом orm_insert. Если вы этого не сделаете, новый ID будет сохранен в старую переменную переменной, и получится не то что мы хотим.
Ладно, теперь мы знаем, как использовать (orm_select) и (orm_insert). Но как обновить существующие данные в базу данных? Вот где мы должны будем использовать orm_update. Этот макрос создает UPDATE-запрос со всеми текущими значениями имеющихся у нас переменных.
Например, пользователь User1 имеет ID 65 (не playerid, ID игрока-в таблице!), 4 уровня, имеет 54634$ и находится где-то в Лос-Сантосе. В этом случае, orm_update бы создать такой запрос:
PHP код:
UPDATE `игроков` SET `Name`='User1', `Деньги`='54634', `Level`='3', `PosX`='745.231', `Букет`='-967.1425', `PosZ`='14.2543', ГДЕ `ID`='65'
Использование:
PHP код:
orm_update(ORM:id);
Теперь мы можем генерировать практически все важные типы запросов, только DELETE-запрос отсутствует. Но не беспокойся, мы сейчас рассмотрим - orm_delete. Как вы могли догадаться, этот макрос создает DELETE-запрос. В нашем примере это было бы сформировать и отправить запрос:
PHP код:
DELETE FROM `players` WHERE `ID`='65'
В отличие от orm_insert, orm_delete имеет дополнительный (необязательный) параметр с именем "clearvars". Если задано значение true, orm_delete не только стереть нужную запись в соответствующей таблице, он также восстановит регистрацию путем установки значениям переменных нулю (все зарегистрированные переменные, даже ключ).
В этом учебнике мы использовали в качестве примера-систему аккаунта, но вы не должны ограничивать себя в этом! Вы можете управлять любыми данными, которые вы хотите, например, данные автомобилей или домов. Вот один пример того, как можно было бы загрузить транспортные средства с ORM системой:
PHP код:
new SQL = -1;
enum e_Vehicle
{
ORM:ORM_ID,
VID,
ID,
ModelID,
Color1,
Plate[32],
Float:Pos[4],
};
new Vehicle[MAX_VEHICLES][e_Vehicle];
public OnGameModeInit()
{
mysql_log();
SQL = mysql_connect("127.0.0.1", "root", "test", "pass");
//загружаем автомобили
mysql_tquery(SQL, "SELECT * FROM `vehicles`", "OnVehiclesLoad", "");
return 1;
}
forward OnVehiclesLoad();
public OnVehiclesLoad()
{
for(new r=0; r < cache_num_rows(); ++r) {
new ORM:ormid = Vehicle[r][ORM_ID] = orm_create("vehicles");
orm_addvar_int(ormid, Vehicle[r][ID], "ID"); //это наш ключ
orm_setkey(ormid, "ID"); //сейчас мы ставим наш ключ для дальнейших запросов
orm_addvar_int(ormid, Vehicle[r][ModelID], "ModelID");
orm_addvar_int(ormid, Vehicle[r][Color1], "Color1");
orm_addvar_string(ormid, Vehicle[r][Plate], 32, "Plate");
orm_addvar_float(ormid, Vehicle[r][Pos][0], "PosX");
orm_addvar_float(ormid, Vehicle[r][Pos][1], "PosY");
orm_addvar_float(ormid, Vehicle[r][Pos][2], "PosZ");
orm_addvar_float(ormid, Vehicle[r][Pos][3], "PosA");
orm_apply_cache(ormid, r);
Vehicle[r][VID] = CreateVehicle(Vehicle[r][ModelID], Vehicle[r][Pos][0], Vehicle[r][Pos][1], Vehicle[r][Pos][2], Vehicle[r][Pos][3], Vehicle[r][Color1], -1, -1);
}
return 1;
}
Ну вот и все.
Автор перевода: georJik