local datafile = require "datafile" local dir = require "pl.dir" local path = require "pl.path" local store = require "volksdata.store" local term = require "volksdata.term" local nsm = require "volksdata.namespace" -- Read only module properties. local PROTECTED = { store = true, reset_store = true, } local config_path = os.getenv("PKAR_CONFIG_DIR") or path.dirname(datafile.path("config/app.lua")) print ("Using config at:", config_path) local config = dofile(path.join(config_path, "app.lua")) local store_id = "file://" .. (os.getenv("PKAR_BASE") or config.fs.dres_path) -- Fill namespace map from config. for pfx, ns in pairs(config.namespace) do nsm.add(pfx, ns) end local M = { -- Project root path. config_path = config_path, config = config, store_id = store_id, --Logger config. logger = require "sllog":init{ {"err", "%T PKAR %-5L ", "%n", io.stderr}, {"warn", "%T PKAR %-5L ", "%n", io.stderr}, {"info", "%T PKAR %-5L ", "%n", io.stderr}, {"debug", "%T PKAR %-5L%f (%S) ", "%n", io.stderr}, timefn=(require "socket" or {}).gettime, report="debug", hookrequire=false, level="debug", }, -- Commonly used terms. RDF_TYPE = term.new_iriref(term.RDF_TYPE), -- Methods. -- Escape strings for use in gsub patterns. escape_ptn = function(src) return src:gsub("[%(%)%.%%%+%-%*%?%[%]%^%$]", "%%%0") end, } --[[ Generate pairtree directory and file path from an ID string and prefix. The directory is created if not existing. The ID string can include the `par:` namespace prefix or the fully qualified namespace. ext is optional, and is appended to the raw path. if no_create is not nil or false, the directory will not be checked for existence or created. This is normally set for web paths. return: full file path, with the optional extension if provided. --]] M.gen_pairtree = function (pfx, id_str, ext, no_create) local bare_id = id_str:gsub(nsm.get_ns("par"), ""):gsub("^par:", "") local res_dir = path.join(pfx, bare_id:sub(1,2), bare_id:sub(3,4)) local created, err if (path.isdir(res_dir)) or no_create then created = false else created, err = dir.makepath(res_dir) if not created then error(err) end end local fpath if (res_dir) then fpath = path.join(res_dir, bare_id .. (ext or "")) end return fpath, created end -- No more assignments to the module afte here. local mt = { __index = function(t, k) if (k == "store") then if not rawget(t, "_store") then rawset(t, "_store", store.new(store.MDB, store_id)) end return rawget(t, "_store") -- WIPE ALL DATA from the store and returns the new empty store handle. elseif (k == "reset_store") then rawset(t, "_store", store.new(store.MDB, store_id, true)) return rawget(t, "_store") end end, __newindex = function () return nil, "Module is read only." end } setmetatable (M, mt) math.randomseed(M.config.id.seed or os.time()) return M