-3

I would like to serialize a table so that I can insert it into a database and retrieve it later on. How would I do this?

hjpotter92
  • 78,589
  • 36
  • 144
  • 183
Tom F
  • 807
  • 6
  • 20

2 Answers2

0

maybe like this https://gist.github.com/rangercyh/5814003

local szStr = ""
function print_lua_table (lua_table, indent)
    indent = indent or 0
    for k, v in pairs(lua_table) do
        if type(k) == "string" then
            k = string.format("%q", k)
        end
        local szSuffix = ""
        if type(v) == "table" then
            szSuffix = "{"
        end
        local szPrefix = string.rep("    ", indent)
        formatting = szPrefix.."["..k.."]".." = "..szSuffix
        if type(v) == "table" then
            szStr = szStr..formatting
            print_lua_table(v, indent + 1)
            szStr = szStr..szPrefix.."},"
        else
            local szValue = ""
            if type(v) == "string" then
                szValue = string.format("%q", v)
            else
                szValue = tostring(v)
            end
            szStr = szStr..formatting..szValue..","
        end
    end
end
rangercyh
  • 37
  • 4
0

How to serialize Lua value nicely?

local serialize
do
    local num_fmt = '%.17g'
    local NaN_serialized = {  -- This idea was stolen from lua-nucleo
        [num_fmt:format(1/0)] = '1/0',
        [num_fmt:format(-1/0)] = '-1/0',
        [num_fmt:format(0/0)] = '0/0'
    }
    local function serialize_table(t, indent)
        indent = indent or ''
        local new_indent = indent..'\t'
        if next(t) == nil then
            return '{}'
        else
            local lines = {}
            local function add_line(key)
                local ser_key = key
                if type(key) ~= 'string' or not key:find'^[%a_][%w_]*$' then
                    ser_key = '['..serialize(key, new_indent)..']'
                end
                table.insert(lines, 
                    ser_key..' = '..serialize(t[key], new_indent))
            end
            local other_keys = {}
            local keys = setmetatable({number = {}, string = {}}, 
                {__index = function() return other_keys end})
            for k in pairs(t) do
                table.insert(keys[type(k)], k)
            end
            table.sort(keys.number)
            table.sort(keys.string)
            for _, k in ipairs(keys.number) do
                add_line(k)
            end
            for _, k in ipairs(keys.string) do
                add_line(k)
            end
            for _, k in ipairs(other_keys) do
                add_line(k)
            end
            return '{\n'..new_indent..table.concat(lines, ',\n'..new_indent)
                ..'\n'..indent..'}'
        end
    end

    function serialize(v, indent)
        if type(v) == 'string' then
            return ('%q'):format(v)
        elseif type(v) == 'boolean' then
            return tostring(v)
        elseif type(v) == 'nil' then
            return tostring(v)
        elseif type(v) == 'number' then
            return (num_fmt:format(v):gsub('^.*', NaN_serialized))
        elseif type(v) == 'table' then
            return serialize_table(v, indent)
        else
            error('Can not serialize '..type(v))
        end
    end
end

-- What it can:
print(serialize(math.huge))
print(serialize'"What\'s up?"\n\t123')
print(serialize{{}, {{}}})

-- And what it can not:
local t = {}
local tt = {[t] = t}
print(serialize(tt)) -- tt is not a tree, so it was serialized incorrectly
Egor Skriptunoff
  • 23,359
  • 2
  • 34
  • 64