diff options
Diffstat (limited to 'tex/context/base/util-sql-imp-swiglib.lua')
-rw-r--r-- | tex/context/base/util-sql-imp-swiglib.lua | 1010 |
1 files changed, 505 insertions, 505 deletions
diff --git a/tex/context/base/util-sql-imp-swiglib.lua b/tex/context/base/util-sql-imp-swiglib.lua index f456c9ccb..719620a6f 100644 --- a/tex/context/base/util-sql-imp-swiglib.lua +++ b/tex/context/base/util-sql-imp-swiglib.lua @@ -1,505 +1,505 @@ -if not modules then modules = { } end modules ['util-sql-swiglib'] = {
- version = 1.001,
- comment = "companion to util-sql.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- As the regular library is flawed (i.e. there are crashes in the table
--- construction code) and also not that efficient, Luigi Scarso looked into
--- a swig binding. This is a bit more low level approach but as we stay
--- closer to the original library it's also less dependant.
-
-local concat = table.concat
-local format = string.format
-local lpegmatch = lpeg.match
-local setmetatable, type = setmetatable, type
-local sleep = os.sleep
-
-local trace_sql = false trackers.register("sql.trace", function(v) trace_sql = v end)
-local trace_queries = false trackers.register("sql.queries",function(v) trace_queries = v end)
-local report_state = logs.reporter("sql","swiglib")
-
-local sql = utilities.sql
-local mysql = require("swiglib.mysql.core") -- "5.6"
-
--- inspect(table.sortedkeys(mysql))
-
-local nofretries = 5
-local retrydelay = 1
-
-local cache = { }
-local helpers = sql.helpers
-local methods = sql.methods
-local validspecification = helpers.validspecification
-local querysplitter = helpers.querysplitter
-local dataprepared = helpers.preparetemplate
-local serialize = sql.serialize
-local deserialize = sql.deserialize
-
-local mysql_initialize = mysql.mysql_init
-
-local mysql_open_connection = mysql.mysql_real_connect
-local mysql_execute_query = mysql.mysql_real_query
-local mysql_close_connection = mysql.mysql_close
-
-local mysql_field_seek = mysql.mysql_field_seek
-local mysql_num_fields = mysql.mysql_num_fields
-local mysql_fetch_field = mysql.mysql_fetch_field
-local mysql_num_rows = mysql.mysql_num_rows
-local mysql_fetch_row = mysql.mysql_fetch_row
-local mysql_fetch_lengths = mysql.mysql_fetch_lengths
-local mysql_init = mysql.mysql_init
-local mysql_store_result = mysql.mysql_store_result
-local mysql_free_result = mysql.mysql_free_result
-local mysql_use_result = mysql.mysql_use_result
-
-local mysql_error_message = mysql.mysql_error
-local mysql_options_argument = mysql.mysql_options_argument
-
-local instance = mysql.MYSQL()
-
-local mysql_constant_false = false
-local mysql_constant_true = true
-
--- if mysql_options_argument then
---
--- mysql_constant_false = mysql_options_argument(false) -- 0 "\0"
--- mysql_constant_true = mysql_options_argument(true) -- 1 "\1"
---
--- -- print(swig_type(mysql_constant_false))
--- -- print(swig_type(mysql_constant_true))
---
--- mysql.mysql_options(instance,mysql.MYSQL_OPT_RECONNECT,mysql_constant_true);
---
--- else
---
--- print("")
--- print("incomplete swiglib.mysql interface")
--- print("")
---
--- end
-
-local typemap = mysql.MYSQL_TYPE_VAR_STRING and {
- [mysql.MYSQL_TYPE_VAR_STRING ] = "string",
- [mysql.MYSQL_TYPE_STRING ] = "string",
- [mysql.MYSQL_TYPE_DECIMAL ] = "number",
- [mysql.MYSQL_TYPE_SHORT ] = "number",
- [mysql.MYSQL_TYPE_LONG ] = "number",
- [mysql.MYSQL_TYPE_FLOAT ] = "number",
- [mysql.MYSQL_TYPE_DOUBLE ] = "number",
- [mysql.MYSQL_TYPE_LONGLONG ] = "number",
- [mysql.MYSQL_TYPE_INT24 ] = "number",
- [mysql.MYSQL_TYPE_YEAR ] = "number",
- [mysql.MYSQL_TYPE_TINY ] = "number",
- [mysql.MYSQL_TYPE_TINY_BLOB ] = "binary",
- [mysql.MYSQL_TYPE_MEDIUM_BLOB] = "binary",
- [mysql.MYSQL_TYPE_LONG_BLOB ] = "binary",
- [mysql.MYSQL_TYPE_BLOB ] = "binary",
- [mysql.MYSQL_TYPE_DATE ] = "date",
- [mysql.MYSQL_TYPE_NEWDATE ] = "date",
- [mysql.MYSQL_TYPE_DATETIME ] = "datetime",
- [mysql.MYSQL_TYPE_TIME ] = "time",
- [mysql.MYSQL_TYPE_TIMESTAMP ] = "time",
- [mysql.MYSQL_TYPE_ENUM ] = "set",
- [mysql.MYSQL_TYPE_SET ] = "set",
- [mysql.MYSQL_TYPE_NULL ] = "null",
-}
-
--- real_escape_string
-
-local function finish(t)
- local r = t._result_
- if r then
- mysql_free_result(r)
- end
-end
-
--- will become metatable magic
-
--- local function analyze(result)
--- mysql_field_seek(result,0)
--- local nofrows = mysql_num_rows(result) or 0
--- local noffields = mysql_num_fields(result)
--- local names = { }
--- local types = { }
--- for i=1,noffields do
--- local field = mysql_fetch_field(result)
--- names[i] = field.name
--- types[i] = field.type
--- end
--- return names, types, noffields, nofrows
--- end
-
-local function getcolnames(t)
- return t.names
-end
-
-local function getcoltypes(t)
- return t.types
-end
-
-local function numrows(t)
- return t.nofrows
-end
-
--- swig_type
-
--- local ulongArray_getitem = mysql.ulongArray_getitem
--- local util_getbytearray = mysql.util_getbytearray
-
--- local function list(t)
--- local result = t._result_
--- local row = mysql_fetch_row(result)
--- local len = mysql_fetch_lengths(result)
--- local result = { }
--- for i=1,t.noffields do
--- local r = i - 1 -- zero offset
--- result[i] = util_getbytearray(row,r,ulongArray_getitem(len,r))
--- end
--- return result
--- end
-
--- local function hash(t)
--- local list = util_mysql_fetch_fields_from_current_row(t._result_)
--- local result = t._result_
--- local fields = t.names
--- local row = mysql_fetch_row(result)
--- local len = mysql_fetch_lengths(result)
--- local result = { }
--- for i=1,t.noffields do
--- local r = i - 1 -- zero offset
--- result[fields[i]] = util_getbytearray(row,r,ulongArray_getitem(len,r))
--- end
--- return result
--- end
-
-local util_mysql_fetch_fields_from_current_row = mysql.util_mysql_fetch_fields_from_current_row
-local util_mysql_fetch_all_rows = mysql.util_mysql_fetch_all_rows
-
-local function list(t)
- return util_mysql_fetch_fields_from_current_row(t._result_)
-end
-
-local function hash(t)
- local list = util_mysql_fetch_fields_from_current_row(t._result_)
- local fields = t.names
- local data = { }
- for i=1,t.noffields do
- data[fields[i]] = list[i]
- end
- return data
-end
-
-local function wholelist(t)
- return util_mysql_fetch_all_rows(t._result_)
-end
-
-local mt = { __index = {
- -- regular
- finish = finish,
- list = list,
- hash = hash,
- wholelist = wholelist,
- -- compatibility
- numrows = numrows,
- getcolnames = getcolnames,
- getcoltypes = getcoltypes,
- -- fallback
- _result_ = nil,
- names = { },
- types = { },
- noffields = 0,
- nofrows = 0,
- }
-}
-
-local nt = setmetatable({},mt)
-
--- session
-
-local function close(t)
- mysql_close_connection(t._connection_)
-end
-
-local function execute(t,query)
- if query and query ~= "" then
- local connection = t._connection_
- local result = mysql_execute_query(connection,query,#query)
- if result == 0 then
- local result = mysql_store_result(connection)
- if result then
- mysql_field_seek(result,0)
- local nofrows = mysql_num_rows(result) or 0
- local noffields = mysql_num_fields(result)
- local names = { }
- local types = { }
- for i=1,noffields do
- local field = mysql_fetch_field(result)
- names[i] = field.name
- types[i] = field.type
- end
- local t = {
- _result_ = result,
- names = names,
- types = types,
- noffields = noffields,
- nofrows = nofrows,
- }
- return setmetatable(t,mt)
- else
- return nt
- end
- end
- end
- return false
-end
-
-local mt = { __index = {
- close = close,
- execute = execute,
- }
-}
-
-local function open(t,database,username,password,host,port)
- local connection = mysql_open_connection(t._session_,host or "localhost",username or "",password or "",database or "",port or 0,0,0)
- if connection then
- local t = {
- _connection_ = connection,
- }
- return setmetatable(t,mt)
- end
-end
-
-local function message(t)
- return mysql_error_message(t._session_)
-end
-
-local function close(t)
- -- dummy, as we have a global session
-end
-
-local mt = {
- __index = {
- connect = open,
- close = close,
- message = message,
- }
-}
-
-local function initialize()
- local session = {
- _session_ = mysql_initialize(instance) -- maybe share, single thread anyway
- }
- return setmetatable(session,mt)
-end
-
--- -- -- --
-
-local function connect(session,specification)
- return session:connect(
- specification.database or "",
- specification.username or "",
- specification.password or "",
- specification.host or "",
- specification.port
- )
-end
-
-local function error_in_connection(specification,action)
- report_state("error in connection: [%s] %s@%s to %s:%s",
- action or "unknown",
- specification.database or "no database",
- specification.username or "no username",
- specification.host or "no host",
- specification.port or "no port"
- )
-end
-
-local function datafetched(specification,query,converter)
- if not query or query == "" then
- report_state("no valid query")
- return { }, { }
- end
- local id = specification.id
- local session, connection
- if id then
- local c = cache[id]
- if c then
- session = c.session
- connection = c.connection
- end
- if not connection then
- session = initialize()
- connection = connect(session,specification)
- if not connection then
- for i=1,nofretries do
- sleep(retrydelay)
- report_state("retrying to connect: [%s.%s] %s@%s to %s:%s",
- id,i,
- specification.database or "no database",
- specification.username or "no username",
- specification.host or "no host",
- specification.port or "no port"
- )
- connection = connect(session,specification)
- if connection then
- break
- end
- end
- end
- if connection then
- cache[id] = { session = session, connection = connection }
- end
- end
- else
- session = initialize()
- connection = connect(session,specification)
- if not connection then
- for i=1,nofretries do
- sleep(retrydelay)
- report_state("retrying to connect: [%s] %s@%s to %s:%s",
- i,
- specification.database or "no database",
- specification.username or "no username",
- specification.host or "no host",
- specification.port or "no port"
- )
- connection = connect(session,specification)
- if connection then
- break
- end
- end
- end
- end
- if not connection then
- report_state("error in connection: %s@%s to %s:%s",
- specification.database or "no database",
- specification.username or "no username",
- specification.host or "no host",
- specification.port or "no port"
- )
- return { }, { }
- end
- query = lpegmatch(querysplitter,query)
- local result, message, okay
- for i=1,#query do
- local q = query[i]
- local r, m = connection:execute(q)
- if m then
- report_state("error in query, stage: %s",string.collapsespaces(q))
- message = message and format("%s\n%s",message,m) or m
- end
- if type(r) == "table" then
- result = r
- okay = true
- elseif not m then
- okay = true
- end
- end
- local data, keys
- if result then
- if converter then
- data = converter.swiglib(result)
- else
- keys = result.names
- data = { }
- for i=1,result.nofrows do
- data[i] = result:hash()
- end
- end
- result:finish() -- result:close()
- elseif message then
- report_state("message %s",message)
- end
- if not keys then
- keys = { }
- end
- if not data then
- data = { }
- end
- if not id then
- connection:close()
- session:close()
- end
- return data, keys
-end
-
-local function execute(specification)
- if trace_sql then
- report_state("executing library")
- end
- if not validspecification(specification) then
- report_state("error in specification")
- return
- end
- local query = dataprepared(specification)
- if not query then
- report_state("error in preparation")
- return
- end
- local data, keys = datafetched(specification,query,specification.converter)
- if not data then
- report_state("error in fetching")
- return
- end
- local one = data[1]
- if one then
- setmetatable(data,{ __index = one } )
- end
- return data, keys
-end
-
-local wraptemplate = [[
-local mysql = require("swigluamysql") -- will be stored in method
-
------ mysql_fetch_row = mysql.mysql_fetch_row
------ mysql_fetch_lengths = mysql.mysql_fetch_lengths
------ util_unpackbytearray = mysql.util_unpackbytearray
-local util_mysql_fetch_fields_from_current_row
- = mysql.util_mysql_fetch_fields_from_current_row
-
-local converters = utilities.sql.converters
-local deserialize = utilities.sql.deserialize
-
-local tostring = tostring
-local tonumber = tonumber
-local booleanstring = string.booleanstring
-
-%s
-
-return function(result)
- if not result then
- return { }
- end
- local nofrows = result.nofrows or 0
- if nofrows == 0 then
- return { }
- end
- local noffields = result.noffields or 0
- local target = { } -- no %s needed here
- result = result._result_
- for i=1,nofrows do
- -- local row = mysql_fetch_row(result)
- -- local len = mysql_fetch_lengths(result)
- -- local cells = util_unpackbytearray(row,noffields,len)
- local cells = util_mysql_fetch_fields_from_current_row(result)
- target[%s] = {
- %s
- }
- end
- return target
-end
-]]
-
-local celltemplate = "cells[%s]"
-
-methods.swiglib = {
- runner = function() end, -- never called
- execute = execute,
- initialize = initialize, -- returns session
- usesfiles = false,
- wraptemplate = wraptemplate,
- celltemplate = celltemplate,
-}
+if not modules then modules = { } end modules ['util-sql-swiglib'] = { + version = 1.001, + comment = "companion to util-sql.lua", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- As the regular library is flawed (i.e. there are crashes in the table +-- construction code) and also not that efficient, Luigi Scarso looked into +-- a swig binding. This is a bit more low level approach but as we stay +-- closer to the original library it's also less dependant. + +local concat = table.concat +local format = string.format +local lpegmatch = lpeg.match +local setmetatable, type = setmetatable, type +local sleep = os.sleep + +local trace_sql = false trackers.register("sql.trace", function(v) trace_sql = v end) +local trace_queries = false trackers.register("sql.queries",function(v) trace_queries = v end) +local report_state = logs.reporter("sql","swiglib") + +local sql = utilities.sql +local mysql = require("swiglib.mysql.core") -- "5.6" + +-- inspect(table.sortedkeys(mysql)) + +local nofretries = 5 +local retrydelay = 1 + +local cache = { } +local helpers = sql.helpers +local methods = sql.methods +local validspecification = helpers.validspecification +local querysplitter = helpers.querysplitter +local dataprepared = helpers.preparetemplate +local serialize = sql.serialize +local deserialize = sql.deserialize + +local mysql_initialize = mysql.mysql_init + +local mysql_open_connection = mysql.mysql_real_connect +local mysql_execute_query = mysql.mysql_real_query +local mysql_close_connection = mysql.mysql_close + +local mysql_field_seek = mysql.mysql_field_seek +local mysql_num_fields = mysql.mysql_num_fields +local mysql_fetch_field = mysql.mysql_fetch_field +local mysql_num_rows = mysql.mysql_num_rows +local mysql_fetch_row = mysql.mysql_fetch_row +local mysql_fetch_lengths = mysql.mysql_fetch_lengths +local mysql_init = mysql.mysql_init +local mysql_store_result = mysql.mysql_store_result +local mysql_free_result = mysql.mysql_free_result +local mysql_use_result = mysql.mysql_use_result + +local mysql_error_message = mysql.mysql_error +local mysql_options_argument = mysql.mysql_options_argument + +local instance = mysql.MYSQL() + +local mysql_constant_false = false +local mysql_constant_true = true + +-- if mysql_options_argument then +-- +-- mysql_constant_false = mysql_options_argument(false) -- 0 "\0" +-- mysql_constant_true = mysql_options_argument(true) -- 1 "\1" +-- +-- -- print(swig_type(mysql_constant_false)) +-- -- print(swig_type(mysql_constant_true)) +-- +-- mysql.mysql_options(instance,mysql.MYSQL_OPT_RECONNECT,mysql_constant_true); +-- +-- else +-- +-- print("") +-- print("incomplete swiglib.mysql interface") +-- print("") +-- +-- end + +local typemap = mysql.MYSQL_TYPE_VAR_STRING and { + [mysql.MYSQL_TYPE_VAR_STRING ] = "string", + [mysql.MYSQL_TYPE_STRING ] = "string", + [mysql.MYSQL_TYPE_DECIMAL ] = "number", + [mysql.MYSQL_TYPE_SHORT ] = "number", + [mysql.MYSQL_TYPE_LONG ] = "number", + [mysql.MYSQL_TYPE_FLOAT ] = "number", + [mysql.MYSQL_TYPE_DOUBLE ] = "number", + [mysql.MYSQL_TYPE_LONGLONG ] = "number", + [mysql.MYSQL_TYPE_INT24 ] = "number", + [mysql.MYSQL_TYPE_YEAR ] = "number", + [mysql.MYSQL_TYPE_TINY ] = "number", + [mysql.MYSQL_TYPE_TINY_BLOB ] = "binary", + [mysql.MYSQL_TYPE_MEDIUM_BLOB] = "binary", + [mysql.MYSQL_TYPE_LONG_BLOB ] = "binary", + [mysql.MYSQL_TYPE_BLOB ] = "binary", + [mysql.MYSQL_TYPE_DATE ] = "date", + [mysql.MYSQL_TYPE_NEWDATE ] = "date", + [mysql.MYSQL_TYPE_DATETIME ] = "datetime", + [mysql.MYSQL_TYPE_TIME ] = "time", + [mysql.MYSQL_TYPE_TIMESTAMP ] = "time", + [mysql.MYSQL_TYPE_ENUM ] = "set", + [mysql.MYSQL_TYPE_SET ] = "set", + [mysql.MYSQL_TYPE_NULL ] = "null", +} + +-- real_escape_string + +local function finish(t) + local r = t._result_ + if r then + mysql_free_result(r) + end +end + +-- will become metatable magic + +-- local function analyze(result) +-- mysql_field_seek(result,0) +-- local nofrows = mysql_num_rows(result) or 0 +-- local noffields = mysql_num_fields(result) +-- local names = { } +-- local types = { } +-- for i=1,noffields do +-- local field = mysql_fetch_field(result) +-- names[i] = field.name +-- types[i] = field.type +-- end +-- return names, types, noffields, nofrows +-- end + +local function getcolnames(t) + return t.names +end + +local function getcoltypes(t) + return t.types +end + +local function numrows(t) + return t.nofrows +end + +-- swig_type + +-- local ulongArray_getitem = mysql.ulongArray_getitem +-- local util_getbytearray = mysql.util_getbytearray + +-- local function list(t) +-- local result = t._result_ +-- local row = mysql_fetch_row(result) +-- local len = mysql_fetch_lengths(result) +-- local result = { } +-- for i=1,t.noffields do +-- local r = i - 1 -- zero offset +-- result[i] = util_getbytearray(row,r,ulongArray_getitem(len,r)) +-- end +-- return result +-- end + +-- local function hash(t) +-- local list = util_mysql_fetch_fields_from_current_row(t._result_) +-- local result = t._result_ +-- local fields = t.names +-- local row = mysql_fetch_row(result) +-- local len = mysql_fetch_lengths(result) +-- local result = { } +-- for i=1,t.noffields do +-- local r = i - 1 -- zero offset +-- result[fields[i]] = util_getbytearray(row,r,ulongArray_getitem(len,r)) +-- end +-- return result +-- end + +local util_mysql_fetch_fields_from_current_row = mysql.util_mysql_fetch_fields_from_current_row +local util_mysql_fetch_all_rows = mysql.util_mysql_fetch_all_rows + +local function list(t) + return util_mysql_fetch_fields_from_current_row(t._result_) +end + +local function hash(t) + local list = util_mysql_fetch_fields_from_current_row(t._result_) + local fields = t.names + local data = { } + for i=1,t.noffields do + data[fields[i]] = list[i] + end + return data +end + +local function wholelist(t) + return util_mysql_fetch_all_rows(t._result_) +end + +local mt = { __index = { + -- regular + finish = finish, + list = list, + hash = hash, + wholelist = wholelist, + -- compatibility + numrows = numrows, + getcolnames = getcolnames, + getcoltypes = getcoltypes, + -- fallback + _result_ = nil, + names = { }, + types = { }, + noffields = 0, + nofrows = 0, + } +} + +local nt = setmetatable({},mt) + +-- session + +local function close(t) + mysql_close_connection(t._connection_) +end + +local function execute(t,query) + if query and query ~= "" then + local connection = t._connection_ + local result = mysql_execute_query(connection,query,#query) + if result == 0 then + local result = mysql_store_result(connection) + if result then + mysql_field_seek(result,0) + local nofrows = mysql_num_rows(result) or 0 + local noffields = mysql_num_fields(result) + local names = { } + local types = { } + for i=1,noffields do + local field = mysql_fetch_field(result) + names[i] = field.name + types[i] = field.type + end + local t = { + _result_ = result, + names = names, + types = types, + noffields = noffields, + nofrows = nofrows, + } + return setmetatable(t,mt) + else + return nt + end + end + end + return false +end + +local mt = { __index = { + close = close, + execute = execute, + } +} + +local function open(t,database,username,password,host,port) + local connection = mysql_open_connection(t._session_,host or "localhost",username or "",password or "",database or "",port or 0,0,0) + if connection then + local t = { + _connection_ = connection, + } + return setmetatable(t,mt) + end +end + +local function message(t) + return mysql_error_message(t._session_) +end + +local function close(t) + -- dummy, as we have a global session +end + +local mt = { + __index = { + connect = open, + close = close, + message = message, + } +} + +local function initialize() + local session = { + _session_ = mysql_initialize(instance) -- maybe share, single thread anyway + } + return setmetatable(session,mt) +end + +-- -- -- -- + +local function connect(session,specification) + return session:connect( + specification.database or "", + specification.username or "", + specification.password or "", + specification.host or "", + specification.port + ) +end + +local function error_in_connection(specification,action) + report_state("error in connection: [%s] %s@%s to %s:%s", + action or "unknown", + specification.database or "no database", + specification.username or "no username", + specification.host or "no host", + specification.port or "no port" + ) +end + +local function datafetched(specification,query,converter) + if not query or query == "" then + report_state("no valid query") + return { }, { } + end + local id = specification.id + local session, connection + if id then + local c = cache[id] + if c then + session = c.session + connection = c.connection + end + if not connection then + session = initialize() + connection = connect(session,specification) + if not connection then + for i=1,nofretries do + sleep(retrydelay) + report_state("retrying to connect: [%s.%s] %s@%s to %s:%s", + id,i, + specification.database or "no database", + specification.username or "no username", + specification.host or "no host", + specification.port or "no port" + ) + connection = connect(session,specification) + if connection then + break + end + end + end + if connection then + cache[id] = { session = session, connection = connection } + end + end + else + session = initialize() + connection = connect(session,specification) + if not connection then + for i=1,nofretries do + sleep(retrydelay) + report_state("retrying to connect: [%s] %s@%s to %s:%s", + i, + specification.database or "no database", + specification.username or "no username", + specification.host or "no host", + specification.port or "no port" + ) + connection = connect(session,specification) + if connection then + break + end + end + end + end + if not connection then + report_state("error in connection: %s@%s to %s:%s", + specification.database or "no database", + specification.username or "no username", + specification.host or "no host", + specification.port or "no port" + ) + return { }, { } + end + query = lpegmatch(querysplitter,query) + local result, message, okay + for i=1,#query do + local q = query[i] + local r, m = connection:execute(q) + if m then + report_state("error in query, stage: %s",string.collapsespaces(q)) + message = message and format("%s\n%s",message,m) or m + end + if type(r) == "table" then + result = r + okay = true + elseif not m then + okay = true + end + end + local data, keys + if result then + if converter then + data = converter.swiglib(result) + else + keys = result.names + data = { } + for i=1,result.nofrows do + data[i] = result:hash() + end + end + result:finish() -- result:close() + elseif message then + report_state("message %s",message) + end + if not keys then + keys = { } + end + if not data then + data = { } + end + if not id then + connection:close() + session:close() + end + return data, keys +end + +local function execute(specification) + if trace_sql then + report_state("executing library") + end + if not validspecification(specification) then + report_state("error in specification") + return + end + local query = dataprepared(specification) + if not query then + report_state("error in preparation") + return + end + local data, keys = datafetched(specification,query,specification.converter) + if not data then + report_state("error in fetching") + return + end + local one = data[1] + if one then + setmetatable(data,{ __index = one } ) + end + return data, keys +end + +local wraptemplate = [[ +local mysql = require("swigluamysql") -- will be stored in method + +----- mysql_fetch_row = mysql.mysql_fetch_row +----- mysql_fetch_lengths = mysql.mysql_fetch_lengths +----- util_unpackbytearray = mysql.util_unpackbytearray +local util_mysql_fetch_fields_from_current_row + = mysql.util_mysql_fetch_fields_from_current_row + +local converters = utilities.sql.converters +local deserialize = utilities.sql.deserialize + +local tostring = tostring +local tonumber = tonumber +local booleanstring = string.booleanstring + +%s + +return function(result) + if not result then + return { } + end + local nofrows = result.nofrows or 0 + if nofrows == 0 then + return { } + end + local noffields = result.noffields or 0 + local target = { } -- no %s needed here + result = result._result_ + for i=1,nofrows do + -- local row = mysql_fetch_row(result) + -- local len = mysql_fetch_lengths(result) + -- local cells = util_unpackbytearray(row,noffields,len) + local cells = util_mysql_fetch_fields_from_current_row(result) + target[%s] = { + %s + } + end + return target +end +]] + +local celltemplate = "cells[%s]" + +methods.swiglib = { + runner = function() end, -- never called + execute = execute, + initialize = initialize, -- returns session + usesfiles = false, + wraptemplate = wraptemplate, + celltemplate = celltemplate, +} |