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)​

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

บรรทัดที่ 70
function DATABASE.GetDumpCommand(platform)
local baseDirRes = MySQL.query.await("SHOW VARIABLES LIKE 'basedir'")

if not (baseDirRes and baseDirRes[1] and baseDirRes[1].Value) then
return nil
end

local baseDir = baseDirRes[1].Value:gsub('[\\/]+$', '')

if platform == 'linux' then
return baseDir .. '/bin/mysqldump'
end

return baseDir .. '\\bin\\mysqldump.exe' -- windows
end

Parameter​

NameTypeDescription
platformstringชื่อแพลตฟอร์มที่เซิร์ฟเวอร์กำลังทำงานอยู่ เช่น windows หรือ linux

Return​

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

FormatServerBackupCommand (function)​

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

บรรทัดที่ 95
function DATABASE.FormatServerBackupCommand(dbUser, dbPass, dbHost, dbPort, dbName, cmdName, backupPath)
local password = (dbPass and ('-p"%s"'):format(dbPass) or '')
local host = (dbHost and ('-h "%s"'):format(dbHost) or '')
local port = (dbPort and ('-P %s'):format(dbPort) or '')

return ('"%s" -u "%s" %s %s %s --single-transaction --quick "%s" > "%s"'):format(
cmdName, dbUser, password, host, port, dbName, backupPath
)
end

Parameter​

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

Return​

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

FormatPlayerBackupCommand (function)​

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

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

return ('"%s" -u "%s" %s %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, host, port, 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)​

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

บรรทัดที่ 132
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)

บรรทัดที่ 139
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)​

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

บรรทัดที่ 149
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)​

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

บรรทัดที่ 168
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)​

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

บรรทัดที่ 185
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 เพื่อใช้ในการ ลบข้อมูล และ สำรองข้อมูล ของผู้เล่น

บรรทัดที่ 198
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
if #rows == 1 then
return rows[1].id
end

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)​

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

บรรทัดที่ 228
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)​

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

บรรทัดที่ 251
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)​

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

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

Parameter​

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

UpdatePlayerConnection (function)​

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

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

Parameter​

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

UpdatePlayerLeaveDays (function)​

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

บรรทัดที่ 276
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)​

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

บรรทัดที่ 293
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)​

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

บรรทัดที่ 308
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จำนวนแถว ที่ดำเนินการลบข้อมูลในตาราง