Redis Lua区分空数组和对象 [英] Redis Lua Differetiating empty array and object

查看:179
本文介绍了Redis Lua区分空数组和对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在Redis 3.2中使用脚本在json对象中设置特定值时,我在cjson lua中遇到了该错误.

I encountered this bug in cjson lua when I was using a script in redis 3.2 to set a particular value in a json object.

当前,redis中的lua不能区分空的json数组或空的json对象.序列化其中包含数组的json对象时,这会导致严重的问题.

Currently, the lua in redis does not differentiate between an empty json array or an empty json object. Which causes serious problems when serialising json objects that have arrays within them.

eval "local json_str = '{\"items\":[],\"properties\":{}}' return cjson.encode(cjson.decode(json_str))" 0

结果:

"{\"items\":{},\"properties\":{}}"

我找到了此解决方案 https://github.com/mpx/lua-cjson/issues/11 ,但是我无法在redis脚本中实现.

I found this solution https://github.com/mpx/lua-cjson/issues/11 but I wasn't able to implement in a redis script.

这是失败的尝试:

eval 

"function cjson.mark_as_array(t) 
local mt = getmetatable(t) or {} 
mt.__is_cjson_array = true 
return setmetatable(t, mt) 
end 
function cjson.is_marked_as_array(t) 
local mt = getmetatable(t) 
return mt and mt.__is_cjson_array end 
local json_str = '{\"items\":[],\"properties\":{}}' 
return cjson.encode(cjson.decode(json_str))" 

0

感谢任何帮助或指针.

推荐答案

有两个计划.

  1. 修改lua-cjson源代码并编译redis,单击通过代码固定:

    local now = redis.call("time")
    -- local timestamp = tonumber(now[1]) * 1000 + math.floor(now[2]/1000)
    math.randomseed(now[2])
    local emptyFlag = "empty_" .. now[1] .. "_" .. now[2] .. "_" .. math.random(10000)
    local emptyArrays = {}
    local function emptyArray()
        if cjson.as_array then
            -- cjson fixed:  https://github.com/xiyuan-fengyu/redis-lua-cjson-empty-table-fix
            local arr = {}
            setmetatable(arr, cjson.as_array)
            return arr
        else
            -- plan 2
            local arr = {}
            table.insert(emptyArrays, arr)
            return arr
        end
    end
    
    local function toJsonStr(obj)
        if #emptyArrays > 0 then
            -- plan 2
            for i, item in ipairs(emptyArrays) do
                if #item == 0 then
                    -- empty array, insert a special mark
                    table.insert(item, 1, emptyFlag)
                end
            end
    
            local jsonStr = cjson.encode(obj)
            -- replace empty array
            jsonStr = (string.gsub(jsonStr, '%["' .. emptyFlag ..  '"]', "[]"))
    
            for i, item in ipairs(emptyArrays) do
                if item[1] == emptyFlag then
                    table.remove(item, 1)
                end
            end
            return jsonStr
        else
            return cjson.encode(obj)
        end
    end
    
    
    -- example
    local arr = emptyArray()
    local str = toJsonStr(arr)
    print(str) -- "[]"
    

    这篇关于Redis Lua区分空数组和对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆