001: /*
002: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
003: [See end of file]
004: */
005:
006: package com.hp.hpl.jena.db;
007:
008: import com.hp.hpl.jena.rdf.model.impl.*;
009: import com.hp.hpl.jena.rdf.model.*;
010: import com.hp.hpl.jena.util.iterator.ExtendedIterator;
011: import com.hp.hpl.jena.enhanced.*;
012: import com.hp.hpl.jena.graph.*;
013:
014: /** A persistent relational database implemention of the RDF API.
015: *
016: * <p>This implementation of the RDF API stores all its data in a relational database.</p>
017: * <p> To construct a persistent RDB Model, first load the jdbc connector for
018: * your database - in this example, mysql:</p>
019: *
020: * <code>
021: * Class.forName("com.mysql.jdbc.Driver");
022: * </code>
023: * <p> Then create a connection to the database: </p>
024: *
025: * <code>
026: * IDBConnection conn = new DBConnection("jdbc:mysql://localhost/test", "test", "", "MySQL");
027: * </code>
028: *
029: * <p> Now, using that connection, you can construct Models in the database:</p>
030: * <code>
031: * Model m = ModelRDB.createModel(conn);
032: * </code>
033: *
034: * @author csayers (based on ModelMem written by bwm and the Jena 1 version of Model RDB by der.)
035: * @version $Revision: 1.22 $
036: */
037: public class ModelRDB extends ModelCom implements Model {
038:
039: protected GraphRDB m_graphRDB = null;
040:
041: /**
042: * Construct a model which is stored persistently in a Relational DataBase
043: *
044: * If a model already exists in the database, then it is opened, otherwise
045: * a new model with default name and formatting is inserted and opened.
046: * @param dbcon a Connection specifying the database connection
047: * @deprecated Since Jena 2.0, this call is not recommended -
048: * in the short-term use ModelRDB.open or ModelRDB.createModel;
049: * in the longer-term use factory methods to construct persistent models.
050: */
051: public ModelRDB(IDBConnection dbcon) throws RDFRDBException {
052: this (BuiltinPersonalities.model, new GraphRDB(dbcon, null,
053: null, !dbcon.containsDefaultModel()));
054: }
055:
056: /**
057: * Construct a model which is stored persistently in a Relational DataBase
058: *
059: * If a model with the specified identifier already exists in the
060: * database, then it is opened, otherwise a new model with default
061: * formatting is inserted and opened.
062: * @param dbcon a Connection specifying the database connection
063: * @param modelID is the identifier of an RDF model within the database.
064: * The modelID "DEFAULT" is reserved and may not be used for user models.
065: * @deprecated Since Jena 2.0, this call is not recommended -
066: * in the short-term use ModelRDB.open or ModelRDB.createModel;
067: * in the longer-term use factory methods to construct persistent models.
068: */
069: public ModelRDB(IDBConnection dbcon, String modelID)
070: throws RDFRDBException {
071: this (BuiltinPersonalities.model, new GraphRDB(dbcon, modelID,
072: null, !dbcon.containsDefaultModel()));
073: }
074:
075: /**
076: * A model which is stored persistently in a Relational DataBase
077: *
078: * Most applications should not call the constructor - use
079: * ModelRDB.createModel (to create a new model) or
080: * ModelRDB.open (to open an exising model).
081: *
082: * @param p the GraphPersonality of the resulting Model
083: * @param graph a GraphRDB to be exposed through the model interface
084: *
085: * @since Jena 2.0
086: */
087: public ModelRDB(GraphPersonality p, GraphRDB graph)
088: throws RDFRDBException {
089: super (graph, p);
090: m_graphRDB = graph;
091: }
092:
093: public ModelRDB(GraphRDB graph) {
094: super (graph);
095: m_graphRDB = graph;
096: }
097:
098: /**
099: * Open the default model from an existing rdf database. The layout and
100: * datatype type information will be dynamically loaded from the database.
101: *
102: * @param dbcon an IDBConnection specifying the database connection
103: */
104: public static ModelRDB open(IDBConnection dbcon)
105: throws RDFRDBException {
106: return open(dbcon, null);
107: }
108:
109: /**
110: * Open an existing rdf database. The layout and datatype type information
111: * will be dynamically loaded from the database.
112: * Will throw an RDFDBException if the database does not seem to formated.
113: * @param dbcon a IDBConnection specifying the database connection
114: * @param name the name of the RDF model to open
115: */
116: public static ModelRDB open(IDBConnection dbcon, String name)
117: throws RDFRDBException {
118: GraphRDB graph = new GraphRDB(dbcon, name, null,
119: GraphRDB.OPTIMIZE_AND_HIDE_ONLY_FULL_REIFICATIONS,
120: false);
121: return new ModelRDB(BuiltinPersonalities.model, graph);
122: }
123:
124: /**
125: * Create a new default model on an existing database.
126: * Will format the database if it has not already been formatted.
127: * @param dbcon a DBConnection specifying the database connection
128: * @since Jena 2.0
129: */
130: public static ModelRDB createModel(IDBConnection dbcon)
131: throws RDFRDBException {
132: return createModel(dbcon, null,
133: getDefaultModelProperties(dbcon));
134: }
135:
136: /**
137: * Create a new model on an existing database.
138: * Will format the database if it has not already been formatted.
139: *
140: * <p>
141: * Use the properties to optionally customize the model - this
142: * won't change the results you see when using the model interface,
143: * but it may alter the speed with which you get them or the space
144: * required by the underlying database.</p>
145: *
146: * <p>
147: * The properties must form a complete and consistent set.
148: * The easist way to get a complete and consistent set is to call
149: * getDefaultModelProperties, modify it, and then use that as an argument
150: * in the call.</p>
151: *
152: * @param dbcon a DBConnection specifying the database connection
153: * @param modelProperties a Model containing customization properties
154: * @since Jena 2.0
155: */
156: public static ModelRDB createModel(IDBConnection dbcon,
157: Model modelProperties) throws RDFRDBException {
158: return createModel(dbcon, null, modelProperties);
159: }
160:
161: /**
162: * Create a new model on an existing database.
163: * Will format the database if it has not already been formatted.
164: * @param dbcon a DBConnectionI specifying the database connection
165: * @param name the name to give the newly created model.
166: * The name "DEFAULT" is reserved and may not be used for user models.
167: */
168: public static ModelRDB createModel(IDBConnection dbcon, String name)
169: throws RDFRDBException {
170: return createModel(dbcon, name,
171: getDefaultModelProperties(dbcon));
172: }
173:
174: /**
175: * Create a new model on an existing database.
176: * Will format the database if it has not already been formatted.
177: *
178: * <p>
179: * Use the properties to optionally customize the model - this
180: * won't change the results you see when using the model interface,
181: * but it may alter the speed with which you get them or the space
182: * required by the underlying database.</p>
183: *
184: * <p>
185: * The properties must form a complete and consistent set.
186: * The easist way to get a complete and consistent set is to call
187: * getDefaultModelProperties, modify it, and then use that as an argument
188: * in the call.</p>
189: *
190: * @param dbcon a DBConnection specifying the database connection
191: * @param name the name to give the newly created model.
192: * The name "DEFAULT" is reserved and may not be used for user models.
193: * @param modelProperties a Model containing customization properties
194: * @since Jena 2.0
195: */
196: public static ModelRDB createModel(IDBConnection dbcon,
197: String name, Model modelProperties) throws RDFRDBException {
198:
199: GraphRDB graph;
200: if (modelProperties != null)
201: graph = new GraphRDB(dbcon, name, modelProperties
202: .getGraph(),
203: GraphRDB.OPTIMIZE_AND_HIDE_ONLY_FULL_REIFICATIONS,
204: true);
205: else
206: graph = new GraphRDB(dbcon, name, null,
207: GraphRDB.OPTIMIZE_AND_HIDE_ONLY_FULL_REIFICATIONS,
208: true);
209: return new ModelRDB(BuiltinPersonalities.model, graph);
210: }
211:
212: /**
213: * Create a new database suitable for storing RDF data. In fact the database has
214: * to exist since jdbc can't create an empty database from a vacuum but it can be empty
215: * and this call will format it with appropriate tables and stored procedures.
216: * <p>
217: * The appropriate RDF-RDB driver to use is assumed to be the class Driver<DatabaseType><LayoutType>.
218: * If that can't be found it defaults to looking for a property file in /etc/Driver<DatabaseType><LayoutType>.config
219: * and uses that to determine the driver class and parameters.</p>
220: *
221: * @param dbcon a DBConnection specifying the database connection
222: * @param layoutType the name of the layout style to use. Currently one of:
223: * "Generic", "Hash", "MMGeneric", "MMHash", "Proc", "ThinProc".
224: * @param databaseType the name of the database type. Currently one of:
225: * "Interbase" "Postgresql" "Mysql" "Oracle". This may seem a little redundant
226: * given that the jdbc uri implicitly contains this information but there is no
227: * standard way of extracting this (esp. if the user connects via a bridge).
228: * @deprecated Since Jena 2.0 this call is no longer needed - it is preferable
229: * to specify the database type when constructing the DBConnection and to modify
230: * the layout by using the properties in the DBConnection. Then use the
231: * call ModelRDB.createModel(IDBConnection)
232: */
233: public static ModelRDB create(IDBConnection dbcon,
234: String layoutType, String databaseType)
235: throws RDFRDBException {
236: dbcon.setDatabaseType(databaseType);
237: return createModel(dbcon, null,
238: getDefaultModelProperties(dbcon));
239: }
240:
241: /**
242: * Create a new database suitable for storing RDF data. In fact the database has
243: * to exist since jdbc can't create an empty database from a vacuum but it can be empty
244: * and this call will format it with appropriate tables and stored procedures.
245: * <p>
246: * Uses a default layout format which is able to support multiple models in a single database.
247: * </p>
248: * @param dbcon a DBConnectionI specifying the database connection
249: * @param databaseType the name of the database type. Currently one of:
250: * "Interbase" "Postgresql" "Mysql" "Oracle". This may seem a little redundant
251: * given that the jdbc uri implicitly contains this information but there is no
252: * standard way of extracting this (esp. if the user connects via a bridge).
253: * @deprecated Since Jena 2.0 this call is no longer needed - it is preferable to
254: * specify the database type when constructing the DBConnection. Then use the call
255: * ModelRDB.createModel(IDBConnection)
256: */
257:
258: public static ModelRDB create(IDBConnection dbcon,
259: String databaseType) throws RDFRDBException {
260: dbcon.setDatabaseType(databaseType);
261: return createModel(dbcon, null,
262: getDefaultModelProperties(dbcon));
263: }
264:
265: /**
266: * Returns a Jena Model containing model-specific properties.
267: * These describe the optimization/layout for this model in the database.
268: *
269: * The returned Model is a copy, modifying it will have no
270: * immediate effect on the database.
271: *
272: *
273: * @since Jena 2.0
274: */
275:
276: public Model getModelProperties() {
277: Model m = ModelFactory.createDefaultModel();
278: Graph g = m.getGraph();
279: ExtendedIterator it = m_graphRDB.getPropertyTriples();
280: while (it.hasNext())
281: g.add((Triple) it.next());
282: return m;
283: }
284:
285: /**
286: * Retrieve a default set of model customization properties
287: *
288: * The returned default set of properties is suitable for use in a call to
289: * ModelRDB.create(..., modelProperties);
290: *
291: * @param dbcon a DBConnectionI specifying the database connection
292: * @return Model containing default properties
293: */
294:
295: public static Model getDefaultModelProperties(IDBConnection dbcon) {
296: return dbcon.getDefaultModelProperties();
297: }
298:
299: /**
300: * List the names of all models stored in the database
301: * @return ExtendedIterator over the model names.
302: */
303:
304: public static ExtendedIterator listModels(IDBConnection dbcon)
305: throws RDFRDBException {
306: return dbcon.getAllModelNames();
307: }
308:
309: /** Close the Model and free up resources held.
310: *
311: * <p>Not all implementations of Model require this method to be called. But
312: * some do, so in general its best to call it when done with the object,
313: * rather than leave it to the finalizer.</p>
314: */
315: public void close() {
316: m_graphRDB.close();
317: }
318:
319: /**
320: * Remove all traces of this particular Model from the database.
321: */
322: public void remove() throws RDFRDBException {
323: m_graphRDB.remove();
324: }
325:
326: /**
327: * A convenience function to return the connection
328: */
329: public IDBConnection getConnection() {
330: return m_graphRDB.getConnection();
331: }
332:
333: /**
334: * Remove all the statements from the database which are associated with just this model.
335: * This no longer reformats the database (which makes it safer and useful for multi-model
336: * databases) but means that it is not guaranteed to garbage collect the resource table.
337: * @deprecated Since Jena 2.0 this call is not recommended (it's name
338: * is misleading) - to clear an entire database use DBConnection.cleanDB,
339: * to remove just this Model use Model.remove().
340: */
341: public void clear() throws RDFRDBException {
342: remove();
343: }
344:
345: /**
346: * Remove a named model from an existing multi-model database.
347: * Will throw an RDFDBException if the database layout does not support
348: * multiple models or if the database does not seem to formated.
349: * @param dbcon a DBConnectionI specifying the database connection
350: * @param name the name to give the newly created model
351: * @deprecated Since Jena 2.0, to remove a model use the ModelRDB.remove()
352: */
353: public static void deleteModel(IDBConnection dbcon, String name)
354: throws RDFRDBException {
355: ModelRDB modelToDelete = ModelRDB.open(dbcon, name);
356: modelToDelete.remove();
357: }
358:
359: /**
360: * Loads all the statements for this model into an in-memory model.
361: * @return a ModelMem containing the whole of the RDB model
362: * @deprecated Since Jena 2.0, this call is not recommended. Instead use
363: * the soon-to-be-released bulk-load functions.
364: */
365: public Model loadAll() {
366: Model m = ModelFactory.createDefaultModel();
367: for (StmtIterator i = this .listStatements(); i.hasNext();) {
368: m.add(i.nextStatement());
369: }
370: return m;
371: }
372:
373: /**
374: * Get the value of DoDuplicateCheck
375: * @return bool boolean
376: */
377: public boolean getDoDuplicateCheck() {
378: return m_graphRDB.getDoDuplicateCheck();
379: }
380:
381: /**
382: * Set the value of DoDuplicateCheck.
383: * @param bool boolean
384: */
385: public void setDoDuplicateCheck(boolean bool) {
386: m_graphRDB.setDoDuplicateCheck(bool);
387: }
388:
389: /**
390: * Set the value of DoFastpath.
391: * @param val boolean
392: */
393: public void setDoFastpath(boolean val) {
394: m_graphRDB.setDoFastpath(val);
395: }
396:
397: /**
398: * Get the value of DoFastpath.
399: * @return boolean
400: */
401: public boolean getDoFastpath() {
402: return m_graphRDB.getDoFastpath();
403: }
404:
405: /**
406: * Set the value of QueryOnlyAsserted.
407: * @param opt boolean
408: */
409: public void setQueryOnlyAsserted(boolean opt) {
410: m_graphRDB.setQueryOnlyAsserted(opt);
411: }
412:
413: /**
414: * Get the value of QueryOnlyAsserted.
415: * @return boolean
416: */
417: public boolean getQueryOnlyAsserted() {
418: return m_graphRDB.getQueryOnlyAsserted();
419: }
420:
421: /**
422: * Set the value of QueryOnlyReified.
423: * @param opt boolean
424: */
425: public void setQueryOnlyReified(boolean opt) {
426: m_graphRDB.setQueryOnlyReified(opt);
427: }
428:
429: /**
430: * Get the value of QueryOnlyReified.
431: * @return boolean
432: */
433: public boolean getQueryOnlyReified() {
434: return m_graphRDB.getQueryOnlyReified();
435: }
436:
437: /**
438: * Set the value of QueryFullReified.
439: * @param opt boolean
440: */
441: public void setQueryFullReified(boolean opt) {
442: m_graphRDB.setQueryFullReified(opt);
443: }
444:
445: /**
446: * Get the value of QueryFullReified.
447: * @return boolean
448: */
449: public boolean getQueryFullReified() {
450: return m_graphRDB.getQueryFullReified();
451: }
452:
453: /**
454: * Set the value of DoImplicitJoin.
455: * @param val boolean
456: */
457: public void setDoImplicitJoin(boolean val) {
458: m_graphRDB.setDoImplicitJoin(val);
459: }
460:
461: }
462:
463: /*
464: (c) Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
465: All rights reserved.
466:
467: Redistribution and use in source and binary forms, with or without
468: modification, are permitted provided that the following conditions
469: are met:
470:
471: 1. Redistributions of source code must retain the above copyright
472: notice, this list of conditions and the following disclaimer.
473:
474: 2. Redistributions in binary form must reproduce the above copyright
475: notice, this list of conditions and the following disclaimer in the
476: documentation and/or other materials provided with the distribution.
477:
478: 3. The name of the author may not be used to endorse or promote products
479: derived from this software without specific prior written permission.
480:
481: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
482: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
483: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
484: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
485: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
486: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
487: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
488: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
489: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
490: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
491: */
|