webmcp

view libraries/mondelefant/mondelefant_atom_connector.lua @ 466:2751b6b81c23

Minor efficiency enhancement in <db_object>:try_save() method
author jbe
date Mon Nov 07 19:32:51 2016 +0100 (2016-11-07)
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 --]]

Impressum / About Us