HomeServer/lualib-src/Server-main/Common/Player/DBData.lua

137 lines
5.0 KiB
Lua
Raw Permalink Normal View History

2024-11-20 15:41:09 +08:00
local skynet = require "skynet"
local oo = require "Class"
local log = require "Log"
local DBData = oo.class()
--检查下是不是有新增的字段
function DBData:CheckNewFields( newTable , initTable)
for key, value in pairs( initTable ) do
if "table" ~= type( value[2] ) then
--非表,如果未给值就必须初始化
if nil == newTable[ value[1] ] then
newTable[value[1] ] = value[2]
end
else
--是表,如果未给值必须初始化
if nil == newTable[ value[1] ] then
newTable[ value[1] ] = {}
end
--遍历子结点
self:CheckNewFields( newTable[ value[1] ] , value[2] )
end
end
end
--遍历用户数据
function DBData:Traversal(newData , oldData)
for key, value in pairs(oldData) do
if "table" ~= type(value[2]) then
newData[value[1]] = value[2]
else
newData[value[1]] = {}
newData[value[1]] = self:Parse( newData[value[1]] , value[1] ,value[2] )
end
end
end
--解析字段
function DBData:Parse( newTable , t1 ,v2 )
if "table" ~= type(v2) then
newTable[t1] =v2
else
for key, value in pairs(v2) do
if "table" ~= type(value[2]) then
newTable[ value[1] ] = value[2]
else
newTable[ value[1] ]= {}
newTable[ value[1] ] = self:Parse(newTable[value[1]] , value[1] , value[2])
end
end
end
return newTable
end
--[[
--需要在这里增加更新玩家字段
function DBData:CheckUserVision( log )
--[[
table.insert(updateData , {"test1",0 }) test1为不存在的字段名0
table.insert(updateData , {"test2",{} }) test2为不存在的字段名
table.insert(updateData , {"test3",{ a = 1 ,b = 2} }) test3为存在的字段名test3是表test3新增a,b字段
--这里添加每个更新版本的玩家字段
local updateData = {}
local sql = ""
self:UpdateDBData( updateData , log )
end
--更新新字段到数据库
function DBData:UpdateDBData(updateData ,log)
log.info("开始更新新字段到数据库")
local newData = {}
local t1 = skynet.GetTime()
self:Traversal(newData , updateData)
--得到数据库中所有玩家数量
local sql = string.format("select count(1) from player" )
local queryData = skynet.server.db:Query(sql)
local id = nil
local userInfo = nil
local jsonInfo = nil
local modifyCount = 0
if #queryData > 0 then
--一次取出太多的数据在内存中,底层会警告,为了更稳固,所以分批读取用户数据进行处理
local curUserCount = tonumber(queryData[1]["count(1)"])
local queryMaxUser = 1000 --每次从数据库中取出玩家数据的数量
local startId = 100000 --帐号的起始ID
local endId = startId + curUserCount --帐号的结束ID
local startPos = 0
local endPos = 0
log.info("数据库总共玩家数量", curUserCount)
for pos = startId, endId , queryMaxUser do
startPos = pos
endPos = startPos + (queryMaxUser - 1)
if endPos > endId then
--如果大于结束ID就获取最终的结束ID
endPos = (startPos + ( endId - startPos)) - 1
end
--根据ID获取用户信息
sql = string.format("select id,data from player where id >= %d and id <= %d",startPos ,endPos )
queryData = skynet.server.db:Query(sql)
log.info(string.format("当前起始ID %d 结束ID %d 的范围 取出数量 %d ",startPos ,endPos , #queryData))
for i = 1, #queryData do
id = tonumber(queryData[i]["id"])
userInfo = queryData[i]["data"]
if userInfo then
jsonInfo = JSON:decode(userInfo)
for key, value in pairs(newData) do
if jsonInfo[ key ] then
for k, v in pairs(value) do
jsonInfo[ key ][ k ] = v
end
else
jsonInfo[ key ] = value
end
end
sql = string.format("update player set data = '%s' where id = %d", JSON:encode(jsonInfo), id)
skynet.server.db:Query(sql)
modifyCount = modifyCount + 1
end
end
end
end
log.info("更新完所有用户需要的时间",skynet.GetTime() - t1, "")
log.info("成功修改玩家数量",modifyCount)
log.info("结束更新新字段到数据库")
end
]]
skynet.server.dbData = DBData
return DBData