csvdatad.lua 2.83 KB
local sharedata = require "skynet.sharedata"
local skynet = require "skynet"
local lfs = require "lfs"
local redisproxy = require "shared.redisproxy"
require "shared.init"
require "utils.init"
require "csvdata.init"
require "skynet.manager"
require "RedisKeys"

-- local csvdb = {}

local function formatFileName(filename)
	filename = string.trim(filename)
	local basename = filename:match("([^/]+)%.lua$")
	if not basename then return end
	local loadname = filename:match("^src/([^.]+)%.lua$")
	loadname = loadname:gsub('/', '.')
	return basename, loadname
end

local function travCsv(rootPath, pathes)
	pathes = pathes or {}
	local modified = false
	local ok, files, iter = pcall(lfs.dir, rootPath)
	if not ok then return modified end
	for entry in files, iter do
		-- 过滤 . 开始的字符串包括 . .. .git .开头的文件名
		if string.byte(entry, 1) ~= 46 then
			local pathfile = rootPath .. '/' .. entry
			local attrs = lfs.attributes(pathfile)
			if attrs.mode == 'directory' then
				modified = travCsv(pathfile, pathes) or modified
			else
				local basename, loadname = formatFileName(pathfile)
				if basename then
					if tonum(pathes[loadname]) < attrs.modification then
						modified = true
						pathes[loadname] = attrs.modification
					end
					if basename == "init" or basename == "init_adv" then
						require(loadname)
					end
				end
			end
		end
	end
	return modified
end

-- 每分钟检查是否有更改
local file2timeMap = {}
local function handle_timeout()
	if travCsv("src/csvdata", file2timeMap) then
		sharedata.update("csvdata", csvdb)
	end
	skynet.timeout(100*5, handle_timeout)
end

-- 重新加载csvdb


local CMD = {}

function CMD.reload(code)
	csvdb = csvdb or {}
	
	local ok, func = pcall(load, code)
	if ok then
		ok = pcall(func)
	end
	if not ok then
		skynet.error("reload_csvdata error by code " .. code)
		return 'error'
	end

	sharedata.update("csvdata", csvdb)
	return 'ok'
end

--更新已经存在的
function CMD.hotfix(fieldss)
	csvdb = csvdb or {}
	for _, fields in ipairs(fieldss) do
		if #fields >= 3 and (type(fields[#fields]) == 'number' or type(fields[#fields]) == 'string') then
			local temp = csvdb
			local ok = false
			for i = 1, #fields - 1 do
				if type(temp) ~= 'table' then break end
				if type(fields[i]) ~= 'number' and type(fields[i]) ~= 'string' then break end
				if i == #fields - 1 then
					if type(temp[fields[i]]) ~= 'number' and type(temp[fields[i]]) ~= 'string' then break end
					temp[fields[i]] = fields[#fields]
				else
					temp = temp[fields[i]]
				end
			end
		end
	end
	sharedata.update("csvdata", csvdb)
	return 'ok'
end

skynet.start(function ()
	travCsv("src/csvdata", file2timeMap)
	sharedata.new("csvdata", csvdb)
	-- handle_timeout()

	skynet.dispatch("lua", function(_, _, command, ...)
		local f = CMD[command]
		skynet.ret(skynet.pack(f(...)))
	end)

	skynet.register "CSVDATA"
end)