Browse Source

Fix (partly unimplemented) Python bindings and tests.

Stefano Cossu 2 years ago
parent
commit
a8b17213be
7 changed files with 93 additions and 30 deletions
  1. 1 1
      TODO.md
  2. 55 16
      cpython/py_graph.h
  3. 2 1
      cpython/py_lsup_rdf.c
  4. 8 2
      include/store.h
  5. 13 0
      src/store.c
  6. 2 2
      test/cpython_test.py
  7. 12 8
      test/test_graph.c

+ 1 - 1
TODO.md

@@ -22,7 +22,7 @@
     - *D* Subclass term types
 - *D* Namespaced IRIs
 - *D* Relative IRIs
-- W Flexible store interface
+- D Flexible store interface
 - *P* Transaction control
 - *P* Turtle serialization / deserialization
 - *P* Full UTF-8 support

+ 55 - 16
cpython/py_graph.h

@@ -155,7 +155,25 @@ Graph_init (GraphObject *self, PyObject *args, PyObject *kwargs)
 
     } else uri = LSUP_iriref_new (NULL, NULL);
 
-    self->ob_struct = LSUP_graph_new (uri, (LSUP_store_type) store_type);
+    // Set up the store if a function for that is defined.
+    const LSUP_StoreInt *sif = LSUP_store_int (store_type);
+    if (UNLIKELY (!sif)) {
+            PyErr_SetString (
+                    PyExc_TypeError,
+                    "No interface defined for given store type.");
+            return -1;
+    }
+    if (sif->setup_fn) {
+        if (sif->setup_fn(NULL, false) < LSUP_OK) {
+            PyErr_SetString (
+                    PyExc_IOError, "Error initializing back end store.");
+            return -1;
+        }
+    }
+
+    // TODO Make store ID, nsm and initial size accessible.
+    self->ob_struct = LSUP_graph_new (
+            uri, (LSUP_StoreType) store_type, NULL, NULL, 0);
     if (!self->ob_struct) {
         PyErr_SetString (PyExc_ValueError, "Could not create graph.");
         return -1;
@@ -210,21 +228,20 @@ static PyGetSetDef Graph_getsetters[] = {
 };
 
 
-static PyObject *
-Graph_copy (PyTypeObject *cls, PyObject *src)
+static int
+Graph_copy_contents (GraphObject *self, GraphObject *dest)
 {
-    if (! PyObject_TypeCheck (src, cls)) return NULL;
-
-    GraphObject *res = (GraphObject *) cls->tp_alloc(cls, 0);
-    if (!res) return NULL;
-
-    res->ob_struct = LSUP_graph_copy (((GraphObject *) src)->ob_struct);
+    if (LSUP_graph_copy_contents (self->ob_struct, dest->ob_struct) < LSUP_OK)
+    {
+        PyErr_SetString (PyExc_ValueError, "Error copying graph contents.");
+        return -1;
+    }
 
-    Py_INCREF(res);
-    return (PyObject *) res;
+    return 0;
 };
 
 
+#if 0
 static PyObject *
 Graph_store (PyObject *self)
 {
@@ -232,7 +249,15 @@ Graph_store (PyObject *self)
             Py_TYPE (self), 0);
     if (!dest_obj) return PyErr_NoMemory();
 
-    LSUP_rc rc = LSUP_graph_store (
+    // TODO Make store ID, nsm and initial size accessible.
+    LSUP_Graph *dest = LSUP_graph_new (
+            uri, LSUP_STORE_HTABLE, NULL, NULL, 0);
+    if (!dest) {
+        PyErr_SetString (PyExc_ValueError, "Could not create graph.");
+        return -1;
+    }
+
+    LSUP_rc rc = LSUP_GraphStore (
             ((GraphObject *) self)->ob_struct, &((dest_obj)->ob_struct), NULL);
     if (rc != LSUP_OK) {
         log_error (LSUP_strerror (rc));
@@ -243,6 +268,7 @@ Graph_store (PyObject *self)
     Py_INCREF (dest_obj);
     return (PyObject *)dest_obj;
 }
+#endif
 
 
 static PyObject *
@@ -394,9 +420,20 @@ Graph_bool_op (
     GraphObject *res = (GraphObject *) cls->tp_alloc (cls, 0);
     if (!res) return NULL;
 
-    res->ob_struct = LSUP_graph_bool_op (
+    LSUP_Graph *dest = LSUP_graph_new (
+            NULL, LSUP_STORE_HTABLE, NULL, NULL, 0);
+    if (!dest) {
+        PyErr_SetString (PyExc_Exception, "Could not create destination graph.");
+        return NULL;
+    }
+
+    LSUP_rc rc = LSUP_graph_bool_op (
             op, ((GraphObject *) gr1)->ob_struct,
-            ((GraphObject *) gr2)->ob_struct);
+            ((GraphObject *) gr2)->ob_struct, res->ob_struct);
+    if (rc < LSUP_OK) {
+        PyErr_SetString (PyExc_Exception, "Error performing boolean operation.");
+        return NULL;
+    }
 
     Py_INCREF(res);
     return (PyObject *) res;
@@ -546,8 +583,8 @@ 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_contents, METH_CLASS | METH_VARARGS,
+        "Copy the contents of a graph into another."
     },
     {
         "from_rdf", (PyCFunction) Graph_new_from_rdf,
@@ -561,10 +598,12 @@ static PyMethodDef Graph_methods[] = {
         "Create a set of graphs from a store SPO lookup."
     },
     */
+    /*
     {
         "store", (PyCFunction) Graph_store, METH_NOARGS,
         "Store a graph into the permanent back end."
     },
+    */
     {"add", (PyCFunction) Graph_add, METH_O, "Add triples to a graph."},
     {
         "remove", (PyCFunction) Graph_remove, METH_VARARGS,

+ 2 - 1
cpython/py_lsup_rdf.c

@@ -181,7 +181,8 @@ PyInit_graph()
     if (!m) return NULL;
 
 #define ENTRY(a, b) \
-    if (PyModule_AddIntConstant (m, "STORE_" #a, b) < 0) return NULL;
+    if (PyModule_AddIntConstant (m, "STORE_" #a, LSUP_STORE_##a) < 0) \
+        return NULL;
     BACKEND_TBL
 #undef ENTRY
 

+ 8 - 2
include/store.h

@@ -34,12 +34,18 @@
 /** @brief Store types. All prefixed with `LSUP_STORE_`.
  */
 typedef enum {
-#define ENTRY(a, b) LSUP_STORE_##a,
-    BACKEND_TBL
+#define ENTRY(a, b) \
+    LSUP_STORE_##a,
+BACKEND_TBL
 #undef ENTRY
 } LSUP_StoreType;
 
 
+/** @brief Return store interface for a specific type.
+ */
+const LSUP_StoreInt *LSUP_store_int (LSUP_StoreType type);
+
+
 /** @brief Store structure.
  *
  * Code using the store interface should create an instance of this structure

+ 13 - 0
src/store.c

@@ -0,0 +1,13 @@
+#include "store.h"
+
+
+const LSUP_StoreInt *
+LSUP_store_int (LSUP_StoreType type) {
+    switch (type) {
+#define ENTRY(a, b) \
+        case LSUP_STORE_##a: return &b;
+BACKEND_TBL
+#undef ENTRY
+        default: return NULL;
+    }
+}

+ 2 - 2
test/cpython_test.py

@@ -67,13 +67,13 @@ class TestTerm(unittest.TestCase):
         self.assertFalse(hasattr(bn, 'lang'))
 
     def test_graph(self):
-        gr = graph.Graph(graph.STORE_MEM)
+        gr = graph.Graph(graph.STORE_HTABLE)
         gr.uri = term.Term(term.TERM_IRIREF, 'urn:c:1')
 
         self.assertEqual(gr.uri, 'urn:c:1')
 
     def test_graph_ops(self):
-        gr = graph.Graph(graph.STORE_MEM)
+        gr = graph.Graph(graph.STORE_HTABLE)
 
         print('Adding triples.')
         gr.add(self.trp)

+ 12 - 8
test/test_graph.c

@@ -5,8 +5,9 @@
 #define N_LUT 13
 
 static int
-_graph_new (LSUP_StoreType type, const LSUP_StoreInt *sif)
+_graph_new (LSUP_StoreType type)
 {
+    const LSUP_StoreInt *sif = LSUP_store_int (type);
     if (sif->setup_fn) sif->setup_fn (NULL, true);
 
     LSUP_Graph *gr = LSUP_graph_new (
@@ -32,8 +33,9 @@ _graph_new (LSUP_StoreType type, const LSUP_StoreInt *sif)
 
 
 static int
-_graph_add (LSUP_StoreType type, const LSUP_StoreInt *sif)
+_graph_add (LSUP_StoreType type)
 {
+    const LSUP_StoreInt *sif = LSUP_store_int (type);
     if (sif->setup_fn) sif->setup_fn (NULL, true);
 
     LSUP_Triple *trp = create_triples();
@@ -66,8 +68,9 @@ _graph_add (LSUP_StoreType type, const LSUP_StoreInt *sif)
 
 
 static int
-_graph_lookup (LSUP_StoreType type, const LSUP_StoreInt *sif)
+_graph_lookup (LSUP_StoreType type)
 {
+    const LSUP_StoreInt *sif = LSUP_store_int (type);
     LSUP_Triple *trp = create_triples();
 
     // Lookup triples.
@@ -157,8 +160,9 @@ _graph_lookup (LSUP_StoreType type, const LSUP_StoreInt *sif)
 
 
 static int
-_graph_remove (LSUP_StoreType type, const LSUP_StoreInt *sif)
+_graph_remove (LSUP_StoreType type)
 {
+    const LSUP_StoreInt *sif = LSUP_store_int (type);
     if (sif->setup_fn) sif->setup_fn (NULL, true);
 
     LSUP_Triple *trp = create_triples();
@@ -222,7 +226,7 @@ test_environment()
 
 static int test_graph_new() {
 #define ENTRY(a, b) \
-    if (_graph_new (LSUP_STORE_##a, &b) != 0) return -1;
+    if (_graph_new (LSUP_STORE_##a) != 0) return -1;
 BACKEND_TBL
 #undef ENTRY
 
@@ -232,7 +236,7 @@ BACKEND_TBL
 
 static int test_graph_add() {
 #define ENTRY(a, b) \
-    if (_graph_add (LSUP_STORE_##a, &b) != 0) return -1;
+    if (_graph_add (LSUP_STORE_##a) != 0) return -1;
 BACKEND_TBL
 #undef ENTRY
 
@@ -242,7 +246,7 @@ BACKEND_TBL
 
 static int test_graph_lookup() {
 #define ENTRY(a, b) \
-    if (_graph_lookup (LSUP_STORE_##a, &b) != 0) return -1;
+    if (_graph_lookup (LSUP_STORE_##a) != 0) return -1;
 BACKEND_TBL
 #undef ENTRY
 
@@ -252,7 +256,7 @@ BACKEND_TBL
 
 static int test_graph_remove() {
 #define ENTRY(a, b) \
-    if (_graph_remove (LSUP_STORE_##a, &b) != 0) return -1;
+    if (_graph_remove (LSUP_STORE_##a) != 0) return -1;
 BACKEND_TBL
 #undef ENTRY