Aller au contenu principal
Version: 1.2.1

Builder (Query Builder)

Le Query Builder te permet de construire des requetes complexes en chainant des methodes. Tu l'obtiens avec Model.query().

local builder = User.query()

Methodes chainables​

Toutes ces methodes retournent le builder, ce qui permet de les chainer.

:where(conditions)​

Ajoute une condition WHERE (reliee par AND).

4 facons de l'utiliser :

-- 1. Egalite simple (table)
:where({ job = "police" })

-- 2. Raccourci egalite (2 arguments, = implicite)
:where("job", "police")

-- 3. Avec operateur (3 arguments)
:where("money", ">", 1000)

-- 4. Operateur dans la table
:where({ money = { ">", 1000 } })
:where({ job = { "LIKE", "%poli%" } })
:where({ id = { "IN", { 1, 2, 3 } } })
:where({ money = { "BETWEEN", { 500, 5000 } } })
:where({ status = { "!=", "banned" } })
:where({ job = { "IS", "NULL" } })
:where({ job = { "IS NOT", "NULL" } })

:::tip Raccourci 2 arguments :where("job", "police") est equivalent a :where({ job = "police" }). C'est plus court quand tu n'as qu'une seule condition. :::


:orWhere(conditions)​

Ajoute une condition reliee par OR.

:where({ job = "police" })
:orWhere({ job = "medic" })
-- SQL: WHERE job = ? OR job = ?

:orderBy(column, direction?)​

Trie les resultats.

ParametreTypeDefautDescription
columnstring—Colonne de tri
direction"ASC" | "DESC""ASC"Sens du tri
:orderBy("money", "DESC")
:orderBy("name") -- ASC par defaut

:orderByDesc(column)​

Raccourci pour ORDER BY ... DESC.

:orderByDesc("money")

:orderByAsc(column)​

Raccourci pour ORDER BY ... ASC.

:orderByAsc("name")

:latest(column?)​

Trie par la colonne donnee en DESC. Defaut : "created_at".

:latest() -- ORDER BY created_at DESC
:latest("updated_at") -- ORDER BY updated_at DESC

:oldest(column?)​

Trie par la colonne donnee en ASC. Defaut : "created_at".

:oldest() -- ORDER BY created_at ASC

:limit(n)​

Limite le nombre de resultats.

:limit(10)

:offset(n)​

Saute les N premiers resultats (pour la pagination).

:offset(20)

:select(columns)​

Specifie les colonnes a selectionner (defaut: "*").

:select("identifier, money")
:select("users.*, profiles.bio")

:leftJoin(table, col1, col2)​

Ajoute un LEFT JOIN.

:leftJoin("profiles", "profiles.user_id", "users.identifier")

:innerJoin(table, col1, col2)​

Ajoute un INNER JOIN.

:innerJoin("vehicles", "vehicles.owner_id", "users.identifier")

:rightJoin(table, col1, col2)​

Ajoute un RIGHT JOIN.

:rightJoin("users", "users.identifier", "vehicles.owner_id")

:groupBy(columns)​

Regroupe les resultats.

:groupBy("job")
:groupBy("job, department")

:having(clause, ...params)​

Filtre les groupes (utilise avec groupBy).

:having("COUNT(*) > ?", 5)
:having("SUM(money) > ?", 10000)

:distinct()​

Active SELECT DISTINCT sur la requete.

:distinct()
-- SQL: SELECT DISTINCT * FROM users ...

:whereNull(column)​

Filtre les lignes ou la colonne est NULL.

:whereNull("deleted_at")
-- SQL: WHERE deleted_at IS NULL

:whereNotNull(column)​

Filtre les lignes ou la colonne n'est pas NULL.

:whereNotNull("email")
-- SQL: WHERE email IS NOT NULL

:whereIn(column, valuesOrSubSQL, params?)​

Filtre avec une liste de valeurs OU une sous-requete IN.

-- Avec un tableau de valeurs
:whereIn("job", { "police", "medic", "fire" })
-- SQL: WHERE job IN (?, ?, ?)

-- Avec une sous-requete
:whereIn("id", "SELECT user_id FROM active_users WHERE last_login > ?", { "2024-01-01" })
-- SQL: WHERE id IN (SELECT user_id FROM active_users WHERE last_login > ?)

:whereNotIn(column, valuesOrSubSQL, params?)​

Filtre avec NOT IN (tableau ou sous-requete).

:whereNotIn("id", { 1, 2, 3 })
-- SQL: WHERE id NOT IN (?, ?, ?)

:whereNotIn("id", "SELECT user_id FROM banned_users")
-- SQL: WHERE id NOT IN (SELECT user_id FROM banned_users)

:whereBetween(column, min, max)​

Raccourci pour BETWEEN.

:whereBetween("money", 500, 5000)
-- SQL: WHERE money BETWEEN ? AND ?

:whereNotBetween(column, min, max)​

Raccourci pour NOT BETWEEN.

:whereNotBetween("money", 0, 100)
-- SQL: WHERE money NOT BETWEEN ? AND ?

:whereLike(column, pattern)​

Raccourci pour LIKE.

:whereLike("name", "%john%")
-- SQL: WHERE name LIKE ?

:whereExists(subSQL, params?)​

Filtre avec WHERE EXISTS (sous-requete).

:whereExists("SELECT 1 FROM vehicles WHERE vehicles.owner_id = users.id")
-- SQL: WHERE EXISTS (SELECT 1 FROM vehicles WHERE vehicles.owner_id = users.id)

:whereRaw(clause, params?)​

Ajoute une clause SQL libre, entouree de parentheses et combinee en AND avec les autres conditions.

:whereRaw("money > ? OR job = ?", { 1000, "police" })
-- SQL: WHERE (money > ? OR job = ?)

:whereRaw("LOWER(name) = ?", { "john" })
-- SQL: WHERE (LOWER(name) = ?)

:::caution Injection SQL Passe toujours les valeurs via params, jamais par concatenation de chaine. :whereRaw("name = '" .. input .. "'") est une porte ouverte a l'injection SQL. :::


:after(column, value, direction?)​

Pagination par curseur : recupere les lignes apres une valeur donnee.

-- Recuperer les 10 joueurs apres l'ID 50
User.query():after("id", 50):limit(10):get()
-- SQL: WHERE id > 50 ORDER BY id ASC LIMIT 10

:before(column, value, direction?)​

Pagination par curseur : recupere les lignes avant une valeur donnee.

User.query():before("id", 50):limit(10):get()
-- SQL: WHERE id < 50 ORDER BY id ASC LIMIT 10

Methodes terminales​

Ces methodes executent la requete et retournent un resultat.

:get() → OrvexInstance[]​

Execute la requete et retourne toutes les lignes.

local results = User.query()
:where({ job = "police" })
:orderBy("money", "DESC")
:get()

:first() → OrvexInstance | nil​

Execute la requete et retourne la premiere ligne (ajoute automatiquement LIMIT 1).

local richest = User.query()
:orderBy("money", "DESC")
:first()

:count() → integer​

Compte les lignes.

local nb = User.query()
:where({ job = "police" })
:count()

:sum(column) → number​

Additionne les valeurs d'une colonne.

local total = User.query()
:where({ job = "police" })
:sum("money")

:avg(column) → number​

Calcule la moyenne.

local avg = User.query():avg("money")

:min(column) → any​

Retourne la valeur minimale.

local min = User.query():min("money")

:max(column) → any​

Retourne la valeur maximale.

local max = User.query():max("money")

:pluck(column) → any[]​

Retourne un tableau des valeurs d'une seule colonne.

local jobs = User.query():pluck("job")
-- { "police", "medic", "firefighter" }

:exists() → boolean​

Verifie si au moins une ligne correspond. Ne charge pas les donnees.

local hasCops = User.query():where("job", "police"):exists()

:chunk(size, callback)​

Traite les resultats par lots pour eviter de tout charger en memoire.

User.query():chunk(100, function(rows, chunkIndex)
-- traiter le lot...
return false -- retourner false pour arreter
end)

:paginate(page, perPage?) → table​

Pagine les resultats automatiquement. Retourne un objet avec les donnees et les metadonnees de pagination.

ParametreTypeDefautDescription
pageinteger—Numero de la page (commence a 1)
perPageinteger15Nombre d'elements par page
local page = User.query()
:where({ job = "police" })
:orderBy("money", "DESC")
:paginate(2, 10)

-- page.data → OrvexInstance[] (les resultats)
-- page.total → nombre total d'enregistrements
-- page.page → 2
-- page.perPage → 10
-- page.lastPage → ceil(total / perPage)

:toSQL() → string, table​

Retourne le SQL genere et les parametres sans executer la requete.

local sql, params = User.query()
:where({ job = "police" })
:where("money", ">", 500)
:toSQL()

print(sql) -- SELECT * FROM users WHERE job = ? AND money > ?
print(params) -- { "police", 500 }

Exemples complets​

Classement avec pagination​

-- Page 2 du top des joueurs (10 par page)
local page2 = User.query()
:where("money", ">", 0)
:orderBy("money", "DESC")
:limit(10)
:offset(10)
:get()

Statistiques par job​

local stats = User.query()
:select("job, COUNT(*) as nb, AVG(money) as avg_money")
:groupBy("job")
:having("COUNT(*) >= ?", 2)
:orderBy("avg_money", "DESC")
:get()

Joueurs avec profil (jointure)​

local players = User.query()
:select("users.*, profiles.bio, profiles.avatar")
:leftJoin("profiles", "profiles.user_id", "users.identifier")
:where({ job = { "IN", { "police", "medic" } } })
:where({ money = { "BETWEEN", { 1000, 50000 } } })
:orderBy("money", "DESC")
:limit(20)
:get()