webmcp
view libraries/mondelefant/mondelefant_atom_connector.lua @ 225:cd7fce06440d
Initialize listeners list in framework/bin/mcp.lua
| author | jbe | 
|---|---|
| date | Fri Feb 27 22:26:12 2015 +0100 (2015-02-27) | 
| parents | 1a85110cdbe2 | 
| children | 11ef7ab67e43 | 
 line source
     1 #!/usr/bin/env lua
     3 local _G             = _G
     4 local _VERSION       = _VERSION
     5 local assert         = assert
     6 local error          = error
     7 local getmetatable   = getmetatable
     8 local ipairs         = ipairs
     9 local next           = next
    10 local pairs          = pairs
    11 local print          = print
    12 local rawequal       = rawequal
    13 local rawget         = rawget
    14 local rawlen         = rawlen
    15 local rawset         = rawset
    16 local select         = select
    17 local setmetatable   = setmetatable
    18 local tonumber       = tonumber
    19 local tostring       = tostring
    20 local type           = type
    22 local math      = math
    23 local string    = string
    24 local table     = table
    26 local mondelefant = require("mondelefant")
    27 local atom        = require("atom")
    28 local json        = require("json")
    30 local _M = {}
    31 if _ENV then
    32   _ENV = _M
    33 else
    34   _G[...] = _M
    35   setfenv(1, _M)
    36 end
    39 input_converters = setmetatable({}, { __mode = "k" })
    41 input_converters["boolean"] = function(conn, value)
    42   if value then return "TRUE" else return "FALSE" end
    43 end
    45 input_converters["number"] = function(conn, value)
    46   local str = tostring(value)
    47   if string.find(str, "^[0-9%.e%-]+$") then
    48     return str
    49   else
    50     return "'NaN'"
    51   end
    52 end
    54 input_converters[atom.fraction] = function(conn, value)
    55   if value.invalid then
    56     return "'NaN'"
    57   else
    58     local n, d = tostring(value.numerator), tostring(value.denominator)
    59     if string.find(n, "^%-?[0-9]+$") and string.find(d, "^%-?[0-9]+$") then
    60       return "(" .. n .. "::numeric / " .. d .. "::numeric)"
    61     else
    62       return "'NaN'"
    63     end
    64   end
    65 end
    67 input_converters[atom.date] = function(conn, value)
    68   return conn:quote_string(tostring(value)) .. "::date"
    69 end
    71 input_converters[atom.timestamp] = function(conn, value)
    72   return conn:quote_string(tostring(value))  -- don't define type
    73 end
    75 input_converters[atom.time] = function(conn, value)
    76   return conn:quote_string(tostring(value)) .. "::time"
    77 end
    80 output_converters = setmetatable({}, { __mode = "k" })
    82 output_converters.int8 = function(str) return atom.integer:load(str) end
    83 output_converters.int4 = function(str) return atom.integer:load(str) end
    84 output_converters.int2 = function(str) return atom.integer:load(str) end
    86 output_converters.numeric = function(str) return atom.number:load(str) end
    87 output_converters.float4  = function(str) return atom.number:load(str) end
    88 output_converters.float8  = function(str) return atom.number:load(str) end
    90 output_converters.bool = function(str) return atom.boolean:load(str) end
    92 output_converters.date = function(str) return atom.date:load(str) end
    94 local timestamp_loader_func = function(str)
    95   local year, month, day, hour, minute, second = string.match(
    96     str,
    97     "^([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])"
    98   )
    99   if year then
   100     return atom.timestamp{
   101       year   = tonumber(year),
   102       month  = tonumber(month),
   103       day    = tonumber(day),
   104       hour   = tonumber(hour),
   105       minute = tonumber(minute),
   106       second = tonumber(second)
   107     }
   108   else
   109     return atom.timestamp.invalid
   110   end
   111 end
   112 output_converters.timestamp = timestamp_loader_func
   113 output_converters.timestamptz = timestamp_loader_func
   115 local time_loader_func = function(str)
   116   local hour, minute, second = string.match(
   117     str,
   118     "^([0-9]?[0-9]):([0-9][0-9]):([0-9][0-9])"
   119   )
   120   if hour then
   121     return atom.time{
   122       hour   = tonumber(hour),
   123       minute = tonumber(minute),
   124       second = tonumber(second)
   125     }
   126   else
   127     return atom.time.invalid
   128   end
   129 end
   130 output_converters.time = time_loader_func
   131 output_converters.timetz = time_loader_func
   133 local json_loader_func = function(str)
   134   return assert(json.import(str))
   135 end
   136 output_converters.json = json_loader_func
   137 output_converters.jsonb = json_loader_func
   139 mondelefant.postgresql_connection_prototype.type_mappings = {
   140   int8 = atom.integer,
   141   int4 = atom.integer,
   142   int2 = atom.integer,
   143   bool = atom.boolean,
   144   date = atom.date,
   145   timestamp = atom.timestamp,
   146   time = atom.time,
   147   text = atom.string,
   148   varchar = atom.string,
   149   json = json,
   150   jsonb = json,
   151 }
   154 function mondelefant.postgresql_connection_prototype.input_converter(conn, value, info)
   155   if value == nil then
   156     return "NULL"
   157   else
   158     local converter =
   159       input_converters[getmetatable(value)] or
   160       input_converters[type(value)]
   161     if converter then
   162       return converter(conn, value)
   163     else
   164       return conn:quote_string(tostring(value))
   165     end
   166   end
   167 end
   169 function mondelefant.postgresql_connection_prototype.output_converter(conn, value, info)
   170   if value == nil then
   171     return nil
   172   else
   173     local converter = output_converters[info.type]
   174     if converter then
   175       return converter(value)
   176     else
   177       return value
   178     end
   179   end
   180 end
   182 return _M
   185 --[[
   187 db = assert(mondelefant.connect{engine='postgresql', dbname='test'})
   188 result = db:query{'SELECT ? + 1', atom.date{ year=1999, month=12, day=31}}
   189 print(result[1][1].year)
   191 --]]
