webmcp

view libraries/mondelefant/mondelefant_atom_connector.lua @ 399:ef3201ed67f5

Bug in <db_handle>:try_query(...) fixed, which caused errors when result contains more than two columns (bug introduced by changeset fb98b17056e5)
author jbe
date Sun Jan 03 21:15:57 2016 +0100 (2016-01-03)
parents fb98b17056e5
children 8b8ebcb87034
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
183 function mondelefant.save_mutability_state(value)
184 local jsontype = json.type(value)
185 if jsontype == "object" or jsontype == "array" then
186 return tostring(value)
187 end
188 end
190 function mondelefant.verify_mutability_state(value, state)
191 return tostring(value) ~= state
192 end
195 return _M
198 --[[
200 db = assert(mondelefant.connect{engine='postgresql', dbname='test'})
201 result = db:query{'SELECT ? + 1', atom.date{ year=1999, month=12, day=31}}
202 print(result[1][1].year)
204 --]]

Impressum / About Us