Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 7 из 7
  1. #1
    Аватар для franked
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.02.2015
    Адрес
    Ташкент епта
    Сообщений
    10
    Репутация:
    0 ±

    Удобство в работе с MySQL

    Привет всем! Я тут недавно подумывал для себя функцию написать,чисто для удобства работы с MySQL плагином в павно. В общем,я очень часто экранирую допустим запросы,и каждый раз писать строку,и mysql_format потом еще и mysql_function_query порой не то, что бы надоедает,но и мешает,грязнит код,и становиться немного не удобнее работать. И я подумывал для себя написать допустим функцию Mysql_query,которая бы принимала сразу строку с SQL запросом и сразу параметры,которые бы подставились потом в SQL запрос. И тут я задумался,что параметров может быть допустим не 5,а больше,бывают разные случаи.(callback'и пока не учитываю,просто хочу научиться писать подобные функции) И по правде говоря,я не знаю как бы ее написать,я только лишь понял,что начало должно быть примерно таким:
    PHP код:
    stock Mysql_query(query_string[], {Float,_}:...)//ну примерно так
    {
    //И тут уже код экранизации и т.д

    Но дело в том,что я наткнулся на тему (кликабельно),в которой есть примеры функции,но там аргументы берутся через getarg (Собственно больше и никак не получиться вроде). А getarg, в случае если мы передали массив (ту же самую строку например),по символьно извлекает строку. И это все делать в цикле и прочее прочее как то тоже не вариант особо. Кто может подсказать показать,как ее можно реализовать? Допустим с помощью того же #emit на этом ассэмблере... Очень хотелось бы научиться писать функции такого рода

  2. #2
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    От Y_Less:
    PHP код:
    #define BYTES_PER_CELL (cellbits / charbits)

    stock SendClientMessageToAllf(colorfstring[], {Float_}:...)
    {
        static const 
    STATIC_ARGS 2;
        new 
    = (numargs() - STATIC_ARGS) * BYTES_PER_CELL;
        if (
    n)
        {
            new 
    message[144], arg_startarg_end;
            
    #emit CONST.alt        fstring
            #emit LCTRL            5
            #emit ADD
            #emit STOR.S.pri        arg_start

            #emit LOAD.S.alt        n
            #emit ADD
            #emit STOR.S.pri        arg_end
            
    do
            {
                
    #emit LOAD.I
                #emit PUSH.pri
                
    arg_end -= BYTES_PER_CELL;
                
    #emit LOAD.S.pri    arg_end
            
    }
            while(
    arg_end arg_start);

            
    #emit PUSH.S            fstring
            #emit PUSH.C            144
            #emit PUSH.ADR            message

            
    += BYTES_PER_CELL 3;
            
    #emit PUSH.S            n
            #emit SYSREQ.C            format

            
    += BYTES_PER_CELL;
            
    #emit LCTRL                4
            #emit LOAD.S.alt        n
            #emit ADD
            #emit SCTRL                4

            
    SendClientMessageToAll(colormessage);
        }
        else
        {
            
    SendClientMessageToAll(colorfstring);
        }
        return 
    1;

    Последний раз редактировалось ziggi; 16.02.2016 в 23:18.

  3. #3
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от ziggi Посмотреть сообщение
    От Y_Less:
    PHP код:
    #define BYTES_PER_CELL (cellbits / charbits)

    stock SendClientMessageToAllf(colorfstring[], {Float_}:...)
    {
        static const 
    STATIC_ARGS 2;
        new 
    = (numargs() - STATIC_ARGS) * BYTES_PER_CELL;
        if (
    n)
        {
            new 
    message[144], arg_startarg_end;
            
    #emit CONST.alt        fstring
            #emit LCTRL            5
            #emit ADD
            #emit STOR.S.pri        arg_start

            #emit LOAD.S.alt        n
            #emit ADD
            #emit STOR.S.pri        arg_end
            
    do
            {
                
    #emit LOAD.I
                #emit PUSH.pri
                
    arg_end -= BYTES_PER_CELL;
                
    #emit LOAD.S.pri    arg_end
            
    }
            while(
    arg_end arg_start);

            
    #emit PUSH.S            fstring
            #emit PUSH.C            144
            #emit PUSH.ADR            message

            
    += BYTES_PER_CELL 3;
            
    #emit PUSH.S            n
            #emit SYSREQ.C            format

            
    += BYTES_PER_CELL;
            
    #emit LCTRL                4
            #emit LOAD.S.alt        n
            #emit ADD
            #emit SCTRL                4

            
    SendClientMessageToAll(colormessage);
        }
        else
        {
            
    SendClientMessageToAll(colorfstring);
        }
        return 
    1;

    Эта функция иногда приводит к крашам. Один из таких случаев приходилось наблюдать, когда я объявил её как экспортируемую (public) и пробовал вызвать через CallLocalFunction (только не спрашивайте, почему), также подойдёт SetTimerEx или CallRemoteFunction - главное, чтобы функция вызывалась из сервера, а не из другой функции на Pawn.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  4. Пользователь сказал cпасибо:
    franked (17.02.2016)
  5. #4
    Аватар для franked
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.02.2015
    Адрес
    Ташкент епта
    Сообщений
    10
    Репутация:
    0 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
      Открыть/закрыть
    Эта функция иногда приводит к крашам. Один из таких случаев приходилось наблюдать, когда я объявил её как экспортируемую (public) и пробовал вызвать через CallLocalFunction (только не спрашивайте, почему), также подойдёт SetTimerEx или CallRemoteFunction - главное, чтобы функция вызывалась из сервера, а не из другой функции на Pawn.
    Блин,жалко . Как же тогда быть? Есть еще варианты,как можно писать подобные функции?

  6. #5
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от franked Посмотреть сообщение
    Блин,жалко . Как же тогда быть? Есть еще варианты,как можно писать подобные функции?
    Функции вряд ли, а вот макрос можно попробовать.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  7. #6
    Аватар для franked
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.02.2015
    Адрес
    Ташкент епта
    Сообщений
    10
    Репутация:
    0 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Функции вряд ли, а вот макрос можно попробовать.
    Да,я тоже подумывал макросом,вот,что из этого вышло:
    PHP код:
    #define MySQL_SendSQuery(%0,%1,%2,%3)    mysql_format(%0, %1, sizeof(%1), %2, %3),mysql_function_query(%0, %1, false, "", "") 
    Типа MySQL_SendSafetyQuery,где будет отправляться безопасный запрос без колбэка. Но вот не задача,не уж то придется для каждого случая свой макрос писать? К примеру,если я захочу примерно той же самой строкой (MySQL_SendCQuery типа CallBackQuery) написать безопасный запрос,как мне дать понять #define'у что под %4 будут передаваться аргументы в функцию mysql_function_query а не в mysql_format?

    Я уже пробовал,нечто подобное:
    PHP код:
    #define MySQL_SendСQuery(%0,%1,%2,%3,%4,%5,%6) format(%1, sizeof(%1), %2, %3),mysql_function_query(%0, %1, true, %4, %5, %6) 
    Но в колбэк всеравно данные не поступают....

    Попробовал сделать еще нечто вроде этого:
    PHP код:
    #define MySQL_Query(%0,%1[%2],%3(%4),%5(%6),%7)    mysql_format(%0, %1, sizeof(%1)+%2, %3, %4),mysql_function_query(%0, %1, true, %5, %6, %7) 
    Немного усовершенствовал даже где-то,но все-равно что-то коллбэк не вызывается...Вроде работает. Однако,пока-что только с одним походу аргументом.

    Я этот макрос заюзал в системе регистрации,и у меня нужный мне колбэк,куда передается playerid вызвался и все проделал,что нужно. Сейчас еще потестю,а пока что,походу только с одним параметром такая фича работает.
    Последний раз редактировалось franked; 17.02.2016 в 15:56.

  8. #7
    Аватар для franked
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.02.2015
    Адрес
    Ташкент епта
    Сообщений
    10
    Репутация:
    0 ±
    А,все,вроде-бы работает,разобрался. Я передавал в callback 2ым аргументом строку,но делал это так: "ds[80]",нужно было убрать квадратные скобки (ну и собственно само значение в них),привык работать со sscanf...

    Получается,некий готовый вариант будет выглядить примерно так:
    PHP код:
    #define MySQL_Query(%0,%1[%2],%3(%4),%5,%6(%7),%8) mysql_format(%0, %1, sizeof(%1)+(%2), %3, %4),mysql_function_query(%0, %1, %5, %6, %7, %8)
    /*
        Пояснения:
    %0 - connectionHandle
    %1 - Переменная,которая будет содержать отформатированный запрос
    %2 - Если допустим хотим добавить в sizeof вычисления,такие как +24(MAX_PLAYER_NAME например) или даже вычесть те же самые маркеры в строке (%s например)
    %3 - Сама строка SQL запроса,с маркерами,куда будут подставляться значения
    %4 - Переменные,которые будут подставляться в будучи формаитрованную SQL строку
    %5 - true/false т.е вешать или не вешать паблик-обработчик нашего запроса (Коллбэк короче).
    %7 - формат[] аргументов, (как в sscanf'e(почти) dsif (где d -integer,s- string,i - integer,f - float ну и т.д. короче))
    %8 - сами аргументы,которые передадутся в коллбэк
    */

    //Использование:

    new STR[80];
    MySQL_Query(conIDSTR[0], "SELECT * FROM `accounts` WHERE `Name` = '%s' LIMIT 1"(Player[playerid][pName]),true,"testQuery_result"("ds"),playerid,STR);

    //Создадим тестовый коллбэк:
    forward testQuery_result(playerid,str[]);
    public 
    testQuery_result(playerid,str[])
    {
        print(
    "=====================================================================================");
        
    printf("[+] testQuery_result MY ID IS: %d\n[+] AND MY STRING IS:\n [++] %s"playeridstr);
        print(
    "=====================================================================================");
    //P.S я пока не стал извлекать из базы данные,т.к базу еще толком не доделал,поэтому такого примера достаточно думаю будет =)
    }

    //Пояснение "Использование":

    new STR[80];//Создаем переменную,которая будет отформатирована

    MySQL_Query(conIDSTR[0], "SELECT * FROM `accounts` WHERE `Name` = '%s' LIMIT 1"(Player[playerid][pName]),true,"testQuery_result"("ds"),playerid,STR);//Фигачим по макросу

    conID и есть connectionHandle (он же %0)

    STR Переменная,содержащая отформатированный запрос (%1)

    [
    0] - Укажемчто ничего не прибавлять/не вычитать в sizeof (Хотя по сути он просто сделает sizeof(STR) + 0) (%2)

    "SELECT * FROM `accounts` WHERE `Name` = '%s' LIMIT 1" SQL запрос с маркером,куда подтсавиться ник игрока (%3)

    (
    Player[playerid][pName]) - в скобках укажем подставляемые параметры в SQL строку (как и в макросеМЕЖДУ ЭТИМИ СКОБКАМИ НЕ ДОЛЖНО БЫТЬ ПРОБЕЛОВ,КАК И В МАКРОСЕ,ИНАЧЕ РУГАТЬСЯ БУДЕТ (по крайней мере у меня ругается) (%4)

    true Укажем,что мы будем использовать колбэк /*В случае FALSE описано ниже*/ (%5)

    "testQuery_result" Укажем название колбэка,который будем использовать (%6)

    (
    "ds") - Параметры аргументов,которые передадим в колбэк (ТАКЖЕ НЕ ДОЛЖНО БЫТЬ ПРОБЕЛОВ) (%7)

    playerid,STR Переменные,которые будет принимать наш колбэк,это id игрока и саму отредактированную строку запроса,которую мы через printf в консоли покажем (%8)

    //В случае false,если мы не хотим вызывать колбэк:

    вместо true ставим false

    вместо 
    "testQuery_result" ставим""

    вместо ("ds"ставим: ("")

    и НЕ вписываем playerid,STR,а пишем""

    //думаю нет смысла пояснять если что и про сам колбэк... 
    Последний раз редактировалось franked; 18.02.2016 в 00:29.

 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •