Writing storage modules

Here follows a stub storage module.

Basics

First we need some initial boilerplate:

-- The provider object
local provider = {};
 
-- This method is called when some module opens a store
function provider:open(store, typ)
    return nil, "unsupported-store";
end
 
-- Tell Prosody about our storage provider
module:provides("storage", provider);

Key-Value stores

There's the gist of a key-value store driver:

local keyval = {};
local keyval_mt = { __index = keyval };
 
function keyval:get(username)
    -- read data for (username, host, store)
    if error then
        return nil, "could not read data"
    end
    return data -- or nil, in case the store is empty
end
 
function keyval:set(username, data)
    -- write data for (username, host, store)
    if error then
        return nil, "could not write data"
    end
    return true -- success
end

There's also some additional boilerplate needed to open the store:

local provider = {};
local drivers = {
    keyval = keyval_mt;
    -- other known types are 'map' and 'archive'
};
 
function provider:open(store, typ)
    local driver = drivers[typ or "keyval"];
    if not driver then
        return nil, "unsupported-store";
    end
    return setmetatable({ host = module.host, store = store }, driver);
end
 
module:provides("storage", provider);

Archive stores

Here's an example archive storage driver:

local archive = {};
local archive_mt = { __index = archive };
 
function keyval:append(username, key, value, when, with)
    -- insert into some store
    return key;
end
 
function keyval:query(username, query)
    -- return an iterator that returns items matching the query object
    return function()
        return key, value, when, with;
    end
end
 
-- Add archive = archive_mt in the driver table from the example 'open' method.
drivers.archive = archive_mt