merge sessions into http module directly
This commit is contained in:
parent
d2f0a75d50
commit
f09c9f345a
File diff suppressed because it is too large
Load Diff
@ -1,211 +0,0 @@
|
|||||||
local kv = require("kv")
|
|
||||||
local crypto = require("crypto")
|
|
||||||
|
|
||||||
local sessions = {}
|
|
||||||
local stores = {}
|
|
||||||
local default_store = nil
|
|
||||||
|
|
||||||
-- ======================================================================
|
|
||||||
-- CORE FUNCTIONS
|
|
||||||
-- ======================================================================
|
|
||||||
|
|
||||||
function sessions.init(store_name, filename)
|
|
||||||
store_name = store_name or "sessions"
|
|
||||||
if not kv.open(store_name, filename) then return false end
|
|
||||||
stores[store_name] = true
|
|
||||||
if not default_store then default_store = store_name end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
function sessions.create(session_id, data, store_name)
|
|
||||||
if type(session_id) ~= "string" then error("session ID must be a string", 2) end
|
|
||||||
if data ~= nil and type(data) ~= "table" then error("data must be a table", 2) end
|
|
||||||
|
|
||||||
store_name = store_name or default_store
|
|
||||||
if not store_name then error("No session store initialized", 2) end
|
|
||||||
|
|
||||||
local session_data = {
|
|
||||||
data = data or {},
|
|
||||||
_created = os.time(),
|
|
||||||
_last_accessed = os.time()
|
|
||||||
}
|
|
||||||
|
|
||||||
return kv.set(store_name, "session:" .. session_id, json.encode(session_data))
|
|
||||||
end
|
|
||||||
|
|
||||||
function sessions.get(session_id, store_name)
|
|
||||||
if type(session_id) ~= "string" then error("session ID must be a string", 2) end
|
|
||||||
|
|
||||||
store_name = store_name or default_store
|
|
||||||
if not store_name then error("No session store initialized", 2) end
|
|
||||||
|
|
||||||
local json_str = kv.get(store_name, "session:" .. session_id)
|
|
||||||
if not json_str then return nil end
|
|
||||||
|
|
||||||
local session_data = json.decode(json_str)
|
|
||||||
if not session_data then return nil end
|
|
||||||
|
|
||||||
-- Update last accessed
|
|
||||||
session_data._last_accessed = os.time()
|
|
||||||
kv.set(store_name, "session:" .. session_id, json.encode(session_data))
|
|
||||||
|
|
||||||
-- Return flattened data with metadata
|
|
||||||
local result = session_data.data or {}
|
|
||||||
result._created = session_data._created
|
|
||||||
result._last_accessed = session_data._last_accessed
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
|
|
||||||
function sessions.update(session_id, data, store_name)
|
|
||||||
if type(session_id) ~= "string" then error("session ID must be a string", 2) end
|
|
||||||
if type(data) ~= "table" then error("data must be a table", 2) end
|
|
||||||
|
|
||||||
store_name = store_name or default_store
|
|
||||||
if not store_name then error("No session store initialized", 2) end
|
|
||||||
|
|
||||||
local json_str = kv.get(store_name, "session:" .. session_id)
|
|
||||||
if not json_str then return false end
|
|
||||||
|
|
||||||
local session_data = json.decode(json_str)
|
|
||||||
if not session_data then return false end
|
|
||||||
|
|
||||||
session_data.data = data
|
|
||||||
session_data._last_accessed = os.time()
|
|
||||||
|
|
||||||
return kv.set(store_name, "session:" .. session_id, json.encode(session_data))
|
|
||||||
end
|
|
||||||
|
|
||||||
function sessions.delete(session_id, store_name)
|
|
||||||
if type(session_id) ~= "string" then error("session ID must be a string", 2) end
|
|
||||||
|
|
||||||
store_name = store_name or default_store
|
|
||||||
if not store_name then error("No session store initialized", 2) end
|
|
||||||
return kv.delete(store_name, "session:" .. session_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
function sessions.cleanup(max_age, store_name)
|
|
||||||
store_name = store_name or default_store
|
|
||||||
if not store_name then error("No session store initialized", 2) end
|
|
||||||
|
|
||||||
local keys = kv.keys(store_name)
|
|
||||||
local current_time = os.time()
|
|
||||||
local deleted = 0
|
|
||||||
|
|
||||||
for _, key in ipairs(keys) do
|
|
||||||
if key:match("^session:") then
|
|
||||||
local json_str = kv.get(store_name, key)
|
|
||||||
if json_str then
|
|
||||||
local session_data = json.decode(json_str)
|
|
||||||
if session_data and session_data._last_accessed then
|
|
||||||
if current_time - session_data._last_accessed > max_age then
|
|
||||||
kv.delete(store_name, key)
|
|
||||||
deleted = deleted + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return deleted
|
|
||||||
end
|
|
||||||
|
|
||||||
function sessions.close(store_name)
|
|
||||||
local success = kv.close(store_name)
|
|
||||||
stores[store_name] = nil
|
|
||||||
if default_store == store_name then
|
|
||||||
default_store = next(stores)
|
|
||||||
end
|
|
||||||
return success
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ======================================================================
|
|
||||||
-- UTILITIES
|
|
||||||
-- ======================================================================
|
|
||||||
|
|
||||||
function sessions.generate_id()
|
|
||||||
return crypto.random_alphanumeric(32)
|
|
||||||
end
|
|
||||||
|
|
||||||
function sessions.exists(session_id, store_name)
|
|
||||||
store_name = store_name or default_store
|
|
||||||
if not store_name then error("No session store initialized", 2) end
|
|
||||||
return kv.has(store_name, "session:" .. session_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
function sessions.list(store_name)
|
|
||||||
store_name = store_name or default_store
|
|
||||||
if not store_name then error("No session store initialized", 2) end
|
|
||||||
|
|
||||||
local keys = kv.keys(store_name)
|
|
||||||
local session_ids = {}
|
|
||||||
|
|
||||||
for _, key in ipairs(keys) do
|
|
||||||
local session_id = key:match("^session:(.+)")
|
|
||||||
if session_id then
|
|
||||||
table.insert(session_ids, session_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return session_ids
|
|
||||||
end
|
|
||||||
|
|
||||||
function sessions.count(store_name)
|
|
||||||
return #sessions.list(store_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
function sessions.reset()
|
|
||||||
stores = {}
|
|
||||||
default_store = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ======================================================================
|
|
||||||
-- OOP INTERFACE
|
|
||||||
-- ======================================================================
|
|
||||||
|
|
||||||
local SessionStore = {}
|
|
||||||
SessionStore.__index = SessionStore
|
|
||||||
|
|
||||||
function sessions.create_store(store_name, filename)
|
|
||||||
if not sessions.init(store_name, filename) then
|
|
||||||
error("Failed to initialize store '" .. store_name .. "'", 2)
|
|
||||||
end
|
|
||||||
return setmetatable({name = store_name}, SessionStore)
|
|
||||||
end
|
|
||||||
|
|
||||||
function SessionStore:create(session_id, data)
|
|
||||||
return sessions.create(session_id, data, self.name)
|
|
||||||
end
|
|
||||||
|
|
||||||
function SessionStore:get(session_id)
|
|
||||||
return sessions.get(session_id, self.name)
|
|
||||||
end
|
|
||||||
|
|
||||||
function SessionStore:update(session_id, data)
|
|
||||||
return sessions.update(session_id, data, self.name)
|
|
||||||
end
|
|
||||||
|
|
||||||
function SessionStore:delete(session_id)
|
|
||||||
return sessions.delete(session_id, self.name)
|
|
||||||
end
|
|
||||||
|
|
||||||
function SessionStore:cleanup(max_age)
|
|
||||||
return sessions.cleanup(max_age, self.name)
|
|
||||||
end
|
|
||||||
|
|
||||||
function SessionStore:exists(session_id)
|
|
||||||
return sessions.exists(session_id, self.name)
|
|
||||||
end
|
|
||||||
|
|
||||||
function SessionStore:list()
|
|
||||||
return sessions.list(self.name)
|
|
||||||
end
|
|
||||||
|
|
||||||
function SessionStore:count()
|
|
||||||
return sessions.count(self.name)
|
|
||||||
end
|
|
||||||
|
|
||||||
function SessionStore:close()
|
|
||||||
return sessions.close(self.name)
|
|
||||||
end
|
|
||||||
|
|
||||||
return sessions
|
|
Loading…
x
Reference in New Issue
Block a user