|
WFTK_EXPORT XML * repos_list (XML * repository, XML * list)
{
WFTK_ADAPTOR * ad;
const char *id = xml_attrval (list, "id");
XML * mark;
XML * mark2;
XML * copy;
XML * user;
const char * line;
const char * end;
char * key;
int count = 0;
struct _repos_remote * sock = (struct _repos_remote *) xml_getbin (repository);
if (sock) { /* Remote. */
xml_setf (sock->parms, "outgoing", "list %s\n", xml_attrval (list, "id"));
_repos_send (sock);
line = _repos_receive (sock);
if (*line == '-') {
xml_set (list, "error-state", line + 6);
return (list);
}
line = strchr (line, '\n') + 1;
while (*line == ' ') {
count++;
copy = xml_create ("record");
end = strchr (line, '\n');
if (!end) break;
xml_set (copy, "id", "");
xml_attrncat (copy, "id", line + 1, end - line - 1);
xml_append (list, copy);
line = end + 1;
}
xml_setnum (list, "count", count);
xml_set (sock->parms, "buffer", "");
return list;
}
if (!strcmp (id, "_todo")) {
user = wftk_session_getuser (repository);
if (user) {
mark = xml_create ("where");
xml_set (mark, "field", "user");
xml_set (mark, "value", xml_attrval (user, "id"));
xml_prepend_pretty (list, mark);
}
}
if (!strcmp (id, "_tasks") || !(strcmp (id, "_todo"))) {
xml_set (list, "actual-list", id);
xml_set (list, "id", "_taskindex");
} else {
xml_unset (list, "actual-list");
}
mark = NULL;
if (*xml_attrval (list, "id")) {
mark = repos_defn (repository, xml_attrval (list, "id"));
if (mark) {
xml_copyinto (list, mark);
}
}
if (!strcmp (id, "_taskindex") && !*xml_attrval (list, "order")) xml_set (list, "order", "priority desc");
if (!strcmp (xml_attrval (list, "storage"), "here")) return list; /* An immediate mode. Handy, eh? */
xml_set (list, "error-state", "");
if (!strcmp (id, "_lists")) {
mark = xml_firstelem (repository);
while (mark) {
if (xml_is (mark, "list") && *xml_attrval (mark, "id") != '_') { /* We don't return overridden pseudolists in _lists. */
xml_append (list, xml_copy (mark));
count++;
}
mark = xml_nextelem (mark);
}
xml_setnum (list, "count", count);
return list;
}
if (!strcmp (id, "_pages")) {
mark = xml_firstelem (repository);
while (mark) {
if (xml_is (mark, "page")) {
xml_append (list, copy = xml_copy (mark));
if (xml_parent (mark) != repository) xml_set (copy, "parent", xml_attrval (xml_parent(mark), "id"));
count++;
if (xml_firstelem (mark)) {
mark = xml_firstelem (mark);
continue;
}
}
do {
if (xml_nextelem (mark)) {
mark = xml_nextelem (mark);
break;
} else {
mark = xml_parent (mark);
if (mark == repository) mark = NULL;
if (!mark) break;
}
} while (1);
}
xml_setnum (list, "count", count);
return list;
}
if (!mark && *xml_attrval (list, "id")) {
xml_setf (list, "error-state", "List %s not defined in repository.", xml_attrval (list, "id"));
repos_log (repository, 2, 0, NULL, "repmgr", "repos_list: list %s not defined", id);
return (list);
}
/* Check for a list-from index and read from that if requested. */
if (*xml_attrval (list, "list-from")) {
mark = xml_locf (list, ".index[%s]", xml_attrval (list, "list-from"));
if (mark) {
mark = xml_copy (mark);
xml_replacecontent (list, xml_createtext ("\n"));
xml_copyinto (list, mark);
xml_free (mark);
}
xml_unset (list, "id");
}
ad = wftk_get_adaptor (repository, LIST, *xml_attrval (list, "id") ? xml_attrval (list, "id") : xml_attrval (list, "storage"));
if (!ad) {
repos_log (repository, 1, 1, NULL, "repmgr", "error while listing %s: can't find adaptor for '%s'",
xml_attrval (list, "id"), xml_attrval (list, "storage"));
xml_setf (list, "error-state", "can't find adaptor for '%s'", xml_attrval (list, "storage"));
return NULL;
}
xml_set (ad->parms, "basedir", xml_attrval (repository, "basedir"));
wftk_call_adaptor (ad, "query", list);
wftk_free_adaptor (repository, ad);
/* Clean up the result list. */
mark = xml_firstelem (list); mark2 = NULL;
while (mark) {
if (xml_is (mark, "field") ||
xml_is (mark, "where") ||
xml_is (mark, "index") ||
xml_is (mark, "state")) {
xml_delete_pretty (mark);
if (mark2) mark = mark2;
else mark = xml_firstelem (list);
} else {
mark2 = mark;
mark = xml_nextelem (mark);
}
}
/*while (mark = xml_loc(list, ".where")) xml_delete (mark);
while (mark = xml_loc(list, ".index")) xml_delete (mark);*/
if (*xml_attrval (list, "actual-list")) {
xml_set (list, "id", xml_attrval (list, "actual-list"));
xml_unset (list, "actual-list");
if (!strcmp (xml_attrval (list, "id"), "_tasks") || !strcmp (xml_attrval (list, "id"), "_todo")) {
mark = xml_firstelem (list);
while (mark) {
key = xmlobj_get (mark, NULL, "key");
if (key) xml_set_nodup (mark, "id", key);
xml_set_nodup (mark, "label", xmlobj_get (mark, NULL, "label"));
xml_set_nodup (mark, "role", xmlobj_get (mark, NULL, "role"));
xml_set_nodup (mark, "user", xmlobj_get (mark, NULL, "user"));
mark = xml_nextelem (mark);
}
}
}
if (*xml_attrval (list, "error-state")) {
repos_log (repository, 2, 0, NULL, "repmgr", "repos_list %s: %s", id, xml_attrval (list, "error-state"));
}
return list;
}
/* TODO: make this work again... (it being inherently more scalable.) */
WFTK_EXPORT XML * repos_list_first (XML * repository, XML * list)
{
WFTK_ADAPTOR * ad;
XML * ret;
XML * mark;
mark = repos_defn (repository, xml_attrval (list, "id"));
if (mark) {
xml_copyinto (list, mark);
}
/* Check for a list-from index and read from that if requested. */
if (*xml_attrval (list, "list-from")) {
mark = xml_locf (list, ".index[%s]", xml_attrval (list, "list-from"));
if (mark) {
mark = xml_copy (mark);
xml_replacecontent (list, xml_createtext ("\n"));
xml_copyinto (list, mark);
xml_free (mark);
}
}
ad = wftk_get_adaptor (repository, LIST, *xml_attrval (list, "id") ? xml_attrval (list, "id") : xml_attrval (list, "storage"));
if (!ad) return NULL;
xml_set (ad->parms, "basedir", xml_attrval (repository, "basedir"));
ret = wftk_call_adaptor (ad, "first", list);
wftk_free_adaptor (repository, ad);
return ret;
}
WFTK_EXPORT XML * repos_list_next (XML * repository, XML * list)
{
WFTK_ADAPTOR * ad;
XML * ret;
/* On list_next, we don't need to do the index substitution because it's already been done. */
ad = wftk_get_adaptor (repository, LIST, *xml_attrval (list, "id") ? xml_attrval (list, "id") : xml_attrval (list, "storage"));
if (!ad) return NULL;
xml_set (ad->parms, "basedir", xml_attrval (repository, "basedir"));
ret = wftk_call_adaptor (ad, "next", list);
wftk_free_adaptor (repository, ad);
return ret;
}
|