Skip to main content

Database

รหัสเริ่มต้นรองรับ oxmysql คุณสามารถแก้ไขรหัสให้มีความเข้ากันได้กับทรัพยากรที่คุณใช้งานได้ที่ไฟล์ server.database.lua

caution

หากคุณไม่ได้ใช้งาน oxmysql อย่าลืม แก้ไข รหัสที่ไฟล์ fxmanifest.lua

server_scripts {
'@oxmysql/lib/MySQL.lua', -- oxmysql
'config/server.config.lua',
'config/auth.config.lua',
'public/database/server.database.lua',
'source/server/framework.server.lua',
'source/server/auth.server.lua',
'source/server/main.server.lua',
'source/server/main.server.js',
'source/server/fileupload.server.js'
}

OnReady (function)

ตรวจสอบการเชื่อมต่อกับ MySQL เสร็จสมบูรณ์และพร้อมใช้งาน (ทำงานเมื่อฐานข้อมูลพร้อมใช้งาน)

บรรทัดที่ 16
DATABASE.OnReady = MySQL.ready

InitDatabase (function)

ดำเนินการตรวจสอบและติดตั้งฐานข้อมูลเมื่อ oxmysql พร้อมใช้งาน

บรรทัดที่ 19
function DATABASE.InitDatabase()
if not pcall(MySQL.scalar.await, 'SELECT 1 FROM `azael_db_guardian`') then
MySQL.query.await([[CREATE TABLE `azael_db_guardian` (
`identifier` VARCHAR(60) NOT NULL,
`lastseen` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`deleted` TINYINT(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '0 = no, 1 = yes',
PRIMARY KEY (`identifier`)
)]])

local success, response = pcall(MySQL.query.await, FRAMEWORK.Database.COPY_DEFAULT)

if not success then
success, response = pcall(MySQL.query.await, FRAMEWORK.Database.COPY_IDENTIFIER)
end

if (success and response?.affectedRows > 0) then
print(('[^2INFO^7] Copying data of ^5%s^7 players to the "^5azael_db_guardian^7" table is completed'):format(response.affectedRows))
end
end
end

GetDBConnection (function)

รับการกำหนดค่าการเชื่อมต่อกับฐานข้อมูลจากไฟล์ server.cfg (ค่าเริ่มต้นรับข้อมูลจาก mysql_connection_string)

บรรทัดที่ 45
function DATABASE.GetDBConnection()
local connStr = GetConvar(CONFIG.Database.GetConVarName, '')
local dbUser, dbPass, dbHost, dbPort, dbName

if connStr:match('user=') then
local connData = {}

for k, v in connStr:gmatch('([^;]+)=([^;]+)') do
connData[k] = v
end

dbUser, dbPass, dbHost, dbPort, dbName = connData.user, connData.password, connData.host, connData.port, connData.database
elseif connStr:match('mysql://') then
dbUser, dbPass, dbHost, dbPort, dbName = connStr:match('mysql://([^:]+):?([^.]*)@([^:/]+):?([^/]*).*/([^?]+)')

if (dbPass and dbPass == '') then dbPass = nil end
if (dbPort and dbPort == '') then dbPort = nil end
end

return dbUser, dbPass, dbHost, dbPort, dbName
end

Return

NameTypeDescription
dbUserstring / nilชื่อผู้ใช้ ฐานข้อมูล
dbPassstring / nilรหัสผ่าน ฐานข้อมูล
dbHoststring / nilโฮสต์ ฐานข้อมูล
dbPortstring / nilพอร์ต ฐานข้อมูล
dbNamestring / nilชื่อ ฐานข้อมูล

GetDumpCommand (function)

รับคำสั่งที่ใช้ในการสำรองฐานข้อมูล

บรรทัดที่ 69
function DATABASE.GetDumpCommand()
local dataDir = MySQL.query.await("SHOW VARIABLES LIKE 'datadir'")

if (dataDir and dataDir[1]) then
local filePath = dataDir[1].Value:gsub('\\data\\', '\\bin\\mysqldump.exe')
local fileExists = io.open(filePath, 'r')

if fileExists then
fileExists:close()

return filePath
end
end
end

Return

NameTypeDescription
filePathstring / nilเส้นทาง โปรแกรม หรือ คำสั่ง ที่ใช้ในการสำรองฐานข้อมูล

FormatServerBackupCommand (function)

จัดรูปแบบคำสั่งสำรองฐานข้อมูลเซิร์ฟเวอร์

บรรทัดที่ 93
function DATABASE.FormatServerBackupCommand(dbUser, dbPass, dbHost, dbPort, dbName, cmdName, backupPath)
return ('"%s" -u %s %s --single-transaction --quick %s > "%s"'):format(cmdName, dbUser, (dbPass and ('-p%s'):format(dbPass) or ''), dbName, backupPath)
end

Parameter

NameTypeDescription
dbUserstringชื่อผู้ใช้ ฐานข้อมูล
dbPassstring / nilรหัสผ่าน ฐานข้อมูล
dbHoststring / nilโฮสต์ ฐานข้อมูล
dbPortstring / nilพอร์ต ฐานข้อมูล
dbNamestringชื่อ ฐานข้อมูล
cmdNamestringเส้นทาง โปรแกรม หรือ คำสั่ง ที่ใช้ในการสำรองฐานข้อมูล
backupPathstringเส้นทางไฟล์ สำรองฐานข้อมูลเซิร์ฟเวอร์

Return

NameTypeDescription
commandstringคำสั่ง เพื่อดำเนินการ สำรองฐานข้อมูลเซิร์ฟเวอร์

FormatPlayerBackupCommand (function)

จัดรูปแบบคำสั่งสำรองฐานข้อมูลผู้เล่น เมื่อถูกลบข้อมูล

บรรทัดที่ 110
function DATABASE.FormatPlayerBackupCommand(dbUser, dbPass, dbHost, dbPort, dbName, cmdName, backupPath, tableName, columnName, identifier, isSpecialId)
local password = (dbPass and ('-p%s'):format(dbPass) or '')
local where = isSpecialId and ('`%s` IN (%s)'):format(columnName, identifier) or FRAMEWORK.Database.WHERE_IDENTIFIER:format(columnName, identifier)

return ('"%s" -u %s %s --no-create-db --no-create-info --skip-triggers --insert-ignore --complete-insert --single-transaction --quick %s %s --where="%s" >> "%s"'):format(cmdName, dbUser, password, dbName, tableName, where, backupPath)
end

Parameter

NameTypeDescription
dbUserstringชื่อผู้ใช้ ฐานข้อมูล
dbPassstring / nilรหัสผ่าน ฐานข้อมูล
dbHoststring / nilโฮสต์ ฐานข้อมูล
dbPortstring / nilพอร์ต ฐานข้อมูล
dbNamestringชื่อ ฐานข้อมูล
cmdNamestringเส้นทาง โปรแกรม หรือ คำสั่ง ที่ใช้ในการสำรองฐานข้อมูล
backupPathstringเส้นทางไฟล์ สำรองฐานข้อมูลผู้เล่น เมื่อถูกลบข้อมูล
tableNamestringชื่อ ตาราง ฐานข้อมูล
columnNamestringชื่อ คอลัมน์ ฐานข้อมูล
identifierstringตัวระบุผู้เล่น หรือ ตัวระบุพิเศษ หาก isSpecialId เท่ากับ true
isSpecialIdbooleanเป็นตัวระบุพิเศษ

Return

NameTypeDescription
commandstringคำสั่ง เพื่อดำเนินการ สำรองฐานข้อมูลผู้เล่น เมื่อถูกลบข้อมูล

GetSchemaTable (function)

รับชื่อ ตาราง, คอลัมน์ บนฐานข้อมูล

บรรทัดที่ 120
function DATABASE.GetSchemaTable(dbName)
return MySQL.query.await(("SELECT table_name, column_name FROM information_schema.columns WHERE table_schema = '%s'"):format(dbName))
end

Parameter

NameTypeDescription
dbNamestringชื่อ ฐานข้อมูล

Return

NameTypeDescription
datatableตารางข้อมูล Schema บนฐานข้อมูล
data[index]tableตารางข้อมูล ชื่อตาราง และ ชื่อคอลัมน์
data[index].table_namestringชื่อ ตาราง
data[index].column_namestringชื่อ คอลัมน์

GetForeignkeyTable (function)

รับชื่อ ตาราง ทีมีความสัมพันธ์กับตารางอื่นๆ (Foreign Keys)

บรรทัดที่ 127
function DATABASE.GetForeignKeyTable(dbName)
return MySQL.query.await(("SELECT table_name, referenced_table_name FROM information_schema.key_column_usage WHERE table_schema = '%s' AND referenced_table_name IS NOT NULL"):format(dbName))
end

Parameter

NameTypeDescription
dbNamestringชื่อ ฐานข้อมูล

Return

NameTypeDescription
datatableตารางข้อมูล Schema บนฐานข้อมูล
data[index]tableตารางข้อมูล ชื่อตาราง ทีมีความสัมพันธ์กับตารางอื่นๆ
data[index].table_namestringชื่อ ตาราง
data[index].referenced_table_namestringชื่อ ตาราง อ้างอิง

GetIdlePlayers (function)

รับข้อมูลผู้เล่นที่ไม่ได้ใช้งาน

บรรทัดที่ 137
function DATABASE.GetIdlePlayers(delStatus, dayLimit, delLimit, ignoreIds)
local query = 'SELECT `identifier`, UNIX_TIMESTAMP(`lastseen`) AS `lastseen` FROM `azael_db_guardian` WHERE `deleted` = ? AND `lastseen` < DATE_SUB(NOW(), INTERVAL ? DAY)'

if (ignoreIds and ignoreIds[1]) then
local idsStr = ("'%s'"):format(table.concat(ignoreIds, "','"))

query = ('%s AND `identifier` NOT IN (%s)'):format(query, idsStr)
end

query = ('%s ORDER BY `lastseen` ASC LIMIT %d'):format(query, delLimit)

return MySQL.query.await(query, { delStatus, dayLimit })
end

Parameter

NameTypeDescription
delStatusbooleanสถานะ ลบข้อมูลผู้เล่น
dayLimitnumberจำนวน วันที่ไม่เชื่อมต่อกับเซิร์ฟเวอร์ (ตามการกำหนดค่า UserIdle.LimitDays)
delLimitnumberจำนวน จำกัดการลบข้อมูลของผู้เล่นสูงสุด (ตามการกำหนดค่า AutoDelete.Limit)
ignoreIdstable / nilตารางข้อมูล ตัวระบุผู้เล่นที่ละเว้น (ตามการกำหนดค่า IgnoreDelete.Identifiers)
ignoreIds[index]stringตัวระบุผู้เล่นที่ละเว้น

Return

NameTypeDescription
datatableตารางข้อมูล ผู้เล่นทั้งหมด ที่เข้าเงื่อนไขถูกลบข้อมูล
data[index]tableตารางข้อมูล ผู้เล่น ที่เข้าเงื่อนไขถูกลบข้อมูล
data[index].identifierstringตัวระบุผู้เล่น
data[index].lastseennumberวันที่ผู้เล่นเชื่อมต่อครั้งล่าสุด

CountIdlePlayers (function)

นับจำนวนผู้เล่นที่ไม่ได้ใช้งาน (ไม่เชื่อมต่อกับเซิร์ฟเวอร์มากกว่าวันที่กำหนด)

บรรทัดที่ 156
function DATABASE.CountIdlePlayers(delStatus, dayLimit, ignoreIds)
local query = 'SELECT COUNT(`identifier`) AS `count` FROM `azael_db_guardian` WHERE `deleted` = ? AND `lastseen` < DATE_SUB(NOW(), INTERVAL ? DAY)'

if (ignoreIds and ignoreIds[1]) then
local idsStr = ("'%s'"):format(table.concat(ignoreIds, "','"))

query = ('%s AND `identifier` NOT IN (%s)'):format(query, idsStr)
end

local rows = MySQL.query.await(query, { delStatus, dayLimit })

return rows[1].count
end

Parameter

NameTypeDescription
delStatusbooleanสถานะ ลบข้อมูลผู้เล่น
dayLimitnumberจำนวน วันที่ไม่เชื่อมต่อกับเซิร์ฟเวอร์ (ตามการกำหนดค่า UserIdle.LimitDays)
ignoreIdstable / nilตารางข้อมูล ตัวระบุผู้เล่นที่ละเว้น (ตามการกำหนดค่า IgnoreDelete.Identifiers)
ignoreIds[index]stringตัวระบุผู้เล่นที่ละเว้น

Return

NameTypeDescription
countnumberจำนวน ผู้เล่นที่ไม่เชื่อมต่อกับเซิร์ฟเวอร์มากกว่าวันที่กำหนด (ตามการกำหนดค่า UserIdle.LimitDays)

GetPlayerData (function)

รับข้อมูล วันที่เชื่อมต่อ และ สถานะการถูกลบ ของผู้เล่น

บรรทัดที่ 173
function DATABASE.GetPlayerData(identifier)
local row = MySQL.prepare.await('SELECT UNIX_TIMESTAMP(`lastseen`) AS `lastseen`, `deleted` FROM `azael_db_guardian` WHERE `identifier` = ? LIMIT 1', { identifier })

if (row and tonumber(row.deleted)) then
row.deleted = row.deleted ~= 0
end

return row
end

Parameter

NameTypeDescription
identifierstringตัวระบุผู้เล่น

Return

NameTypeDescription
datatableตารางข้อมูล ผู้เล่น
data.lastseennumberวันที่ผู้เล่นเชื่อมต่อครั้งล่าสุด
data.deletedbooleanสถานะ ถูกลบข้อมูล

GetForeignCharIds (function)

รับรายการตัวระบุที่ถูกสร้างโดย Framework เพื่อใช้ในการ ลบข้อมูล และ สำรองข้อมูล ของผู้เล่น

บรรทัดที่ 186
function DATABASE.GetForeignCharIds(identifier)
local idsStr

if FRAMEWORK.Database.FOREIGN_IDENTIFIERS then
local rows = MySQL.query.await(FRAMEWORK.Database.FOREIGN_IDENTIFIERS, { identifier })

if (rows and rows[1]) then
idsStr = {}

for i = 1, #rows, 1 do
idsStr[i] = rows[i]['id']
end

idsStr = ("'%s'"):format(table.concat(idsStr, "','"))
end
end

return idsStr
end
info

รหัสภายในฟังก์ชันนี้จะอ้างอิงจากฐานข้อมูลของ QBCore Framework เนื่องจาก Framework นี้จะอ้างอิงตัวระบุจากคอลัมน์ citizenid

Parameter

NameTypeDescription
identifierstringตัวระบุผู้เล่น

Return

NameTypeDescription
idsStrstring / nilรายการตัวระบุ Framework ของผู้เล่นทั้งหมด (ตัวอย่าง: 'ID_1' หรือ 'ID_1', 'ID_2', 'ID_3')

GetKeysByIdentifier (function)

รับคีย์อ้างอิงจาก ตัวระบุ เพื่อ สำรองข้อมูล หรือ ลบข้อมูล ของผู้เล่น

บรรทัดที่ 212
function DATABASE.GetKeysByIdentifier(identifier, tableName, idColumnName, keyColumnName)
local rows = MySQL.query.await(('SELECT `%s` AS `key` FROM `%s` WHERE `%s` = ?'):format(keyColumnName, tableName, idColumnName), { identifier })
local keysStr

if (rows and rows[1]) then
keysStr = {}

for i = 1, #rows, 1 do
keysStr[i] = rows[i]['key']
end

keysStr = ("'%s'"):format(table.concat(keysStr, "','"))
end

return keysStr
end

Parameter

NameTypeDescription
identifierstringตัวระบุผู้เล่น
tableNamestringชื่อตาราง
idColumnNamestringชื่อคอลัมน์ ตัวระบุ
keyColumnNamestringชื่อคอลัมน์ คีย์อ้างอิง

Return

NameTypeDescription
keysStrstring / nilรายการคีย์อ้างอิง (ตัวอย่าง: 'KEY_1' หรือ 'KEY_1', 'KEY_2', 'KEY_3')

DoesRowExist (function)

ตรวจสอบว่ามีข้อมูลอยู่หรือไม่

บรรทัดที่ 235
function DATABASE.DoesRowExist(identifier, tableName, columnName, isSpecialId)
local where = isSpecialId and ('`%s` IN (%s)'):format(columnName, identifier) or FRAMEWORK.Database.WHERE_IDENTIFIER:format(columnName, identifier)
local row = MySQL.scalar.await(('SELECT 1 FROM `%s` WHERE %s'):format(tableName, where))

return row ~= nil
end

Parameter

NameTypeDescription
identifierstringตัวระบุผู้เล่น หรือ ตัวระบุพิเศษ หาก isSpecialId เท่ากับ true
tableNamestringชื่อตาราง
columnNamestringชื่อคอลัมน์
isSpecialIdbooleanเป็นตัวระบุพิเศษ

Return

NameTypeDescription
existsbooleanสถานะ ข้อมูลมีอยู่จริง

InsertPlayerConnection (function)

บันทึกข้อมูลการเชื่อมต่อผู้เล่น

บรรทัดที่ 245
function DATABASE.InsertPlayerConnection(identifier)
MySQL.insert('INSERT INTO `azael_db_guardian` (`identifier`) VALUES (?)', { identifier })
end

Parameter

NameTypeDescription
identifierstringตัวระบุผู้เล่น

UpdatePlayerConnection (function)

บันทึกข้อมูลการเชื่อมต่อผู้เล่น

บรรทัดที่ 252
function DATABASE.UpdatePlayerConnection(identifier)
MySQL.prepare('UPDATE `azael_db_guardian` SET lastseen = CURRENT_TIMESTAMP WHERE `identifier` = ?', { identifier })
end

Parameter

NameTypeDescription
identifierstringตัวระบุผู้เล่น

UpdatePlayerLeaveDays (function)

อัพเดทวันที่เชื่อมต่อให้ผู้เล่น ในกรณีแจ้งลาต่างๆ

บรรทัดที่ 260
function DATABASE.UpdatePlayerLeaveDays(identifier, days)
local success, err = pcall(MySQL.update.await, 'UPDATE `azael_db_guardian` SET lastseen = DATE_ADD(CURRENT_TIMESTAMP, INTERVAL ? DAY) WHERE `identifier` = ?', { days, identifier })

if pcall(MySQL.scalar.await, 'SELECT 1 FROM `azael_dc_whitelisted` WHERE `identifier` = ?', { identifier }) then
local unixTime = (days * 86400) + os.time()

MySQL.update('UPDATE `azael_dc_whitelisted` SET connect = ? WHERE `identifier` = ?', { unixTime, identifier })
end

return success, err
end
info
  • อ้างอิงจากวันที่ดำเนินการและเพิ่มจำนวนวันให้ตามที่กำหนด
  • หากใช้งาน azael_dc-whitelisted จะดำเนินการอัพเดทวันลาไปยังตาราง azael_dc_whitelisted คอลัมน์ connect โดยอัตโนมัติ

Parameter

NameTypeDescription
identifierstringตัวระบุผู้เล่น
daysnumberจำนวนวันลา

Return

NameTypeDescription
successbooleanสถานะ ดำเนินการสำเร็จ
errstring / nilข้อผิดพลาด หากดำเนินการล้มเหลว

UpdateDeletionStatus (function)

อัพเดตสถานะการลบข้อมูลผู้เล่น

บรรทัดที่ 277
function DATABASE.UpdateDeletionStatus(identifier, delStatus)
local success, err = pcall(MySQL.update.await, (delStatus
and 'UPDATE `azael_db_guardian` SET deleted = ? WHERE `identifier` = ?'
or 'UPDATE `azael_db_guardian` SET lastseen = CURRENT_TIMESTAMP, deleted = ? WHERE `identifier` = ?'
), { delStatus, identifier })

return success, err
end

Parameter

NameTypeDescription
identifierstringตัวระบุผู้เล่น
delStatusbooleanสถานะ ลบข้อมูลผู้เล่น

Return

NameTypeDescription
successbooleanสถานะ ดำเนินการสำเร็จ
errstring / nilข้อผิดพลาด หากดำเนินการล้มเหลว

DeletePlayerData (function)

ลบข้อมูลผู้เล่นออกจากฐานข้อมูล

บรรทัดที่ 292
function DATABASE.DeletePlayerData(identifier, tableName, columnName, isSpecialId)
local where = isSpecialId and ('`%s` IN (%s)'):format(columnName, identifier) or FRAMEWORK.Database.WHERE_IDENTIFIER:format(columnName, identifier)
local success, rows = pcall(MySQL.update.await, ('DELETE FROM `%s` WHERE %s'):format(tableName, where))

if not success then
print(('[^1ERROR^7] %s'):format(rows))

return false, 0
end

return rows ~= 0, rows
end

Parameter

NameTypeDescription
identifierstringตัวระบุผู้เล่น หรือ ตัวระบุพิเศษ หาก isSpecialId เท่ากับ true
tableNamestringชื่อตาราง
columnNamestringชื่อคอลัมน์
isSpecialIdbooleanเป็นตัวระบุพิเศษ

Return

NameTypeDescription
successbooleanสถานะ ดำเนินการสำเร็จ
rowsnumberจำนวนแถว ที่ดำเนินการลบข้อมูลในตาราง