webmcp
changeset 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 | 75fd8869bc4e |
children | 77355fe3b1cc |
files | libraries/mondelefant/mondelefant_atom_connector.lua libraries/mondelefant/mondelefant_native.c |
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
2.1 --- a/libraries/mondelefant/mondelefant_native.c Sat Oct 19 20:45:35 2019 +0200 2.2 +++ b/libraries/mondelefant/mondelefant_native.c Mon Oct 21 19:55:13 2019 +0200 2.3 @@ -73,6 +73,7 @@ 2.4 case 28: return "xid"; 2.5 case 29: return "cid"; 2.6 case 114: return "json"; 2.7 + case 199: return "json_array"; 2.8 case 600: return "point"; 2.9 case 601: return "lseg"; 2.10 case 602: return "path"; 2.11 @@ -87,18 +88,38 @@ 2.12 case 829: return "macaddr"; 2.13 case 869: return "inet"; 2.14 case 650: return "cidr"; 2.15 + case 1000: return "bool_array"; 2.16 + case 1001: return "bytea_array"; 2.17 + case 1002: return "char_array"; 2.18 + case 1005: return "int2_array"; 2.19 + case 1007: return "int4_array"; 2.20 + case 1009: return "text_array"; 2.21 + case 1015: return "varchar_array"; 2.22 + case 1016: return "int8_array"; 2.23 + case 1021: return "float4_array"; 2.24 + case 1022: return "float8_array"; 2.25 case 1042: return "bpchar"; 2.26 case 1043: return "varchar"; 2.27 case 1082: return "date"; 2.28 case 1083: return "time"; 2.29 case 1114: return "timestamp"; 2.30 + case 1115: return "timestamp_array"; 2.31 + case 1182: return "date_array"; 2.32 + case 1183: return "time_array"; 2.33 case 1184: return "timestamptz"; 2.34 + case 1185: return "timestamptz_array"; 2.35 case 1186: return "interval"; 2.36 + case 1187: return "interval_array"; 2.37 + case 1231: return "numeric_array"; 2.38 case 1266: return "timetz"; 2.39 + case 1270: return "timetz_array"; 2.40 case 1560: return "bit"; 2.41 + case 1561: return "bit_array"; 2.42 case 1562: return "varbit"; 2.43 + case 1563: return "varbit_array"; 2.44 case 1700: return "numeric"; 2.45 case 3802: return "jsonb"; 2.46 + case 3807: return "jsonb_array"; 2.47 default: return NULL; 2.48 } 2.49 }