Skip to content

Commit

Permalink
support for deleting triples
Browse files Browse the repository at this point in the history
  • Loading branch information
William Waites committed Feb 26, 2010
1 parent 77c8b7c commit c397507
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 9 deletions.
3 changes: 3 additions & 0 deletions _py4s.pxd
Expand Up @@ -113,6 +113,9 @@ cdef extern from "frontend/import.h":
int fs_import_stream_data(fsp_link *link, unsigned char *data, size_t count)
int fs_import_stream_finish(fsp_link *link, int *count, int *errors)

cdef extern from "frontend/update.h":
int fs_update(fsp_link *link, char *update, char **message, int unsafe)

cdef extern from "glib/gslist.h":
ctypedef struct GSList:
char *data
Expand Down
8 changes: 7 additions & 1 deletion _py4s.pyx
Expand Up @@ -51,7 +51,7 @@ cdef class FourStoreClient:
def cursor(self):
return _Cursor(self)

cdef _n3(s):
def _n3(s):
return " ".join([x.n3() for x in s])

cdef class _Cursor:
Expand Down Expand Up @@ -144,6 +144,12 @@ cdef class _Cursor:
if transaction:
self.commit()

def update(self, query):
cdef char *message
py4s.fs_update(self._link, query, &message, 1)
if message != NULL:
raise FourStoreError("%s: -- %s" % (message, query))

def transaction(self, context="local:"):
if isinstance(context, Graph): context = context.identifier
content_type = "application/x-turtle"
Expand Down
45 changes: 41 additions & 4 deletions py4s/__init__.py
Expand Up @@ -2,7 +2,7 @@
from rdflib.term import Variable
from rdflib.store import Store, VALID_STORE, NO_STORE
from rdflib.plugin import register
from _py4s import FourStoreClient, FourStoreError
from _py4s import FourStoreClient, FourStoreError, _n3

__all__ = ["FourStore", "FourStoreError"]

Expand Down Expand Up @@ -33,9 +33,32 @@ def addN(self, slist, **kw):
"""Add a list of quads to the graph"""
for s,p,o,c in slist:
self.add((s,p,o), context=c, **kw)
def remove(self, *av, **kw):
"""Remove a triple from the graph (unimplemented)"""
raise FourStoreError("Triple Removal Not Implemented")
def remove(self, statement, context="local:"):
"""Remove a triple from the graph"""
if isinstance(context, Graph): _context = context.identifier
else: _context = context
s,p,o = statement
bindings = (
s or Variable("s"),
p or Variable("p"),
o or Variable("o")
)

construct = "CONSTRUCT { " + _n3(bindings) + " } WHERE { "
if _context and _context != "local:": construct += "GRAPH <%s> { " % _context
construct += _n3(bindings)
if _context and _context != "local:": construct += " }"
construct += " }"

result = self.cursor().execute(construct)

delete = "DELETE { "
if _context and _context != "local:": delete += "GRAPH <%s> { " % _context
delete += " .\n".join(map(_n3, result.triples((None, None, None))))
if _context and _context != "local:": delete += " }"
delete += " }"

self.cursor().update(delete)

def __contains__(self, statement, context="local:"):
if isinstance(context, Graph): _context = context.identifier
Expand All @@ -47,6 +70,20 @@ def __contains__(self, statement, context="local:"):
query += " }"
return bool(self.cursor().execute(query))

def contexts(self, triple=None):
if triple is None: triple = (None,None,None)
s,p,o = triple
bindings = (
s or Variable("s"),
p or Variable("p"),
o or Variable("o")
)
query = "SELECT DISTINCT ?g WHERE { GRAPH ?g { "
query += " ".join([x.n3() for x in bindings])
query += " } }"
for g, in self.query(query):
yield Graph(self, identifier=g)

def triples(self, statement, context="local:", **kw):
"""Return triples matching (s,p,o) pattern"""

Expand Down
1 change: 1 addition & 0 deletions setup.py
Expand Up @@ -115,6 +115,7 @@ def uniqify(l):
"src/frontend/query-data.c",
"src/frontend/order.c",
"src/frontend/import.c",
"src/frontend/update.c",
"py4s_helpers.c",
],
extra_compile_args=["-std=gnu99"],
Expand Down
14 changes: 10 additions & 4 deletions tests/test_4store.py
Expand Up @@ -2,10 +2,10 @@
try:
from rdflib.term import URIRef, Literal
from rdflib.namespace import RDF, RDFS
from rdflib.graph import Graph
from rdflib.graph import Graph, ConjunctiveGraph
except ImportError:
from rdflib import URIRef, RDF, RDFS, Literal
from rdflib.Graph import Graph
from rdflib.Graph import Graph, ConjunctiveGraph
from StringIO import StringIO

TEST_GRAPH = "http://example.org/"
Expand Down Expand Up @@ -35,10 +35,16 @@ def test_11_add_triple(self):
g.add(s)
for count, in store.query("SELECT DISTINCT COUNT(?s) AS c WHERE { graph <%s> { ?s ?p ?o } }" % TEST_GRAPH): pass
assert count == 3
def test_11_construct(self):
def test_20_remove(self):
assert store.query("ASK WHERE { ?s ?p ?o }")
g = ConjunctiveGraph(store)
for ctx in g.contexts():
store.remove((None,None,None), context=ctx)
assert not store.query("ASK WHERE { ?s ?p ?o }")
def test_13_construct(self):
g = store.query("CONSTRUCT { <http://foo> ?p ?o } WHERE { ?s ?p ?o } LIMIT 2")
assert len(g) == 2
def test_12_triples(self):
def test_14_triples(self):
g = Graph(store, identifier=TEST_GRAPH)
for s,p,o in g.triples((URIRef("http://irl.styx.org/foo"), None, None)):
## should only have one
Expand Down

0 comments on commit c397507

Please sign in to comment.