[MYSQ] INSERT/UPDATE Sentence Maker
#1
Como el titulo indica ni mas ni menos. Whatdone

facil uso:
Código PHP:
// INSERT
    
sid sql_init(SQL_INSERT);
    
sql_set_table(sid"tabla")
    
sql_set_value(sid"c1""data^"")
    sql_set_value(sid, "
c2", "%s", "data")
    sql_execute(sid);
    //UPDATE
    sid = sql_init(SQL_UPDATE)
    sql_set_table(sid, "
tabla")
    sql_set_value(sid, "
c1", "data")
    sql_update_value(sid, "
c2", "123", true, "c2", "+")
    sql_update_value(sid, "
c3", "jose")
    sql_set_where(sid, "
player", "SUGI", "pass", "^"2\ \^"23");
    sql_execute(sid)
    // MANUAL WHERE 
    sid = sql_init(SQL_UPDATE)
    sql_set_table(sid, "
tabla")
    sql_set_value(sid, "
c1", "data")
    sql_update_value(sid, "
c2", "123", true, "c2", "+")
    sql_update_value(sid, "
c3", "jose")
    sql_set_where_manual(sid, "
player='jose' AND pass='sugi123'");
    sql_execute(sid) 

quedaria algo como:
[Imagen: qm5g8h2iQ-qb0Ux8uSzbZw.png]

cuando tenga un chancecito lo explico mejor
si alguien aporta mejoras al mismo, se le agradece


Código PHP:
#include <sqlx>

enum SQL_QUERY_MODE
{
    
SQL_INSERT,
    
SQL_UPDATE
}

const 
__SQL_MAX_COLUMN_BUF_SIZE 256
const __SQL_MAX_QUERY_BUF_SIZE 1280
const __SQL_MAX_IDENTIFIER_NUMS 4
const __SQL_TABLE_SIZE_BUFF 32

stock Trie
:_QUERY_SENTENCER
stock any
:_QUERY_IDENTIFIER 0;


enum _:__QS_ARRAY
{
    
SQL_QUERY_MODE:__SQL_MODE,
    
__TABLE[__SQL_TABLE_SIZE_BUFF],
    Array:
__COLUMN,
    Array:
__DATA,
    Array:
__WHERE_C,
    Array:
__WHERE_D,
    
__WHERE_MANUAL[__SQL_MAX_COLUMN_BUF_SIZE]
}
/**
 * Inicia Preparacion de la oracion sql
 *
 * @param mode      Modo
 * 
 * @return identificador del inicios
 *
 */
stock SQL_DATA:sql_init(SQL_QUERY_MODE:mode)
{
    if(!(
SQL_INSERT <= mode <= SQL_UPDATE))
    {
        
log_error(AMX_ERR_NATIVE"[AMXX] SQL Mode not valid!")
        return 
any:0;
    }
    new 
a[__QS_ARRAY], num[__SQL_MAX_IDENTIFIER_NUMS];
    if(!
_QUERY_SENTENCER)
    {
        
_QUERY_SENTENCER TrieCreate()
    }
    
a[__SQL_MODE] = mode
    _QUERY_IDENTIFIER 
+= 1;
    
num_to_str(_QUERY_IDENTIFIERnumcharsmax(num))
    
TrieSetArray(_QUERY_SENTENCERnumasizeof(a))
    return 
_QUERY_IDENTIFIER;
}
/**
 * Establece la tabla a trabajar
 *
 * @param id        Identificador
 * @param table     Tabla a trabajar
 * 
 * @noreturn
 *
 */
stock sql_set_table(SQL_DATA:id, const table[])
{
    new 
a[__QS_ARRAY], num[__SQL_MAX_IDENTIFIER_NUMS];
    
num_to_str(any:idnumcharsmax(num))
    if(
TrieGetArray(_QUERY_SENTENCERnumasizeof(a)) == false)
    {
        
log_error(AMX_ERR_NATIVE"[AMXX] SQL DATA ID not valid!")
        return;
    }
    
formatex(a[__TABLE], charsmax(a[__TABLE]), "%s"table);
    
TrieSetArray(_QUERY_SENTENCERnumasizeof(a))
}
/**
 * Establece la tabla a trabajar
 *
 * @param id            Identificador
 * @param column        Establece una columna
 * @param data          Datos a establecer en una columna
 * @param ...           Datos para formatear el texto establecido en data
 *
 * @noreturn
 *
 */
stock sql_set_value(SQL_DATA:id, const column[], const data[], any:...)
{
    new 
a[__QS_ARRAY], num[__SQL_MAX_IDENTIFIER_NUMS], buff[__SQL_MAX_COLUMN_BUF_SIZE];
    
num_to_str(any:idnumcharsmax(num))
    if(
TrieGetArray(_QUERY_SENTENCERnumasizeof(a)) == false)
    {
        
log_error(AMX_ERR_NATIVE"[AMXX] SQL DATA ID not valid!")
        return;
    }
    
vformat(buffcharsmax(buff), data4);
    new Array:
a[__COLUMN];
    new Array:
a[__DATA];
    if(!
c)
    {
        
ArrayCreate(__SQL_MAX_COLUMN_BUF_SIZE)
        
ArrayCreate(__SQL_MAX_COLUMN_BUF_SIZE)
        
a[__COLUMN] = c
        a
[__DATA] = d
    
}
    
replace_all(buffcharsmax(buff), "\", "\\");
    replace_all(buff, charsmax(buff), "
^"""\^"");
    
    ArrayPushString(c, column)
    ArrayPushString(d, buff)
    TrieSetArray(_QUERY_SENTENCER, num, a, sizeof(a))
}
/**
 * Actualiza datos de una columna
 * Esta funcion esta pensada para usar numeros enteros/flotantes
 * Pero se pueden usar strings
 *
 * @param id                            Identificador
 * @param column                        Establece una columna
 * @param data                          Datos a establecer en una columna
 * @param update_with_other_column      con true para actualizar con datos de otra columna
 * @param update_from                   si "
update_with_other_column" se estable en true se debe establecer la columna para tomar los datos de esa columna
 * @param update_operator               se utiliza un operador logico para relizar operaciones matematicas usando de base los datos de la columna establecida por "
update_from"
 *
 * @noreturn
 *
 */
stock sql_update_value(SQL_DATA:id, const column[], const data[], bool:update_with_other_column=false, const update_from[]="", const update_operator[]="")
{
    new a[__QS_ARRAY], num[__SQL_MAX_IDENTIFIER_NUMS], buff[__SQL_MAX_COLUMN_BUF_SIZE];
    num_to_str(any:id, num, charsmax(num))
    if(TrieGetArray(_QUERY_SENTENCER, num, a, sizeof(a)) == false)
    {
        log_error(AMX_ERR_NATIVE, "
[AMXXSQL DATA ID not valid!")
        return;
    }
    if(a[__SQL_MODE] != SQL_UPDATE)
    {
        log_error(AMX_ERR_NATIVE, "
[AMXXSQL DATA ID IS NOT UPDATE MODE!")
        return;
    }
    new Array:c = a[__COLUMN];
    new Array:d = a[__DATA];
    if(!c)
    {
        c = ArrayCreate(__SQL_MAX_COLUMN_BUF_SIZE)
        d = ArrayCreate(__SQL_MAX_COLUMN_BUF_SIZE)
        a[__COLUMN] = c
        a[__DATA] = d
    }
    if(update_with_other_column && update_from[0] && update_operator[0])
    {
        formatex(buff, charsmax(buff), "
`%s`%s%i", update_from, update_operator, str_to_num(data));
    }
    else
    {
        copy(buff, charsmax(buff), data)
        replace_all(buff, charsmax(buff), "
\", "\\");
        replace_all(buff, charsmax(buff), "
^"""\^"");
        
    }
    ArrayPushString(c, column)
    ArrayPushString(d, buff)
    TrieSetArray(_QUERY_SENTENCER, num, a, sizeof(a))
}
/**
 * Establece una condicion manual
 *
 * @param id            Identificador
 * @param where         Establece una condicion de manera manual
 * @param ...           Datos para formatear el texto establecido en where
 *
 * @noreturn
 *
 */
stock sql_set_where_manual(SQL_DATA:id, const where[], any:...)
{
    new a[__QS_ARRAY], num[__SQL_MAX_IDENTIFIER_NUMS]
    num_to_str(any:id, num, charsmax(num))
    if(TrieGetArray(_QUERY_SENTENCER, num, a, sizeof(a)) == false)
    {
        log_error(AMX_ERR_NATIVE, "
[AMXXSQL DATA ID not valid!")
        return;
    }
    vformat(a[__WHERE_MANUAL], charsmax(a[__WHERE_MANUAL]), where, 3);
    TrieSetArray(_QUERY_SENTENCER, num, a, sizeof(a))
}
/**
 * Establece una condicion Formateada
 *
 * @param id            Identificador
 * @param ...           Se establece una condicion sql preformateada con datos, 
 *                      donde el primer argumento sera la columna y el segundo 
 *                      argumento seria el dato de la columna a verificar
 *                      Este argumento tendra un "
escape string", los 
 *                      argumentos siguentes argumetos se cumpliran de la misma 
 *                      manera que el argumento 1 y 2
 *
 * @note                Ejemplo: sql_set_where(id, "
user", "SU^"GI")
 *                      
en la oracion sql se rellenaria asi WHERE `user`="SU\"GI"
 
*                      Otro Ejemplo sql_set_where(id"user""SU^"GI", "password", "Sugiiiiisaiiii^"^"")
 *                      en la oracion sql se rellenaria asi WHERE `user`="
SU\"GI" AND `password`="Sugiiiiisaiiii\"\""
 
*
 *
 * @
noreturn
 
*
 */
stock sql_set_where(SQL_DATA:idany:...)
{
    new 
a[__QS_ARRAY], num[__SQL_MAX_IDENTIFIER_NUMS], data[__SQL_MAX_COLUMN_BUF_SIZE]
    
num_to_str(any:idnumcharsmax(num))
    if(
TrieGetArray(_QUERY_SENTENCERnumasizeof(a)) == false)
    {
        
log_error(AMX_ERR_NATIVE"[AMXX] SQL DATA ID not valid!")
        return;
    }
    new Array:
a[__WHERE_C];
    new Array:
a[__WHERE_D];
    if(!
c)
    {
        
ArrayCreate(__SQL_MAX_COLUMN_BUF_SIZE)
        
ArrayCreate(__SQL_MAX_COLUMN_BUF_SIZE)
        
a[__WHERE_C] = c
        a
[__WHERE_D] = d
    
}
    new 
posch;
    for(new 
numargs() ; i++)
    {
        
pos 0;
        while((
ch getarg(ipos )))
        {
            
data[pos++] = ch;
        }
        
data[pos++] = '^0';
        if((
2) == 0)
        {
            
replace_all(datacharsmax(data), "\", "\\");
            replace_all(data, charsmax(data), "
^"""\^"");
            ArrayPushString(d, data);
        }
        else
        {
            ArrayPushString(c, data);
        }
    }
    TrieSetArray(_QUERY_SENTENCER, num, a, sizeof(a))
}
/**
 * Ejecuta una una Oracion SQL 
 *
 * @note The handler should look like:
 *       public QueryHandler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime)
 *       failstate - One of the three TQUERY_ defines.
 *       query     - Handle to the query, do not free it.
 *       error     - An error message, if any.
 *       errnum    - An error code, if any.
 *       data      - Data array you passed in.
 *       size      - Size of the data array you passed in.
 *       queuetime - Amount of gametime that passed while the query was resolving.
 * @note This will not interrupt gameplay in the event of a poor/lossed 
 *       connection, however, the interface is more complicated and 
 *       asynchronous. Furthermore, a new connection/disconnection is 
 *       made for each query to simplify driver support.
 * @note The handle does not need to be freed.
 *
 * @param id            Identificador
 * @param SQL_TUPLE     Tuple handle, returned from SQL_MakeDbTuple().
 * @param Handler       A function to be called when the query finishes. It has to be public.
 * @param data          Additional data array that will be passed to the handler function.
 * @param dataSize      The size of the additional data array. 
 * 
 *
 * @noreturn
 *
 */
stock sql_execute(SQL_DATA:id, Handle:SQL_TUPLE, const Handler[], const szData[]="", DataSize=0)
{
    new a[__QS_ARRAY], num[__SQL_MAX_IDENTIFIER_NUMS], data[__SQL_MAX_COLUMN_BUF_SIZE], query[__SQL_MAX_QUERY_BUF_SIZE], len;
    num_to_str(any:id, num, charsmax(num))
    if(TrieGetArray(_QUERY_SENTENCER, num, a, sizeof(a)) == false)
    {
        log_error(AMX_ERR_NATIVE, "
[AMXXSQL DATA ID not valid!")
        return;
    }

    len = formatex(query, charsmax(query), "
%`%s", a[__SQL_MODE] == SQL_INSERT ? "INSERT INTO" : a[__SQL_MODE] == SQL_UPDATE ? "UPDATE" : "", a[__TABLE])
    new Array:d, Array:c, i;
    c = a[__COLUMN];
    d = a[__DATA];
    if(a[__SQL_MODE] == SQL_INSERT)
    {
        len += add(query[len], charsmax(query), "
(");
        for( i = 0 ; i < ArraySize(c) ; i++)
        {
            ArrayGetString(c, i, data, charsmax(data))
            len += formatex(query[len], charsmax(query), "
%s`%s`", i > 0 ? "," : "", data);
        }
        len += add(query[len], charsmax(query), "
VALUES (");
        for( i = 0 ; i < ArraySize(d) ; i++)
        {
            ArrayGetString(d, i, data, charsmax(data))
            len += formatex(query[len], charsmax(query), "
%s^"%s^"", i > 0 ? "," : "", data);
        }
        len += add(query[len], charsmax(query), "
)");
    }
    else if(a[__SQL_MODE] == SQL_UPDATE)
    {
        len += add(query[len], charsmax(query), "
SET ");
        new data2[__SQL_MAX_COLUMN_BUF_SIZE]
        for( i = 0 ; i < ArraySize(c) ; i++)
        {
            ArrayGetString(c, i, data, charsmax(data))
            ArrayGetString(d, i, data2, charsmax(data2))
            len += formatex(query[len], charsmax(query), "
%s`%s`=%s%s%s", i > 0 ? "," : "", data, data2[0] != '`' ? "^"" ""data2data2[0] != '`' "^"" : "");
        }
        if(!a[__WHERE_MANUAL])
        {
            new Array:wc, Array:wd;
            wd = a[__WHERE_D]
            wc = a[__WHERE_C]
            len += add(query[len], charsmax(query), " 
WHERE ");
            for(new i = 0 ; i < ArraySize(wc) ; i++)
            {
                ArrayGetString(wc, i, data, charsmax(data))
                ArrayGetString(wd, i, data2, charsmax(data2))
                len += formatex(query[len], charsmax(query), "
%s`%s`=^"%s^"", i > 0 ? " AND " : "", data, data2)
            }
            ArrayDestroy(wc)
            ArrayDestroy(wd)
        }
        else
        {
            len += formatex(query[len], charsmax(query), " 
WHERE %s", a[__WHERE_MANUAL]);
        }
        
    }
    server_print(query)
    ArrayDestroy(c)
    ArrayDestroy(d)
    TrieDeleteKey(_QUERY_SENTENCER, num)
    SQL_ThreadQuery(SQL_TUPLE, Handler, query, szData, DataSize);



Archivos adjuntos
.inc   sql_helper.inc (Tamaño: 11.67 KB / Descargas: 6)
Competitive/Face it Pick Up Game (PUG) servidor de prueba: 45.77.94.109:27016 Click para Entrar
[Imagen: b_350_20_5A6C3E_383F2D_D2E1B5_2E3226.png]

(14/08/2015, 10:15 PM)Sugisaki escribió: "El mundo es caotico, irracional e injusto. No tiene ningun significado"
Palabras que desde hace mucho tiempo he buscado para describir, ¿Que es el mundo?
Crab

Código PHP:
if(ayuda && free)
{
    exit();

Responder
#2
Buen Aporte!Mario
Corazón I dream of someday being able to have your near. Corazón
[Imagen: 76561199006140497.png]
Responder
#3
Excelente aporte @Sugisaki, estaría bueno también que añadas:
Código PHP:
sql_set_where(where[]=""any:...) // En el caso que sea algun SELECT?
sql_set_order(order[]=""// En el caso que sea algun SELECT?
sql_set_limit(startend// En el caso que sea algun SELECT? 

Nothingdohere

OFF:
(01/12/2019, 04:01 PM)andres_1041 escribió: Buen Aporte!Mario

No tienes ni la más mínima idea de cómo funciona y en qué facilita las cosas Oh god why
[Imagen: b_350_20_323957_202743_f19a15_111111.png]

Estudia siempre; el tiempo es oro, lo material se puede recuperar pero el tiempo no se puede recuperar.
(02/10/2016, 05:05 PM)meTaLiCroSS escribió: Siempre me gusta ayudar cuando alguien esta interesado realmente en ver que esta programando.
(08/08/2019, 05:32 PM)meTaLiCroSS escribió: grax x el dato cr4ck


Mis aportes

PLUGINS
MAPAS
Menú LANG [SF] Sistema de Frags
Say System (Admin Prefix)
Responder
#4
Justo tenia que hacer un sistema de cuentas, veremos a ver que pex.
Responder
#5
Esta muy bueno, sería algo así como
$query->bindValue ??



Solo una duda eso protege caracteres sql??
[Imagen: zcsztw-4.png] [Imagen: 6u5fj2-4.png]
[Imagen: linkedin_thumb_image.png][Imagen: 76561198283253977.png][Imagen: linkedin_thumb_image.png]
Responder
#6
un novato en mysql se le hará mas fácil de usar :3 aunque igual den aprender mysql
una eternidad para aportarlo ¬¬
[Imagen: 76561198090851442.png]
Responder
#7
Qué hay de SELECT, DELETE, EXISTS y COUNT?

Eficiente sería que hacer una consulta tome una sola línea de código sino por qué alguien se molestaría escribiendo 5 líneas para hacer un simple update?
Podés comprobar en el sma de mi plugin de estadísticas generales donde armé una función (muy pobre pero sirve como concepto) para realizar muchas consultas pero había quedado breve y simple.

Podés obtener mejores ideas de lo que dije anteriormente acá:
https://github.com/LuKks/like-mysql
https://github.com/LuKks/like-mysql/blob...r/index.js
Para INSERT y UPDATE creo que sería difícil lograrlo en una línea (en AMXX) pero para el resto de consultas es factible.

Además, nombrás a tus funciones como "prepare" pero no son técnicamente consultas preparadas así que tenés que utilizar la función escape en cada valor para evitar SQL injection, de otra forma, nosotros al usar tu código tenemos que usar escape lo cual sería ultra tedioso y extenso, aparte todos se olvidan de hacerlo.

No inspira confianza usar un código donde hay una función llamada "STUPID_FUNCTION".
Podés cambiarlo a "sql_init" y que nosotros tengamos que añadirlo en plugin_init así evitás llamadas innecesarias pero lo importante era el nombre de la función.

Podrías intentar organizar el código en un .inc así como hice en mis redes neuronales o sino también podés crear natives, aunque es más simple include.

(01/12/2019, 04:30 PM)totopizza escribió: Excelente aporte @Sugisaki, estaría bueno también que añadas:
Código PHP:
sql_set_where(where[]=""any:...) // En el caso que sea algun SELECT?
sql_set_order(order[]=""// En el caso que sea algun SELECT?
sql_set_limit(startend// En el caso que sea algun SELECT? 

Nothingdohere

No te olvides del identificador.

Código PHP:
new SQL_DATA:sid sql_prepare_update("pug_stats_player""id='%i' ORDER BY id DESC LIMIT 1"1);
// sql_set_value ...
// sql_execute ... 
vs
Código PHP:
new SQL_DATA:sid sql_prepare_update("pug_stats_player""id='%i'"1);
// sql_set_value ...
sql_set_order(sid"id DESC")
sql_set_limit(sid1);
// sql_execute ... 

Ahora imaginá que tenés 10 updates en todo tu plugin, incluso con 1 update prefiero la primer forma.
Responder
#8
(02/12/2019, 02:37 PM)LuKks escribió: Eficiente sería que hacer una consulta tome una sola línea de código sino por qué alguien se molestaría escribiendo 5 líneas para hacer un simple update?
A que te refieres cuando dices eficiencia?
Tecnicamente no estas enviando consultas por el numero de funciones sql_* que exista en un frame.

"Eficiente" seria realizar una consulta update extremadamente larga de una manera la cual sea legible.

Imagina tener mmmmm 15 columnas, las cual, las acualizas/insertas cada vez que se desconecta un jugador, tendrias que realizar tecnicas en el editor para poder formatear la "Oracion SQL" la cual no se te mezcle datos de una columna con otra, o que te falte una variable, o que agreges columnas nuevas al proyecto. La tecnica que usaba era alinear las columnas con los caracteres de escape y las variables unas abajo de otras para no tener problemas de formato ya que se retrasaria el proyecto

(esto es un ejemplo)
[Imagen: Ys007LDBSXugYY3_ODhQ3A.png]

(02/12/2019, 02:37 PM)LuKks escribió: Podés obtener mejores ideas de lo que dije anteriormente acá:
https://github.com/LuKks/like-mysql
https://github.com/LuKks/like-mysql/blob...r/index.js
Para INSERT y UPDATE creo que sería difícil lograrlo en una línea (en AMXX) pero para el resto de consultas es factible.
Proud dejame revisar

(02/12/2019, 02:37 PM)LuKks escribió: Además, nombrás a tus funciones como "prepare" pero no son técnicamente consultas preparadas así que tenés que utilizar la función escape en cada valor para evitar SQL injection, de otra forma, nosotros al usar tu código tenemos que usar escape lo cual sería ultra tedioso y extenso, aparte todos se olvidan de hacerlo.

no esta diseñado para captar datos introducidos por el usuario, si te refieres al nombre, basta con hacer
Código PHP:
sql_set_value(x"x""^"%s^""name 

(02/12/2019, 02:37 PM)LuKks escribió: No inspira confianza usar un código donde hay una función llamada "STUPID_FUNCTION".
Podés cambiarlo a "sql_init" y que nosotros tengamos que añadirlo en plugin_init así evitás llamadas innecesarias pero lo importante era el nombre de la función.
Whatdone
no hace peso esa condicion, se puede mejorar, pero lo hice por lo mas rapido

estare por mejorar esas cositas Proud
Competitive/Face it Pick Up Game (PUG) servidor de prueba: 45.77.94.109:27016 Click para Entrar
[Imagen: b_350_20_5A6C3E_383F2D_D2E1B5_2E3226.png]

(14/08/2015, 10:15 PM)Sugisaki escribió: "El mundo es caotico, irracional e injusto. No tiene ningun significado"
Palabras que desde hace mucho tiempo he buscado para describir, ¿Que es el mundo?
Crab

Código PHP:
if(ayuda && free)
{
    exit();

Responder
#9
(02/12/2019, 04:42 PM)Sugisaki escribió: A que te refieres cuando dices eficiencia?
Tecnicamente no estas enviando consultas por el numero de funciones sql_* que exista en un frame.

"Eficiente" seria realizar una consulta update extremadamente larga de una manera la cual sea legible.

Mala elección mía de palabra, quise decir más productivo en cuanto a escribir el código necesario para realizar la consulta.

(02/12/2019, 04:42 PM)Sugisaki escribió: no esta diseñado para captar datos introducidos por el usuario, si te refieres al nombre, basta con hacer
Código PHP:
sql_set_value(x"x""^"%s^""name 

Eso no evita SQL injection. Lo que sucede es que ^" sirve para insertar comilla sin hacer conflicto de sintaxis en AMXX.
En MySQL los strings van entre comillas y en AMXX los strings también se definen con comillas.

Así sería seguro:
Código PHP:
sql_set_value(x"x""^"%s^""mysql_escape_string(name)) 
Pero el escape lo tiene que hacer tu librería internamente, no es negociable, y aparte nos ahorrás el mysql_escape_string a todos.



Veo mucho código repetido:
Código PHP:
if(== 0)
{
    
len += formatex(query[len], charsmax(query), "`%s`"data);
}
else
{
    
len += formatex(query[len], charsmax(query), ",`%s`"data);


Aprovecho para decir que las llaves quedan mejor así:
Código PHP:
if(== 0) {
  
len += formatex(query[len], charsmax(query), "`%s`"data);
} else {
  
len += formatex(query[len], charsmax(query), ",`%s`"data);


Lo importante es que si vemos código repetido, casi siempre hay una forma de reducirlo:
Código PHP:
len += formatex(query[len], charsmax(query), "%s`%s`"== "" ","data); 

Si paso un string de 300 caracteres no alcanza el buffer:
Código PHP:
stock sql_set_value(SQL_DATA:sql_id, const colum[], const value[], any:...) {
    new 
buf[256], num[4]
    
vformat(bufcharsmax(buf), value4)
    
// ...

Lo mismo para el resto de valores, tablas, queries, etcétera.
Algunas const con valores máximos podría resolverlo, si alguien necesita más sería fácil de incrementar.

__count no provoca un error cuando se pase el límite máximo de integer? Si count vuelve a cero el código seguiría funcionando correctamente?
Responder
#10
(02/12/2019, 06:15 PM)LuKks escribió: Eso no evita SQL injection. Lo que sucede es que ^" sirve para insertar comilla sin hacer conflicto de sintaxis en AMXX.
En MySQL los strings van entre comillas y en AMXX los strings también se definen con comillas.

(30/10/2014, 04:30 PM)meTaLiCroSS escribió: El string seria tomado como "holamundo'peperulz'jeje'", solo tomara como inicio y termino las comillas dobles, las comillas simples no importaran un huevo. Y un nombre de CS no puede tener comilla doble, entonces no hay de que atarearse.


(02/12/2019, 06:15 PM)LuKks escribió: Aprovecho para decir que las llaves quedan mejor así:
Código PHP:
if(== 0) {
  
len += formatex(query[len], charsmax(query), "`%s`"data);
} else {
  
len += formatex(query[len], charsmax(query), ",`%s`"data);

eso depende del programador no afecta la logica del codigo

(02/12/2019, 06:15 PM)LuKks escribió: Lo importante es que si vemos código repetido, casi siempre hay una forma de reducirlo:
Código PHP:
len += formatex(query[len], charsmax(query), "%s`%s`"== "" ","data); 

Whatdone, si eso lo vi, si ves un poco mas baja esta esa condicion y me dio pereza modificarla
(02/12/2019, 06:15 PM)LuKks escribió: Si paso un string de 300 caracteres no alcanza el buffer:

que columna tendra mas de 256 caracteres? Whatever


(02/12/2019, 06:15 PM)LuKks escribió: __count no provoca un error cuando se pase el límite máximo de integer? Si count vuelve a cero el código seguiría funcionando correctamente?
no hay problema, al momento que se ejecuta sql_execute se elimina los datos referente a la identificacion dejandola libre
PD: tiene que ser uns sv que nunca se apague para que llegue a su valor maximo (2,147,483,647)
Competitive/Face it Pick Up Game (PUG) servidor de prueba: 45.77.94.109:27016 Click para Entrar
[Imagen: b_350_20_5A6C3E_383F2D_D2E1B5_2E3226.png]

(14/08/2015, 10:15 PM)Sugisaki escribió: "El mundo es caotico, irracional e injusto. No tiene ningun significado"
Palabras que desde hace mucho tiempo he buscado para describir, ¿Que es el mundo?
Crab

Código PHP:
if(ayuda && free)
{
    exit();

Responder
#11
(02/12/2019, 07:47 PM)Sugisaki escribió:
(02/12/2019, 06:15 PM)LuKks escribió: Eso no evita SQL injection. Lo que sucede es que ^" sirve para insertar comilla sin hacer conflicto de sintaxis en AMXX.
En MySQL los strings van entre comillas y en AMXX los strings también se definen con comillas.

(30/10/2014, 04:30 PM)meTaLiCroSS escribió: El string seria tomado como "holamundo'peperulz'jeje'", solo tomara como inicio y termino las comillas dobles, las comillas simples no importaran un huevo. Y un nombre de CS no puede tener comilla doble, entonces no hay de que atarearse.

Entonces habría que eliminar la función escape porque no sirve para nada, quién fue el tonto que la creó?
Quitando el sarcasmo, no estamos hablando del valor name únicamente, estamos hablando de cualquier valor de tipo string.

Por ejemplo, mi contraseña es hw"y1!23
Código PHP:
new password[] = "hw^"y1!23";
sql_prepare_update("
pug_stats_player", "password = ^"%s^"", password); 
La query va a quedar: password = "hw"y1!23"
Por lo tanto va a fallar, y gracias al universo no fue SQL injection.

(02/12/2019, 07:47 PM)Sugisaki escribió:
(02/12/2019, 06:15 PM)LuKks escribió: Aprovecho para decir que las llaves quedan mejor así:
Código PHP:
if(== 0) {
  
len += formatex(query[len], charsmax(query), "`%s`"data);
} else {
  
len += formatex(query[len], charsmax(query), ",`%s`"data);

eso depende del programador no afecta la logica del codigo

Eso depende de si querés que otro desarrollador lea tu código.
Publicamos aportes porque queremos que otros lo vean, lean, usen, etcétera.
Es como escribir un libro con faltas ortográficas, seguro que las palabras se entienden pero se sufre mucho al leer y menos personas lo terminan leyendo.

(02/12/2019, 07:47 PM)Sugisaki escribió:
(02/12/2019, 06:15 PM)LuKks escribió: Lo importante es que si vemos código repetido, casi siempre hay una forma de reducirlo:
Código PHP:
len += formatex(query[len], charsmax(query), "%s`%s`"== "" ","data); 

Whatdone, si eso lo vi, si ves un poco mas baja esta esa condicion y me dio pereza modificarla
(02/12/2019, 06:15 PM)LuKks escribió: Si paso un string de 300 caracteres no alcanza el buffer:

que columna tendra mas de 256 caracteres? Whatever

Es obvio que probablemente ninguna columna pero valores? E incluso múltiples valores?
Por ejemplo, estoy registrando todo lo que los usuarios dicen por say y alguien escribe 250 caracteres, entonces ya no me alcanza porque todavía falta INSERT y demás partes de la query.
Y si en la misma query estoy registrando el nombre, la fecha y otros datos? No alcanza.

Leyendo noté que el buffer de count es de 4:
Código PHP:
new num[4
Cuando count llegue a 10000 entonces num va a quedar 1000.
Y si continúo haciendo consultas num va a seguir siendo 1000 nueve veces más, lo cual provocaría resultados inesperados (query no enviada o error dependiendo del código).

(02/12/2019, 07:47 PM)Sugisaki escribió:
(02/12/2019, 06:15 PM)LuKks escribió: __count no provoca un error cuando se pase el límite máximo de integer? Si count vuelve a cero el código seguiría funcionando correctamente?
no hay problema, al momento que se ejecuta sql_execute se elimina los datos referente a la identificacion dejandola libre

Me refería a count mismo, pero poco importa ya que ahora está el problema del buffer num.


Mis comentarios son simplemente feedback para que mejores aún más el aporte, no tenés que aplicar nada de lo que dije pero no te molesta la posibilidad de que tu código le genere errores o problemas en los plugins de otras personas?
Responder
#12
(02/12/2019, 09:45 PM)LuKks escribió: Es obvio que probablemente ninguna columna pero valores? E incluso múltiples valores?
Por ejemplo, estoy registrando todo lo que los usuarios dicen por say y alguien escribe 250 caracteres, entonces ya no me alcanza porque todavía falta INSERT y demás partes de la query.
Y si en la misma query estoy registrando el nombre, la fecha y otros datos? No alcanza.

el tamaño maximo final de la oracion es 1280 lo de 256 es el tamaño buffer por columna
Código PHP:
stock sql_execute(SQL_DATA:sql_idHandle:hquery, const handler[], const szData[]=""datasize=0)
{
    new 
query[1280], data[256], ilennum[4], m;

(02/12/2019, 09:45 PM)LuKks escribió: Eso depende de si querés que otro desarrollador lea tu código.
Publicamos aportes porque queremos que otros lo vean, lean, usen, etcétera.
Es como escribir un libro con faltas ortográficas, seguro que las palabras se entienden pero se sufre mucho al leer y menos personas lo terminan leyendo.
ve arkshine's indent Roflmao
recalco siempre y cuando no afecte la funcionalidad lo puedes escribir como sea, eso es comodidad del programador, a mi no me gustan las cosas amontonadas, queda feo a simple vista
(RegameDLL Github)
[Imagen: fzVQFsTRRSSWzITk4CPV-Q.png]

(02/12/2019, 09:45 PM)LuKks escribió: Cuando count llegue a 10000 entonces num va a quedar 1000.
Y si continúo haciendo consultas num va a seguir siendo 1000 nueve veces más, lo cual provocaría resultados inesperados (query no enviada o error dependiendo del código).
mmm no tanto, ya que al llamar sql_execute en el mismo frame del sql_prepare* se eliminara su contenido peeero si pospones la ejecucion del sql_execute para se llame en otro frame o estes usando 2 o mas sql_prepare* en paralelo ahi si te puedes asustar, pero hay que ser medio maniatico para hacer 999+ en menos de 30 min (tiempo promedio de duracion del mapa)

(02/12/2019, 09:45 PM)LuKks escribió: Mis comentarios son simplemente feedback para que mejores aún más el aporte
Sep lo entiendo y lo agradezco Proud, no me molesto, solo respondo tus inquietudes Proud

(02/12/2019, 09:45 PM)LuKks escribió: no tenés que aplicar nada de lo que dije pero no te molesta la posibilidad de que tu código le genere errores o problemas en los plugins de otras personas?

de errores se aprende Trolleyes, yo tengo una manera peculiar de hacer un proyecto primero hago algo lo cual es lo mas feo posible ya que se me da por la mente asi, sobre la marcha voy aplicando parches y mejoras sobre el mismo, cambiando funciones y hasta rework el proyecto entero puedes echarle un ojo al fpug, ve la version 1.21 que esta en am-es y ve la de github, veras que funcionan IGUAL, pero escrito de otra manera
Competitive/Face it Pick Up Game (PUG) servidor de prueba: 45.77.94.109:27016 Click para Entrar
[Imagen: b_350_20_5A6C3E_383F2D_D2E1B5_2E3226.png]

(14/08/2015, 10:15 PM)Sugisaki escribió: "El mundo es caotico, irracional e injusto. No tiene ningun significado"
Palabras que desde hace mucho tiempo he buscado para describir, ¿Que es el mundo?
Crab

Código PHP:
if(ayuda && free)
{
    exit();

Responder
#13
Codigo Completamente reescrito y medio documentado Whatever
Ahora escapa las comillas dobles y el slash inverso (es el unico metodo de inyeccion sql por amxx)
Código PHP:
// INSERT
    
sid sql_init(SQL_INSERT);
    
sql_set_table(sid"tabla")
    
sql_set_value(sid"c1""data^"")
    sql_set_value(sid, "
c2", "%s", "data")
    sql_execute(sid);
    //UPDATE
    sid = sql_init(SQL_UPDATE)
    sql_set_table(sid, "
tabla")
    sql_set_value(sid, "
c1", "data")
    sql_update_value(sid, "
c2", "123", true, "c2", "+")
    sql_update_value(sid, "
c3", "jose")
    sql_set_where(sid, "
player", "SUGI", "pass", "^"2\ \^"23");
    sql_execute(sid)
    // MANUAL WHERE 
    sid = sql_init(SQL_UPDATE)
    sql_set_table(sid, "
tabla")
    sql_set_value(sid, "
c1", "data")
    sql_update_value(sid, "
c2", "123", true, "c2", "+")
    sql_update_value(sid, "
c3", "jose")
    sql_set_where_manual(sid, "
player='jose' AND pass='sugi123'");
    sql_execute(sid) 

quedaria algo como:
[Imagen: qm5g8h2iQ-qb0Ux8uSzbZw.png]
Competitive/Face it Pick Up Game (PUG) servidor de prueba: 45.77.94.109:27016 Click para Entrar
[Imagen: b_350_20_5A6C3E_383F2D_D2E1B5_2E3226.png]

(14/08/2015, 10:15 PM)Sugisaki escribió: "El mundo es caotico, irracional e injusto. No tiene ningun significado"
Palabras que desde hace mucho tiempo he buscado para describir, ¿Que es el mundo?
Crab

Código PHP:
if(ayuda && free)
{
    exit();

Responder
#14
No man, tiene que ser ultra simple.

Código PHP:
insert("users""points"10000"level"85"admin""full")

update("users""points"15000"id = %i"5)

//
public update(table[], any:...) {}
public 
insert(table[], any:...) {} 

Esto de simplificar las queries lo hice en PHP hace años (http://i.imgur.com/YAQeeKl.png).
Hace bastante lo re-hice en Node.js que es donde te dije que obtengas ideas: like-mysql

Pensá que ya todos lograron hacer sus plugins con mysql sin tu librería entonces por qué deberían usarla? Por eso tiene que ser suficientemente buena así vale la pena depender de la librería.
Destro no te publica el vault medio armado con funciones básicas faltantes, te publica todo el sistema completo de manera consistente y con actualizaciones retrocompatibles.

Insert
Código PHP:
insert("users""points"10000"level"85"admin""full"
tabla, columna, valor, columna, valor, ...
Usando numargs() y getarg(i) lo tenés hecho, vas tomando de a pares.

Update
Código PHP:
update("users""points"15000"id = %i"5
tabla, columna, valor, ..., where, valores, ...
Al where lo identificás porque tiene al menos un espacio.

Si vés mi librería notarás que mi update también te permite sumar, restar, etcétera y acá lo podemos lograr así:
Código PHP:
update("users""points=points+%i"1000"id = %i"5
Similar al where, a esto lo identificás porque tiene el signo = y no tiene espacios.

Por cierto, el select, count, exists y delete no tienen mayor complejidad pero al menos select y delete deberían estar disponibles.

Después si querés ser un héroe, se puede simplificar el tema de las comillas.
Por ejemplo, tenés lo siguiente que sería lo normal:
Código PHP:
update("users""points"15000"name = ^"%s^"""LuKks"
Pero es molesto lidiar con ^" porque es repetitivo y queda confuso para alguien nuevo.
En cambio, se puede lo siguiente:
Código PHP:
update("users""points"15000"name = %s""LuKks"
Sí, sin comillas.
Vos como librería ya tenés el %s que indica que es un string así que se pueden añadir automáticamente y les ahorrás a todos tanto drama con comillas.
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)