// Sessions native nh_create_factory(host[], db[], user[], password[], privileges_flags); native nh_destory_factory(factory); native nh_open_session(factory); native nh_close_session(session); // Mappings native nh_table(table[]); native nh_id(field[], enum_field); native nh_map(field[], enum_field, length = 0); // If mapping an array (or string) use length argument too. native nh_references(field, second_mapping, key); native nh_has_many(field, second_mapping, key); // Queries native nh_select(connection, mapping); native nh_join(connection, type, mapping, second_mapping); native nh_exec(query, callback[] = "", format[] = "", ...); native nh_save(connection, mapping, data[]); native nh_update(connection, mapping, data[]); native nh_save_or_update(connection, mapping, data[]); // Operations native nh_first(query); native nh_single(query); native nh_where(query, flags, field, value[]); native nh_skip(query, field, value); native nh_take(query, field, value); native nh_order_by(query, field, asc = true); native nh_group_by(query, field); native nh_starts_with(query, field, value[]); native nh_ends_with(query, field, value[]); native nh_contains(query, field, value[]); // Lazy loading native nh_get(data, dest[]);
enum NH_PRIVILEGES { NH_PRIVILEGE_SELECT NH_PRIVILEGE_JOIN NH_PRIVILEGE_INSERT NH_PRIVILEGE_UPDATE NH_PRIVILEGE_DELETE } enum NH_WHERE { NH_WHERE_EQUALS NH_WHERE_BIGGER_THAN NH_WHERE_LESS_THAN, NH_WHERE_AND, NH_WHERE_OR }
#include <a_samp> #include <nhibernate> #define MAX_PROPS 50 #define MAX_PROP_NAME 24 #define MAX_PASSWORD_LENGTH 25 #define MIN_PASSWORD_LENGTH 6 #define SQL_HOST "localhost" #define SQL_DB "db" #define SQL_READ_USER "ruser" #define SQL_READ_PASS "rpassword" #define SQL_WRITE_USER "ruser" #define SQL_WRITE_PASS "rpassword" enum { DIALOG_REGISTER, DIALOG_LOGIN, DIALOG_INF } new g_Connection_Read, g_Connection_Write; enum e_Player { p_Id, p_Name[MAX_PLAYER_NAME], bool:IsRegistered, bool:IsLoggedIn, p_Kills, p_Deaths, p_Tag[20], p_Props[MAX_PROPS] } enum e_Prop { pr_Id, pr_Name[MAX_PROP_NAME], pr_Player } new g_Players[MAX_PLAYERS][e_Player], g_Props[MAX_PROPS][e_Prop]; main() { } public OnGameModeInit() { new read_factory = nh_create_factory(SQL_HOST, SQL_DB, SQL_READ_USER, SQL_READ_PASS, NH_PRIVILEGE_SELECT | NH_PRIVILEGE_JOIN); g_Connection_Read = nh_open_session(nh_create_factory); new write_factory = nh_create_factory(SQL_HOST, SQL_DB, SQL_WRITE_USER, SQL_WRITE_PASS, NH_PRIVILEGE_INSERT | NH_PRIVILEGE_UPDATE | NH_PRIVILEGE_DELETE); g_Connection_Write = nh_open_session(write_factory); return 1; } Map<e_Prop>() { nh_table("props"); nh_id("id", pr_Id); nh_map("name", pr_Name, MAX_PROP_NAME); nh_map("player", pr_Player); return 1; } Map<e_Player>() { nh_table("accounts"); nh_id("id", p_Id); nh_map("name", p_Name, MAX_PLAYER_NAME); nh_map("kills", p_Kills); nh_map("deaths", p_Deaths); nh_map("tag", p_Tag, 20); nh_has_many(p_Props, props, pr_Player); return 1; } public OnGameModeExit() { nh_close_session(g_Connection_Read); nh_close_session(g_Connection_Write); return 1; } public OnPlayerConnect(playerid) { for(new i = 0; e_Player:i < e_Player; i++) { g_Players[playerid][e_Player:i] = 0; } new player_name[MAX_PLAYER_NAME]; GetPlayerName(playerid, player_name, MAX_PLAYER_NAME); new player_query = nh_select(g_Connection_Read, "accounts"); nh_first(player_query); nh_where(player_query, NH_EQUALS, p_Name, player_name); nh_exec(player_query, "OnPlayerConnect_", "d", playerid); return 1; } forward OnPlayerConnect_(data, playerid); public OnPlayerConnect_(data, playerid) { if(!nh_is_null(data)) { g_Players[playerid][IsRegistered] = true; ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Welcome! Log-in Please!", "Welcome!\nIt appears that your account was found in our database!\nTherefore you may log-in to your account!\nEnter your password below:\n", "Log-in", "Quit"); } else { ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, "Welcome! Register Please!", "Welcome!\nIt appears your account can not be found in our database.\nTherefore you may register your account and create a new one!\nPlease insert your password below:", "Register", "Quit"); } } public OnPlayerDisconnect(playerid, reason) { nh_update(g_Connection_Write, g_Players[playerid]); // nh_update executes automaticlly, updated the record where identity is the same as g_Player[playerid][p_Id] return 1; } public OnPlayerDeath(playerid, killerid, reason) { g_Players[playerid][Deaths]++; if(killerid != INVALID_PLAYER_ID) { g_Players[killerid][Kills]++; } return 1; } public OnPlayerCommandText(playerid, cmdtext[]) { if(!g_Players[playerid][IsLoggedIn]) return SendClientMessage(playerid, -1, "You cannt send commands before signing in"); return 0; } public OnPlayerRequestSpawn(playerid) { if(!g_Players[playerid][IsLoggedIn]) return SendClientMessage(playerid, -1, "You cannt spawn before signing in"); return 1; } public OnPlayerText(playerid, text[]) { if(!g_Players[playerid][IsLoggedIn]) return SendClientMessage(playerid, -1, "You cannt use the chat before signing in"), 0; return 1; } forward OnPlayerLogin(data, playerid); public OnPlayerLogin(data, playerid) { if(!nh_is_null(data)) { g_Players[playerid][IsLoggedIn] = true; nh_get(data, g_Players[playerid]); } else { ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Welcome! Login Please! - Incorrect PASSWORD!", "Welcome!\nIt appears that you haven't entered a CORRECT login password\nTherefore you must enter a CORRECT password\nPlease insert your password below:", "Log-in", "Quit"); } return 1; } public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) { if(dialogid == DIALOG_REGISTER) { if(!response) { SendClientMessage(playerid, -1, "BB"); return SetTimerEx("OnPlayerKick", 100, false, "d", playerid); } else { if(!CheckPassword(inputtext)) { return ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, "Welcome! Register Please! - No PASSWORD entered!", "Welcome!\nIt appears that you haven't entered a registration password\nIt also seems that you haven't entered anything at all.\nPlease insert your password below:", "Register", "Quit"); } else { GetPlayerName(playerid, g_Players[playerid][Name], MAX_PLAYER_NAME); nh_save(g_Connection_Write, "accounts", g_Players[playerid]); } } return 1; } if(dialogid == DIALOG_LOGIN) { if(!response) { SendClientMessage(playerid, -1, "BB"); return SetTimerEx("OnPlayerKick", 100, false, "d", playerid); } else { if(!CheckPassword(inputtext)) { return ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Welcome! Login Please! - No PASSWORD entered!", "Welcome!\nIt appears that you haven't entered a login password\nIt also seems that you haven't entered anything at all.\nPlease insert your password below:", "Log-in", "Quit"); } else { new player_name[MAX_PLAYER_NAME]; GetPlayerName(playerid, player_name, MAX_PLAYER_NAME); new player_query = nh_select(g_Connection_Read, "accounts"); nh_first(player_query); nh_where(player_query, NH_EQUALS, p_Name, player_name); nh_where(player_query, NH_EQUALS | NH_AND, -1, inputtext, "password"); nh_exec(player_query, "OnPlayerLogin", "d", playerid); } } return 1; } return 0; } forward OnPlayerKick(playerid); public OnPlayerKick(playerid) { Kick(playerid); } stock CheckPassword(password[]) { return strlen(password) >= MIN_PASSWORD_LENGTH && strlen(password) <= MAX_PASSWORD_LENGTH; }
So, where's the difference between this and the existing ORM system in the MySQL plugin?
|
There's a tutorial about the ORM system here and here are all the functions listed in the include.
I'm not quite sure if lazy initialization is possible, you'd have to know when a variable is used. But I'm also not sure if lazy init is a good approach here. We have OnGameModeInit to initialize all variables/systems and we also don't really care if a gamemode is taking long to load. In addition to that, lazy init could cause evil lags while players are ingame, and that's really bad. IMO it's better if OnGameModeInit takes one minute to initialize all systems than several initializations (and thus several possible lags) during gaming on the server. |
In the inside it actually using the mysql plugin |
The version that you using in your server. This plugin isn't using code from mysql plugin inside, its hooking the function that needed to the plugin to work and using them, you can choose what version to use. Currently you need version that supports cache.
Also: the mysql plugin should be added in the server.cfg too. |
Good work on this, +REP, But why making thinks harder? What's wrong with ORM? What's wrong with Cache?
Nevermind, Good job, tho. |