|
WFTK_EXPORT XML * repos_attach_open (XML * repository, const char *list_id, const char * key, const char * field, const char * filename)
{
XML * handle;
XML * list;
XML * fld;
XML * fld_def;
XML * object;
WFTK_ADAPTOR * ad_l;
WFTK_ADAPTOR * ad_f = NULL;
/* Get list definition. */
list = repos_defn (repository, list_id);
if (!list) return 0;
/* Retrieve object. */
ad_l = wftk_get_adaptor (repository, LIST, *xml_attrval (list, "id") ? xml_attrval (list, "id") : xml_attrval (list, "storage"));
if (!ad_l) return NULL;
xml_set (ad_l->parms, "basedir", xml_attrval (repository, "basedir"));
object = wftk_call_adaptor (ad_l, "get", list, key);
if (!object) {
wftk_free_adaptor (repository, ad_l);
return 0;
}
/* Find appropriate field -- in object first, then if not found, in list definition. */
if (field && *field) {
fld = xmlobj_is_field (object, list, field);
fld_def = xml_search (list, "field", "id", field);
if (!fld) {
fld = xml_create ("field");
xml_set (fld, "id", field);
if (fld_def) {
xml_set (fld, "type", xml_attrval (fld_def, "type"));
} else {
xml_set (fld, "type", "document");
}
xml_append_pretty (object, fld);
}
} else {
fld = xml_search (object, "field", "type", "document");
fld_def = xml_search (list, "field", "type", "document");
if (!fld && !fld_def) {
wftk_free_adaptor (repository, ad_l);
xml_free (object);
return 0;
}
if (!fld) {
fld = xml_create ("field");
xml_set (fld, "id", xml_attrval (fld_def, "id"));
xml_append_pretty (object, fld);
}
}
field = (char *) xml_attrval (fld, "id");
/* Perform the actual attachment. */
if (fld_def) {
if (*xml_attrval (fld_def, "storage")) ad_f = wftk_get_adaptor (repository, LIST, *xml_attrval (fld_def, "id") ? xml_attrval (fld_def, "id") : xml_attrval (fld_def, "storage"));
if (ad_f) xml_set (ad_f->parms, "basedir", xml_attrval (repository, "basedir"));
if (*xml_attrval (fld_def, "ver-keep")) {
if (!*xml_attrval (fld, "ver")) xml_set (fld, "ver", "0");
xml_setnum (fld, "next-ver", xml_attrvalnum (fld, "ver") + 1);
}
} else {
if (*xml_attrval (fld, "ver")) {
xml_setnum (fld, "next-ver", xml_attrvalnum (fld, "ver") + 1);
}
}
handle = wftk_call_adaptor (ad_f ? ad_f : ad_l, "attach_open", list, key, field, filename, xml_attrval (fld, "next-ver"));
wftk_free_adaptor (repository, ad_l);
if (ad_f) wftk_free_adaptor (repository, ad_f);
xml_setnum (handle, "size", 0);
xml_set (handle, "list", list_id);
xml_set (handle, "key", key);
xml_set (handle, "field", field);
xml_free (object);
return handle;
}
WFTK_EXPORT int repos_attach_write (void * buf, size_t size, size_t number, XML * handle)
{
WFTK_ADAPTOR * ad;
if (!handle) return 0;
if (!buf) return 0;
if (!size || !number) return 0;
ad = wftk_get_adaptor (handle, LIST, xml_attrval (handle, "adaptor"));
if (!ad) return 0;
wftk_call_adaptor (ad, "attach_write", buf, size, number, handle);
wftk_free_adaptor (handle, ad);
xml_setnum (handle, "size", xml_attrvalnum (handle, "size") + xml_attrvalnum (handle, "last-write"));
return xml_attrvalnum (handle, "last-write");
}
WFTK_EXPORT int repos_attach_cancel (XML * handle)
{
WFTK_ADAPTOR * ad;
if (!handle) return 0;
ad = wftk_get_adaptor (handle, LIST, xml_attrval (handle, "adaptor"));
if (!ad) return 0;
wftk_call_adaptor (ad, "attach_cancel", handle);
wftk_free_adaptor (handle, ad);
return 0;
}
WFTK_EXPORT int repos_attach_close (XML * repository, XML * handle)
{
WFTK_ADAPTOR * ad;
XML * list;
XML * fld;
XML * fld_def;
XML * object;
const char * list_id;
const char * key;
const char * field;
WFTK_ADAPTOR * ad_l;
if (!handle) return 0;
list_id = xml_attrval (handle, "list");
key = xml_attrval (handle, "key");
field = xml_attrval (handle, "field");
/* Get list definition. */
list = repos_defn (repository, list_id);
if (!list) return 0;
/* Retrieve object. */
ad_l = wftk_get_adaptor (repository, LIST, *xml_attrval (list, "id") ? xml_attrval (list, "id") : xml_attrval (list, "storage"));
if (!ad_l) return 0;
xml_set (ad_l->parms, "basedir", xml_attrval (repository, "basedir"));
object = wftk_call_adaptor (ad_l, "get", list, key);
if (!object) {
wftk_free_adaptor (repository, ad_l);
return 0;
}
/* Find appropriate field -- in object first, then if not found, in list definition. */
if (field && *field) {
fld = xmlobj_is_field (object, list, field);
fld_def = xml_search (list, "field", "id", field);
if (!fld) {
fld = xml_create ("field");
xml_set (fld, "id", field);
if (fld_def) {
xml_set (fld, "type", xml_attrval (fld_def, "type"));
} else {
xml_set (fld, "type", "document");
}
xml_append_pretty (object, fld);
}
} else {
fld = xml_search (object, "field", "type", "document");
fld_def = xml_search (list, "field", "type", "document");
if (!fld && !fld_def) {
wftk_free_adaptor (repository, ad_l);
xml_free (object);
return 0;
}
if (!fld) {
fld = xml_create ("field");
xml_set (fld, "id", xml_attrval (fld_def, "id"));
xml_append_pretty (object, fld);
}
}
field = (char *) xml_attrval (fld, "id");
/* Complete attachment process. */
ad = wftk_get_adaptor (repository, LIST, xml_attrval (handle, "adaptor"));
if (!ad) return 0;
wftk_call_adaptor (ad, "attach_close", handle);
wftk_free_adaptor (repository, ad);
/* Update the object. */
if (*xml_attrval (fld, "next-ver")) {
xml_set (fld, "ver", xml_attrval (fld, "next-ver"));
fld = xmlobj_ver_direct (fld, xml_attrval (fld, "ver"));
}
xml_set (fld, "size", xml_attrval (handle, "size"));
xml_set (fld, "mimetype", xml_attrval (handle, "mimetype"));
xml_set (fld, "location", xml_attrval (handle, "location"));
wftk_call_adaptor (ad_l, "update", list, object);
/* Log the change. */
if (strcmp (xml_attrval (list, "logging"), "off")) { /* TODO: check overall setting as well. Need a setting checker which scans upward. */
_repos_log (repository, "mod", list_id, object ? repos_getkey (repository, list_id, object) : key);
}
_repos_publish_obj (repository, list_id, object);
/* Free everything up. */
wftk_free_adaptor (repository, ad_l);
xml_free (object);
return 0;
}
WFTK_EXPORT int repos_attach (XML * repository, const char * list_id, const char * key, const char * field, const char * filename, FILE * incoming)
{
XML * handle;
XML * list;
XML * fld;
XML * fld_def;
XML * object;
WFTK_ADAPTOR * ad_l = NULL;
WFTK_ADAPTOR * ad_f = NULL;
char buf[1024];
int total = 0;
int number;
/* Get list definition. */
list = repos_defn (repository, list_id);
if (!list) return 0;
/* Retrieve object. */
ad_l = wftk_get_adaptor (repository, LIST, *xml_attrval (list, "id") ? xml_attrval (list, "id") : xml_attrval (list, "storage"));
if (!ad_l) return 0;
xml_set (ad_l->parms, "basedir", xml_attrval (repository, "basedir"));
object = wftk_call_adaptor (ad_l, "get", list, key);
if (!object) {
wftk_free_adaptor (repository, ad_l);
return 0;
}
/* Find appropriate field -- in object first, then if not found, in list definition. */
if (field && *field) {
fld = xmlobj_is_field (object, list, field);
fld_def = xml_search (list, "field", "id", field);
if (!fld) {
fld = xml_create ("field");
xml_set (fld, "id", field);
if (fld_def) {
xml_set (fld, "type", xml_attrval (fld_def, "type"));
} else {
xml_set (fld, "type", "document");
}
xml_append_pretty (object, fld);
}
} else {
fld = xml_search (object, "field", "type", "document");
fld_def = xml_search (list, "field", "type", "document");
if (!fld && !fld_def) {
wftk_free_adaptor (repository, ad_l);
xml_free (object);
return 0;
}
if (!fld) {
fld = xml_create ("field");
xml_set (fld, "id", xml_attrval (fld_def, "id"));
xml_append_pretty (object, fld);
}
}
field = (char *) xml_attrval (fld, "id");
/* Perform the actual attachment. */
if (fld_def) {
if (*xml_attrval (fld_def, "storage")) ad_f = wftk_get_adaptor (repository, LIST, *xml_attrval (fld_def, "id") ? xml_attrval (fld_def, "id") : xml_attrval (fld_def, "storage"));
if (ad_f) xml_set (ad_f->parms, "basedir", xml_attrval (repository, "basedir"));
if (*xml_attrval (fld_def, "ver-keep")) {
if (!*xml_attrval (fld, "ver")) xml_set (fld, "ver", "0");
xml_setnum (fld, "next-ver", xml_attrvalnum (fld, "ver") + 1);
}
} else {
if (*xml_attrval (fld, "ver")) {
xml_setnum (fld, "next-ver", xml_attrvalnum (fld, "ver") + 1);
}
}
handle = wftk_call_adaptor (ad_f ? ad_f : ad_l, "attach_open", list, key, field, filename, xml_attrval (fld, "next-ver"));
while (number = fread (buf, 1, sizeof (buf), incoming)) {
total += number;
wftk_call_adaptor (ad_f ? ad_f : ad_l, "attach_write", buf, 1, number, handle);
if (number < sizeof(buf)) break;
}
wftk_call_adaptor (ad_f ? ad_f : ad_l, "attach_close", handle);
xml_setnum (handle, "size", total);
/* Update the object. */
if (*xml_attrval (fld, "next-ver")) {
xml_set (fld, "ver", xml_attrval (fld, "next-ver"));
fld = xmlobj_ver_direct (fld, xml_attrval (fld, "ver"));
}
xml_set (fld, "size", xml_attrval (handle, "size"));
xml_set (fld, "mimetype", xml_attrval (handle, "mimetype"));
xml_set (fld, "location", xml_attrval (handle, "location"));
wftk_call_adaptor (ad_l, "update", list, object);
/* Log the change. */
if (strcmp (xml_attrval (list, "logging"), "off")) { /* TODO: check overall setting as well. Need a setting checker which scans upward. */
_repos_log (repository, "att", list_id, object ? repos_getkey (repository, list_id, object) : key);
}
_repos_publish_obj (repository, list_id, object);
/* Free everything up. */
wftk_free_adaptor (repository, ad_l);
if (ad_f) wftk_free_adaptor (repository, ad_f);
xml_free (object);
xml_free (handle);
return total;
}
|