2026-04-14 17:41:39 +02:00

142 lines
5.6 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- ============================================================
-- db/main.lua Database module (cache + core queries)
-- ============================================================
_G.db = { cache = {} }
-- ──────────────────────────────────────────────
-- saveCache
-- cacheName : string cache key name
-- cacheId : any secondary identifier
-- data : any data to store
-- ttl : number? time-to-live in seconds (default 3 600 000)
-- ──────────────────────────────────────────────
function db.saveCache(self, cacheName, data, cacheId, ttl)
if not data then
Debug("No data to save to cache", cacheName, cacheId)
return
end
local expireAt = os.time() + (ttl or 3600000)
self.cache[#self.cache + 1] = {
name = cacheName,
id = cacheId,
time = os.time(),
expire = expireAt,
data = data,
}
Debug("db:saveCache", cacheName, cacheId)
end
-- ──────────────────────────────────────────────
-- clearCache
-- cacheName : string cache key to clear
-- cacheId : any? optional secondary identifier
-- ──────────────────────────────────────────────
function db.clearCache(self, cacheName, cacheId)
self.cache = table.filter(self.cache, function(entry)
return entry.name ~= cacheName
end)
Debug("db:clearCache", cacheName, cacheId)
end
-- ──────────────────────────────────────────────
-- getCache
-- Returns the cached data, or nil if not found.
-- ──────────────────────────────────────────────
function db.getCache(self, cacheName, cacheId)
local found = table.find(self.cache, function(entry)
return entry.name == cacheName
end)
if found then
Debug("db:getCache", cacheName, cacheId)
return found.data
end
return nil
end
-- ──────────────────────────────────────────────
-- convertVectors
-- Recursively converts plain {x,y,z[,w]} tables
-- to FiveM vec3/vec4 native types.
-- ──────────────────────────────────────────────
function db.convertVectors(self, value)
if type(value) ~= "table" then return value end
-- vec4 detection
if value.w and value.x and value.y and value.z then
return vec4(value.x, value.y, value.z, value.w)
end
-- Recurse into nested tables
for key, nested in pairs(value) do
if type(nested) == "table" then
value[key] = self:convertVectors(nested)
end
end
return value
end
-- ──────────────────────────────────────────────
-- getGarages
-- Fetches all player_garages rows and decodes
-- their JSON columns into Lua tables.
-- ──────────────────────────────────────────────
function db.getGarages()
local rows = MySQL.query.await("SELECT * FROM player_garages")
for _, garage in pairs(rows) do
-- Normalize available flag
garage.available = (garage.available == true or garage.available == 1) or false
garage.zone = json.decode(garage.zone)
garage.coords = json.decode(garage.coords)
garage.shell = json.decode(garage.shell)
garage.holders = (garage.holders and json.decode(garage.holders)) or {}
garage.jobs = (garage.jobs and json.decode(garage.jobs)) or {}
garage.gangs = (garage.gangs and json.decode(garage.gangs)) or {}
garage.interior_type = garage.interior_type or "ipl"
end
return rows
end
-- ──────────────────────────────────────────────
-- checkVehicleGarages
-- For each vehicle whose garage no longer exists,
-- moves it to the nearest impound. Used by /migratev5.
-- ──────────────────────────────────────────────
function db.checkVehicleGarages()
local selectQuery = string.format("SELECT type, garage, plate FROM `%s`", garageTable)
local vehicles = MySQL.query.await(selectQuery)
local pendingUpdates = {}
for _, row in pairs(vehicles) do
if row.garage ~= "OUT" then
local garageExists = Config.Garages[row.garage]
if not garageExists then
local impound = GetImpoundOfType(row.type)
local updateQuery = string.format("UPDATE `%s` SET garage = ? WHERE plate = ?", garageTable)
pendingUpdates[#pendingUpdates + 1] = {
query = updateQuery,
values = { impound, row.plate },
}
end
end
end
if #pendingUpdates > 0 then
Debug("db.checkVehicleGarages", "We collected", #pendingUpdates, "queries to update vehicles because their garages were not found")
MySQL.transaction(pendingUpdates)
end
end