webmcp
diff libraries/mondelefant/mondelefant_atom_connector.lua @ 548:a006593b747c
Basic support for database array types (integers and strings)
author | jbe |
---|---|
date | Mon Oct 21 19:55:13 2019 +0200 (2019-10-21) |
parents | b29e082cafb8 |
children | 77355fe3b1cc |
line diff
1.1 --- a/libraries/mondelefant/mondelefant_atom_connector.lua Sat Oct 19 20:45:35 2019 +0200 1.2 +++ b/libraries/mondelefant/mondelefant_atom_connector.lua Mon Oct 21 19:55:13 2019 +0200 1.3 @@ -93,6 +93,19 @@ 1.4 return conn:quote_string(tostring(value)) .. "::time" 1.5 end 1.6 1.7 +input_converters["table"] = function(conn, value) -- integer and text arrays 1.8 + -- TODO: support more types 1.9 + local parts = { "{" } 1.10 + for i, v in ipairs(value) do 1.11 + if i > 1 then parts[#parts+1] = "," end 1.12 + parts[#parts+1] = '"' 1.13 + parts[#parts+1] = string.gsub(tostring(v), '[\\"]', '\\%0') 1.14 + parts[#parts+1] = '"' 1.15 + end 1.16 + parts[#parts+1] = "}" 1.17 + return conn:quote_string(table.concat(parts)) 1.18 +end 1.19 + 1.20 1.21 output_converters = setmetatable({}, { __mode = "k" }) 1.22 1.23 @@ -108,7 +121,7 @@ 1.24 1.25 output_converters.date = function(str) return atom.date:load(str) end 1.26 1.27 -local timestamp_loader_func = function(str) 1.28 +local function timestamp_loader_func(str) 1.29 local year, month, day, hour, minute, second = string.match( 1.30 str, 1.31 "^([0-9][0-9][0-9][0-9])%-([0-9][0-9])%-([0-9][0-9]) ([0-9]?[0-9]):([0-9][0-9]):([0-9][0-9])" 1.32 @@ -129,7 +142,7 @@ 1.33 output_converters.timestamp = timestamp_loader_func 1.34 output_converters.timestamptz = timestamp_loader_func 1.35 1.36 -local time_loader_func = function(str) 1.37 +local function time_loader_func(str) 1.38 local hour, minute, second = string.match( 1.39 str, 1.40 "^([0-9]?[0-9]):([0-9][0-9]):([0-9][0-9])" 1.41 @@ -147,7 +160,7 @@ 1.42 output_converters.time = time_loader_func 1.43 output_converters.timetz = time_loader_func 1.44 1.45 -local json_loader_func = function(str) 1.46 +local function json_loader_func(str) 1.47 return assert(json.import(str)) 1.48 end 1.49 output_converters.json = json_loader_func 1.50 @@ -187,11 +200,51 @@ 1.51 if value == nil then 1.52 return nil 1.53 else 1.54 - local converter = output_converters[info.type] 1.55 - if converter then 1.56 - return converter(value) 1.57 + local array_type = string.match(info.type, "^(.*)_array$") 1.58 + if array_type then 1.59 + local result = {} 1.60 + local count = 0 1.61 + local inner_converter = output_converters[array_type] 1.62 + if not inner_converter then 1.63 + inner_converter = function(x) return x end 1.64 + end 1.65 + value = string.match(value, "^{(.*)}$") 1.66 + if not value then 1.67 + error("Could not parse database array") 1.68 + end 1.69 + local pos = 1 1.70 + while pos <= #value do 1.71 + count = count + 1 1.72 + if string.find(value, '^""$', pos) then 1.73 + result[count] = inner_converter("") 1.74 + pos = pos + 2 1.75 + elseif string.find(value, '^"",', pos) then 1.76 + result[count] = inner_converter("") 1.77 + pos = pos + 3 1.78 + elseif string.find(value, '^"', pos) then 1.79 + local p1, p2, entry = string.find(value, '^"(.-[^\\])",', pos) 1.80 + if not p1 then 1.81 + p1, p2, entry = string.find(value, '^"(.*[^\\])"$', pos) 1.82 + end 1.83 + if not entry then error("Could not parse database array") end 1.84 + entry = string.gsub(entry, "\\(.)", "%1") 1.85 + result[count] = inner_converter(entry) 1.86 + pos = p2 + 1 1.87 + else 1.88 + local p1, p2, entry = string.find(value, '^(.-),', pos) 1.89 + if not p1 then p1, p2, entry = string.find(value, '^(.*)$', pos) end 1.90 + result[count] = inner_converter(entry) 1.91 + pos = p2 + 1 1.92 + end 1.93 + end 1.94 + return result 1.95 else 1.96 - return value 1.97 + local converter = output_converters[info.type] 1.98 + if converter then 1.99 + return converter(value) 1.100 + else 1.101 + return value 1.102 + end 1.103 end 1.104 end 1.105 end