From da71198611425eaf96e07171bb07a01df69cd6d6 Mon Sep 17 00:00:00 2001 From: NullSablex <244216261+NullSablex@users.noreply.github.com> Date: Sat, 26 Sep 2026 06:18:19 -0300 Subject: [PATCH] docs: deixa explicito que o callback e opcional, e corrige a promessa de ordem Duas coisas que a documentacao dizia mal, as duas confirmadas rodando um gamemode de teste contra um servidor SA-MP e um MariaDB de verdade. 1. O callback e opcional, e ninguem percebia Nao-bloqueante nao obriga a escrever callback para tudo: as oito natives que aceitam `callback` aceitam com valor padrao `""`, e sem ele a query roda e o resultado e descartado. Uma escrita e uma linha, sem forward e sem public. As unicas excecoes sao `mysql_hash_password` e `mysql_verify_password`, cujo callback e obrigatorio - o hash so existe atraves dele - e que ja recusam callback vazio com aviso no log. Isso estava documentado em uma subsecao no fim da pagina de queries, enquanto a primeira linha dizia "o callback e invocado num tick posterior" e nenhum dos onze exemplos mostrava a forma sem callback. Quem lia saia convencido do contrario, e era a origem da reclamacao de que o plugin "obriga a encher o codigo de callback". 2. A garantia de ordem e de callback, nao de execucao `mysql_query` e FIFO na ENTREGA DOS CALLBACKS. A execucao nao e ordenada: cada query ganha uma thread e uma conexao do pool no momento em que e submetida, entao duas submetidas em sequencia rodam ao mesmo tempo no servidor. Um `CREATE TABLE` seguido de `INSERT` falha com "table doesn't exist" - foi o que o teste mostrou. A tabela comparativa ainda sugeria `mysql_query` para "SELECT chains that depend on order", que e exatamente o uso que quebra. Agora a pagina diz qual ferramenta serializa de verdade: `mysql_query_file` para schema e transacao para escritas dependentes, ambas verificadas no mesmo teste. Mudancas: README (destaque e quick start com as duas formas), pagina de queries (abertura, secao de ordem e tabela), `@param callback` do template do include - que alimenta o hover do PawnPro e chega aos dois includes gerados - e dois exemplos novos, 12_no_callback e 13_ordering. --- README.md | 9 +++-- docs/queries.md | 35 ++++++++++++++++++-- examples/12_no_callback.pwn | 65 +++++++++++++++++++++++++++++++++++++ examples/13_ordering.pwn | 65 +++++++++++++++++++++++++++++++++++++ examples/README.md | 7 ++++ include/mysql_samp.inc | 39 ++++++++++++++-------- include/mysql_samp.inc.in | 39 ++++++++++++++-------- include/mysql_samp_omp.inc | 39 ++++++++++++++-------- 8 files changed, 253 insertions(+), 45 deletions(-) create mode 100644 examples/12_no_callback.pwn create mode 100644 examples/13_ordering.pwn diff --git a/README.md b/README.md index 08d3fb0..dcbd738 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ The same binary loads on SA-MP and on Open Multiplayer — natively as a compone ### Highlights - **Zero external dependencies** — no `libmysqlclient`, no OpenSSL. The MySQL protocol and TLS (via rustls) are compiled directly into the binary. -- **All queries are non-blocking** — `mysql_query` runs on background threads with FIFO ordering. The server never stalls. +- **All queries are non-blocking** — `mysql_query` runs on background threads and the server never stalls. **That does not mean a callback for everything:** the callback is optional, so a write is one line (`mysql_query(conn, "UPDATE …")`) with no forward and no public. You pass a callback only to read a result back. - **Connection pool** — automatic reuse through `mysql::Pool`, thread-safe by design, with a configurable ceiling. - **Credentials out of the source** — `mysql_connect_file` reads them from a config file your repository does not have to carry. - **Schema scripts** — `mysql_query_file` runs a `.sql` file's statements in order, non-blocking. @@ -82,8 +82,11 @@ public OnGameModeInit() { return 1; } - // Non-blocking query with callback + // Reading a result: needs a callback, because the rows arrive later mysql_query(gMysql, "SELECT * FROM players LIMIT 10", "OnPlayersLoaded"); + + // Writing: no callback, no forward, no public - and still non-blocking + mysql_query(gMysql, "UPDATE server_state SET last_start = NOW()"); return 1; } @@ -105,7 +108,7 @@ public OnGameModeExit() { } ``` -Browse the [examples/](examples/) folder for self-contained `.pwn` scripts covering connection setup, threaded queries, ORM, TLS, error handling, prepared statements, transactions, password hashing, config files, `.sql` scripts and multi-result sets. For anything carrying player input, start with [`08_prepared_statements.pwn`](examples/08_prepared_statements.pwn). The plugin natives (`mysql_*`, `cache_*`, `orm_*`) and the `OnQueryError` forward are identical across SA-MP and Open Multiplayer, so every example builds and runs on both — the only thing that differs between servers is the installation path documented above. +Browse the [examples/](examples/) folder for self-contained `.pwn` scripts covering connection setup, threaded queries, ORM, TLS, error handling, prepared statements, transactions, password hashing, config files, `.sql` scripts and multi-result sets. For anything carrying player input, start with [`08_prepared_statements.pwn`](examples/08_prepared_statements.pwn); for the callback-free form and for what is and is not ordered, see [`12_no_callback.pwn`](examples/12_no_callback.pwn) and [`13_ordering.pwn`](examples/13_ordering.pwn). The plugin natives (`mysql_*`, `cache_*`, `orm_*`) and the `OnQueryError` forward are identical across SA-MP and Open Multiplayer, so every example builds and runs on both — the only thing that differs between servers is the installation path documented above. ## Documentation diff --git a/docs/queries.md b/docs/queries.md index 865800c..c20bd88 100644 --- a/docs/queries.md +++ b/docs/queries.md @@ -1,6 +1,17 @@ # Queries -Every query in mysql_samp is **non-blocking**: the statement runs on a worker thread and the callback is invoked on a later tick. The server never freezes waiting for the database. +Every query in mysql_samp is **non-blocking**: the statement runs on a worker thread and the result reaches your script on a later tick. The server never freezes waiting for the database. + +**The callback is optional.** Non-blocking does not mean "you have to write a callback for everything" — every native on this page takes `callback` with a default of `""`, and passing nothing means fire-and-forget: + +```pawn +// One line, no callback, no forward, no public. The server keeps running. +mysql_query(g_mysql, "UPDATE players SET last_login = NOW() WHERE id = 1"); +``` + +That covers most of what a script does with a database: `UPDATE`, `INSERT`, `DELETE`. You only need a callback when you want to **read** the result back, because a value that arrives later has nowhere else to arrive. A failure still reaches [`OnQueryError`](errors.md) either way, so a discarded result is not a silent one. + +The two exceptions are [`mysql_hash_password` and `mysql_verify_password`](security.md#password-storage): their callback is required, since the hash or the match result exists only there. Called with an empty callback they log a warning and return `false`. ## mysql_query — FIFO-ordered @@ -18,7 +29,24 @@ native bool:mysql_query(connId, const query[], const callback[] = "", const form **Returns:** `true` if the query was queued, `false` if `connId` is unknown. -**Ordering guarantee:** callbacks are delivered in **submission order**, even when the underlying queries finish out of order. A slow query blocks the dispatch of later callbacks until it completes. +**Ordering guarantee — read this one carefully.** What is ordered is the **delivery of callbacks**, in submission order, even when the underlying queries finish out of order. A slow query holds back the dispatch of later callbacks until it completes. + +**Execution is not ordered.** Each query gets its own worker thread and its own pool connection the moment you submit it, so they run *at the same time* on the server. Two statements where the second depends on the first will race: + +```pawn +// BROKEN: these run concurrently. The INSERT usually fails with +// "Table 'x' doesn't exist" because the CREATE has not finished yet. +mysql_query(g_mysql, "CREATE TABLE x (id INT)"); +mysql_query(g_mysql, "INSERT INTO x (id) VALUES (1)"); +``` + +When one statement depends on another, pick the tool that actually serialises them: + +| What you need | Use | +|---|---| +| Schema setup, migrations, any `.sql` script | [`mysql_query_file`](#running-a-sql-file) — statements run in order, on one connection | +| Writes that depend on each other | [`mysql_transaction_*`](#transactions) — one connection, in order, all-or-nothing | +| A read that depends on a write | The callback of the write | ```pawn mysql_query(g_mysql, "SELECT * FROM players WHERE level > 5", "OnHighLevelPlayers"); @@ -94,7 +122,8 @@ mysql_pquery(g_mysql, "SELECT * FROM rewards WHERE id = 1", "OnRewards"); |---|---|---| | Threading | One worker thread per query | One worker thread per query | | Callback order | FIFO (submission order) | First done, first dispatched | -| Typical use | SELECT chains that depend on order | UPDATE/INSERT and independent reads | +| Execution order | **Not ordered** — concurrent | **Not ordered** — concurrent | +| Typical use | Reads whose callbacks must arrive in order | UPDATE/INSERT and independent reads | | Reordering cost | Yes — results buffer until the next sequence is available | None | Both natives create one OS thread per query — the cost of a thread spawn is roughly the cost of one TCP round-trip, well below the cost of a real MySQL query. diff --git a/examples/12_no_callback.pwn b/examples/12_no_callback.pwn new file mode 100644 index 0000000..b6bfc86 --- /dev/null +++ b/examples/12_no_callback.pwn @@ -0,0 +1,65 @@ +// 12_no_callback.pwn - non-blocking queries WITHOUT a callback (fire-and-forget). +// +// Non-blocking does not mean "write a callback for everything". Every native +// that takes a callback takes it with a default of "", and passing nothing +// runs the query and discards the result. That is one line, no forward, no +// public - and the server still never blocks. +// +// Use it for writes: UPDATE, INSERT, DELETE. You need a callback only to read +// a result back, because a value that arrives later has nowhere else to go. +// The two password natives are the exception: their callback is required. +// +// A failure is NOT silenced - it still reaches OnQueryError. +// +// Careful with ordering: queries submitted one after the other run +// CONCURRENTLY, each on its own connection. See 13 below for what to use when +// one statement depends on another. + +#include +#include + +#define MYSQL_HOST "127.0.0.1" +#define MYSQL_USER "samp" +#define MYSQL_PASSWORD "secret" +#define MYSQL_DATABASE "samp_server" + +new g_MysqlConn = 0; + +public OnGameModeInit() +{ + g_MysqlConn = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE); + return 1; +} + +public OnPlayerDisconnect(playerid, reason) +{ + new name[MAX_PLAYER_NAME]; + GetPlayerName(playerid, name, sizeof(name)); + + new query[256]; + mysql_format(g_MysqlConn, query, sizeof(query), + "UPDATE players SET last_seen = NOW() WHERE name = '%e'", name); + + // No callback: the write is dispatched and the result discarded. + mysql_query(g_MysqlConn, query); + return 1; +} + +public OnPlayerDeath(playerid, killerid, reason) +{ + new query[128]; + mysql_format(g_MysqlConn, query, sizeof(query), + "UPDATE players SET deaths = deaths + 1 WHERE id = %d", playerid); + + // Independent writes have no reason to be ordered: mysql_pquery skips the + // FIFO buffering entirely. Also callback-free. + mysql_pquery(g_MysqlConn, query); + return 1; +} + +// Errors still arrive, even with no callback on the query that failed. +public OnQueryError(errorid, const error[], const callback[], const query[], connId) +{ + printf("[MySQL] error %d on '%s': %s", errorid, query, error); + return 1; +} diff --git a/examples/13_ordering.pwn b/examples/13_ordering.pwn new file mode 100644 index 0000000..9cf5848 --- /dev/null +++ b/examples/13_ordering.pwn @@ -0,0 +1,65 @@ +// 13_ordering.pwn - what is ordered, what is not, and what to use instead. +// +// mysql_query is described as FIFO. What that orders is the DELIVERY OF +// CALLBACKS, in submission order. It does NOT order execution: each query +// gets its own worker thread and its own pool connection as soon as it is +// submitted, so submitted statements run at the same time on the server. +// +// This matters the moment one statement depends on another. + +#include +#include + +#define MYSQL_HOST "127.0.0.1" +#define MYSQL_USER "samp" +#define MYSQL_PASSWORD "secret" +#define MYSQL_DATABASE "samp_server" + +new g_MysqlConn = 0; + +public OnGameModeInit() +{ + g_MysqlConn = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE); + + // WRONG - these race. The INSERT usually fails with "table doesn't exist", + // because the CREATE is still running on another connection. + // + // mysql_query(g_MysqlConn, "CREATE TABLE stats (id INT, kills INT)"); + // mysql_query(g_MysqlConn, "INSERT INTO stats VALUES (1, 0)"); + + // RIGHT for schema work: one file, statements run in order, one + // connection, still non-blocking, still no callback needed. + // The path is relative to the server root, not to scriptfiles/. + mysql_query_file(g_MysqlConn, "schema.sql"); + return 1; +} + +// RIGHT for writes that depend on each other: a transaction runs its steps in +// order on one connection, and rolls back if any of them fails. +StorePurchase(playerid, itemid, price) +{ + new tx = mysql_transaction_new(g_MysqlConn); + if (tx == 0) + return 0; + + new query[192]; + + mysql_format(g_MysqlConn, query, sizeof(query), + "UPDATE players SET money = money - %d WHERE id = %d", price, playerid); + mysql_transaction_add(tx, query); + + mysql_format(g_MysqlConn, query, sizeof(query), + "INSERT INTO inventory (player_id, item_id) VALUES (%d, %d)", playerid, itemid); + mysql_transaction_add(tx, query); + + // No callback here either: either both steps land, or neither does. + mysql_transaction_execute(tx); + return 1; +} + +// RIGHT for a read that depends on a write: chain it in the write's callback. +public OnQueryError(errorid, const error[], const callback[], const query[], connId) +{ + printf("[MySQL] error %d on '%s': %s", errorid, query, error); + return 1; +} diff --git a/examples/README.md b/examples/README.md index 853fa9f..073a2fa 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,6 +2,11 @@ Runnable Pawn snippets showing how to use the plugin on **SA-MP** and **Open Multiplayer**. The plugin natives (`mysql_*`, `cache_*`, `orm_*`) and the `OnQueryError` forward are identical across both servers — every snippet here exercises only the plugin API. +> **Non-blocking does not mean a callback for everything.** Every native that takes a `callback` takes it with a +> default of `""`, so a write is one line and nothing else — see [`12_no_callback.pwn`](12_no_callback.pwn). +> The exception is the two password natives, whose callback is required. Most examples below pass a callback +> because they read a result back, not because it is mandatory. + > **Start with [`08_prepared_statements.pwn`](08_prepared_statements.pwn) for anything involving player input.** `mysql_format` (example 04) escapes values into the SQL text, which is correct only as long as the escaping matches the server's `sql_mode`. Prepared statements bind values server-side, so there is nothing to escape and nothing to get wrong. | File | Topic | @@ -17,6 +22,8 @@ Runnable Pawn snippets showing how to use the plugin on **SA-MP** and **Open Mul | [`09_transactions.pwn`](09_transactions.pwn) | `mysql_transaction_*` — all-or-nothing batches | | [`10_password_hashing.pwn`](10_password_hashing.pwn) | Argon2id: `mysql_hash_password` / `mysql_verify_password` | | [`11_config_and_scripts.pwn`](11_config_and_scripts.pwn) | `mysql_connect_file`, `mysql_query_file`, multiple result sets | +| [`12_no_callback.pwn`](12_no_callback.pwn) | Fire-and-forget: non-blocking queries **without** a callback | +| [`13_ordering.pwn`](13_ordering.pwn) | What is ordered (callbacks) and what is not (execution), and what to use instead | ### Companion files diff --git a/include/mysql_samp.inc b/include/mysql_samp.inc index 6259c42..d198ccc 100644 --- a/include/mysql_samp.inc +++ b/include/mysql_samp.inc @@ -207,7 +207,8 @@ native bool:mysql_log(log_level); * * @param connId connection id * @param query the SQL - * @param callback callback to fire with the result, or "" for none + * @param callback callback to fire with the result. Optional: "" (the + * default) discards the result and fires nothing * @param format types of the extra callback args ("d" int, "f" float, "s" string) * @return true if submitted, false on a bad connection */ @@ -218,7 +219,8 @@ native bool:mysql_query(connId, const query[], const callback[] = "", const form * * @param connId connection id * @param query the SQL - * @param callback callback to fire with the result, or "" for none + * @param callback callback to fire with the result. Optional: "" (the + * default) discards the result and fires nothing * @param format types of the extra callback args * @return true if submitted, false on a bad connection */ @@ -265,7 +267,8 @@ native mysql_format(connId, dest[], max_len, const format[], {Float,_}:...); * * @param connId connection id * @param path path to the .sql file - * @param callback callback to fire with the last statement's result, or "" + * @param callback callback to fire with the last statement's result. + * Optional: "" (the default) discards it * @param format types of the extra callback args * @return true if submitted, false on a bad connection or unreadable file */ @@ -338,7 +341,8 @@ native bool:mysql_stmt_bind_null(stmtId); * not match the number of `?` placeholders. * * @param stmtId statement id - * @param callback callback to fire with the result, or "" for none + * @param callback callback to fire with the result. Optional: "" (the + * default) discards the result and fires nothing * @param format types of the extra callback args * @return true if submitted, false on a bad id or arity mismatch */ @@ -348,7 +352,8 @@ native bool:mysql_stmt_execute(stmtId, const callback[] = "", const format[] = " * Executes a statement on a worker thread, parallel: no ordering guarantee. * * @param stmtId statement id - * @param callback callback to fire with the result, or "" for none + * @param callback callback to fire with the result. Optional: "" (the + * default) discards the result and fires nothing * @param format types of the extra callback args * @return true if submitted, false on a bad id or arity mismatch */ @@ -593,7 +598,8 @@ native orm_errno(orm_id); * SELECTs the row matching the key and fills the bound variables. * * @param orm_id ORM id - * @param callback callback to fire when done, or "" + * @param callback callback to fire when done. Optional: "" (the default) + * runs the operation and fires nothing * @param format types of the extra callback args * @return true if submitted, false on failure */ @@ -603,7 +609,8 @@ native bool:orm_select(orm_id, const callback[] = "", const format[] = "", {Floa * UPDATEs the row matching the key with the bound variables. * * @param orm_id ORM id - * @param callback callback to fire when done, or "" + * @param callback callback to fire when done. Optional: "" (the default) + * runs the operation and fires nothing * @param format types of the extra callback args * @return true if submitted, false on failure */ @@ -613,7 +620,8 @@ native bool:orm_update(orm_id, const callback[] = "", const format[] = "", {Floa * INSERTs a row from the bound variables. * * @param orm_id ORM id - * @param callback callback to fire when done, or "" + * @param callback callback to fire when done. Optional: "" (the default) + * runs the operation and fires nothing * @param format types of the extra callback args * @return true if submitted, false on failure */ @@ -623,7 +631,8 @@ native bool:orm_insert(orm_id, const callback[] = "", const format[] = "", {Floa * DELETEs the row matching the key. * * @param orm_id ORM id - * @param callback callback to fire when done, or "" + * @param callback callback to fire when done. Optional: "" (the default) + * runs the operation and fires nothing * @param format types of the extra callback args * @return true if submitted, false on failure */ @@ -633,7 +642,8 @@ native bool:orm_delete(orm_id, const callback[] = "", const format[] = "", {Floa * INSERTs when the key is empty, UPDATEs otherwise. * * @param orm_id ORM id - * @param callback callback to fire when done, or "" + * @param callback callback to fire when done. Optional: "" (the default) + * runs the operation and fires nothing * @param format types of the extra callback args * @return true if submitted, false on failure */ @@ -711,7 +721,8 @@ native bool:orm_setkey(orm_id, const column_name[]); * Hashes a password with Argon2id, off the server thread. * * @param password the plaintext - * @param callback callback receiving the PHC hash as its first argument + * @param callback callback receiving the PHC hash as its first argument. + * REQUIRED - the hash is delivered only through it * @param format types of the extra callback args * @return true if queued, false if the callback is empty, the password exceeds * 1 KiB, or the work queue is full @@ -723,7 +734,8 @@ native bool:mysql_hash_password(const password[], const callback[], const format * * @param password the plaintext * @param hash the stored PHC string - * @param callback callback receiving the bool result as its first argument + * @param callback callback receiving the bool result as its first + * argument. REQUIRED - the result arrives only through it * @param format types of the extra callback args * @return true if queued, false if the callback is empty, the password exceeds * 1 KiB, or the work queue is full @@ -772,7 +784,8 @@ native bool:mysql_transaction_add_stmt(txId, stmtId); * afterwards). The callback receives the cache of the LAST step. * * @param txId transaction id - * @param callback callback to fire on commit, or "" + * @param callback callback to fire on commit. Optional: "" (the default) + * commits and fires nothing * @param format types of the extra callback args * @return true if submitted, false on a bad id or empty batch */ diff --git a/include/mysql_samp.inc.in b/include/mysql_samp.inc.in index 2f785f3..402b58b 100644 --- a/include/mysql_samp.inc.in +++ b/include/mysql_samp.inc.in @@ -207,7 +207,8 @@ native bool:mysql_log(log_level); * * @param connId connection id * @param query the SQL - * @param callback callback to fire with the result, or "" for none + * @param callback callback to fire with the result. Optional: "" (the + * default) discards the result and fires nothing * @param format types of the extra callback args ("d" int, "f" float, "s" string) * @return true if submitted, false on a bad connection */ @@ -218,7 +219,8 @@ native bool:mysql_query(connId, const query[], const callback[] = "", const form * * @param connId connection id * @param query the SQL - * @param callback callback to fire with the result, or "" for none + * @param callback callback to fire with the result. Optional: "" (the + * default) discards the result and fires nothing * @param format types of the extra callback args * @return true if submitted, false on a bad connection */ @@ -265,7 +267,8 @@ native mysql_format(connId, dest[], max_len, const format[], {Float,_}:...); * * @param connId connection id * @param path path to the .sql file - * @param callback callback to fire with the last statement's result, or "" + * @param callback callback to fire with the last statement's result. + * Optional: "" (the default) discards it * @param format types of the extra callback args * @return true if submitted, false on a bad connection or unreadable file */ @@ -338,7 +341,8 @@ native bool:mysql_stmt_bind_null(stmtId); * not match the number of `?` placeholders. * * @param stmtId statement id - * @param callback callback to fire with the result, or "" for none + * @param callback callback to fire with the result. Optional: "" (the + * default) discards the result and fires nothing * @param format types of the extra callback args * @return true if submitted, false on a bad id or arity mismatch */ @@ -348,7 +352,8 @@ native bool:mysql_stmt_execute(stmtId, const callback[] = "", const format[] = " * Executes a statement on a worker thread, parallel: no ordering guarantee. * * @param stmtId statement id - * @param callback callback to fire with the result, or "" for none + * @param callback callback to fire with the result. Optional: "" (the + * default) discards the result and fires nothing * @param format types of the extra callback args * @return true if submitted, false on a bad id or arity mismatch */ @@ -593,7 +598,8 @@ native orm_errno(orm_id); * SELECTs the row matching the key and fills the bound variables. * * @param orm_id ORM id - * @param callback callback to fire when done, or "" + * @param callback callback to fire when done. Optional: "" (the default) + * runs the operation and fires nothing * @param format types of the extra callback args * @return true if submitted, false on failure */ @@ -603,7 +609,8 @@ native bool:orm_select(orm_id, const callback[] = "", const format[] = "", {Floa * UPDATEs the row matching the key with the bound variables. * * @param orm_id ORM id - * @param callback callback to fire when done, or "" + * @param callback callback to fire when done. Optional: "" (the default) + * runs the operation and fires nothing * @param format types of the extra callback args * @return true if submitted, false on failure */ @@ -613,7 +620,8 @@ native bool:orm_update(orm_id, const callback[] = "", const format[] = "", {Floa * INSERTs a row from the bound variables. * * @param orm_id ORM id - * @param callback callback to fire when done, or "" + * @param callback callback to fire when done. Optional: "" (the default) + * runs the operation and fires nothing * @param format types of the extra callback args * @return true if submitted, false on failure */ @@ -623,7 +631,8 @@ native bool:orm_insert(orm_id, const callback[] = "", const format[] = "", {Floa * DELETEs the row matching the key. * * @param orm_id ORM id - * @param callback callback to fire when done, or "" + * @param callback callback to fire when done. Optional: "" (the default) + * runs the operation and fires nothing * @param format types of the extra callback args * @return true if submitted, false on failure */ @@ -633,7 +642,8 @@ native bool:orm_delete(orm_id, const callback[] = "", const format[] = "", {Floa * INSERTs when the key is empty, UPDATEs otherwise. * * @param orm_id ORM id - * @param callback callback to fire when done, or "" + * @param callback callback to fire when done. Optional: "" (the default) + * runs the operation and fires nothing * @param format types of the extra callback args * @return true if submitted, false on failure */ @@ -711,7 +721,8 @@ native bool:orm_setkey(orm_id, const column_name[]); * Hashes a password with Argon2id, off the server thread. * * @param password the plaintext - * @param callback callback receiving the PHC hash as its first argument + * @param callback callback receiving the PHC hash as its first argument. + * REQUIRED - the hash is delivered only through it * @param format types of the extra callback args * @return true if queued, false if the callback is empty, the password exceeds * 1 KiB, or the work queue is full @@ -723,7 +734,8 @@ native bool:mysql_hash_password(const password[], const callback[], const format * * @param password the plaintext * @param hash the stored PHC string - * @param callback callback receiving the bool result as its first argument + * @param callback callback receiving the bool result as its first + * argument. REQUIRED - the result arrives only through it * @param format types of the extra callback args * @return true if queued, false if the callback is empty, the password exceeds * 1 KiB, or the work queue is full @@ -772,7 +784,8 @@ native bool:mysql_transaction_add_stmt(txId, stmtId); * afterwards). The callback receives the cache of the LAST step. * * @param txId transaction id - * @param callback callback to fire on commit, or "" + * @param callback callback to fire on commit. Optional: "" (the default) + * commits and fires nothing * @param format types of the extra callback args * @return true if submitted, false on a bad id or empty batch */ diff --git a/include/mysql_samp_omp.inc b/include/mysql_samp_omp.inc index 1616d16..7401a0e 100644 --- a/include/mysql_samp_omp.inc +++ b/include/mysql_samp_omp.inc @@ -213,7 +213,8 @@ native bool:MySQL_Log(log_level) = mysql_log; * * @param connId connection id * @param query the SQL - * @param callback callback to fire with the result, or "" for none + * @param callback callback to fire with the result. Optional: "" (the + * default) discards the result and fires nothing * @param format types of the extra callback args ("d" int, "f" float, "s" string) * @return true if submitted, false on a bad connection */ @@ -224,7 +225,8 @@ native bool:MySQL_Query(connId, const query[], const callback[] = "", const form * * @param connId connection id * @param query the SQL - * @param callback callback to fire with the result, or "" for none + * @param callback callback to fire with the result. Optional: "" (the + * default) discards the result and fires nothing * @param format types of the extra callback args * @return true if submitted, false on a bad connection */ @@ -271,7 +273,8 @@ native MySQL_Format(connId, dest[], max_len, const format[], {Float,_}:...) = my * * @param connId connection id * @param path path to the .sql file - * @param callback callback to fire with the last statement's result, or "" + * @param callback callback to fire with the last statement's result. + * Optional: "" (the default) discards it * @param format types of the extra callback args * @return true if submitted, false on a bad connection or unreadable file */ @@ -344,7 +347,8 @@ native bool:MySQL_StmtBindNull(stmtId) = mysql_stmt_bind_null; * not match the number of `?` placeholders. * * @param stmtId statement id - * @param callback callback to fire with the result, or "" for none + * @param callback callback to fire with the result. Optional: "" (the + * default) discards the result and fires nothing * @param format types of the extra callback args * @return true if submitted, false on a bad id or arity mismatch */ @@ -354,7 +358,8 @@ native bool:MySQL_StmtExecute(stmtId, const callback[] = "", const format[] = "" * Executes a statement on a worker thread, parallel: no ordering guarantee. * * @param stmtId statement id - * @param callback callback to fire with the result, or "" for none + * @param callback callback to fire with the result. Optional: "" (the + * default) discards the result and fires nothing * @param format types of the extra callback args * @return true if submitted, false on a bad id or arity mismatch */ @@ -599,7 +604,8 @@ native ORM_Errno(orm_id) = orm_errno; * SELECTs the row matching the key and fills the bound variables. * * @param orm_id ORM id - * @param callback callback to fire when done, or "" + * @param callback callback to fire when done. Optional: "" (the default) + * runs the operation and fires nothing * @param format types of the extra callback args * @return true if submitted, false on failure */ @@ -609,7 +615,8 @@ native bool:ORM_Select(orm_id, const callback[] = "", const format[] = "", {Floa * UPDATEs the row matching the key with the bound variables. * * @param orm_id ORM id - * @param callback callback to fire when done, or "" + * @param callback callback to fire when done. Optional: "" (the default) + * runs the operation and fires nothing * @param format types of the extra callback args * @return true if submitted, false on failure */ @@ -619,7 +626,8 @@ native bool:ORM_Update(orm_id, const callback[] = "", const format[] = "", {Floa * INSERTs a row from the bound variables. * * @param orm_id ORM id - * @param callback callback to fire when done, or "" + * @param callback callback to fire when done. Optional: "" (the default) + * runs the operation and fires nothing * @param format types of the extra callback args * @return true if submitted, false on failure */ @@ -629,7 +637,8 @@ native bool:ORM_Insert(orm_id, const callback[] = "", const format[] = "", {Floa * DELETEs the row matching the key. * * @param orm_id ORM id - * @param callback callback to fire when done, or "" + * @param callback callback to fire when done. Optional: "" (the default) + * runs the operation and fires nothing * @param format types of the extra callback args * @return true if submitted, false on failure */ @@ -639,7 +648,8 @@ native bool:ORM_Delete(orm_id, const callback[] = "", const format[] = "", {Floa * INSERTs when the key is empty, UPDATEs otherwise. * * @param orm_id ORM id - * @param callback callback to fire when done, or "" + * @param callback callback to fire when done. Optional: "" (the default) + * runs the operation and fires nothing * @param format types of the extra callback args * @return true if submitted, false on failure */ @@ -717,7 +727,8 @@ native bool:ORM_SetKey(orm_id, const column_name[]) = orm_setkey; * Hashes a password with Argon2id, off the server thread. * * @param password the plaintext - * @param callback callback receiving the PHC hash as its first argument + * @param callback callback receiving the PHC hash as its first argument. + * REQUIRED - the hash is delivered only through it * @param format types of the extra callback args * @return true if queued, false if the callback is empty, the password exceeds * 1 KiB, or the work queue is full @@ -729,7 +740,8 @@ native bool:MySQL_HashPassword(const password[], const callback[], const format[ * * @param password the plaintext * @param hash the stored PHC string - * @param callback callback receiving the bool result as its first argument + * @param callback callback receiving the bool result as its first + * argument. REQUIRED - the result arrives only through it * @param format types of the extra callback args * @return true if queued, false if the callback is empty, the password exceeds * 1 KiB, or the work queue is full @@ -778,7 +790,8 @@ native bool:MySQL_TransactionAddStmt(txId, stmtId) = mysql_transaction_add_stmt; * afterwards). The callback receives the cache of the LAST step. * * @param txId transaction id - * @param callback callback to fire on commit, or "" + * @param callback callback to fire on commit. Optional: "" (the default) + * commits and fires nothing * @param format types of the extra callback args * @return true if submitted, false on a bad id or empty batch */