Browse Source

Initial (faulty) Python graph from lookup method.

Stefano Cossu 3 years ago
parent
commit
99a7057b0e
7 changed files with 97 additions and 55 deletions
  1. 75 39
      cpython/py_graph.h
  2. 2 1
      include/core.h
  3. 2 2
      include/environment.h
  4. 2 2
      include/graph.h
  5. 1 0
      src/core.c
  6. 7 7
      src/environment.c
  7. 8 4
      src/graph.c

+ 75 - 39
cpython/py_graph.h

@@ -172,7 +172,10 @@ Graph_get_uri (GraphObject *self, void *closure)
 static int
 Graph_set_uri (GraphObject *self, PyObject *value, void *closure)
 {
-    if (!PyObject_TypeCheck (value, &TermType)) return -1;
+    if (!PyObject_TypeCheck (value, &TermType)) {
+        PyErr_SetString (PyExc_TypeError, "URI is not a Term type.");
+        return -1;
+    }
 
     LSUP_rc rc = LSUP_graph_set_uri (
             self->ob_struct, ((TermObject*)value)->ob_struct->data);
@@ -208,13 +211,6 @@ Graph_copy (PyTypeObject *cls, PyObject *src)
 static PyObject *
 Graph_store (PyObject *self)
 {
-    /*
-    PyObject *dest_obj = PyObject_CallFunction (self, "b", LSUP_STORE_MDB);
-    if (UNLIKELY (!dest_obj)) {
-        PyErr_SetString (PyExc_SystemError, "Error Creating stored graph.");
-        return NULL;
-    }
-    */
     GraphObject *dest_obj = (GraphObject *) Py_TYPE (self)->tp_alloc(
             Py_TYPE (self), 0);
     if (!dest_obj) return PyErr_NoMemory();
@@ -292,6 +288,68 @@ Graph_new_from_rdf (PyTypeObject *cls, PyObject *args)
 }
 
 
+/** @brief Build a triple pattern for lookup purposes.
+ */
+inline static int build_trp_pattern (PyObject *args, LSUP_Term *spo[])
+{
+    PyObject *s_obj, *p_obj, *o_obj;
+
+    if (! (PyArg_ParseTuple (args, "OOO", &s_obj, &p_obj, &o_obj)))
+        return -1;
+
+    if (s_obj != Py_None && !PyObject_TypeCheck (s_obj, &TermType)) {
+        PyErr_SetString (PyExc_TypeError, "Subject must be a term or None.");
+        return -1;
+    }
+    if (p_obj != Py_None && !PyObject_TypeCheck (p_obj, &TermType)) {
+        PyErr_SetString (PyExc_TypeError, "Predicate must be a term or None.");
+        return -1;
+    }
+    if (o_obj != Py_None && !PyObject_TypeCheck (o_obj, &TermType)) {
+        PyErr_SetString (PyExc_TypeError, "Object must be a term or None.");
+        return -1;
+    }
+
+    spo[0] = s_obj != Py_None ? ((TermObject *)s_obj)->ob_struct : NULL;
+    spo[1] = s_obj != Py_None ? ((TermObject *)p_obj)->ob_struct : NULL;
+    spo[2] = s_obj != Py_None ? ((TermObject *)o_obj)->ob_struct : NULL;
+
+    return 0;
+}
+
+
+static PyObject *
+Graph_new_set_from_store_lookup (PyTypeObject *cls, PyObject *args)
+{
+    LSUP_Term *spo[3];
+
+    if (UNLIKELY ((build_trp_pattern (args, spo)) < 0)) return NULL;
+
+    LSUP_Graph **gr_a = LSUP_graph_new_lookup (spo[0], spo[1], spo[2]);
+    if (UNLIKELY (!gr_a)) {
+        // TODO implement LSUP_strerror for more details.
+        PyErr_SetString (PyExc_SystemError, "Error looking up triples.");
+        return NULL;
+    }
+
+    PyObject *ret = PySet_New (NULL);
+
+    size_t i;
+    for (i = 0; gr_a[i] != NULL; i++) {
+        PyObject *gr_obj = cls->tp_alloc(cls, 0);
+        if (!gr_obj) return NULL;
+        ((GraphObject *) gr_obj)->ob_struct = gr_a[i];
+
+        Py_INCREF (gr_obj);
+        PySet_Add (ret, gr_obj);
+    }
+    log_debug ("Found %lu graphs for pattern.", i + 1);
+
+    Py_INCREF (ret);
+    return ret;
+}
+
+
 static PyObject *
 Graph_richcmp (PyObject *self, PyObject *other, int op)
 {
@@ -377,34 +435,6 @@ finalize:
 }
 
 
-inline static int build_trp_pattern (PyObject *args, LSUP_Term *spo[])
-{
-    PyObject *s_obj, *p_obj, *o_obj;
-
-    if (! (PyArg_ParseTuple (args, "OOO", &s_obj, &p_obj, &o_obj)))
-        return -1;
-
-    if (s_obj != Py_None && !PyObject_TypeCheck (s_obj, &TermType)) {
-        PyErr_SetString (PyExc_TypeError, "Subject must be a term or None.");
-        return -1;
-    }
-    if (p_obj != Py_None && !PyObject_TypeCheck (p_obj, &TermType)) {
-        PyErr_SetString (PyExc_TypeError, "Predicate must be a term or None.");
-        return -1;
-    }
-    if (o_obj != Py_None && !PyObject_TypeCheck (o_obj, &TermType)) {
-        PyErr_SetString (PyExc_TypeError, "Object must be a term or None.");
-        return -1;
-    }
-
-    spo[0] = s_obj != Py_None ? ((TermObject *)s_obj)->ob_struct : NULL;
-    spo[1] = s_obj != Py_None ? ((TermObject *)p_obj)->ob_struct : NULL;
-    spo[2] = s_obj != Py_None ? ((TermObject *)o_obj)->ob_struct : NULL;
-
-    return 0;
-}
-
-
 static PyObject *Graph_remove (PyObject *self, PyObject *args)
 {
     LSUP_rc rc;
@@ -499,12 +529,18 @@ Graph_encode (PyObject *self, PyObject *args)
 
 static PyMethodDef Graph_methods[] = {
     {
-        "copy", (PyCFunction) Graph_copy,
-        METH_CLASS | METH_VARARGS, "Copy a graph."
+        "copy", (PyCFunction) Graph_copy, METH_CLASS | METH_VARARGS,
+        "Copy a graph."
     },
     {
         "from_rdf", (PyCFunction) Graph_new_from_rdf,
-        METH_CLASS | METH_VARARGS, "Create a graph from a RDF file."
+        METH_CLASS | METH_VARARGS,
+        "Create a graph from a RDF file."
+    },
+    {
+        "from_lookup", (PyCFunction) Graph_new_set_from_store_lookup,
+        METH_CLASS | METH_VARARGS,
+        "Create a set of graphs from a store SPO lookup."
     },
     {
         "store", (PyCFunction) Graph_store, METH_NOARGS,

+ 2 - 1
include/core.h

@@ -73,11 +73,12 @@ typedef int LSUP_rc;
 #define LSUP_IO_ERR         -88893
 #define LSUP_MEM_ERR        -88892
 #define LSUP_CONFLICT_ERR   -88891
+#define LSUP_ENV_ERR        -88890
 // NOTE When adding new error codes, use a value larger than the last one
 // in the list. Also change LSUP_MAX_ERROR.
 
 #define LSUP_MIN_ERROR      LSUP_ERROR
-#define LSUP_MAX_ERROR      LSUP_CONFLICT_ERR
+#define LSUP_MAX_ERROR      LSUP_ENV_ERR
 
 extern char *warning_msg[], *error_msg[];
 

+ 2 - 2
include/environment.h

@@ -12,8 +12,8 @@
 
 typedef struct env_t {
     LSUP_Buffer *       default_ctx;            // Default context URI.
-    LSUP_MDBStore *     mdbstore;               // MDB permanent store handle.
-    LSUP_MDBStore *     mdbstore_ramdisk;       // MDB RAM disk store handle.
+    LSUP_MDBStore *     mdb_store;              // MDB permanent store handle.
+    LSUP_MDBStore *     mdb_store_ramdisk;      // MDB RAM disk store handle.
     LSUP_NSMap *        nsm;                    // Namespace prefix map.
 } LSUP_Env;
 

+ 2 - 2
include/graph.h

@@ -80,12 +80,12 @@ LSUP_graph_new_env (const LSUP_Env *env, const LSUP_store_type store_type);
  */
 LSUP_Graph **
 LSUP_graph_new_lookup_env (
-        const LSUP_Graph *gr, const LSUP_Env *env, const LSUP_Term *s,
+        const LSUP_Env *env, const LSUP_Term *s,
         const LSUP_Term *p, const LSUP_Term *o);
 
 /** @brief Shortcut for #LSUP_graph_new_lookup_env() on default MDB store.
  */
-#define LSUP_graph_new_lookup (s, p, o) \
+#define LSUP_graph_new_lookup(s, p, o) \
     LSUP_graph_new_lookup_env (LSUP_default_env, (s), (p), (o))
 
 

+ 1 - 0
src/core.c

@@ -29,6 +29,7 @@ char *err_msg[] = {
     "LSUP_IO_ERR: Input/Output error.",
     "LSUP_MEM_ERR: Memory error.",
     "LSUP_CONFLICT_ERR: A resource conflict resulted in an invalid state.",
+    "LSUP_ENV_ERR: Invalid environment. Did you call LSUP_init()?",
 };
 
 

+ 7 - 7
src/environment.c

@@ -35,20 +35,20 @@ LSUP_env_new (
 
     // Permanent store.
     if (LSUP_mdbstore_setup (mdb_path, false) != LSUP_OK) return NULL;
-    env->mdbstore = LSUP_mdbstore_new (mdb_path, env->default_ctx);
-    if (UNLIKELY (!env->mdbstore)) return NULL;
+    env->mdb_store = LSUP_mdbstore_new (mdb_path, env->default_ctx);
+    if (UNLIKELY (!env->mdb_store)) return NULL;
     log_info ("Initialized persistent back end at %s.", mdb_path);
 
     // RAM disk store.
     if (LSUP_mdbstore_setup (mdb_ramdisk_path, true) != LSUP_OK)
         return NULL;
-    env->mdbstore_ramdisk = LSUP_mdbstore_new (
+    env->mdb_store_ramdisk = LSUP_mdbstore_new (
             mdb_ramdisk_path, env->default_ctx);
-    if (UNLIKELY (!env->mdbstore_ramdisk)) return NULL;
+    if (UNLIKELY (!env->mdb_store_ramdisk)) return NULL;
     log_info ("Initialized RAM disk back end at %s.", mdb_ramdisk_path);
 
     // Get default namespace from store.
-    RCNL (LSUP_mdbstore_nsm_get (env->mdbstore, &env->nsm));
+    RCNL (LSUP_mdbstore_nsm_get (env->mdb_store, &env->nsm));
 
     return env;
 }
@@ -96,8 +96,8 @@ LSUP_init (void)
 void
 LSUP_env_free (LSUP_Env *env)
 {
-    LSUP_mdbstore_free (env->mdbstore);
-    LSUP_mdbstore_free (env->mdbstore_ramdisk);
+    LSUP_mdbstore_free (env->mdb_store);
+    LSUP_mdbstore_free (env->mdb_store_ramdisk);
     LSUP_buffer_free (env->default_ctx);
     LSUP_nsmap_free (env->nsm);
     free (env);

+ 8 - 4
src/graph.c

@@ -76,10 +76,10 @@ LSUP_graph_new_env (const LSUP_Env *env, const LSUP_store_type store_type)
         if (UNLIKELY (!gr->ht_store)) return NULL;
 
     } else if (gr->store_type == LSUP_STORE_MDB) {
-        gr->mdb_store = env->mdbstore;
+        gr->mdb_store = env->mdb_store;
 
     } else { // LSUP_STORE_MDB_TMP
-        gr->mdb_store = env->mdbstore_ramdisk;
+        gr->mdb_store = env->mdb_store_ramdisk;
     }
 
     log_debug ("Graph created.");
@@ -89,15 +89,19 @@ LSUP_graph_new_env (const LSUP_Env *env, const LSUP_store_type store_type)
 
 LSUP_Graph **
 LSUP_graph_new_lookup_env (
-        const LSUP_Graph *gr, const LSUP_Env *env, const LSUP_Term *s,
+        const LSUP_Env *env, const LSUP_Term *s,
         const LSUP_Term *p, const LSUP_Term *o)
 {
+    if (UNLIKELY (!env)) {
+        log_error ("No valid environment passed. Did you call LSUP_init()?");
+        return NULL;
+    }
     LSUP_Buffer *ss = LSUP_buffer_new_from_term (s);
     LSUP_Buffer *sp = LSUP_buffer_new_from_term (p);
     LSUP_Buffer *so = LSUP_buffer_new_from_term (o);
 
     LSUP_Buffer **ctx_a = LSUP_mdbstore_lookup_contexts (
-            gr->mdb_store, ss, sp, so);
+            env->mdb_store, ss, sp, so);
     if (UNLIKELY (!ctx_a)) return NULL;
 
     LSUP_buffer_free (ss);