# $Id: N3ModelJenaRdb.py,v 1.3 2002/05/16 13:19:01 graham Exp $ # # Extension of N3ModelJenaMem to interface with Jena RDB-based # RDF statement store. # # TODO: # - Fix up so that database is formatted automatically the first time it is used. # #--------+---------+---------+---------+---------+---------+---------+---------+ # # Copyright (c) 2002, G. KLYNE # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. The name of the author may not be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # #--------+---------+---------+---------+---------+---------+---------+---------+ # $Source: /file/cvsdev/PythonN3/N3ModelJenaRdb.py,v $ # $Author: graham $ # $Revision: 1.3 $ $Date: 2002/05/16 13:19:01 $ #--------+---------+---------+---------+---------+---------+---------+---------+ # 1 2 3 4 5 6 7 8 # Edit this to match local test environment DBURL = "jdbc:mysql://luggage/TestN3ModelJenaRdb" import sys # import string # import StringIO from N3Exception import N3Exception from N3ModelJenaMem import N3ModelJenaMem from N3Node import N3Node from N3Statement import N3Statement from N3Model import N3Model # Import Java shim-class # # For a simple class file, without a package statement, this has the effect # of importing the java class directly into the current Python module's # namespace. If it were a Python class, one would expect to write: # from N3JenaRdb import N3JenaRdb # to acheive the same effect. # import N3JenaRdb from com.hp.hpl.mesa.rdf.jena.model import Model # from com.hp.hpl.mesa.rdf.jena.model import Selector # from com.hp.hpl.mesa.rdf.jena.model import Statement # from com.hp.hpl.mesa.rdf.jena.model import Property # from com.hp.hpl.mesa.rdf.jena.model import Resource # from com.hp.hpl.mesa.rdf.jena.model import Literal # from com.hp.hpl.mesa.rdf.jena.model import RDFNode # from com.hp.hpl.mesa.rdf.jena.model import StmtIterator # from com.hp.hpl.mesa.rdf.jena.model import AnonId # from com.hp.hpl.mesa.rdf.jena.common import ResourceImpl # from com.hp.hpl.mesa.rdf.jena.common import SelectorImpl from com.hp.hpl.mesa.rdf.jena.rdb import ModelRDB #--------+---------+---------+---------+---------+---------+---------+---------+ # N3DatabaseTypeException # N3DatabaseInitializeFailed # class N3DatabaseTypeException( N3Exception ): """ Exception raised when unable to figure the Jena database type from the supplied dburl value. Attributes: subproto - is the subprotocol name from the jdbc URL, for which no correspnding Jena database type can be determined. """ def __init__(self, subproto): self.message = ( "Can't determine database type - " + "unrecognized subprotocol name: " + str(subproto) ) class N3DatabaseInitializeFailed( N3Exception ): """ Exception raised when unable to figure the Jena database type from the supplied dburl value. Attributes: diag - is a diagnistic string with information about the reason for the failure. """ def __init__(self, diag): self.message = ( "Can't initialize database: " + str(diag) ) #--------+---------+---------+---------+---------+---------+---------+---------+ # N3ModelJenaRdb - graph access using a Jena memory-based RDF store # class N3ModelJenaRdb( N3ModelJenaMem ): """ N3ModelJenaRdb - extend N3ModelHenamem to interface with a Jena RDB-based RDF store. """ def __init__( self, dburl, dbuser, dbpass, modelid=None, dbtype=None ): """ Construct a model using a supplied database repository. Parameters: dburl is the JDBC URL of the database to be accessed; e.g. jdbc:mysql://luggage.atuin.ninebynine.org/SemaFor dbuser is the username to use for accessing the database. dbpass is the password to use for accessing the database. modelid is the identifier of the Jena model to be accessed in the database. dbtype is the type of database used to hold the knowledgebase; e.g. "Mysql" (see Jena RDB notes for more details). If not specified, this constructor will try to guess an appropriate value from the supplied 'dburl'. """ # NOTE - N3ModelJenaMem.__init__() is deliberately skipped: N3Model.__init__( self ) # Jena initialization: # Instantiate Java wrapper class to do the hairy initialization DBTypeList = { "mysql": "Mysql" } if not dbtype: lst = dburl.split( ':', 2 ) subprotocol = lst[1] if subprotocol in DBTypeList.keys(): dbtype = DBTypeList[subprotocol] else: raise N3DatabaseTypeException( subprotocol ) self.JenaRdb = N3JenaRdb( dbtype, dburl, dbuser, dbpass ) self.Model = self.JenaRdb.getModel() self.ModelId = modelid if not self.Model: raise N3DatabaseInitializeFailed( self.JenaRdb.getError() ) return ; def format( self ): """ Initialize a new database for storing RDF model data. NOTE: the database is required to exist before a database model can be created to use it. Thismethof simply forces an initialization of the database. Returns: True value if database is formatted OK, otherwise False. """ self.Model = self.JenaRdb.format() if self.Model: self.Model.remove( self.Model ) return 1 return 0 def close( self ): self.JenaRdb.close() self.JenaRdb = None self.Model = None self.ModelId = None N3Model.close( self ) return def debug( self, val ): sys.stdout.write( "N3ModelJenaRdb: " + val + "\n" ) return # End of N3ModelJenaRdb #--------+---------+---------+---------+---------+---------+---------+---------+ # Stand-alone test code follows: # if __name__ == '__main__': # Some basic tests sys.stdout.write( "N3ModelJenaRdb tests\n" ) sys.stdout.write( "Node tests\n" ) Node1 = N3Node() sys.stdout.write( "Node 1: "+str(Node1)+"\n" ) Node2 = N3Node( uri='http://example.org/base/local' ) sys.stdout.write( "Node 2: "+str(Node2)+"\n" ) Node3 = N3Node( ns='http://example.org/base/', name='local' ) sys.stdout.write( "Node 3: "+str(Node3)+"\n" ) Node4 = N3Node( lit='a string' ) sys.stdout.write( "Node 4: "+str(Node4)+"\n" ) if Node1 == Node1: sys.stdout.write( "Node1 == Node1 (OK)\n" ) else: sys.stdout.write( "Node1 != Node1 (Error)\n" ) if Node2 == Node3: sys.stdout.write( "Node2 == Node3 (OK)\n" ) else: sys.stdout.write( "Node2 != Node3 (Error)\n" ) sys.stdout.write( "Statement tests\n" ) Stmt1 = N3Statement( Node1, Node2, Node4 ) sys.stdout.write( "Stmt 1: "+str(Stmt1)+"\n" ) Stmt2 = N3Statement( Node1, Node3, Node4 ) sys.stdout.write( "Stmt 2: "+str(Stmt2)+"\n" ) if Stmt1 == Stmt2: sys.stdout.write( "Stmt1 == Stmt2 (OK)\n" ) else: sys.stdout.write( "Stmt1 != Stmt2 (Error)\n" ) sys.stdout.write( "********************\n" ) sys.stdout.write( "Database Model tests\n" ) Model = N3ModelJenaRdb( DBURL, "graham", "graham" ) Model.format() # Initialize database Node5 = Model.makeNode( "rdf:type" ) sys.stdout.write( "Node 5: "+str(Node5)+"\n" ) Node6 = Model.makeNode( ":foo" ) sys.stdout.write( "Node 6: "+str(Node6)+"\n" ) Stmt3 = N3Statement( Node1, Node5, Node4 ) Stmt4 = N3Statement( Node1, Node6, Node5 ) Model.addStatement( Stmt1 ) Model.addStatement( Stmt2 ) Model.addStatement( Stmt3 ) Model.addStatement( Stmt4 ) # Simple query Q1 = Model.findStatements( Node1, Node5, None ) if len(Q1) != 1: sys.stdout.write( "Q1, 1 result expected, got: "+ str(len(Q1))+"\n" ) sys.stdout.write( "Q1 result expected: "+str(Stmt3)+"\n" ) if Q1[0] != Stmt3: sys.stdout.write( "Q1 result returned: "+str(Q1[0])+" (error)\n" ) # Another simple query Q2 = Model.findStatements( Node1, Node6, None ) if len(Q2) != 1: sys.stdout.write( "Q2, 1 result expected, got: "+ str(len(Q2))+"\n" ) sys.stdout.write( "Q2 result expected: "+str(Stmt4)+"\n" ) if Q2[0] != Stmt4: sys.stdout.write( "Q2 result returned: "+str(Q1[0])+" (error)\n" ) # Blank node query Node7 = N3Node() Q3 = Model.findStatements( Node1, Node6, Node7 ) sys.stdout.write( "Q3 no result expected\n" ) if len(Q3) != 0: sys.stdout.write( "Q3, No result expected, got: "+ str(len(Q3))+"\n" ) # List query: sys.stdout.write( "Q4 list result test\n" ) Node8 = Model.makeNode( "rdf:li" ) Stmt51 = N3Statement( Node1, Node8, N3Node(lit="1") ) Stmt52 = N3Statement( Node1, Node8, N3Node(lit="2") ) Stmt53 = N3Statement( Node1, Node8, N3Node(lit="3") ) Stmt54 = N3Statement( Node1, Node8, N3Node(lit="4") ) Model.addStatement( Stmt51 ) Model.addStatement( Stmt52 ) Model.addStatement( Stmt53 ) Model.addStatement( Stmt54 ) Q4 = Model.listObjectValues( Node1, Node8 ) sys.stdout.write( "Q4: "+repr(Q4)+"\n" ) #### if len(Q4) != 4: sys.stdout.write( "Q4, 4 results expected, got: "+str(len(Q4))+"\n" ) if Q4[0] != Stmt51.getObject(): sys.stdout.write( "Q4[0], expected "+str(Stmt51.getObject())+ ", got: "+str(Q4[0])+"\n" ) if Q4[1] != Stmt52.getObject(): sys.stdout.write( "Q4[1], expected "+str(Stmt52.getObject())+ ", got: "+str(Q4[1])+"\n" ) if Q4[2] != Stmt53.getObject(): sys.stdout.write( "Q4[2], expected "+str(Stmt53.getObject())+ ", got: "+str(Q4[2])+"\n" ) if Q4[3] != Stmt54.getObject(): sys.stdout.write( "Q4[3], expected "+str(Stmt54.getObject())+ ", got: "+str(Q4[3])+"\n" ) # List path query: sys.stdout.write( "Q5 path list result test\n" ) Node91 = N3Node() Node92 = N3Node() Stmt61 = N3Statement( Node1, Node8, Node91 ) Stmt62 = N3Statement( Node91, Node8, N3Node(lit="62") ) Stmt63 = N3Statement( Node91, Node8, N3Node(lit="63") ) Stmt64 = N3Statement( Node1, Node8, Node92 ) Stmt65 = N3Statement( Node92, Node8, N3Node(lit="65") ) Stmt66 = N3Statement( Node92, Node8, N3Node(lit="66") ) Model.addStatement( Stmt61 ) Model.addStatement( Stmt62 ) Model.addStatement( Stmt63 ) Model.addStatement( Stmt64 ) Model.addStatement( Stmt65 ) Model.addStatement( Stmt66 ) Q5 = Model.listPathValues( Node1, (Node8,Node8) ) sys.stdout.write( "Q5: "+repr(Q5)+"\n" ) #### if len(Q5) != 4: sys.stdout.write( "Q5, 4 results expected, got: "+str(len(Q5))+"\n" ) if Q5[0] != Stmt62.getObject(): sys.stdout.write( "Q5[0], expected "+str(Stmt62.getObject())+ ", got: "+str(Q5[0])+"\n" ) if Q5[1] != Stmt63.getObject(): sys.stdout.write( "Q5[1], expected "+str(Stmt63.getObject())+ ", got: "+str(Q5[1])+"\n" ) if Q5[2] != Stmt65.getObject(): sys.stdout.write( "Q5[2], expected "+str(Stmt65.getObject())+ ", got: "+str(Q5[2])+"\n" ) if Q5[3] != Stmt66.getObject(): sys.stdout.write( "Q5[3], expected "+str(Stmt66.getObject())+ ", got: "+str(Q5[3])+"\n" ) # Count total number of statements in database Q6 = Model.findStatements( None, None, None ) sys.stdout.write( "Q6, number or statements in store: "+str(len(Q6))+"\n" ) sys.stdout.write( "**************************************\n" ) sys.stdout.write( "Reopen database and re-run query tests\n" ) Model1 = N3ModelJenaRdb( DBURL, "graham", "graham" ) # Simple query Q1 = Model1.findStatements( Node1, Node5, None ) if len(Q1) != 1: sys.stdout.write( "Q1, 1 result expected, got: "+ str(len(Q1))+"\n" ) sys.stdout.write( "Q1 result expected: "+str(Stmt3)+"\n" ) if Q1[0] != Stmt3: sys.stdout.write( "Q1 result returned: "+str(Q1[0])+" (error)\n" ) # Another simple query Q2 = Model1.findStatements( Node1, Node6, None ) if len(Q2) != 1: sys.stdout.write( "Q2, 1 result expected, got: "+ str(len(Q2))+"\n" ) sys.stdout.write( "Q2 result expected: "+str(Stmt4)+"\n" ) if Q2[0] != Stmt4: sys.stdout.write( "Q2 result returned: "+str(Q1[0])+" (error)\n" ) # Blank node query Node7 = N3Node() Q3 = Model1.findStatements( Node1, Node6, Node7 ) sys.stdout.write( "Q3 no result expected\n" ) if len(Q3) != 0: sys.stdout.write( "Q3, No result expected, got: "+ str(len(Q3))+"\n" ) # List query: # (Note - two extra results compared with first round because of # Q5 test adding additional results.) sys.stdout.write( "Q4 list result test\n" ) Q4 = Model1.listObjectValues( Node1, Node8 ) sys.stdout.write( "Q4: "+repr(Q4)+"\n" ) #### if len(Q4) != 6: sys.stdout.write( "Q4, 6 results expected, got: "+str(len(Q4))+"\n" ) if Q4[0] != Stmt51.getObject(): sys.stdout.write( "Q4[0], expected "+str(Stmt51.getObject())+ ", got: "+str(Q4[0])+"\n" ) if Q4[1] != Stmt52.getObject(): sys.stdout.write( "Q4[1], expected "+str(Stmt52.getObject())+ ", got: "+str(Q4[1])+"\n" ) if Q4[2] != Stmt53.getObject(): sys.stdout.write( "Q4[2], expected "+str(Stmt53.getObject())+ ", got: "+str(Q4[2])+"\n" ) if Q4[3] != Stmt54.getObject(): sys.stdout.write( "Q4[3], expected "+str(Stmt54.getObject())+ ", got: "+str(Q4[3])+"\n" ) # List path query: sys.stdout.write( "Q5 path list result test\n" ) Q5 = Model1.listPathValues( Node1, (Node8,Node8) ) sys.stdout.write( "Q5: "+repr(Q5)+"\n" ) #### if len(Q5) != 4: sys.stdout.write( "Q5, 4 results expected, got: "+str(len(Q5))+"\n" ) if Q5[0] != Stmt62.getObject(): sys.stdout.write( "Q5[0], expected "+str(Stmt62.getObject())+ ", got: "+str(Q5[0])+"\n" ) if Q5[1] != Stmt63.getObject(): sys.stdout.write( "Q5[1], expected "+str(Stmt63.getObject())+ ", got: "+str(Q5[1])+"\n" ) if Q5[2] != Stmt65.getObject(): sys.stdout.write( "Q5[2], expected "+str(Stmt65.getObject())+ ", got: "+str(Q5[2])+"\n" ) if Q5[3] != Stmt66.getObject(): sys.stdout.write( "Q5[3], expected "+str(Stmt66.getObject())+ ", got: "+str(Q5[3])+"\n" ) # Count total number of statements in database Q6 = Model1.findStatements( None, None, None ) sys.stdout.write( "Q6, number of statements in store: "+str(len(Q6))+"\n" ) Model1.resetModel() Q7 = Model1.findStatements( None, None, None ) sys.stdout.write( "Q7, number of statements in store: "+str(len(Q7))+"\n" ) sys.stdout.write( "Exiting\n" ) #--------+---------+---------+---------+---------+---------+---------+---------+ # # $Log: N3ModelJenaRdb.py,v $ # Revision 1.3 2002/05/16 13:19:01 graham # Fix use of Jena ModelDB.create() method. # (db is initialized only if not already present.) # # Revision 1.2 2002/05/15 17:44:48 graham # Updated N3ModelJena-readme and todo entries # # Revision 1.1 2002/05/15 17:21:13 graham # N3ModelJenaRdb.py, with supporting code, # works with a Jena RDB model store. # Tested against a MySQL server. # #