From 4b0789906177b28aa420df36172df127a533cb75 Mon Sep 17 00:00:00 2001 From: Selt <83926739+seltonmt012@users.noreply.github.com> Date: Tue, 28 Jul 2026 01:51:54 +0200 Subject: [PATCH] fix(es_extended/server/modules/createJob): only insert what is missing The jobs row was inserted unconditionally, so adding a grade to an existing job hit a duplicate primary key and rolled the whole transaction back. The guard above it only caught the case where there was nothing to add, and it read ESX.Jobs, which does not list jobs that have no grades yet. --- .../es_extended/server/modules/createJob.lua | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/[core]/es_extended/server/modules/createJob.lua b/[core]/es_extended/server/modules/createJob.lua index a5712cf4..48f55540 100644 --- a/[core]/es_extended/server/modules/createJob.lua +++ b/[core]/es_extended/server/modules/createJob.lua @@ -5,22 +5,8 @@ local NOTIFY_TYPES = { ERROR = "^5[%s]^7-^1[ERROR]^7 %s" } -local function doesJobAndGradesExist(name, grades) - if not ESX.Jobs[name] then - return false - end - - for _, grade in ipairs(grades) do - if not ESX.DoesJobExist(name, grade.grade) then - return false - end - end - - return true -end - local function generateNewJobTable(name, label, grades, jobType) - local job = { name = name, label = label, type = jobType, grades = {} } + local job = ESX.Jobs[name] or { name = name, label = label, type = jobType, grades = {} } for _, v in pairs(grades) do job.grades[tostring(v.grade)] = { job_name = name, grade = v.grade, name = v.name, label = v.label, salary = v.salary, skin_male = v.skin_male or '{}', skin_female = v.skin_female or '{}' } end @@ -66,22 +52,38 @@ function ESX.CreateJob(name, label, grades, jobType) jobType = "civ" end - local currentJobExist = doesJobAndGradesExist(name, grades) + local jobExists = MySQL.scalar.await('SELECT 1 FROM `jobs` WHERE `name` = ?', { name }) ~= nil + local existingGrades = {} - if currentJobExist then - notify("ERROR",currentResourceName, 'Job or grades already exists: `%s`', name) - return success + if jobExists then + local rows = MySQL.query.await('SELECT `grade` FROM `job_grades` WHERE `job_name` = ?', { name }) + + for i = 1, #(rows or {}) do + existingGrades[rows[i].grade] = true + end end - local queries = { - { query = 'INSERT INTO `jobs` (`name`, `label`, `type`) VALUES (?, ?, ?)', values = { name, label, jobType } } - } + local queries = {} + + if not jobExists then + queries[#queries + 1] = { + query = 'INSERT INTO `jobs` (`name`, `label`, `type`) VALUES (?, ?, ?)', + values = { name, label, jobType } + } + end for _, grade in pairs(grades) do - queries[#queries + 1] = { - query = 'INSERT INTO job_grades (job_name, grade, name, label, salary, skin_male, skin_female) VALUES (?, ?, ?, ?, ?, ?, ?)', - values = { name, grade.grade, grade.name, grade.label, grade.salary, grade.skin_male and json.encode(grade.skin_male) or '{}', grade.skin_female and json.encode(grade.skin_female) or '{}' } - } + if not existingGrades[grade.grade] then + queries[#queries + 1] = { + query = 'INSERT INTO job_grades (job_name, grade, name, label, salary, skin_male, skin_female) VALUES (?, ?, ?, ?, ?, ?, ?)', + values = { name, grade.grade, grade.name, grade.label, grade.salary, grade.skin_male and json.encode(grade.skin_male) or '{}', grade.skin_female and json.encode(grade.skin_female) or '{}' } + } + end + end + + if not queries[1] then + notify("ERROR",currentResourceName, 'Job or grades already exists: `%s`', name) + return success end success = exports.oxmysql:transaction_async(queries)