14
14
from rdflib .py3compat import PY3
15
15
from rdflib .plugins .stores .regexmatching import REGEXTerm
16
16
from sqlalchemy import Column , Table , MetaData , Index , types
17
+ from sqlalchemy .sql import select
17
18
from .termutils import REVERSE_TERM_COMBINATIONS
18
19
from .termutils import TERM_INSTANTIATION_DICT
19
20
from .termutils import constructGraph
@@ -272,6 +273,16 @@ def createTerm(
272
273
store .otherCache [(termType , termString )] = rt
273
274
return rt
274
275
276
+ class TermType (types .TypeDecorator ):
277
+
278
+ impl = types .Text
279
+
280
+ def process_bind_param (self , value , dialect ):
281
+ if isinstance (value , (QuotedGraph , Graph )):
282
+ return value .identifier
283
+ else :
284
+ return value
285
+
275
286
276
287
class SQLGenerator (object ):
277
288
@@ -406,72 +417,67 @@ def normalizeTerm(self, term):
406
417
else :
407
418
return term .encode ('utf-8' )
408
419
409
- def buildTypeSQLCommand (self , member , klass , context , storeId ):
420
+ def buildTypeSQLCommand (self , member , klass , context ):
410
421
"""
411
422
Builds an insert command for a type table
412
423
"""
413
424
#columns: member,klass,context
414
- rt = "INSERT INTO %s_type_statements" % storeId + \
415
- " (member,klass,context,termComb) VALUES (%s, %s, %s,%s)"
416
- return rt , [
417
- self .normalizeTerm (member ),
418
- self .normalizeTerm (klass ),
419
- self .normalizeTerm (context .identifier ),
420
- int (type2TermCombination (member , klass , context ))]
425
+ rt = self .tables ['type_statements' ].insert ()
426
+ return rt , {
427
+ 'member' : member ,
428
+ 'klass' : klass ,
429
+ 'context' : context .identifier ,
430
+ 'termComb' : int (type2TermCombination (member , klass , context ))}
421
431
422
432
def buildLiteralTripleSQLCommand (
423
- self , subject , predicate , obj , context , storeId ):
433
+ self , subject , predicate , obj , context ):
424
434
"""
425
435
Builds an insert command for literal triples (statements where the
426
436
object is a Literal)
427
437
"""
428
438
triplePattern = int (
429
439
statement2TermCombination (subject , predicate , obj , context ))
430
- literal_table = "%s_literal_statements" % storeId
431
- command = "INSERT INTO %s " % literal_table + \
432
- "( subject,predicate,object,context,termComb,objLanguage," + \
433
- "objDatatype) VALUES (%s, %s, %s, %s, %s,%s,%s)"
434
- return command , [
435
- self . normalizeTerm ( subject ) ,
436
- self . normalizeTerm ( predicate ) ,
437
- self . normalizeTerm (obj ) ,
438
- self . normalizeTerm ( context . identifier ),
439
- triplePattern ,
440
- isinstance ( obj , Literal ) and obj . language or None ,
441
- isinstance ( obj , Literal ) and obj . datatype or None ]
440
+ command = self . tables [ 'literal_statements' ]. insert ()
441
+ values = {
442
+ 'subject' : subject ,
443
+ 'predicate' : predicate ,
444
+ 'object' : obj ,
445
+ 'context' : context . identifier ,
446
+ 'termComb' : triplePattern ,
447
+ 'objLanguage' : isinstance (obj , Literal ) and obj . language or None ,
448
+ 'objDatatype' : isinstance ( obj , Literal ) and obj . datatype or None
449
+ }
450
+ return command , values
451
+
442
452
443
453
def buildTripleSQLCommand (
444
- self , subject , predicate , obj , context , storeId , quoted ):
454
+ self , subject , predicate , obj , context , quoted ):
445
455
"""
446
456
Builds an insert command for regular triple table
447
457
"""
448
- stmt_table = quoted and "%s_quoted_statements" % storeId \
449
- or "%s_asserted_statements" % storeId
458
+ stmt_table = quoted and self . tables [ 'quoted_statements' ] \
459
+ or self . tables [ 'asserted_statements' ]
450
460
triplePattern = statement2TermCombination (
451
461
subject , predicate , obj , context )
462
+ command = stmt_table .insert ()
452
463
if quoted :
453
- command = "INSERT INTO %s " % stmt_table + \
454
- "(subject,predicate,object,context,termComb," + \
455
- "objLanguage,objDatatype) VALUES " + \
456
- "(%s, %s, %s, %s, %s,%s,%s)"
457
- params = [
458
- self .normalizeTerm (subject ),
459
- self .normalizeTerm (predicate ),
460
- self .normalizeTerm (obj ),
461
- self .normalizeTerm (context .identifier ),
462
- triplePattern ,
463
- isinstance (obj , Literal ) and obj .language or None ,
464
- isinstance (obj , Literal ) and obj .datatype or None ]
464
+ params = {
465
+ 'subject' : subject ,
466
+ 'predicate' : predicate ,
467
+ 'object' : obj ,
468
+ 'context' : context .identifier ,
469
+ 'termComb' : triplePattern ,
470
+ 'objLanguage' : isinstance (obj , Literal ) and obj .language or None ,
471
+ 'objDatatype' : isinstance (obj , Literal ) and obj .datatype or None
472
+ }
465
473
else :
466
- command = "INSERT INTO %s " % stmt_table + \
467
- "(subject,predicate,object,context,termComb) " + \
468
- "VALUES (%s, %s, %s, %s, %s)"
469
- params = [
470
- self .normalizeTerm (subject ),
471
- self .normalizeTerm (predicate ),
472
- self .normalizeTerm (obj ),
473
- self .normalizeTerm (context .identifier ),
474
- triplePattern ]
474
+ params = {
475
+ 'subject' : subject ,
476
+ 'predicate' : predicate ,
477
+ 'object' : obj ,
478
+ 'context' : context .identifier ,
479
+ 'termComb' : triplePattern
480
+ }
475
481
return command , params
476
482
477
483
def buildClause (
@@ -853,9 +859,6 @@ def close(self, commit_pending_transaction=False):
853
859
"""
854
860
FIXME: Add documentation!!
855
861
"""
856
- pass
857
- #if commit_pending_transaction:
858
- # self.connection.commit()
859
862
try :
860
863
self .engine .close ()
861
864
except :
@@ -883,76 +886,56 @@ def destroy(self, configuration):
883
886
# _logger.debug(
884
887
# "Destroyed Close World Universe %s" % (self.identifier))
885
888
886
- # Triple Methods
887
- def add ( self , ( subject , predicate , obj ), context = None , quoted = False ):
888
- """ Add a triple to the store of triples. """
889
+ def __getBuildCommand ( self , ( subject , predicate , obj ), context = None , quoted = False ):
890
+
891
+ buildCommandType = None
889
892
if quoted or predicate != RDF .type :
890
893
# Quoted statement or non rdf:type predicate
891
894
# check if object is a literal
892
895
if isinstance (obj , Literal ):
893
896
addCmd , params = self .buildLiteralTripleSQLCommand (
894
- subject , predicate , obj , context , self ._internedId )
897
+ subject , predicate , obj , context )
898
+ buildCommandType = 'literal'
895
899
else :
896
900
addCmd , params = self .buildTripleSQLCommand (
897
- subject , predicate , obj , context , self ._internedId , quoted )
901
+ subject , predicate , obj , context , quoted )
902
+ buildCommandType = 'other'
898
903
elif predicate == RDF .type :
899
904
#asserted rdf:type statement
900
- addCmd , params = self .buildTypeSQLCommand (
901
- subject , obj , context , self ._internedId )
905
+ addCmd , params = self .buildTypeSQLCommand (subject , obj , context )
906
+ buildCommandType = 'type'
907
+ return buildCommandType , addCmd , params
908
+
909
+
910
+ # Triple Methods
911
+ def add (self , (subject , predicate , obj ), context = None , quoted = False ):
912
+ """ Add a triple to the store of triples. """
913
+
914
+ _ , addCmd , params = self .__getBuildCommand ((subject , predicate , obj ), context , quoted )
902
915
with self .engine .connect () as connection :
903
- trans = connection .begin ()
904
916
try :
905
- self .executeSQL (addCmd , params , connection = connection )
906
- trans .commit ()
917
+ connection .execute (addCmd , params )
907
918
except Exception , msg :
908
- _logger .debug ("Add failed %s with commands %s" % (msg , addCmd ))
909
- trans .rollback ()
919
+ _logger .debug ("Add failed %s with commands %s params %s" % (msg , str (addCmd ), repr (params )))
910
920
911
921
def addN (self , quads ):
912
- literalTriples = []
913
- typeTriples = []
914
- otherTriples = []
915
- literalTripleInsertCmd = None
916
- typeTripleInsertCmd = None
917
- otherTripleInsertCmd = None
922
+
923
+ cmdTriplesDict = {
924
+ }
925
+
918
926
for subject , predicate , obj , context in quads :
919
- if isinstance (context , QuotedGraph ) or predicate != RDF .type :
920
- # Quoted statement or non rdf:type predicate
921
- # check if object is a literal
922
- if isinstance (obj , Literal ):
923
- cmd , params = self .buildLiteralTripleSQLCommand (
924
- subject , predicate , obj , context , self ._internedId )
925
- literalTripleInsertCmd = \
926
- literalTripleInsertCmd is not None \
927
- and literalTripleInsertCmd or cmd
928
- literalTriples .append (params )
929
- else :
930
- cmd , params = self .buildTripleSQLCommand (
931
- subject , predicate , obj , context , self ._internedId ,
932
- isinstance (context , QuotedGraph ))
933
- otherTripleInsertCmd = \
934
- otherTripleInsertCmd is not None \
935
- and otherTripleInsertCmd or cmd
936
- otherTriples .append (params )
937
- elif predicate == RDF .type :
938
- #asserted rdf:type statement
939
- cmd , params = self .buildTypeSQLCommand (
940
- subject , obj , context , self ._internedId )
941
- typeTripleInsertCmd = \
942
- typeTripleInsertCmd is not None \
943
- and typeTripleInsertCmd or cmd
944
- typeTriples .append (params )
945
-
946
- self .executeSQL (literalTripleInsertCmd , literalTriples , paramList = True )
927
+ buildCommandType , cmd , params = \
928
+ self .__getBuildCommand ((subject , predicate , obj ), context , isinstance (context , QuotedGraph ))
929
+
930
+ cmdTriple = cmdTripleDict .get (buildCommandType , {})
931
+ cmdTriple .setdefault ('cmd' , cmd )
932
+ cmdTriple .setdefault ('params' , []).append (params )
933
+
947
934
with self .engine .connect () as connection :
948
935
trans = connection .begin ()
949
936
try :
950
- if literalTriples :
951
- self .executeSQL (literalTripleInsertCmd , literalTriples , paramList = True , connection = connection )
952
- if typeTriples :
953
- self .executeSQL (typeTripleInsertCmd , typeTriples , paramList = True , connection = connection )
954
- if otherTriples :
955
- self .executeSQL (otherTripleInsertCmd , otherTriples , paramList = True , connection = connection )
937
+ for cmdTriple in cmdTripleDict .values ():
938
+ connection .execute (cmdTriple ['cmd' ], cmdTriple ['params' ])
956
939
except Exception , msg :
957
940
_logger .debug ("AddN failed %s" % msg )
958
941
trans .rollback ()
@@ -1474,60 +1457,52 @@ def value(self, subject,
1474
1457
def bind (self , prefix , namespace ):
1475
1458
""" """
1476
1459
with self .engine .connect () as connection :
1477
- trans = connection .begin ()
1478
1460
try :
1479
- connection .execute (
1480
- "INSERT INTO %s_namespace_binds " +
1481
- "(prefix,uri) VALUES ('%s', '%s')" % (
1482
- self ._internedId ,
1483
- prefix ,
1484
- namespace ))
1485
- trans .commit ()
1461
+ ins = self .tables ['namespace_binds' ].insert ().values (prefix = prefix , uri = namesapce )
1462
+ connection .execute (ins )
1486
1463
except Exception , msg :
1487
1464
_logger .debug ("Namespace binding failed %s" % msg )
1488
- trans .rollback ()
1489
1465
1490
1466
def prefix (self , namespace ):
1491
1467
""" """
1492
1468
with self .engine .connect () as connection :
1493
- res = connection . execute ( "SELECT prefix FROM %s_namespace_binds WHERE uri = '%s'" % (
1494
- self . _internedId ,
1495
- namespace ) )
1469
+ nb_table = self . tables [ 'namespace_binds' ]
1470
+ s = select ([ nb_table . c . prefix ]). where ( nb_table . c . uri == namespace )
1471
+ res = connection . execute ( s )
1496
1472
rt = [rtTuple [0 ] for rtTuple in res .fetchall ()]
1473
+ res .close ()
1497
1474
return rt and rt [0 ] or None
1498
1475
1499
1476
def namespace (self , prefix ):
1500
1477
""" """
1501
1478
res = None
1502
1479
try :
1503
1480
with self .engine .connect () as connection :
1504
- res = connection .execute (
1505
- "SELECT uri FROM %s_namespace_binds WHERE prefix = '%s'" % (
1506
- self ._internedId ,
1507
- prefix ))
1481
+ nb_table = self .tables ['namespace_binds' ]
1482
+ s = select ([nb_table .c .uri ]).where (nb_table .c .prefix == prefix )
1483
+ res = connection .execute (s )
1508
1484
except :
1509
1485
return None
1510
1486
rt = [rtTuple [0 ] for rtTuple in res .fetchall ()]
1487
+ res .close ()
1511
1488
return rt and rt [0 ] or None
1512
1489
1513
1490
def namespaces (self ):
1514
1491
""" """
1515
1492
with self .engine .connect () as connection :
1516
- res = connection .execute ("SELECT prefix, uri FROM %s_namespace_binds;" % (
1517
- self ._internedId ))
1518
- rt = res .fetchall ()
1519
- for prefix , uri in rt :
1493
+ res = connection .execute (self .tables ['namespace_binds' ].select ())
1494
+ for prefix , uri in res .fetchall ():
1520
1495
yield prefix , uri
1521
1496
1522
1497
def __create_table_definitions (self ):
1523
1498
self .metadata = MetaData ()
1524
1499
self .tables = {
1525
1500
'asserted_statements' :
1526
1501
Table ('%s_asserted_statements' % self ._internedId , self .metadata ,
1527
- Column ('subject' , types . Text , nullable = False ),
1528
- Column ('predicate' , types . Text , nullable = False ),
1529
- Column ('object' , types . Text , nullable = False ),
1530
- Column ('context' , types . Text , nullable = False ),
1502
+ Column ('subject' , TermType , nullable = False ),
1503
+ Column ('predicate' , TermType , nullable = False ),
1504
+ Column ('object' , TermType , nullable = False ),
1505
+ Column ('context' , TermType , nullable = False ),
1531
1506
Column ('termcomb' , types .Integer , nullable = False , key = "termComb" ),
1532
1507
Index ("%s_A_termComb_index" % self ._internedId , 'termComb' ),
1533
1508
Index ("%s_A_s_index" % self ._internedId , 'subject' ),
@@ -1537,9 +1512,9 @@ def __create_table_definitions(self):
1537
1512
),
1538
1513
'type_statements' :
1539
1514
Table ('%s_type_statements' % self ._internedId , self .metadata ,
1540
- Column ('member' , types . Text , nullable = False ),
1541
- Column ('klass' , types . Text , nullable = False ),
1542
- Column ('context' , types . Text , nullable = False ),
1515
+ Column ('member' , TermType , nullable = False ),
1516
+ Column ('klass' , TermType , nullable = False ),
1517
+ Column ('context' , TermType , nullable = False ),
1543
1518
Column ('termcomb' , types .Integer , nullable = False , key = "termComb" ),
1544
1519
Index ("%s_T_termComb_index" % self ._internedId , 'termComb' ),
1545
1520
Index ("%s_member_index" % self ._internedId , 'member' ),
@@ -1548,10 +1523,10 @@ def __create_table_definitions(self):
1548
1523
),
1549
1524
'literal_statements' :
1550
1525
Table ('%s_literal_statements' % self ._internedId , self .metadata ,
1551
- Column ('subject' , types . Text , nullable = False ),
1552
- Column ('predicate' , types . Text , nullable = False ),
1553
- Column ('object' , types . Text ),
1554
- Column ('context' , types . Text , nullable = False ),
1526
+ Column ('subject' , TermType , nullable = False ),
1527
+ Column ('predicate' , TermType , nullable = False ),
1528
+ Column ('object' , TermType ),
1529
+ Column ('context' , TermType , nullable = False ),
1555
1530
Column ('termcomb' , types .Integer , nullable = False , key = "termComb" ),
1556
1531
Column ('objlanguage' , types .String (255 ), key = "objLanguage" ),
1557
1532
Column ('objdatatype' , types .String (255 ), key = "objDatatype" ),
@@ -1562,10 +1537,10 @@ def __create_table_definitions(self):
1562
1537
),
1563
1538
'quoted_statements' :
1564
1539
Table ("%s_quoted_statements" % self ._internedId , self .metadata ,
1565
- Column ('subject' , types . Text , nullable = False ),
1566
- Column ('predicate' , types . Text , nullable = False ),
1567
- Column ('object' , types . Text ),
1568
- Column ('context' , types . Text , nullable = False ),
1540
+ Column ('subject' , TermType , nullable = False ),
1541
+ Column ('predicate' , TermType , nullable = False ),
1542
+ Column ('object' , TermType ),
1543
+ Column ('context' , TermType , nullable = False ),
1569
1544
Column ('termcomb' , types .Integer , nullable = False , key = "termComb" ),
1570
1545
Column ('objlanguage' , types .String (255 ), key = "objLanguage" ),
1571
1546
Column ('objdatatype' , types .String (255 ), key = "objDatatype" ),
0 commit comments