/* * Copyright Aduna (http://www.aduna-software.com/) (c) 2008. * * Licensed under the Aduna BSD-style license. */ package org.openrdf.sail.rdbms; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.util.Iterator; import javax.imageio.spi.ServiceRegistry; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; import org.openrdf.sail.SailConnection; import org.openrdf.sail.SailException; import org.openrdf.sail.helpers.SailBase; import org.openrdf.sail.rdbms.exceptions.RdbmsException; /** * The RDBMS SAIL for relational database storage in Sesame. This class acts * both as a base class for database specific stores as well as a generic store * that can infer the type of database through the JDBC connection. * * @author James Leigh * */ public class RdbmsStore extends SailBase { private RdbmsConnectionFactory factory; private String jdbcDriver; private String url; private String user; private String password; private int maxTripleTables; private boolean triplesIndexed = true; private boolean sequenced = true; public RdbmsStore() { super(); } public RdbmsStore(String url) { this.url = url; } public RdbmsStore(String url, String user, String password) { this.url = url; this.user = user; this.password = password; } public RdbmsStore(String jdbcDriver, String jdbcUrl) { this.jdbcDriver = jdbcDriver; this.url = jdbcUrl; } public RdbmsStore(String jdbcDriver, String jdbcUrl, String user, String password) { this.jdbcDriver = jdbcDriver; this.url = jdbcUrl; this.user = user; this.password = password; } public int getMaxNumberOfTripleTables() { return maxTripleTables; } public void setMaxNumberOfTripleTables(int max) { maxTripleTables = max; } public boolean isIndexed() { return triplesIndexed; } public void setIndexed(boolean indexed) throws SailException { triplesIndexed = indexed; if (factory != null) { factory.setTriplesIndexed(triplesIndexed); } } public boolean isSequenced() { return sequenced; } public void setSequenced(boolean useSequence) { this.sequenced = useSequence; } public void initialize() throws SailException { if (factory == null) { try { factory = createFactory(jdbcDriver, url, user, password); } catch (SailException e) { throw e; } catch (Exception e) { throw new RdbmsException(e); } } factory.setMaxNumberOfTripleTables(maxTripleTables); factory.setTriplesIndexed(triplesIndexed); factory.setSequenced(sequenced); factory.init(); } public boolean isWritable() throws SailException { return factory.isWritable(); } public RdbmsValueFactory getValueFactory() { return factory.getValueFactory(); } @Override protected SailConnection getConnectionInternal() throws SailException { return factory.createConnection(); } @Override protected void shutDownInternal() throws SailException { DataSource ds = factory.getDataSource(); factory.shutDown(); if (ds instanceof BasicDataSource) { try { ((BasicDataSource)ds).close(); } catch (SQLException e) { throw new RdbmsException(e); } } } protected void setConnectionFactory(RdbmsConnectionFactory factory) { this.factory = factory; } private RdbmsConnectionFactory createFactory(String jdbcDriver, String url, String user, String password) throws Exception { if (jdbcDriver != null) { Class.forName(jdbcDriver); } DataSource ds = lookupDataSource(url, user, password); Connection con; if (user == null || url.startsWith("jdbc:")) { con = ds.getConnection(); } else { con = ds.getConnection(user, password); } try { DatabaseMetaData metaData = con.getMetaData(); RdbmsConnectionFactory factory = newFactory(metaData); factory.setSail(this); if (user == null || url.startsWith("jdbc:")) { factory.setDataSource(ds); } else { factory.setDataSource(ds, user, password); } return factory; } finally { con.close(); } } private DataSource lookupDataSource(String url, String user, String password) throws NamingException { if (url.startsWith("jdbc:")) { BasicDataSource ds = new BasicDataSource(); ds.setUrl(url); ds.setUsername(user); ds.setPassword(password); return ds; } return (DataSource)new InitialContext().lookup(url); } private RdbmsConnectionFactory newFactory(DatabaseMetaData metaData) throws SQLException { String dbn = metaData.getDatabaseProductName(); String dbv = metaData.getDatabaseProductVersion(); RdbmsConnectionFactory factory; Iterator<RdbmsProvider> providers; providers = ServiceRegistry.lookupProviders(RdbmsProvider.class); while (providers.hasNext()) { RdbmsProvider provider = providers.next(); factory = provider.createRdbmsConnectionFactory(dbn, dbv); if (factory != null) return factory; } return new RdbmsConnectionFactory(); } }