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  }

Impressum / About Us