-- ============================================================ -- db/decorate.lua – Decoration object CRUD queries -- ============================================================ local SQL = { INSERT_OBJECT = [[ INSERT INTO qs_garage_decorations (creator, insideId, modelName, coords, rotation, inStash, inside, created, uniq, lightData) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ]], DELETE_OBJECT = "DELETE FROM qs_garage_decorations WHERE id = ?", SELECT_OBJECTS = "SELECT * FROM qs_garage_decorations WHERE insideId = ?", } -- ────────────────────────────────────────────── -- saveObject -- Inserts a new decoration and returns its new DB id. -- ────────────────────────────────────────────── function db.saveObject(creatorIdentifier, objectData) local lightDataEncoded = objectData.lightData and json.encode(objectData.lightData) or nil local newId = MySQL.insert.await(SQL.INSERT_OBJECT, { creatorIdentifier, objectData.insideId, objectData.modelName, json.encode(objectData.coords), json.encode(objectData.rotation), objectData.inStash, objectData.inside, os.date("%Y-%m-%d %H:%M:%S"), objectData.uniq, lightDataEncoded, }) Debug("db.saveObject", "Saved", objectData.insideId, "Id", newId, "Data", objectData) return newId end -- ────────────────────────────────────────────── -- getObjects -- Fetches all decoration objects for a given garage -- and decodes their JSON/timestamp fields. -- ────────────────────────────────────────────── function db.getObjects(garageId) local rows = MySQL.query.await(SQL.SELECT_OBJECTS, { garageId }) for _, row in ipairs(rows) do row.coords = json.decode(row.coords) row.rotation = json.decode(row.rotation) -- Convert stored millisecond timestamp to os.time() seconds local timestampSeconds = math.floor(row.created / 1000) row.created = os.time(os.date("*t", timestampSeconds)) row.uniq = row.uniq or tostring("garage_" .. row.id) row.lightData = row.lightData and json.decode(row.lightData) or nil end return rows end -- ────────────────────────────────────────────── -- updateObject -- Builds a dynamic SET clause from the provided -- updateData table and executes the update. -- ────────────────────────────────────────────── function db.updateObject(objectId, updateData) if not updateData then Debug("db.updateObject", "No data to update") return false end Debug("db.updateObject", updateData) local setClause = "UPDATE qs_garage_decorations SET" local params = {} for key, value in pairs(updateData) do setClause = setClause .. string.format(" `%s` = :%s,", key, key) -- False is valid only for boolean columns like inStash/inside if value == false and key ~= "inStash" and key ~= "inside" then value = nil Debug("db.updateObject", "Set", key, "to nil because of false") end params[key] = value end -- Remove trailing comma and append WHERE clause setClause = setClause:sub(1, -2) .. " WHERE id = :id" params.id = objectId Debug("params", params) return MySQL.update.await(setClause, params) end -- ────────────────────────────────────────────── -- deleteObject -- ────────────────────────────────────────────── function db.deleteObject(objectId) MySQL.prepare(SQL.DELETE_OBJECT, { objectId }) return true end -- ────────────────────────────────────────────── -- deleteAllObjects -- ────────────────────────────────────────────── function db.deleteAllObjects(garageId) Debug("db.deleteAllObjects", garageId) ClearDecorations(garageId) MySQL.prepare.await("DELETE FROM qs_garage_decorations WHERE insideId = ?", { garageId }) return true end