Passing this along. The tests are complete except for the fixture TestableDatabase. You can replace that with any Graph after calling:
graph.bind(STAFF, '')
... and add the triples in corpN3 to it.
The tests should explain what they're all about, but this is just the implementation of class-as-boolean for rdfalchemy.
######################################################################
corpN3 = """
@prefix rdfs: <
http://www.w3.org/2000/01/rdf-schema#> .
<> rdfs:label "Test document - Corporate Staff" .
<> rdfs:comment "So much Enterprise you'll crap yourself!" .
:Employee a rdfs:Class .
:PeoplePerson a rdfs:Class .
:StraightShooterWithUpperManagementWrittenAllOverHim a rdfs:Class .
:e1230 :firstname "Peter";
:lastname "Gibbons";
:supervisor :e1001;
a :Employee;
a :StraightShooterWithUpperManagementWrittenAllOverHim ;
:nickname "\"The Gib\"";
# do _not_ give him a :middlename. testing defaults.
.
:e1001 :firstname "Bill";
:lastname "Lumbergh";
:supervisor :e900;
a :PeoplePerson;
a :Employee;
.
"""
class rdfIsInstance(rdfAbstract):
"""
An rdfalchemy descriptor that makes a boolean out of Bar in this
construction:
:Bar a rdfs:Class .
:foo a :Bar.
Does *not* check for is-a semantics at this point - just exact boolean
match on that class.
"""
def __init__(self, classToCheck):
self.klass = classToCheck
def __get__(self, obj, cls):
#code to check for obj a self.klass
if obj is None:
return self
if self.klass in obj.__dict__:
return obj.__dict__[self.klass]
qText = "ASK { %s a %s . }" % (obj.n3(), self.klass.n3())
q = obj.db.query(qText)
ret = list(q.askAnswer)[0]
obj.__dict__[self.klass] = ret
return ret
def __set__(self, obj, true_false):
"""
Create the triple for obj
"""
obj.__dict__[self.klass] = true_false
obj.db.set((obj.resUri, self.klass, true_false))
def __delete__(self, obj):
if obj.__dict__.has_key(self.klass):
del obj.__dict__[self.klass]
print "DELETED"
for s,p,o in obj.db.triples((obj.resUri, RDF_a, self.klass)):
obj.db.remove((s,p,o))
STAFF = Namespace('
http://corp.com/staff#')
class Employee2(rdfSubject):
"""
Employee, using the rdfalchemy ORM
"""
rdf_type = STAFF.Employee
firstname = rdfSingle(STAFF.firstname)
lastname = rdfSingle(STAFF.lastname)
straightShooter = sparqly.rdfIsInstance(
STAFF.StraightShooterWithUpperManagementWrittenAllOverHim)
peoplePerson = sparqly.rdfIsInstance( STAFF.PeoplePerson)
nickname = rdfSingle(STAFF.nickname)
class RDFAlchemyDescriptorTestCase(unittest.TestCase):
"""
Tests of the rdfIsInstance descriptor
"""
def test_basicSchemaCreate(self):
"""
We can use an in-memory store
"""
michael = Employee2()
michael.firstname = "Michael"
michael.lastname = "Bolton"
self.assertEqual(michael.lastname, "Bolton")
def test_basicSchemaAccess(self):
"""
We can access the data through the sqlalchemy ORM
"""
db = TestableDatabase()
db.extendFromFilename(sibpath(__file__, 'corp.n3'))
rdfSubject.db = db.graph
peter = Employee2.get_by(lastname='Gibbons')
self.assertEqual(peter.firstname, 'Peter')
self.assertEqual(peter.nickname, '"The Gib"')
peter.nickname = "Gibster"
self.assertEqual(peter.nickname, 'Gibster')
def test_readUpdateDescriptor(self):
"""
Access a rdfIsInstance descriptor that was already specified in n3
"""
peter = Employee2.get_by(lastname='Gibbons')
self.assertTrue(peter.straightShooter, "Peter should be a straight shooter")
peter.straightShooter = False
self.failIf(peter.straightShooter, "Peter should no longer be a straight shooter")
def test_createDescriptor(self):
"""
Create a rdfIsInstance descriptor
"""
peter = Employee2.get_by(lastname='Gibbons')
self.assertEqual(peter.peoplePerson, False, "peter.peoplePerson should be False")
peter.peoplePerson = True
self.assertTrue(peter.peoplePerson, "Peter should now be a people person")
def test_deleteDescriptor(self):
"""
Delete a rdfIsInstance descriptor
"""
bill = Employee2.get_by(lastname='Lumbergh')
self.assertTrue(bill.peoplePerson, "bill should be a people person")
del bill.peoplePerson
self.failIf(bill.peoplePerson, "bill.peoplePerson should have been deleted")
_____________________