mirror of
https://github.com/sky-systems/sky_phone.git
synced 2026-08-29 00:01:29 +00:00
BLD - add standalone phone development workflow
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
---
|
||||
name: oxmysql
|
||||
description: "OxMySQL for FiveM - SQL integrations with MySQL/MariaDB. Use when writing or editing server-side database code: queries, inserts, updates, transactions, or any resource that uses oxmysql (query, insert, prepare, update, single, scalar, rawExecute, transaction)."
|
||||
author: germanfndez
|
||||
version: "1.0.0"
|
||||
mcp-server: projecthub
|
||||
---
|
||||
|
||||
# OxMySQL
|
||||
|
||||
SQL integration for FiveM using OxMySQL (replacement for mysql-async / ghmattimysql). Server-side only. Use MariaDB over MySQL 8 for compatibility.
|
||||
|
||||
## When to use
|
||||
|
||||
- User asks for database queries, inserts, updates, or SQL in a FiveM resource.
|
||||
- Editing or writing code that uses `MySQL.*` or `exports.oxmysql`.
|
||||
- Designing tables, upserts, or transactions.
|
||||
|
||||
## Setup
|
||||
- Lua: `server_script '@oxmysql/lib/MySQL.lua'` in fxmanifest (above other scripts).
|
||||
|
||||
## Rules
|
||||
|
||||
Read the rule that matches what you're doing:
|
||||
|
||||
- **rules/placeholders.md** — Safe parameters (`?` placeholders), avoid SQL injection.
|
||||
- **rules/query.md** — `MySQL.query` / `MySQL.query.await`: SELECT returns rows; other statements return insertId/affectedRows.
|
||||
- **rules/insert.md** — `MySQL.insert`: insert row, returns insert id.
|
||||
- **rules/prepare.md** — `MySQL.prepare`: prepared statements, only `?` placeholders; faster for repeated queries.
|
||||
- **rules/update.md** — `MySQL.update`: update rows, returns affected count.
|
||||
- **rules/single.md** — `MySQL.single`: one row or nil.
|
||||
- **rules/scalar.md** — `MySQL.scalar`: single value (one row, one column).
|
||||
- **rules/rawExecute.md** — `MySQL.rawExecute`: raw execution, no automatic result shape.
|
||||
- **rules/transaction.md** — `MySQL.transaction`: run multiple queries in a transaction.
|
||||
|
||||
## References (look up if not covered in the rules above)
|
||||
|
||||
If something isn't covered in the rules above, check the official docs:
|
||||
|
||||
- **OxMySQL (index):** https://coxdocs.dev/oxmysql
|
||||
- **Placeholders:** https://coxdocs.dev/oxmysql/placeholders
|
||||
- **Functions (query, insert, prepare, update, single, scalar, rawExecute, transaction):** https://coxdocs.dev/oxmysql (Functions section)
|
||||
@@ -0,0 +1,26 @@
|
||||
# insert
|
||||
|
||||
Inserts a row and returns the insert id (or nil/falsy on failure).
|
||||
|
||||
**Lua (Promise)**
|
||||
|
||||
```lua
|
||||
local id = MySQL.insert.await('INSERT INTO `users` (identifier, firstname, lastname) VALUES (?, ?, ?)', { identifier, firstName, lastName })
|
||||
print(id)
|
||||
```
|
||||
|
||||
**Lua (Callback)**
|
||||
|
||||
```lua
|
||||
MySQL.insert('INSERT INTO `users` (identifier, firstname, lastname) VALUES (?, ?, ?)', { identifier, firstName, lastName }, function(id)
|
||||
print(id)
|
||||
end)
|
||||
```
|
||||
|
||||
**JavaScript**
|
||||
|
||||
```js
|
||||
const insertId = await MySQL.insert('INSERT INTO `users` (identifier, firstname, lastname) VALUES (?, ?, ?)', [identifier, firstName, lastName]);
|
||||
```
|
||||
|
||||
Reference: [insert – coxdocs.dev](https://coxdocs.dev/oxmysql/Functions/insert).
|
||||
@@ -0,0 +1,11 @@
|
||||
# Placeholders
|
||||
|
||||
Use `?` for values; parameters as array or object. Prevents SQL injection.
|
||||
|
||||
```lua
|
||||
MySQL.scalar('SELECT `username` FROM `users` WHERE `identifier` = ? AND `group` = ?', { identifier, group })
|
||||
```
|
||||
|
||||
Named placeholders (`@name`) are deprecated; use positional `?` and pass array. For prepared statements use **rules/prepare.md** (only `?` and `??` for column names).
|
||||
|
||||
Reference: [Placeholders – coxdocs.dev](https://coxdocs.dev/oxmysql/placeholders).
|
||||
@@ -0,0 +1,29 @@
|
||||
# prepare
|
||||
|
||||
Prepared statements: faster for repeated queries. **Only `?` (value) and `??` (column name) placeholders** — named placeholders throw.
|
||||
|
||||
- Date does not return the datestring commonly used in FiveM.
|
||||
- TINYINT(1) and BIT do not return boolean.
|
||||
- SELECT result shape: column, row, or array of rows depending on columns/rows selected (unlike rawExecute).
|
||||
|
||||
**Lua (Promise)**
|
||||
|
||||
```lua
|
||||
local response = MySQL.prepare.await('SELECT `firstname`, `lastname` FROM `users` WHERE `identifier` = ?', { identifier })
|
||||
```
|
||||
|
||||
**Lua (Callback)**
|
||||
|
||||
```lua
|
||||
MySQL.prepare('SELECT `firstname`, `lastname` FROM `users` WHERE `identifier` = ?', { identifier }, function(response)
|
||||
-- use response
|
||||
end)
|
||||
```
|
||||
|
||||
**Upsert (insert or update on duplicate)**
|
||||
|
||||
```lua
|
||||
MySQL.prepare('INSERT INTO ox_inventory (owner, name, data) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE data = VALUES(data)', { owner, dbId, inventory })
|
||||
```
|
||||
|
||||
Reference: [prepare – coxdocs.dev](https://coxdocs.dev/oxmysql/Functions/prepare).
|
||||
@@ -0,0 +1,37 @@
|
||||
# query
|
||||
|
||||
SELECT returns all matching rows (array of rows). Other statements return insertId, affectedRows, etc.
|
||||
|
||||
**Lua (Promise)**
|
||||
|
||||
```lua
|
||||
local response = MySQL.query.await('SELECT `firstname`, `lastname` FROM `users` WHERE `identifier` = ?', { identifier })
|
||||
if response then
|
||||
for i = 1, #response do
|
||||
local row = response[i]
|
||||
print(row.firstname, row.lastname)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
**Lua (Callback)**
|
||||
|
||||
```lua
|
||||
MySQL.query('SELECT `firstname`, `lastname` FROM `users` WHERE `identifier` = ?', { identifier }, function(response)
|
||||
if response then
|
||||
for i = 1, #response do
|
||||
local row = response[i]
|
||||
print(row.firstname, row.lastname)
|
||||
end
|
||||
end
|
||||
end)
|
||||
```
|
||||
|
||||
**JavaScript**
|
||||
|
||||
```js
|
||||
const rows = await MySQL.query('SELECT `firstname`, `lastname` FROM `users` WHERE `identifier` = ?', [identifier]);
|
||||
// rows is array of objects
|
||||
```
|
||||
|
||||
Reference: [query – coxdocs.dev](https://coxdocs.dev/oxmysql/Functions/query).
|
||||
@@ -0,0 +1,19 @@
|
||||
# rawExecute
|
||||
|
||||
Executes raw SQL. Does not normalize result shape like query/prepare (SELECT returns raw result). Use when you need full control or non-standard result handling.
|
||||
|
||||
**Lua (Promise)**
|
||||
|
||||
```lua
|
||||
local result = MySQL.rawExecute.await('DELETE FROM `sessions` WHERE `expires` < NOW()')
|
||||
```
|
||||
|
||||
**Lua (Callback)**
|
||||
|
||||
```lua
|
||||
MySQL.rawExecute('DELETE FROM `sessions` WHERE `expires` < NOW()', {}, function(result)
|
||||
-- raw result
|
||||
end)
|
||||
```
|
||||
|
||||
Prefer **query**, **insert**, **update**, **single**, **scalar**, or **prepare** when they match the use case; use rawExecute only when necessary. Reference: [rawExecute – coxdocs.dev](https://coxdocs.dev/oxmysql/Functions/rawExecute).
|
||||
@@ -0,0 +1,27 @@
|
||||
# scalar
|
||||
|
||||
Returns a single value (one row, one column). Use for COUNT, one field, etc.
|
||||
|
||||
**Lua (Promise)**
|
||||
|
||||
```lua
|
||||
local count = MySQL.scalar.await('SELECT COUNT(*) FROM `users` WHERE `group` = ?', { group })
|
||||
local name = MySQL.scalar.await('SELECT `username` FROM `users` WHERE `identifier` = ?', { identifier })
|
||||
```
|
||||
|
||||
**Lua (Callback)**
|
||||
|
||||
```lua
|
||||
MySQL.scalar('SELECT `username` FROM `users` WHERE `identifier` = ?', { identifier }, function(name)
|
||||
if name then print(name) end
|
||||
end)
|
||||
```
|
||||
|
||||
**JavaScript**
|
||||
|
||||
```js
|
||||
const count = await MySQL.scalar('SELECT COUNT(*) FROM `users` WHERE `group` = ?', [group]);
|
||||
const name = await MySQL.scalar('SELECT `username` FROM `users` WHERE `identifier` = ?', [identifier]);
|
||||
```
|
||||
|
||||
Reference: [scalar – coxdocs.dev](https://coxdocs.dev/oxmysql/Functions/scalar).
|
||||
@@ -0,0 +1,29 @@
|
||||
# single
|
||||
|
||||
Returns a single row (first match) or nil/null if none.
|
||||
|
||||
**Lua (Promise)**
|
||||
|
||||
```lua
|
||||
local user = MySQL.single.await('SELECT * FROM `users` WHERE `identifier` = ?', { identifier })
|
||||
if user then
|
||||
print(user.firstname, user.lastname)
|
||||
end
|
||||
```
|
||||
|
||||
**Lua (Callback)**
|
||||
|
||||
```lua
|
||||
MySQL.single('SELECT * FROM `users` WHERE `identifier` = ?', { identifier }, function(user)
|
||||
if user then print(user.firstname) end
|
||||
end)
|
||||
```
|
||||
|
||||
**JavaScript**
|
||||
|
||||
```js
|
||||
const user = await MySQL.single('SELECT * FROM `users` WHERE `identifier` = ?', [identifier]);
|
||||
// user is one object or null
|
||||
```
|
||||
|
||||
Reference: [single – coxdocs.dev](https://coxdocs.dev/oxmysql/Functions/single).
|
||||
@@ -0,0 +1,35 @@
|
||||
# transaction
|
||||
|
||||
Run multiple queries in a transaction. If any fails, the transaction is rolled back.
|
||||
|
||||
**Lua (Promise)**
|
||||
|
||||
```lua
|
||||
MySQL.transaction.await({
|
||||
{ query = 'UPDATE `accounts` SET `balance` = `balance` - ? WHERE `id` = ?', values = { amount, fromId } },
|
||||
{ query = 'UPDATE `accounts` SET `balance` = `balance` + ? WHERE `id` = ?', values = { amount, toId } },
|
||||
})
|
||||
```
|
||||
|
||||
**Lua (Callback)**
|
||||
|
||||
```lua
|
||||
MySQL.transaction({
|
||||
{ query = 'UPDATE `accounts` SET `balance` = `balance` - ? WHERE `id` = ?', values = { amount, fromId } },
|
||||
{ query = 'UPDATE `accounts` SET `balance` = `balance` + ? WHERE `id` = ?', values = { amount, toId } },
|
||||
}, function(success)
|
||||
if not success then -- rollback happened
|
||||
end
|
||||
end)
|
||||
```
|
||||
|
||||
**JavaScript**
|
||||
|
||||
```js
|
||||
await MySQL.transaction([
|
||||
{ query: 'UPDATE `accounts` SET `balance` = `balance` - ? WHERE `id` = ?', values: [amount, fromId] },
|
||||
{ query: 'UPDATE `accounts` SET `balance` = `balance` + ? WHERE `id` = ?', values: [amount, toId] },
|
||||
]);
|
||||
```
|
||||
|
||||
Reference: [transaction – coxdocs.dev](https://coxdocs.dev/oxmysql/Functions/transaction).
|
||||
@@ -0,0 +1,25 @@
|
||||
# update
|
||||
|
||||
Updates rows; returns affected row count (or result object with affectedRows).
|
||||
|
||||
**Lua (Promise)**
|
||||
|
||||
```lua
|
||||
local affected = MySQL.update.await('UPDATE `users` SET `lastname` = ? WHERE `identifier` = ?', { newLastName, identifier })
|
||||
```
|
||||
|
||||
**Lua (Callback)**
|
||||
|
||||
```lua
|
||||
MySQL.update('UPDATE `users` SET `lastname` = ? WHERE `identifier` = ?', { newLastName, identifier }, function(affected)
|
||||
-- use affected
|
||||
end)
|
||||
```
|
||||
|
||||
**JavaScript**
|
||||
|
||||
```js
|
||||
const result = await MySQL.update('UPDATE `users` SET `lastname` = ? WHERE `identifier` = ?', [newLastName, identifier]);
|
||||
```
|
||||
|
||||
Always use `?` placeholders for values. Reference: [update – coxdocs.dev](https://coxdocs.dev/oxmysql/Functions/update).
|
||||
Reference in New Issue
Block a user