Browse Source

Merge branch 'master' of ssh://ktx/home/stefano/git/lsup_repo

Stefano Cossu 2 years ago
parent
commit
b698150d82
4 changed files with 178 additions and 6 deletions
  1. 38 4
      include/desc.h
  2. 12 0
      src/core.c
  3. 123 2
      src/desc.c
  4. 5 0
      test/test_desc.c

+ 38 - 4
include/desc.h

@@ -73,7 +73,10 @@ typedef struct desc_t {
  *  `#set37205`, `#~alice`, or `#ancillary`. Fragments beginning with two
  *  underscores are reserved for internal use and are not allowed in the input.
  *
- * @param[out] rsrc Resource handle. It must be freed with #LSR_desc_free().
+ * @param[out] rsrc Resource handle pointer. The handle should be freed with
+ *  #LSR_desc_free(). On a non-success return code, the handle may be garbage.
+ *
+ * @return LSUP_OK on success; < 0 on error.
  */
 LSUP_rc
 LSR_desc_new_multi (LSUP_Graph *const *data, LSR_Desc **rsrc);
@@ -86,7 +89,10 @@ LSR_desc_new_multi (LSUP_Graph *const *data, LSR_Desc **rsrc);
  *
  * @param[in] data Single graph to insert.
  *
- * @param[out] rsrc Resource handle. It must be freed with #LSR_desc_free().
+ * @param[out] rsrc Resource handle pointer. The handle should be freed with
+ *  #LSR_desc_free(). On a non-success return code, the handle may be garbage.
+ *
+ * @return LSUP_OK on success; < 0 on error.
  */
 LSUP_rc
 LSR_desc_new (const LSUP_Graph *data, LSR_Desc **rsrc);
@@ -102,8 +108,9 @@ LSR_desc_new (const LSUP_Graph *data, LSR_Desc **rsrc);
  * @param[in] id ID of the resource to be retrieved, without the namespace.
  *
  * @param[out] rsrc Resource handle to be populated with the found resource. It
- *  must be freed with #LSR_desc_free(). If NULL, the resource is only checked
- *  for existence (much faster).
+ *  should be freed with #LSR_desc_free(). If NULL, the resource is only
+ *  checked for existence (much faster). On a non-success return code, the
+ *  handle may be garbage.
  *
  * @return LSUP_OK if the resource is found; LSUP_NORESULT if not found; <0
  *  on error.
@@ -118,6 +125,33 @@ void
 LSR_desc_free (LSR_Desc *rsrc);
 
 
+/** @brief Get resource metadata.
+ *
+ * Return all repository-managed triples about the resource.
+ *
+ * @param[in] rsrc Resource to be inspected.
+ *
+ * @return In-memory graph with metadata triples.
+ */
+LSUP_Graph *
+LSR_desc_metadata (const LSR_Desc *rsrc);
+
+
+/** @brief Get user-defined data.
+ *
+ * Return all user-defined triples in the resource in a single graph.
+ *
+ * The resulting graph IRI is the resource IRI with a random fragment string
+ * appended.
+ *
+ * @param[in] rsrc Resource to be inspected.
+ *
+ * @return NULL-terminated array of in-memory graphs with data triples.
+ */
+LSUP_Graph **
+LSR_desc_user_data (const LSR_Desc *rsrc);
+
+
 /** @brief Store a DESC-R, overwriting any data if it already exists.
  *
  * This is a "create or overwrite" function that deletes any existing resource

+ 12 - 0
src/core.c

@@ -125,6 +125,18 @@ void LSR_done (void)
 
     log_info ("Tearing down LSUP repo environment.");
 
+    LSR_TermMap *entry, *tmp;
+    HASH_ITER (hh, LSR_managed_preds, entry, tmp) {
+        HASH_DEL (LSR_managed_preds, entry);
+        LSUP_term_free (entry->term);
+        free (entry);
+    }
+    HASH_ITER (hh, LSR_managed_types, entry, tmp) {
+        HASH_DEL (LSR_managed_types, entry);
+        LSUP_term_free (entry->term);
+        free (entry);
+    }
+
     hashmap_free (LSR_managed_preds);
     hashmap_free (LSR_managed_types);
     LSUP_done();

+ 123 - 2
src/desc.c

@@ -293,7 +293,7 @@ LSUP_desc_update (LSR_id id, LSUP_Term **remove, LSUP_Triple *add)
 
 
 LSUP_rc
-LSR_desc_get (const uuid_t id, LSR_Desc **rsrc)
+LSR_desc_get (const uuid_t id, LSR_Desc **rsrc_p)
 {
     LSUP_rc rc = LSUP_OK;
 
@@ -336,7 +336,7 @@ LSR_desc_get (const uuid_t id, LSR_Desc **rsrc)
     }
     LSUP_graph_iter_free (it);
 
-    rc = LSR_desc_new_multi (data, rsrc);
+    rc = LSR_desc_new_multi (data, rsrc_p);
 
     i = 0;
     while (i < ct) LSUP_graph_free (data[i++]);
@@ -353,6 +353,77 @@ finally:
 }
 
 
+LSUP_Graph *
+LSR_desc_metadata (const LSR_Desc *rsrc)
+{
+    uuid_t uuid;
+    char 
+        *rsrc_uri_str = LSUP_graph_uri (rsrc->admin_data)->data,
+        *frag = "#metadata-",
+        uuid_str [UUID_STR_LEN],
+        id_str [8],
+        *uri_str = malloc (
+                strlen (frag) + strlen (rsrc_uri_str) + sizeof (id_str));
+    if (UNLIKELY (!uri_str)) return NULL;
+
+    uuid_generate_random (uuid);
+    uuid_unparse_lower (uuid, uuid_str);
+    strncpy (id_str, uuid_str, sizeof (id_str) - 1);
+
+    sprintf (uri_str, "%s%s%s", rsrc_uri_str, frag, id_str);
+
+    LSUP_Graph *res = LSUP_graph_copy (rsrc->admin_data);
+    if (LIKELY (res))
+        LSUP_graph_set_uri (res, LSUP_iriref_new (uri_str, NULL));
+
+    free (uri_str);
+    free (rsrc_uri_str);
+    free (uuid);
+
+    return res;
+}
+
+
+LSUP_Graph **
+LSR_desc_user_data (const LSR_Desc *rsrc)
+{
+    uuid_t uuid;
+    char 
+        *rsrc_uri_str = LSUP_graph_uri (rsrc->admin_data)->data,
+        *frag = "#metadata-",
+        uuid_str [UUID_STR_LEN],
+        id_str [8],
+        *uri_str = malloc (
+                strlen (frag) + strlen (rsrc_uri_str) + sizeof (id_str));
+    if (UNLIKELY (!uri_str)) return NULL;
+
+    size_t ct = 0;
+    while (rsrc->user_data[ct]) ct ++;
+    LSUP_Graph **res = malloc (sizeof *res * (ct + 1));
+    if (UNLIKELY (!res)) return NULL;
+
+    for (size_t i = 0; i < ct; i++) {
+        uuid_generate_random (uuid);
+        uuid_unparse_lower (uuid, uuid_str);
+        strncpy (id_str, uuid_str, sizeof (id_str) - 1);
+
+        sprintf (uri_str, "%s%s%s", rsrc_uri_str, frag, id_str);
+
+        res[i] = LSUP_graph_copy (rsrc->user_data[i]);
+        if (LIKELY (res))
+            LSUP_graph_set_uri (res[i], LSUP_iriref_new (uri_str, NULL));
+    }
+
+    res[ct] = NULL;
+
+    free (uri_str);
+    free (rsrc_uri_str);
+    free (uuid);
+
+    return res;
+}
+
+
 void LSR_desc_free (LSR_Desc *rsrc)
 {
     size_t i = 0;
@@ -364,3 +435,53 @@ void LSR_desc_free (LSR_Desc *rsrc)
     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;
+    LSUP_rc rc = LSR_desc_get (rsrc->id, &old_rsrc);
+    if (UNLIKELY (rc < 0)) return rc;
+
+    // Remove all existing user graphs.
+    if (rc == LSUP_OK) {
+        //LSUP_Term *main_data_urn = LSUP_graph_uri (old_rsrc->main_data);
+        for (size_t i = 0; old_rsrc->user_data[i] != NULL; i++) {
+            LSUP_Term *gr_uri = LSUP_graph_uri (old_rsrc->user_data[i]);
+            size_t ct;
+            // Remove triples from user graph.
+            LSUP_graph_remove (old_rsrc->user_data[i], NULL, NULL, NULL, &ct);
+            log_debug ( "Removed %lu triples from graph %s", ct, gr_uri->data);
+
+            // Remove user graph metadata.
+            LSUP_graph_remove (old_rsrc->main_data, gr_uri, NULL, NULL, NULL);
+            LSUP_graph_remove (old_rsrc->main_data, NULL, NULL, gr_uri, NULL);
+        }
+    } else rc = LSUP_OK;
+
+    // Add new triples.
+    for (size_t i = 0; rsrc->user_data[i] != NULL; i++) {
+        //LSUP_Term *gr_uri = LSUP_graph_uri (rsrc->user_data[i]);
+
+        log_trace ("Storing data graph #%lu", i);
+        LSUP_graph_store (rsrc->user_data[i], NULL, NULL);
+    }
+
+    // Update admin data.
+    LSUP_graph_store (rsrc->admin_data, NULL, NULL);
+    // Update graph metadata.
+    LSUP_graph_store (rsrc->main_data, NULL, NULL);
+
+    return rc;
+}
+
+
+LSUP_rc
+LSUP_desc_update (LSR_id id, LSUP_Term **remove, LSUP_Triple *add)
+{
+    LSUP_rc rc = LSUP_OK;
+
+    return rc;
+}

+ 5 - 0
test/test_desc.c

@@ -47,6 +47,8 @@ test_desc_create()
     LSR_Desc *rsrc;
     EXPECT_PASS (LSR_desc_new_multi (data, &rsrc));
 
+    // Free input handles before using the resource to ensure that these
+    // pointers are not being referenced by the resource.
     LSUP_graph_free (gr1);
     LSUP_graph_free (gr2);
 
@@ -57,6 +59,9 @@ test_desc_create()
 
     // TODO more action
 
+    // Store for next test before freeing.
+    EXPECT_PASS (LSR_desc_store (rsrc));
+
     LSR_desc_free (rsrc);
 
     return 0;