DATASTORE adaptor: role


This is the DATASTORE adaptor which exposes role assignments as data-like objects. To read a role assignment for role "Secretary", for instance, we just get the value "role:Secretary". To assign said role, we just set the value -- and that just calls back into the wftk API to assign the role.
 
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "../wftk.h"
#include "../wftk_internals.h"
The adaptor_info structure is used to pass adaptor info (duh) back to the config module when it's building an adaptor instance. Here's what it contains:
 
static char *names[] = 
{
   "init",
   "free",
   "info",
   "get",
   "set",
   "store",
   "isnull",
   "makenull"
};

XML * DATASTORE_role_init     (WFTK_ADAPTOR * ad, va_list args);
XML * DATASTORE_role_free     (WFTK_ADAPTOR * ad, va_list args);
XML * DATASTORE_role_info     (WFTK_ADAPTOR * ad, va_list args);
XML * DATASTORE_role_get      (WFTK_ADAPTOR * ad, va_list args);
XML * DATASTORE_role_set      (WFTK_ADAPTOR * ad, va_list args);
XML * DATASTORE_role_store    (WFTK_ADAPTOR * ad, va_list args);
XML * DATASTORE_role_isnull   (WFTK_ADAPTOR * ad, va_list args);
XML * DATASTORE_role_makenull (WFTK_ADAPTOR * ad, va_list args);

static WFTK_API_FUNC vtab[] = 
{
   DATASTORE_role_init,
   DATASTORE_role_free,
   DATASTORE_role_info,
   DATASTORE_role_get,
   DATASTORE_role_set,
   DATASTORE_role_store,
   DATASTORE_role_isnull,
   DATASTORE_role_makenull
};

static struct adaptor_info _DATASTORE_role_info =
{
   8,
   names,
   vtab
};
Cool. So here's the incredibly complex function which returns a pointer to that:
 
struct adaptor_info * DATASTORE_role_get_info ()
{
   return & _DATASTORE_role_info;
}
Thus concludes the communication with the config module. In most modules, we'd do some kind of initialization, but the role datastore doesn't need any.
 
XML * DATASTORE_role_init (WFTK_ADAPTOR * ad, va_list args) { return (XML *) 0; }
XML * DATASTORE_role_free (WFTK_ADAPTOR * ad, va_list args) { return (XML *) 0; }
Next up is the info call, which builds and returns a little XML telling the caller about the adaptor. If the adaptor itself is NULL, then it just returns info about the installed adaptor handler; otherwise it's free to elaborate on the adaptor instance.
 
XML * DATASTORE_role_info (WFTK_ADAPTOR * ad, va_list args) {
   XML * info;

   info = xml_create ("info");
   xml_set (info, "type", "datastore");
   xml_set (info, "name", "role");
   xml_set (info, "ver", "1.1.0");
   xml_set (info, "compiled", __TIME__ " " __DATE__);
   xml_set (info, "author", "Michael Roberts");
   xml_set (info, "contact", "wftk@vivtek.com");
   xml_set (info, "extra_functions", "0");

   return (info);
}

So. A datastore adaptor basically just provides get and set functionality for named values. The names will basically always start with the name of the adaptor, so we need to strip that off first. Otherwise the role datastore is pretty rocket-surgery-free.
 
XML * DATASTORE_role_get  (WFTK_ADAPTOR * ad, va_list args)
{
   XML * datasheet = (XML *) 0;
   char * name;
   char * colon;

   if (args) datasheet = va_arg (args, XML *);
   if (!datasheet) {
      xml_set (ad->parms, "error", "No datasheet supplied.");
      return (XML *) 0;
   }
   name = va_arg (args, char *);
   if (!name) {
      xml_set (ad->parms, "error", "No role named.");
      return (XML *) 0;
   }

   colon = strchr (name, ':');
   return (wftk_session_stashvalue (ad->session, wftk_role_user (ad->session, datasheet, colon ? colon + 1 : name)));
}
That's rather satisfying. Let's do the setting end.
 
XML * DATASTORE_role_set  (WFTK_ADAPTOR * ad, va_list args)
{
   XML * datasheet = (XML *) 0;
   char * name;
   char * value;
   char * colon;

   if (args) datasheet = va_arg (args, XML *);
   if (!datasheet) {
      xml_set (ad->parms, "error", "No datasheet supplied.");
      return (XML *) 0;
   }
   name = va_arg (args, char *);
   if (!name) {
      xml_set (ad->parms, "error", "No role named.");
      return (XML *) 0;
   }
   value = va_arg (args, char *);

   colon = strchr (name, ':');
   wftk_role_assign (ad->session, datasheet, colon ? colon + 1 : name, value);
   return (XML *) 0;
}
(July 23, 2001) I added a new function to the datastore API; "store" does the same as "set" excep that it receives a data XML element instead of a string value; this is useful for cached data (like currecord). I don't expect the role adaptor to be used this way, but somebody might try it, so let's be safe, shall we?
 
XML * DATASTORE_role_store (WFTK_ADAPTOR * ad, va_list args)
{
   XML * data = (XML *) 0;
   char * name;
   char * value;
   char * colon;

   if (args) data = va_arg (args, XML *);
   if (!data) {
      xml_set (ad->parms, "error", "No data given.");
      return (XML *) 0;
   }
   if (!xml_parent (data)) {
      xml_set (ad->parms, "error", "Data not in datasheet.");
      return (XML *) 0;
   }

   wftk_role_assign (ad->session, xml_parent(data), xml_attrval (data, "id"), xml_attrval (data, "value"));

   return (XML *) 0;
}
Easy!

I don't really care much about null values here. Really, the null value thing is pretty undefined anyway. ... No pun intended. Really.
 
XML * DATASTORE_role_isnull   (WFTK_ADAPTOR * ad, va_list args) { return (XML *) 0; }
XML * DATASTORE_role_makenull (WFTK_ADAPTOR * ad, va_list args) { return (XML *) 0; }

This code and documentation are released under the terms of the GNU license. They are additionally copyright (c) 2000, Vivtek. All rights reserved except those explicitly granted under the terms of the GNU license. This presentation was prepared with LPML. Try literate programming. You'll like it.