webmcp
view libraries/mondelefant/mondelefant_atom_connector.lua @ 42:5ce77ccdd550
Added TODO related to library compilation to Makefile.options
| author | jbe | 
|---|---|
| date | Sat Oct 16 17:55:15 2010 +0200 (2010-10-16) | 
| parents | 985024b16520 | 
| children | 3d43a5cf17c1 | 
 line source
     1 #!/usr/bin/env lua
     3 local _G             = _G
     4 local _VERSION       = _VERSION
     5 local assert         = assert
     6 local collectgarbage = collectgarbage
     7 local dofile         = dofile
     8 local error          = error
     9 local getfenv        = getfenv
    10 local getmetatable   = getmetatable
    11 local ipairs         = ipairs
    12 local load           = load
    13 local loadfile       = loadfile
    14 local loadstring     = loadstring
    15 local module         = module
    16 local next           = next
    17 local pairs          = pairs
    18 local pcall          = pcall
    19 local print          = print
    20 local rawequal       = rawequal
    21 local rawget         = rawget
    22 local rawset         = rawset
    23 local require        = require
    24 local select         = select
    25 local setfenv        = setfenv
    26 local setmetatable   = setmetatable
    27 local tonumber       = tonumber
    28 local tostring       = tostring
    29 local type           = type
    30 local unpack         = unpack
    31 local xpcall         = xpcall
    33 local coroutine = coroutine
    34 local debug     = debug
    35 local io        = io
    36 local math      = math
    37 local os        = os
    38 local package   = package
    39 local string    = string
    41 local mondelefant = require("mondelefant")
    42 local atom        = require("atom")
    44 module(...)
    47 input_converters = setmetatable({}, { __mode = "k" })
    49 input_converters["boolean"] = function(conn, value)
    50   if value then return "TRUE" else return "FALSE" end
    51 end
    53 input_converters["number"] = function(conn, value)
    54   local str = tostring(value)
    55   if string.find(str, "^[0-9%.e%-]+$") then
    56     return str
    57   else
    58     return "'NaN'"
    59   end
    60 end
    62 input_converters[atom.fraction] = function(conn, value)
    63   if value.invalid then
    64     return "'NaN'"
    65   else
    66     local n, d = tostring(value.numerator), tostring(value.denominator)
    67     if string.find(n, "^%-?[0-9]+$") and string.find(d, "^%-?[0-9]+$") then
    68       return "(" .. n .. "::numeric / " .. d .. "::numeric)"
    69     else
    70       return "'NaN'"
    71     end
    72   end
    73 end
    75 input_converters[atom.date] = function(conn, value)
    76   return conn:quote_string(tostring(value)) .. "::date"
    77 end
    79 input_converters[atom.timestamp] = function(conn, value)
    80   return conn:quote_string(tostring(value))  -- don't define type
    81 end
    83 input_converters[atom.time] = function(conn, value)
    84   return conn:quote_string(tostring(value)) .. "::time"
    85 end
    88 output_converters = setmetatable({}, { __mode = "k" })
    90 output_converters.int8 = function(str) return atom.integer:load(str) end
    91 output_converters.int4 = function(str) return atom.integer:load(str) end
    92 output_converters.int2 = function(str) return atom.integer:load(str) end
    94 output_converters.numeric = function(str) return atom.number:load(str) end
    95 output_converters.float4  = function(str) return atom.number:load(str) end
    96 output_converters.float8  = function(str) return atom.number:load(str) end
    98 output_converters.bool = function(str) return atom.boolean:load(str) end
   100 output_converters.date = function(str) return atom.date:load(str) end
   102 local timestamp_loader_func = function(str)
   103   local year, month, day, hour, minute, second = string.match(
   104     str,
   105     "^([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])"
   106   )
   107   if year then
   108     return atom.timestamp{
   109       year   = tonumber(year),
   110       month  = tonumber(month),
   111       day    = tonumber(day),
   112       hour   = tonumber(hour),
   113       minute = tonumber(minute),
   114       second = tonumber(second)
   115     }
   116   else
   117     return atom.timestamp.invalid
   118   end
   119 end
   120 output_converters.timestamp = timestamp_loader_func
   121 output_converters.timestamptz = timestamp_loader_func
   123 local time_loader_func = function(str)
   124   local hour, minute, second = string.match(
   125     str,
   126     "^([0-9]?[0-9]):([0-9][0-9]):([0-9][0-9])"
   127   )
   128   if hour then
   129     return atom.time{
   130       hour   = tonumber(hour),
   131       minute = tonumber(minute),
   132       second = tonumber(second)
   133     }
   134   else
   135     return atom.time.invalid
   136   end
   137 end
   138 output_converters.time = time_loader_func
   139 output_converters.timetz = time_loader_func
   141 mondelefant.postgresql_connection_prototype.type_mappings = {
   142   int8 = atom.integer,
   143   int4 = atom.integer,
   144   int2 = atom.integer,
   145   bool = atom.boolean,
   146   date = atom.date,
   147   timestamp = atom.timestamp,
   148   time = atom.time,
   149   text = atom.string,
   150   varchar = atom.string,
   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
   183 --[[
   185 db = assert(mondelefant.connect{engine='postgresql', dbname='test'})
   186 result = db:query{'SELECT ? + 1', atom.date{ year=1999, month=12, day=31}}
   187 print(result[1][1].year)
   189 --]]
