webmcp
view libraries/mondelefant/mondelefant_atom_connector.lua @ 471:a9fea293b2d6
New function format.file_path_element(...)
| author | jbe | 
|---|---|
| date | Thu May 25 02:46:23 2017 +0200 (2017-05-25) | 
| parents | 8b8ebcb87034 | 
| children | b29e082cafb8 | 
 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 integer_string = string.format("%i", value)
    47   if tonumber(integer_string) == value then
    48     return integer_string
    49   else
    50     local number_string = tostring(value)
    51     if string.find(number_string, "^[0-9.e+-]+$") then
    52       return number_string
    53     else
    54       return "'NaN'"
    55     end
    56   end
    57 end
    59 input_converters[atom.fraction] = function(conn, value)
    60   if value.invalid then
    61     return "'NaN'"
    62   else
    63     local n, d = tostring(value.numerator), tostring(value.denominator)
    64     if string.find(n, "^%-?[0-9]+$") and string.find(d, "^%-?[0-9]+$") then
    65       return "(" .. n .. "::numeric / " .. d .. "::numeric)"
    66     else
    67       return "'NaN'"
    68     end
    69   end
    70 end
    72 input_converters[atom.date] = function(conn, value)
    73   return conn:quote_string(tostring(value)) .. "::date"
    74 end
    76 input_converters[atom.timestamp] = function(conn, value)
    77   return conn:quote_string(tostring(value))  -- don't define type
    78 end
    80 input_converters[atom.time] = function(conn, value)
    81   return conn:quote_string(tostring(value)) .. "::time"
    82 end
    85 output_converters = setmetatable({}, { __mode = "k" })
    87 output_converters.int8 = function(str) return atom.integer:load(str) end
    88 output_converters.int4 = function(str) return atom.integer:load(str) end
    89 output_converters.int2 = function(str) return atom.integer:load(str) end
    91 output_converters.numeric = function(str) return atom.number:load(str) end
    92 output_converters.float4  = function(str) return atom.number:load(str) end
    93 output_converters.float8  = function(str) return atom.number:load(str) end
    95 output_converters.bool = function(str) return atom.boolean:load(str) end
    97 output_converters.date = function(str) return atom.date:load(str) end
    99 local timestamp_loader_func = function(str)
   100   local year, month, day, hour, minute, second = string.match(
   101     str,
   102     "^([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])"
   103   )
   104   if year then
   105     return atom.timestamp{
   106       year   = tonumber(year),
   107       month  = tonumber(month),
   108       day    = tonumber(day),
   109       hour   = tonumber(hour),
   110       minute = tonumber(minute),
   111       second = tonumber(second)
   112     }
   113   else
   114     return atom.timestamp.invalid
   115   end
   116 end
   117 output_converters.timestamp = timestamp_loader_func
   118 output_converters.timestamptz = timestamp_loader_func
   120 local time_loader_func = function(str)
   121   local hour, minute, second = string.match(
   122     str,
   123     "^([0-9]?[0-9]):([0-9][0-9]):([0-9][0-9])"
   124   )
   125   if hour then
   126     return atom.time{
   127       hour   = tonumber(hour),
   128       minute = tonumber(minute),
   129       second = tonumber(second)
   130     }
   131   else
   132     return atom.time.invalid
   133   end
   134 end
   135 output_converters.time = time_loader_func
   136 output_converters.timetz = time_loader_func
   138 local json_loader_func = function(str)
   139   return assert(json.import(str))
   140 end
   141 output_converters.json = json_loader_func
   142 output_converters.jsonb = json_loader_func
   144 mondelefant.postgresql_connection_prototype.type_mappings = {
   145   int8 = atom.integer,
   146   int4 = atom.integer,
   147   int2 = atom.integer,
   148   bool = atom.boolean,
   149   date = atom.date,
   150   timestamp = atom.timestamp,
   151   time = atom.time,
   152   text = atom.string,
   153   varchar = atom.string,
   154   json = json,
   155   jsonb = json,
   156 }
   159 function mondelefant.postgresql_connection_prototype.input_converter(conn, value, info)
   160   if value == nil then
   161     return "NULL"
   162   else
   163     local converter =
   164       input_converters[getmetatable(value)] or
   165       input_converters[type(value)]
   166     if converter then
   167       return converter(conn, value)
   168     else
   169       return conn:quote_string(tostring(value))
   170     end
   171   end
   172 end
   174 function mondelefant.postgresql_connection_prototype.output_converter(conn, value, info)
   175   if value == nil then
   176     return nil
   177   else
   178     local converter = output_converters[info.type]
   179     if converter then
   180       return converter(value)
   181     else
   182       return value
   183     end
   184   end
   185 end
   188 function mondelefant.save_mutability_state(value)
   189   local jsontype = json.type(value)
   190   if jsontype == "object" or jsontype == "array" then
   191     return tostring(value)
   192   end
   193 end
   195 function mondelefant.verify_mutability_state(value, state)
   196   return tostring(value) ~= state
   197 end
   200 return _M
   203 --[[
   205 db = assert(mondelefant.connect{engine='postgresql', dbname='test'})
   206 result = db:query{'SELECT ? + 1', atom.date{ year=1999, month=12, day=31}}
   207 print(result[1][1].year)
   209 --]]
