001: /*
002: * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
003: *
004: * Licensed under the Aduna BSD-style license.
005: */
006: package org.openrdf.sail.rdbms;
007:
008: import static java.sql.Connection.TRANSACTION_READ_COMMITTED;
009:
010: import java.sql.Connection;
011: import java.sql.SQLException;
012:
013: import javax.sql.DataSource;
014:
015: import org.openrdf.model.impl.ValueFactoryImpl;
016: import org.openrdf.sail.SailConnection;
017: import org.openrdf.sail.SailException;
018: import org.openrdf.sail.helpers.DefaultSailChangedEvent;
019: import org.openrdf.sail.rdbms.evaluation.QueryBuilderFactory;
020: import org.openrdf.sail.rdbms.evaluation.RdbmsEvaluationFactory;
021: import org.openrdf.sail.rdbms.exceptions.RdbmsException;
022: import org.openrdf.sail.rdbms.managers.BNodeManager;
023: import org.openrdf.sail.rdbms.managers.HashManager;
024: import org.openrdf.sail.rdbms.managers.LiteralManager;
025: import org.openrdf.sail.rdbms.managers.NamespaceManager;
026: import org.openrdf.sail.rdbms.managers.PredicateManager;
027: import org.openrdf.sail.rdbms.managers.TransTableManager;
028: import org.openrdf.sail.rdbms.managers.TripleManager;
029: import org.openrdf.sail.rdbms.managers.TripleTableManager;
030: import org.openrdf.sail.rdbms.managers.UriManager;
031: import org.openrdf.sail.rdbms.optimizers.RdbmsQueryOptimizer;
032: import org.openrdf.sail.rdbms.optimizers.SelectQueryOptimizerFactory;
033: import org.openrdf.sail.rdbms.schema.BNodeTable;
034: import org.openrdf.sail.rdbms.schema.HashTable;
035: import org.openrdf.sail.rdbms.schema.IdSequence;
036: import org.openrdf.sail.rdbms.schema.IntegerIdSequence;
037: import org.openrdf.sail.rdbms.schema.LiteralTable;
038: import org.openrdf.sail.rdbms.schema.LongIdSequence;
039: import org.openrdf.sail.rdbms.schema.NamespacesTable;
040: import org.openrdf.sail.rdbms.schema.TableFactory;
041: import org.openrdf.sail.rdbms.schema.URITable;
042: import org.openrdf.sail.rdbms.schema.ValueTableFactory;
043:
044: /**
045: * Responsible to initialise and wire all components together that will be
046: * needed to satisfy any sail connection request.
047: *
048: * @author James Leigh
049: *
050: */
051: public class RdbmsConnectionFactory {
052: private RdbmsStore sail;
053: private DataSource ds;
054: private String user;
055: private String password;
056: private Connection resourceInserts;
057: private Connection literalInserts;
058: private Connection hashLookups;
059: private Connection nsAndTableIndexes;
060: private NamespaceManager namespaces;
061: private TripleTableManager tripleTableManager;
062: private HashManager hashManager;
063: private RdbmsValueFactory vf;
064: private UriManager uriManager;
065: private BNodeManager bnodeManager;
066: private LiteralManager literalManager;
067: private PredicateManager predicateManager;
068: private int maxTripleTables;
069: private boolean triplesIndexed = true;
070: private boolean sequenced;
071: private HashTable hashTable;
072: private URITable uriTable;
073: private BNodeTable bnodeTable;
074: private LiteralTable literalTable;
075: private IdSequence ids;
076:
077: public void setSail(RdbmsStore sail) {
078: this .sail = sail;
079: }
080:
081: public DataSource getDataSource() {
082: return ds;
083: }
084:
085: public void setDataSource(DataSource ds) {
086: this .ds = ds;
087: }
088:
089: public void setDataSource(DataSource ds, String user,
090: String password) {
091: this .ds = ds;
092: this .user = user;
093: this .password = password;
094: }
095:
096: public int getMaxNumberOfTripleTables() {
097: return maxTripleTables;
098: }
099:
100: public void setMaxNumberOfTripleTables(int max) {
101: maxTripleTables = max;
102: }
103:
104: public boolean isSequenced() {
105: return sequenced || hashManager != null;
106: }
107:
108: public void setSequenced(boolean useSequence) {
109: this .sequenced = useSequence;
110: }
111:
112: public boolean isTriplesIndexed() {
113: return triplesIndexed;
114: }
115:
116: public void setTriplesIndexed(boolean triplesIndexed)
117: throws SailException {
118: this .triplesIndexed = triplesIndexed;
119: if (tripleTableManager != null) {
120: try {
121: if (triplesIndexed) {
122: tripleTableManager.createTripleIndexes();
123: } else {
124: tripleTableManager.dropTripleIndexes();
125: }
126: } catch (SQLException e) {
127: throw new RdbmsException(e);
128: }
129: }
130: }
131:
132: public RdbmsValueFactory getValueFactory() {
133: return vf;
134: }
135:
136: public void init() throws SailException {
137: try {
138: nsAndTableIndexes = getConnection();
139: resourceInserts = getConnection();
140: literalInserts = getConnection();
141: nsAndTableIndexes.setAutoCommit(true);
142: resourceInserts.setAutoCommit(true);
143: literalInserts.setAutoCommit(true);
144: bnodeManager = new BNodeManager();
145: uriManager = new UriManager();
146: literalManager = new LiteralManager();
147: ValueTableFactory tables = createValueTableFactory();
148: tables.setSequenced(sequenced);
149: if (sequenced) {
150: ids = new IntegerIdSequence();
151: tables.setIdSequence(ids);
152: hashLookups = getConnection();
153: hashLookups.setAutoCommit(true);
154: hashManager = new HashManager();
155: hashTable = tables.createHashTable(hashLookups,
156: hashManager.getQueue());
157: ids.setHashTable(hashTable);
158: ids.init();
159: hashManager.setHashTable(hashTable);
160: hashManager.setBNodeManager(bnodeManager);
161: hashManager.setLiteralManager(literalManager);
162: hashManager.setUriManager(uriManager);
163: hashManager.setIdSequence(ids);
164: hashManager.init();
165: } else {
166: ids = new LongIdSequence();
167: ids.init();
168: tables.setIdSequence(ids);
169: }
170: namespaces = new NamespaceManager();
171: namespaces.setConnection(resourceInserts);
172: NamespacesTable nsTable = tables
173: .createNamespacesTable(nsAndTableIndexes);
174: nsTable.initialize();
175: namespaces.setNamespacesTable(nsTable);
176: namespaces.initialize();
177: bnodeManager.setHashManager(hashManager);
178: bnodeManager.setIdSequence(ids);
179: uriManager.setHashManager(hashManager);
180: uriManager.setIdSequence(ids);
181: bnodeTable = tables.createBNodeTable(resourceInserts,
182: bnodeManager.getQueue());
183: uriTable = tables.createURITable(resourceInserts,
184: uriManager.getQueue());
185: literalManager.setHashManager(hashManager);
186: literalManager.setIdSequence(ids);
187: literalTable = tables.createLiteralTable(literalInserts,
188: literalManager.getQueue());
189: literalTable.setIdSequence(ids);
190: vf = new RdbmsValueFactory();
191: vf.setDelegate(ValueFactoryImpl.getInstance());
192: vf.setIdSequence(ids);
193: uriManager.setUriTable(uriTable);
194: uriManager.init();
195: predicateManager = new PredicateManager();
196: predicateManager.setUriManager(uriManager);
197: tripleTableManager = new TripleTableManager(tables);
198: tripleTableManager.setConnection(nsAndTableIndexes);
199: tripleTableManager.setIdSequence(ids);
200: tripleTableManager.setBNodeManager(bnodeManager);
201: tripleTableManager.setUriManager(uriManager);
202: tripleTableManager.setLiteralManager(literalManager);
203: tripleTableManager.setHashManager(hashManager);
204: tripleTableManager.setPredicateManager(predicateManager);
205: tripleTableManager
206: .setMaxNumberOfTripleTables(maxTripleTables);
207: tripleTableManager.setIndexingTriples(triplesIndexed);
208: tripleTableManager.initialize();
209: if (triplesIndexed) {
210: tripleTableManager.createTripleIndexes();
211: } else {
212: tripleTableManager.dropTripleIndexes();
213: }
214: bnodeManager.setTable(bnodeTable);
215: bnodeManager.init();
216: vf.setBNodeManager(bnodeManager);
217: vf.setURIManager(uriManager);
218: literalManager.setTable(literalTable);
219: literalManager.init();
220: vf.setLiteralManager(literalManager);
221: vf.setPredicateManager(predicateManager);
222: } catch (SQLException e) {
223: throw new RdbmsException(e);
224: }
225: }
226:
227: public boolean isWritable() throws SailException {
228: try {
229: return !nsAndTableIndexes.isReadOnly();
230: } catch (SQLException e) {
231: throw new RdbmsException(e);
232: }
233: }
234:
235: public SailConnection createConnection() throws SailException {
236: try {
237: Connection db = getConnection();
238: db.setAutoCommit(true);
239: if (db.getTransactionIsolation() != TRANSACTION_READ_COMMITTED) {
240: db.setTransactionIsolation(TRANSACTION_READ_COMMITTED);
241: }
242: TripleManager tripleManager = new TripleManager();
243: RdbmsTripleRepository s = new RdbmsTripleRepository();
244: s.setTripleManager(tripleManager);
245: s.setValueFactory(vf);
246: s.setConnection(db);
247: s.setBNodeTable(bnodeTable);
248: s.setURITable(uriTable);
249: s.setLiteralTable(literalTable);
250: s.setIdSequence(ids);
251: DefaultSailChangedEvent sailChangedEvent = new DefaultSailChangedEvent(
252: sail);
253: s.setSailChangedEvent(sailChangedEvent);
254: TableFactory tables = createTableFactory();
255: TransTableManager trans = createTransTableManager();
256: trans.setIdSequence(ids);
257: tripleManager.setTransTableManager(trans);
258: trans.setBatchQueue(tripleManager.getQueue());
259: trans.setSailChangedEvent(sailChangedEvent);
260: trans.setConnection(db);
261: trans.setTemporaryTableFactory(tables);
262: trans.setStatementsTable(tripleTableManager);
263: trans.setFromDummyTable(getFromDummyTable());
264: trans.initialize();
265: s.setTransaction(trans);
266: QueryBuilderFactory bfactory = createQueryBuilderFactory();
267: bfactory.setValueFactory(vf);
268: bfactory.setUsingHashTable(hashManager != null);
269: s.setQueryBuilderFactory(bfactory);
270: RdbmsConnection conn = new RdbmsConnection(sail, s);
271: conn.setNamespaces(namespaces);
272: RdbmsEvaluationFactory efactory = new RdbmsEvaluationFactory();
273: efactory.setQueryBuilderFactory(bfactory);
274: efactory.setRdbmsTripleRepository(s);
275: efactory.setIdSequence(ids);
276: conn.setRdbmsEvaluationFactory(efactory);
277: RdbmsQueryOptimizer optimizer = createOptimizer();
278: SelectQueryOptimizerFactory selectOptimizerFactory = createSelectQueryOptimizerFactory();
279: selectOptimizerFactory.setTransTableManager(trans);
280: selectOptimizerFactory.setValueFactory(vf);
281: selectOptimizerFactory.setIdSequence(ids);
282: optimizer
283: .setSelectQueryOptimizerFactory(selectOptimizerFactory);
284: optimizer.setValueFactory(vf);
285: optimizer.setBnodeTable(bnodeTable);
286: optimizer.setUriTable(uriTable);
287: optimizer.setLiteralTable(literalTable);
288: optimizer.setHashTable(hashTable);
289: conn.setRdbmsQueryOptimizer(optimizer);
290: return conn;
291: } catch (SQLException e) {
292: throw new RdbmsException(e);
293: }
294: }
295:
296: public void shutDown() throws SailException {
297: try {
298: if (tripleTableManager != null) {
299: tripleTableManager.close();
300: }
301: if (uriManager != null) {
302: uriManager.close();
303: }
304: if (bnodeManager != null) {
305: bnodeManager.close();
306: }
307: if (literalManager != null) {
308: literalManager.close();
309: }
310: if (hashManager != null) {
311: hashManager.close();
312: }
313: if (resourceInserts != null) {
314: resourceInserts.close();
315: resourceInserts = null;
316: }
317: if (literalInserts != null) {
318: literalInserts.close();
319: literalInserts = null;
320: }
321: if (hashLookups != null) {
322: hashLookups.close();
323: hashLookups = null;
324: }
325: if (nsAndTableIndexes != null) {
326: nsAndTableIndexes.close();
327: nsAndTableIndexes = null;
328: }
329: } catch (SQLException e) {
330: throw new RdbmsException(e);
331: }
332: }
333:
334: protected QueryBuilderFactory createQueryBuilderFactory() {
335: return new QueryBuilderFactory();
336: }
337:
338: protected ValueTableFactory createValueTableFactory() {
339: return new ValueTableFactory(createTableFactory());
340: }
341:
342: protected TableFactory createTableFactory() {
343: return new TableFactory();
344: }
345:
346: protected TransTableManager createTransTableManager() {
347: return new TransTableManager();
348: }
349:
350: protected RdbmsQueryOptimizer createOptimizer() {
351: return new RdbmsQueryOptimizer();
352: }
353:
354: protected SelectQueryOptimizerFactory createSelectQueryOptimizerFactory() {
355: return new SelectQueryOptimizerFactory();
356: }
357:
358: protected String getFromDummyTable() {
359: return "FROM DUAL";
360: }
361:
362: protected Connection getConnection() throws SQLException {
363: if (user == null)
364: return ds.getConnection();
365: return ds.getConnection(user, password);
366: }
367:
368: }
|