webmcp

annotate 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
rev   line source
jbe/bsw@0 1 #!/usr/bin/env lua
jbe/bsw@0 2
jbe/bsw@0 3 local _G = _G
jbe/bsw@0 4 local _VERSION = _VERSION
jbe/bsw@0 5 local assert = assert
jbe/bsw@0 6 local error = error
jbe/bsw@0 7 local getmetatable = getmetatable
jbe/bsw@0 8 local ipairs = ipairs
jbe/bsw@0 9 local next = next
jbe/bsw@0 10 local pairs = pairs
jbe/bsw@0 11 local print = print
jbe/bsw@0 12 local rawequal = rawequal
jbe/bsw@0 13 local rawget = rawget
jbe@64 14 local rawlen = rawlen
jbe/bsw@0 15 local rawset = rawset
jbe/bsw@0 16 local select = select
jbe/bsw@0 17 local setmetatable = setmetatable
jbe/bsw@0 18 local tonumber = tonumber
jbe/bsw@0 19 local tostring = tostring
jbe/bsw@0 20 local type = type
jbe/bsw@0 21
jbe/bsw@0 22 local math = math
jbe/bsw@0 23 local string = string
jbe@64 24 local table = table
jbe/bsw@0 25
jbe/bsw@0 26 local mondelefant = require("mondelefant")
jbe/bsw@0 27 local atom = require("atom")
jbe@177 28 local json = require("json")
jbe/bsw@0 29
jbe@64 30 local _M = {}
jbe@64 31 if _ENV then
jbe@64 32 _ENV = _M
jbe@64 33 else
jbe@64 34 _G[...] = _M
jbe@64 35 setfenv(1, _M)
jbe@64 36 end
jbe/bsw@0 37
jbe/bsw@0 38
jbe/bsw@0 39 input_converters = setmetatable({}, { __mode = "k" })
jbe/bsw@0 40
jbe/bsw@0 41 input_converters["boolean"] = function(conn, value)
jbe/bsw@0 42 if value then return "TRUE" else return "FALSE" end
jbe/bsw@0 43 end
jbe/bsw@0 44
jbe/bsw@0 45 input_converters["number"] = function(conn, value)
jbe@419 46 local integer_string = string.format("%i", value)
jbe@419 47 if tonumber(integer_string) == value then
jbe@419 48 return integer_string
jbe/bsw@0 49 else
jbe@419 50 local number_string = tostring(value)
jbe@419 51 if string.find(number_string, "^[0-9.e+-]+$") then
jbe@419 52 return number_string
jbe@419 53 else
jbe@419 54 return "'NaN'"
jbe@419 55 end
jbe/bsw@0 56 end
jbe/bsw@0 57 end
jbe/bsw@0 58
jbe/bsw@0 59 input_converters[atom.fraction] = function(conn, value)
jbe/bsw@0 60 if value.invalid then
jbe/bsw@0 61 return "'NaN'"
jbe/bsw@0 62 else
jbe/bsw@0 63 local n, d = tostring(value.numerator), tostring(value.denominator)
jbe/bsw@0 64 if string.find(n, "^%-?[0-9]+$") and string.find(d, "^%-?[0-9]+$") then
jbe/bsw@0 65 return "(" .. n .. "::numeric / " .. d .. "::numeric)"
jbe/bsw@0 66 else
jbe/bsw@0 67 return "'NaN'"
jbe/bsw@0 68 end
jbe/bsw@0 69 end
jbe/bsw@0 70 end
jbe/bsw@0 71
jbe/bsw@0 72 input_converters[atom.date] = function(conn, value)
jbe/bsw@0 73 return conn:quote_string(tostring(value)) .. "::date"
jbe/bsw@0 74 end
jbe/bsw@0 75
jbe/bsw@0 76 input_converters[atom.timestamp] = function(conn, value)
jbe/bsw@0 77 return conn:quote_string(tostring(value)) -- don't define type
jbe/bsw@0 78 end
jbe/bsw@0 79
jbe/bsw@0 80 input_converters[atom.time] = function(conn, value)
jbe/bsw@0 81 return conn:quote_string(tostring(value)) .. "::time"
jbe/bsw@0 82 end
jbe/bsw@0 83
jbe/bsw@0 84
jbe/bsw@0 85 output_converters = setmetatable({}, { __mode = "k" })
jbe/bsw@0 86
jbe/bsw@0 87 output_converters.int8 = function(str) return atom.integer:load(str) end
jbe/bsw@0 88 output_converters.int4 = function(str) return atom.integer:load(str) end
jbe/bsw@0 89 output_converters.int2 = function(str) return atom.integer:load(str) end
jbe/bsw@0 90
jbe/bsw@0 91 output_converters.numeric = function(str) return atom.number:load(str) end
jbe/bsw@0 92 output_converters.float4 = function(str) return atom.number:load(str) end
jbe/bsw@0 93 output_converters.float8 = function(str) return atom.number:load(str) end
jbe/bsw@0 94
jbe/bsw@0 95 output_converters.bool = function(str) return atom.boolean:load(str) end
jbe/bsw@0 96
jbe/bsw@0 97 output_converters.date = function(str) return atom.date:load(str) end
jbe/bsw@0 98
jbe/bsw@0 99 local timestamp_loader_func = function(str)
jbe@1 100 local year, month, day, hour, minute, second = string.match(
jbe/bsw@0 101 str,
jbe@1 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])"
jbe/bsw@0 103 )
jbe@1 104 if year then
jbe/bsw@0 105 return atom.timestamp{
jbe@1 106 year = tonumber(year),
jbe@1 107 month = tonumber(month),
jbe@1 108 day = tonumber(day),
jbe/bsw@0 109 hour = tonumber(hour),
jbe/bsw@0 110 minute = tonumber(minute),
jbe/bsw@0 111 second = tonumber(second)
jbe/bsw@0 112 }
jbe/bsw@0 113 else
jbe/bsw@0 114 return atom.timestamp.invalid
jbe/bsw@0 115 end
jbe/bsw@0 116 end
jbe/bsw@0 117 output_converters.timestamp = timestamp_loader_func
jbe/bsw@0 118 output_converters.timestamptz = timestamp_loader_func
jbe/bsw@0 119
jbe/bsw@0 120 local time_loader_func = function(str)
jbe@1 121 local hour, minute, second = string.match(
jbe/bsw@0 122 str,
jbe@1 123 "^([0-9]?[0-9]):([0-9][0-9]):([0-9][0-9])"
jbe/bsw@0 124 )
jbe@1 125 if hour then
jbe/bsw@0 126 return atom.time{
jbe/bsw@0 127 hour = tonumber(hour),
jbe/bsw@0 128 minute = tonumber(minute),
jbe/bsw@0 129 second = tonumber(second)
jbe/bsw@0 130 }
jbe/bsw@0 131 else
jbe/bsw@0 132 return atom.time.invalid
jbe/bsw@0 133 end
jbe/bsw@0 134 end
jbe/bsw@0 135 output_converters.time = time_loader_func
jbe/bsw@0 136 output_converters.timetz = time_loader_func
jbe/bsw@0 137
jbe@178 138 local json_loader_func = function(str)
jbe@178 139 return assert(json.import(str))
jbe@178 140 end
jbe@178 141 output_converters.json = json_loader_func
jbe@178 142 output_converters.jsonb = json_loader_func
jbe@176 143
jbe/bsw@0 144 mondelefant.postgresql_connection_prototype.type_mappings = {
jbe/bsw@0 145 int8 = atom.integer,
jbe/bsw@0 146 int4 = atom.integer,
jbe/bsw@0 147 int2 = atom.integer,
jbe/bsw@0 148 bool = atom.boolean,
jbe/bsw@0 149 date = atom.date,
jbe/bsw@0 150 timestamp = atom.timestamp,
jbe/bsw@0 151 time = atom.time,
jbe/bsw@0 152 text = atom.string,
jbe/bsw@0 153 varchar = atom.string,
jbe@176 154 json = json,
jbe@176 155 jsonb = json,
jbe/bsw@0 156 }
jbe/bsw@0 157
jbe/bsw@0 158
jbe/bsw@0 159 function mondelefant.postgresql_connection_prototype.input_converter(conn, value, info)
jbe/bsw@0 160 if value == nil then
jbe/bsw@0 161 return "NULL"
jbe/bsw@0 162 else
jbe/bsw@0 163 local converter =
jbe/bsw@0 164 input_converters[getmetatable(value)] or
jbe/bsw@0 165 input_converters[type(value)]
jbe/bsw@0 166 if converter then
jbe/bsw@0 167 return converter(conn, value)
jbe/bsw@0 168 else
jbe/bsw@0 169 return conn:quote_string(tostring(value))
jbe/bsw@0 170 end
jbe/bsw@0 171 end
jbe/bsw@0 172 end
jbe/bsw@0 173
jbe/bsw@0 174 function mondelefant.postgresql_connection_prototype.output_converter(conn, value, info)
jbe/bsw@0 175 if value == nil then
jbe/bsw@0 176 return nil
jbe/bsw@0 177 else
jbe/bsw@0 178 local converter = output_converters[info.type]
jbe/bsw@0 179 if converter then
jbe/bsw@0 180 return converter(value)
jbe/bsw@0 181 else
jbe/bsw@0 182 return value
jbe/bsw@0 183 end
jbe/bsw@0 184 end
jbe/bsw@0 185 end
jbe/bsw@0 186
jbe@374 187
jbe@374 188 function mondelefant.save_mutability_state(value)
jbe@374 189 local jsontype = json.type(value)
jbe@374 190 if jsontype == "object" or jsontype == "array" then
jbe@374 191 return tostring(value)
jbe@374 192 end
jbe@374 193 end
jbe@374 194
jbe@374 195 function mondelefant.verify_mutability_state(value, state)
jbe@375 196 return tostring(value) ~= state
jbe@374 197 end
jbe@374 198
jbe@375 199
jbe@64 200 return _M
jbe@64 201
jbe/bsw@0 202
jbe/bsw@0 203 --[[
jbe/bsw@0 204
jbe/bsw@0 205 db = assert(mondelefant.connect{engine='postgresql', dbname='test'})
jbe/bsw@0 206 result = db:query{'SELECT ? + 1', atom.date{ year=1999, month=12, day=31}}
jbe/bsw@0 207 print(result[1][1].year)
jbe/bsw@0 208
jbe/bsw@0 209 --]]

Impressum / About Us