|
@@ -1,10 +1,5 @@
|
|
|
#include "desc.h"
|
|
|
|
|
|
-static LSUP_rc
|
|
|
-desc_update (
|
|
|
- LSR_Desc *rsrc, LSUP_Graph *const *rm_data,
|
|
|
- LSUP_Graph *const *add_data, bool _new);
|
|
|
-
|
|
|
|
|
|
LSUP_rc
|
|
|
LSR_desc_new_multi (LSUP_Graph *const *data, LSR_Desc **rsrc_p)
|
|
@@ -16,9 +11,6 @@ LSR_desc_new_multi (LSUP_Graph *const *data, LSR_Desc **rsrc_p)
|
|
|
|
|
|
uuid_generate_random (rsrc->id);
|
|
|
|
|
|
- LSUP_Graph *const *rm_data = {NULL};
|
|
|
- PCHECK (desc_update (rsrc, rm_data, data, true), finally);
|
|
|
-
|
|
|
// Default context graph.
|
|
|
LSUP_Term *main_data_urn = LSR_id_to_urn (rsrc->id, "__main");
|
|
|
rsrc->main_data = LSUP_graph_new (NULL, main_data_urn, LSUP_default_nsm);
|
|
@@ -27,97 +19,82 @@ LSR_desc_new_multi (LSUP_Graph *const *data, LSR_Desc **rsrc_p)
|
|
|
"Main data graph: %s",
|
|
|
LSUP_graph_uri(rsrc->main_data)->data);
|
|
|
|
|
|
- LSUP_GraphIterator *add_it = NULL;
|
|
|
-
|
|
|
- LSUP_Term *s, *p, *o;
|
|
|
- LSUP_Triple dest_spo_s;
|
|
|
- LSUP_Triple *dest_spo = &dest_spo_s;
|
|
|
+ PCHECK (LSR_desc_update (rsrc, NULL, data), finally);
|
|
|
|
|
|
LSUP_Term *rsrc_uri = LSR_id_to_urn (rsrc->id, NULL);
|
|
|
- LSUP_Term *rdf_t = LSUP_iriref_new ("rdf:type", LSUP_default_nsm);
|
|
|
|
|
|
/* BEGIN adding managed (admin) data. */
|
|
|
|
|
|
- LSUP_Term *gr_uri = LSR_id_to_urn (rsrc->id, "__admin");
|
|
|
- rsrc->admin_data = LSUP_graph_new (NULL, gr_uri, NULL);
|
|
|
+ LSUP_Term *admin_uri = LSR_id_to_urn (rsrc->id, "__admin");
|
|
|
+ rsrc->admin_data = LSUP_graph_new (NULL, admin_uri, NULL);
|
|
|
+
|
|
|
log_debug (
|
|
|
"Admin data graph (@%p): %s",
|
|
|
- LSUP_graph_uri(rsrc->admin_data),
|
|
|
- LSUP_graph_uri(rsrc->admin_data)->data);
|
|
|
-
|
|
|
- add_it = LSUP_graph_add_init (rsrc->admin_data);
|
|
|
- s = LSUP_iriref_new("", NULL); // Relative to resource URI.
|
|
|
- LSUP_Triple admin_spo_s;
|
|
|
- LSUP_Triple *admin_spo = &admin_spo_s;
|
|
|
-
|
|
|
- // RDF types.
|
|
|
- p = rdf_t;
|
|
|
+ LSUP_graph_uri (rsrc->admin_data),
|
|
|
+ LSUP_graph_uri (rsrc->admin_data)->data);
|
|
|
|
|
|
- o = LSUP_iriref_new ("lsup:Resource", LSUP_default_nsm);
|
|
|
- LSUP_triple_init (admin_spo, s, p, o);
|
|
|
- LSUP_graph_add_iter (add_it, admin_spo);
|
|
|
- LSUP_term_free (o);
|
|
|
-
|
|
|
- o = LSUP_iriref_new ("lsup:DescriptiveResource", LSUP_default_nsm);
|
|
|
- LSUP_triple_init (admin_spo, s, p, o);
|
|
|
- LSUP_graph_add_iter (add_it, admin_spo);
|
|
|
- LSUP_term_free (o);
|
|
|
-
|
|
|
- // Timestamps. For now, second precision is fine.
|
|
|
+ // Calculate timestamp.
|
|
|
time_t now;
|
|
|
time (&now);
|
|
|
- char buf [sizeof ("0000-00-00T00:00:00Z")];
|
|
|
- strftime (buf, sizeof (buf), "%FT%TZ", gmtime (&now));
|
|
|
-
|
|
|
- p = LSUP_iriref_new ("lsup:created", LSUP_default_nsm);
|
|
|
- o = LSUP_literal_new (
|
|
|
- buf, LSUP_iriref_new ("xsd:dateTime", LSUP_default_nsm));
|
|
|
- LSUP_triple_init (admin_spo, s, p, o);
|
|
|
- LSUP_graph_add_iter (add_it, admin_spo);
|
|
|
- LSUP_term_free (p);
|
|
|
-
|
|
|
- p = LSUP_iriref_new ("lsup:lastModified", LSUP_default_nsm);
|
|
|
- LSUP_triple_init (admin_spo, s, p, o);
|
|
|
- LSUP_graph_add_iter (add_it, admin_spo);
|
|
|
- LSUP_term_free (p);
|
|
|
- LSUP_term_free (o);
|
|
|
- LSUP_graph_add_done (add_it);
|
|
|
+ char tstamp [sizeof ("0000-00-00T00:00:00Z")];
|
|
|
+ strftime (tstamp, sizeof (tstamp), "%FT%TZ", gmtime (&now));
|
|
|
+
|
|
|
+ LSUP_Term
|
|
|
+ *s = LSUP_iriref_new("", NULL), // Relative to resource URI.
|
|
|
+ *created_t = LSUP_iriref_new ("lsup:created", LSUP_default_nsm),
|
|
|
+ *rsrc_t = LSUP_iriref_new ("lsup:Resource", LSUP_default_nsm),
|
|
|
+ *desc_rsrc_t = LSUP_iriref_new (
|
|
|
+ "lsup:DescriptiveResource", LSUP_default_nsm),
|
|
|
+ *ts_t = LSUP_literal_new (
|
|
|
+ tstamp, LSUP_iriref_new ("xsd:dateTime", LSUP_default_nsm));
|
|
|
+
|
|
|
+ LSUP_Triple *admin_trp[] = {
|
|
|
+ LSUP_triple_new (s, LSR_rdf_t, rsrc_t),
|
|
|
+ LSUP_triple_new (s, LSR_rdf_t, desc_rsrc_t),
|
|
|
+ LSUP_triple_new (s, created_t, ts_t),
|
|
|
+ NULL,
|
|
|
+ };
|
|
|
+
|
|
|
+ rc = LSUP_graph_add (rsrc->admin_data, admin_trp, NULL);
|
|
|
+ PCHECK (rc, finally);
|
|
|
+
|
|
|
+ for (size_t i = 0; admin_trp[i]; i++)
|
|
|
+ free (admin_trp[i]);
|
|
|
+ LSUP_term_free (s);
|
|
|
+ LSUP_term_free (created_t);
|
|
|
+ LSUP_term_free (rsrc_t);
|
|
|
+ LSUP_term_free (desc_rsrc_t);
|
|
|
+ LSUP_term_free (ts_t);
|
|
|
|
|
|
/* END adding admin data. */
|
|
|
|
|
|
/* BEGIN adding graph metadata (main). */
|
|
|
|
|
|
- add_it = LSUP_graph_add_init (rsrc->main_data);
|
|
|
- LSUP_term_free (s);
|
|
|
- s = gr_uri;
|
|
|
- p = rdf_t;
|
|
|
-
|
|
|
- o = LSUP_iriref_new ("lsup:Metadata", LSUP_default_nsm);
|
|
|
- LSUP_triple_init (dest_spo, s, p, o);
|
|
|
- LSUP_graph_add_iter (add_it, dest_spo);
|
|
|
- LSUP_term_free (o);
|
|
|
-
|
|
|
- o = LSUP_iriref_new ("lsup:AdminMetadata", LSUP_default_nsm);
|
|
|
- LSUP_triple_init (dest_spo, s, p, o);
|
|
|
- LSUP_graph_add_iter (add_it, dest_spo);
|
|
|
- LSUP_term_free (o);
|
|
|
-
|
|
|
- // Relationship between data graph and resource.
|
|
|
- p = LSUP_iriref_new ("foaf:primaryTopic", LSUP_default_nsm);
|
|
|
- o = rsrc_uri;
|
|
|
- LSUP_triple_init (dest_spo, s, p, o);
|
|
|
- LSUP_graph_add_iter (add_it, dest_spo);
|
|
|
- LSUP_term_free (p);
|
|
|
- LSUP_term_free (s); // === gr_uri
|
|
|
-
|
|
|
- LSUP_graph_add_done (add_it);
|
|
|
- add_it = NULL;
|
|
|
+ LSUP_Term
|
|
|
+ *meta_t = LSUP_iriref_new ("lsup:Metadata", LSUP_default_nsm),
|
|
|
+ *admin_meta_t = LSUP_iriref_new (
|
|
|
+ "lsup:AdminMetadata", LSUP_default_nsm),
|
|
|
+ *topic_t = LSUP_iriref_new ("foaf:primaryTopic", LSUP_default_nsm);
|
|
|
+ LSUP_Triple *main_trp[] = {
|
|
|
+ LSUP_triple_new (admin_uri, LSR_rdf_t, meta_t),
|
|
|
+ LSUP_triple_new (admin_uri, LSR_rdf_t, admin_meta_t),
|
|
|
+ LSUP_triple_new (admin_uri, topic_t, rsrc_uri),
|
|
|
+ NULL
|
|
|
+ };
|
|
|
+
|
|
|
+ rc = LSUP_graph_add (rsrc->main_data, main_trp, NULL);
|
|
|
+
|
|
|
+ for (size_t i = 0; main_trp[i]; i++)
|
|
|
+ free (main_trp[i]);
|
|
|
+ LSUP_term_free (meta_t);
|
|
|
+ LSUP_term_free (admin_meta_t);
|
|
|
+ LSUP_term_free (topic_t);
|
|
|
|
|
|
/* END adding graph metadata. */
|
|
|
|
|
|
finally:
|
|
|
LSUP_term_free (rsrc_uri);
|
|
|
- LSUP_term_free (rdf_t);
|
|
|
+ LSUP_term_free (admin_uri);
|
|
|
|
|
|
if (rc < 0) goto fail;
|
|
|
|
|
@@ -128,17 +105,29 @@ finally:
|
|
|
return rc;
|
|
|
|
|
|
fail:
|
|
|
- LSUP_graph_add_done (add_it);
|
|
|
LSR_desc_free (rsrc);
|
|
|
*rsrc_p = NULL;
|
|
|
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+void LSR_desc_free (LSR_Desc *rsrc)
|
|
|
+{
|
|
|
+ size_t i = 0;
|
|
|
+ while (rsrc->user_data[i])
|
|
|
+ LSUP_graph_free (rsrc->user_data[i++]);
|
|
|
+ free (rsrc->user_data);
|
|
|
+
|
|
|
+ LSUP_graph_free (rsrc->admin_data);
|
|
|
+ LSUP_graph_free (rsrc->main_data);
|
|
|
+ free (rsrc);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
LSUP_rc
|
|
|
LSR_desc_store (const LSR_Desc *rsrc)
|
|
|
{
|
|
|
- // TODO Make atomic. Needs to implement transactions in backend.
|
|
|
LSR_Desc *old_rsrc;
|
|
|
PRCCK (LSR_desc_get (rsrc->id, &old_rsrc));
|
|
|
|
|
@@ -315,44 +304,41 @@ LSR_desc_user_data (const LSR_Desc *rsrc)
|
|
|
}
|
|
|
|
|
|
|
|
|
-LSUP_Graph *
|
|
|
+LSUP_rc
|
|
|
LSR_desc_update (
|
|
|
- LSR_Desc *rsrc, LSUP_Graph *const *remove, LSUP_Graph *const *add)
|
|
|
-{ return desc_update (rsrc, remove, add, false); }
|
|
|
-
|
|
|
-
|
|
|
-void LSR_desc_free (LSR_Desc *rsrc)
|
|
|
-{
|
|
|
- size_t i = 0;
|
|
|
- while (rsrc->user_data[i])
|
|
|
- LSUP_graph_free (rsrc->user_data[i++]);
|
|
|
- free (rsrc->user_data);
|
|
|
-
|
|
|
- LSUP_graph_free (rsrc->admin_data);
|
|
|
- LSUP_graph_free (rsrc->main_data);
|
|
|
- free (rsrc);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/** @brief Update a resource's user data.
|
|
|
- *
|
|
|
- * This is exposed externally by #LSR_desc_update(), in which it only differs
|
|
|
- * from the additional "new" parameter, which is used by #LSR_desc_new_multi()
|
|
|
- * to indicate that the resource being updated has just been created.
|
|
|
- */
|
|
|
-static LSUP_rc
|
|
|
-desc_update (
|
|
|
LSR_Desc *rsrc, LSUP_Graph *const *rm_data,
|
|
|
- LSUP_Graph *const *add_data, bool _new)
|
|
|
+ LSUP_Graph *const *add_data)
|
|
|
{
|
|
|
LSUP_rc rc = LSUP_NOACTION;
|
|
|
LSUP_Term *rsrc_uri = LSR_id_to_urn (rsrc->id, NULL);
|
|
|
|
|
|
+ size_t ct;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * REMOVE user data.
|
|
|
+ */
|
|
|
+
|
|
|
+ if (rm_data) {
|
|
|
+ // Count graphs to be removed.
|
|
|
+ ct = 0;
|
|
|
+ while (add_data[ct]) ct++;
|
|
|
+ for (size_t i = 0; i < ct; i++) {
|
|
|
+ LSUP_Term *gr_uri = LSUP_graph_uri (rm_data[i]);
|
|
|
+ // TODO remove ops.
|
|
|
+ // TODO if graph is empty after removal, remove it.
|
|
|
+ LSUP_term_free (gr_uri);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * ADD user data.
|
|
|
+ */
|
|
|
+
|
|
|
// Count graphs inserted and allocate space.
|
|
|
- size_t ct = 0;
|
|
|
+ ct = 0;
|
|
|
while (add_data[ct]) ct++;
|
|
|
rsrc->user_data = calloc (sizeof (*rsrc->user_data), ct + 1);
|
|
|
- if (UNLIKELY (! rsrc->user_data)) return NULL;
|
|
|
+ if (UNLIKELY (! rsrc->user_data)) return LSUP_MEM_ERR;
|
|
|
|
|
|
LSUP_Triple spo_s;
|
|
|
LSUP_Triple *spo = &spo_s;
|
|
@@ -383,6 +369,7 @@ desc_update (
|
|
|
|
|
|
// Loop over graph triples.
|
|
|
LSUP_Term *dest_s, *dest_p, *dest_o;
|
|
|
+ LSUP_Triple *src_spo;
|
|
|
while (LSUP_graph_iter_next (lu_it, &src_spo) == LSUP_OK) {
|
|
|
dest_s = LSUP_IS_IRI (src_spo->s) ?
|
|
|
LSUP_iriref_relative (rsrc_uri, src_spo->s) : src_spo->s;
|
|
@@ -412,7 +399,7 @@ desc_update (
|
|
|
if (tmp_rc != LSUP_OK) {
|
|
|
log_error (
|
|
|
"Referenced subject does not exist: %s",
|
|
|
- dest_s->data + strlen (LSR_RSRC_NS));
|
|
|
+ dest_s->data);
|
|
|
rc = LSUP_VALUE_ERR;
|
|
|
goto finally;
|
|
|
}
|
|
@@ -434,7 +421,7 @@ desc_update (
|
|
|
if (
|
|
|
LSUP_term_equals (
|
|
|
gr_uri, LSUP_iriref_absolute (rsrc_uri, spo->s))
|
|
|
- && LSUP_term_equals (rdf_t, spo->p)
|
|
|
+ && LSUP_term_equals (LSR_rdf_t, spo->p)
|
|
|
) {
|
|
|
// If the resource is a special type, handle specific workflow.
|
|
|
if (hashmap_get (LSR_managed_types, spo->o)) {
|
|
@@ -461,8 +448,13 @@ loop_end:
|
|
|
if (dest_o != src_spo->o) LSUP_term_free (dest_o);
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * UPDATE graph metadata.
|
|
|
+ */
|
|
|
+
|
|
|
// Add user graph metadata to default graph.
|
|
|
- admin_add_it = LSUP_graph_add_init (rsrc->main_data);
|
|
|
+ LSUP_GraphIterator *admin_add_it = LSUP_graph_add_init (
|
|
|
+ rsrc->main_data);
|
|
|
dest_s = gr_uri;
|
|
|
dest_p = LSUP_iriref_new ("rdf:type", LSUP_default_nsm);
|
|
|
|
|
@@ -492,9 +484,10 @@ loop_end:
|
|
|
|
|
|
finally:
|
|
|
LSUP_term_free (rsrc_uri);
|
|
|
- LSUP_graph_iter_free (lu_it);
|
|
|
- LSUP_graph_add_done (add_it);
|
|
|
+ if (lu_it) LSUP_graph_iter_free (lu_it);
|
|
|
+ if (add_it) LSUP_graph_add_done (add_it);
|
|
|
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
|