From 69d2352af4b60929b37fc49f3bdb263977016244 Mon Sep 17 00:00:00 2001 From: Marius Date: Fri, 19 Oct 2012 01:20:13 +0300 Subject: stable 2012.05.30 11:26 --- tex/context/base/util-sql-imp-client.lua | 253 ------------------------------- 1 file changed, 253 deletions(-) delete mode 100644 tex/context/base/util-sql-imp-client.lua (limited to 'tex/context/base/util-sql-imp-client.lua') diff --git a/tex/context/base/util-sql-imp-client.lua b/tex/context/base/util-sql-imp-client.lua deleted file mode 100644 index 8e174fc99..000000000 --- a/tex/context/base/util-sql-imp-client.lua +++ /dev/null @@ -1,253 +0,0 @@ -if not modules then modules = { } end modules ['util-sql-client'] = { - 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" -} - --- todo: make a converter - -local rawset, setmetatable = rawset, setmetatable -local P, S, V, C, Cs, Ct, Cc, Cg, Cf, patterns, lpegmatch = lpeg.P, lpeg.S, lpeg.V, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.Cc, lpeg.Cg, lpeg.Cf, lpeg.patterns, lpeg.match - -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","client") - -local sql = require("util-sql") -local helpers = sql.helpers -local methods = sql.methods -local validspecification = helpers.validspecification -local preparetemplate = helpers.preparetemplate -local splitdata = helpers.splitdata -local replacetemplate = utilities.templates.replace -local serialize = sql.serialize -local deserialize = sql.deserialize - --- Experiments with an p/action demonstrated that there is not much gain. We could do a runtime --- capture but creating all the small tables is not faster and it doesn't work well anyway. - -local separator = P("\t") -local newline = patterns.newline -local empty = Cc("") - -local entry = C((1-separator-newline)^0) -- C 10% faster than Cs - -local unescaped = P("\\n") / "\n" - + P("\\t") / "\t" - + P("\\0") / "\000" - + P("\\\\") / "\\" - -local entry = Cs((unescaped + (1-separator-newline))^0) -- C 10% faster than Cs but Cs needed due to nesting - -local getfirst = Ct( entry * (separator * (entry+empty))^0) + newline -local skipfirst = (1-newline)^1 * newline -local getfirstline = C((1-newline)^0) - -local cache = { } - -local function splitdata(data) -- todo: hash on first line ... maybe move to client module - if data == "" then - if trace_sql then - report_state("no data") - end - return { }, { } - end - local first = lpegmatch(getfirstline,data) - if not first then - if trace_sql then - report_state("no data") - end - return { }, { } - end - local p = cache[first] - if p then - -- report_state("reusing: %s",first) - local entries = lpegmatch(p.parser,data) - return entries or { }, p.keys - elseif p == false then - return { }, { } - elseif p == nil then - local keys = lpegmatch(getfirst,first) or { } - if #keys == 0 then - if trace_sql then - report_state("no banner") - end - cache[first] = false - return { }, { } - end - -- quite generic, could be a helper - local n = #keys - if n == 0 then - report_state("no fields") - cache[first] = false - return { }, { } - end - if n == 1 then - local key = keys[1] - if trace_sql then - report_state("one field with name",key) - end - p = Cg(Cc(key) * entry) - else - for i=1,n do - local key = keys[i] - if trace_sql then - report_state("field %s has name %q",i,key) - end - local s = Cg(Cc(key) * entry) - if p then - p = p * separator * s - else - p = s - end - end - end - p = Cf(Ct("") * p,rawset) * newline^1 - p = skipfirst * Ct(p^0) - cache[first] = { parser = p, keys = keys } - local entries = lpegmatch(p,data) - return entries or { }, keys - end -end - -local splitter = skipfirst * Ct((Ct(entry * (separator * entry)^0) * newline^1)^0) - -local function getdata(data) - return lpegmatch(splitter,data) -end - -helpers.splitdata = splitdata -helpers.getdata = getdata - -local function dataprepared(specification) - local query = preparetemplate(specification) - if query then - io.savedata(specification.queryfile,query) - os.remove(specification.resultfile) - if trace_queries then - report_state("query: %s",query) - end - return true - else - -- maybe push an error - os.remove(specification.queryfile) - os.remove(specification.resultfile) - end -end - -local function datafetched(specification,runner) - local command = replacetemplate(runner,specification) - if trace_sql then - local t = osclock() - report_state("command: %s",command) - local okay = os.execute(command) - report_state("fetchtime: %.3f sec",osclock()-t) -- not okay under linux - return okay == 0 - else - return os.execute(command) == 0 - end -end - -local function dataloaded(specification) - if trace_sql then - local t = osclock() - local data = io.loaddata(specification.resultfile) or "" - report_state("datasize: %.3f MB",#data/1024/1024) - report_state("loadtime: %.3f sec",osclock()-t) - return data - else - return io.loaddata(specification.resultfile) or "" - end -end - -local function dataconverted(data,converter) - if converter then - local data = getdata(data) - if data then - converter.client(data) - end - return data - elseif trace_sql then - local t = osclock() - local data, keys = splitdata(data) - report_state("converttime: %.3f",osclock()-t) - report_state("keys: %s ",#keys) - report_state("entries: %s ",#data) - return data, keys - else - return splitdata(data) - end -end - --- todo: new, etc - -local function execute(specification) - if trace_sql then - report_state("executing client") - end - if not validspecification(specification) then - report_state("error in specification") - return - end - if not dataprepared(specification) then - report_state("error in preparation") - return - end - if not datafetched(specification,methods.client.runner) then - report_state("error in fetching, query: %s",string.collapsespaces(io.loaddata(specification.queryfile))) - return - end - local data = dataloaded(specification) - if not data then - report_state("error in loading") - return - end - local data, keys = dataconverted(data,specification.converter) - if not data then - report_state("error in converting") - return - end - local one = data[1] - if one then - setmetatable(data,{ __index = one } ) - end - return data, keys -end - --- The following is not that (memory) efficient but normally we will use --- the lib anyway. Of course we could make a dedicated converter and/or --- hook into the splitter code but ... it makes not much sense because then --- we can as well move the builder to the library modules. - -local wraptemplate = [[ -local converters = utilities.sql.converters -local deserialize = utilities.sql.deserialize - -local tostring = tostring -local tonumber = tonumber -local booleanstring = string.booleanstring - -%s - -return function(data) - for i=1,#data do - local cells = data[i] - data[i] = { - %s - } - end - return data -end -]] - -local celltemplate = "cells[%s]" - -methods.client = { - runner = [[mysql --batch --user="%username%" --password="%password%" --host="%host%" --port=%port% --database="%database%" --default-character-set=utf8 < "%queryfile%" > "%resultfile%"]], - execute = execute, - usesfiles = true, - wraptemplate = wraptemplate, - celltemplate = celltemplate, -} -- cgit v1.2.3