org.apache.cayenne.dba.AutoAdapter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cayenne-client-nodeps
Show all versions of cayenne-client-nodeps
Cayenne Object Persistence Framework
/*****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
****************************************************************/
package org.apache.cayenne.dba;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collection;
import javax.sql.DataSource;
import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.access.DataNode;
import org.apache.cayenne.access.OperationObserver;
import org.apache.cayenne.access.QueryLogger;
import org.apache.cayenne.access.QueryTranslator;
import org.apache.cayenne.access.trans.QualifierTranslator;
import org.apache.cayenne.access.trans.QueryAssembler;
import org.apache.cayenne.access.types.ExtendedTypeMap;
import org.apache.cayenne.dba.db2.DB2Sniffer;
import org.apache.cayenne.dba.derby.DerbySniffer;
import org.apache.cayenne.dba.frontbase.FrontBaseSniffer;
import org.apache.cayenne.dba.hsqldb.HSQLDBSniffer;
import org.apache.cayenne.dba.ingres.IngresSniffer;
import org.apache.cayenne.dba.mysql.MySQLSniffer;
import org.apache.cayenne.dba.openbase.OpenBaseSniffer;
import org.apache.cayenne.dba.oracle.OracleSniffer;
import org.apache.cayenne.dba.postgres.PostgresSniffer;
import org.apache.cayenne.dba.sqlserver.SQLServerSniffer;
import org.apache.cayenne.dba.sybase.SybaseSniffer;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbRelationship;
import org.apache.cayenne.query.BatchQuery;
import org.apache.cayenne.query.Query;
import org.apache.cayenne.query.SQLAction;
/**
* A DbAdapter that automatically detects the kind of database it is running on and
* instantiates an appropriate DB-specific adapter, delegating all subsequent method calls
* to this adapter.
*
* @since 1.2
* @author Andrus Adamchik
*/
public class AutoAdapter implements DbAdapter {
// hardcoded factories for adapters that we know how to auto-detect
static final DbAdapterFactory[] DEFAULT_FACTORIES = new DbAdapterFactory[] {
new MySQLSniffer(), new PostgresSniffer(), new OracleSniffer(),
new SQLServerSniffer(), new HSQLDBSniffer(), new DB2Sniffer(),
new SybaseSniffer(), new DerbySniffer(), new OpenBaseSniffer(),
new FrontBaseSniffer(), new IngresSniffer()
};
/**
* Returns a DbAdapterFactory configured to detect all databases officially supported
* by Cayenne.
*/
public static DbAdapterFactory getDefaultFactory() {
return new DbAdapterFactoryChain(Arrays.asList(DEFAULT_FACTORIES));
}
protected DbAdapterFactory adapterFactory;
protected DataSource dataSource;
protected PkGenerator pkGenerator;
/**
* The actual adapter that is delegated method execution.
*/
DbAdapter adapter;
/**
* Creates an AutoAdapter that can detect adapters known to Cayenne.
*/
public AutoAdapter(DataSource dataSource) {
this(null, dataSource);
}
/**
* Creates an AutoAdapter with specified adapter factory and DataSource. If
* adapterFactory is null, default factory is used.
*/
public AutoAdapter(DbAdapterFactory adapterFactory, DataSource dataSource) {
// sanity check
if (dataSource == null) {
throw new CayenneRuntimeException("Null dataSource");
}
this.adapterFactory = adapterFactory != null
? adapterFactory
: createDefaultFactory();
this.dataSource = dataSource;
}
/**
* Called from constructor to initialize factory in case no factory was specified by
* the object creator.
*/
protected DbAdapterFactory createDefaultFactory() {
return getDefaultFactory();
}
/**
* Returns a proxied DbAdapter, lazily creating it on first invocation.
*/
protected DbAdapter getAdapter() {
if (adapter == null) {
synchronized (this) {
if (adapter == null) {
this.adapter = loadAdapter();
}
}
}
return adapter;
}
/**
* Opens a connection, retrieves JDBC metadata and attempts to guess adapter form it.
*/
protected DbAdapter loadAdapter() {
DbAdapter adapter = null;
try {
Connection c = dataSource.getConnection();
try {
adapter = adapterFactory.createAdapter(c.getMetaData());
}
finally {
try {
c.close();
}
catch (SQLException e) {
// ignore...
}
}
}
catch (SQLException e) {
throw new CayenneRuntimeException("Error detecting database type", e);
}
if (adapter == null) {
QueryLogger.log("Failed to detect database type, using default adapter");
adapter = new JdbcAdapter();
}
else {
QueryLogger.log("Detected and installed adapter: "
+ adapter.getClass().getName());
}
return adapter;
}
// ---- DbAdapter methods ----
public String getBatchTerminator() {
return getAdapter().getBatchTerminator();
}
/**
* @deprecated since 1.2 this method is deprecated in DbAdapter interface.
*/
public DataNode createDataNode(String name) {
return getAdapter().createDataNode(name);
}
/**
* @deprecated since 1.2 this method is deprecated in DbAdapter interface.
*/
public QueryTranslator getQueryTranslator(Query query) throws Exception {
return getAdapter().getQueryTranslator(query);
}
public QualifierTranslator getQualifierTranslator(QueryAssembler queryAssembler) {
return getAdapter().getQualifierTranslator(queryAssembler);
}
public SQLAction getAction(Query query, DataNode node) {
return getAdapter().getAction(query, node);
}
public boolean supportsFkConstraints() {
return getAdapter().supportsFkConstraints();
}
public boolean supportsUniqueConstraints() {
return getAdapter().supportsUniqueConstraints();
}
public boolean supportsGeneratedKeys() {
return getAdapter().supportsGeneratedKeys();
}
public boolean supportsBatchUpdates() {
return getAdapter().supportsBatchUpdates();
}
public String dropTable(DbEntity entity) {
return getAdapter().dropTable(entity);
}
public String createTable(DbEntity entity) {
return getAdapter().createTable(entity);
}
public String createUniqueConstraint(DbEntity source, Collection columns) {
return getAdapter().createUniqueConstraint(source, columns);
}
public String createFkConstraint(DbRelationship rel) {
return getAdapter().createFkConstraint(rel);
}
public String[] externalTypesForJdbcType(int type) {
return getAdapter().externalTypesForJdbcType(type);
}
public ExtendedTypeMap getExtendedTypes() {
return getAdapter().getExtendedTypes();
}
/**
* Returns a primary key generator.
*/
public PkGenerator getPkGenerator() {
return (pkGenerator != null) ? pkGenerator : getAdapter().getPkGenerator();
}
/**
* Sets a PK generator override. If set to non-null value, such PK generator will be
* used instead of the one provided by wrapped adapter.
*/
public void setPkGenerator(PkGenerator pkGenerator) {
this.pkGenerator = pkGenerator;
}
public DbAttribute buildAttribute(
String name,
String typeName,
int type,
int size,
int precision,
boolean allowNulls) {
return getAdapter().buildAttribute(
name,
typeName,
type,
size,
precision,
allowNulls);
}
public void bindParameter(
PreparedStatement statement,
Object object,
int pos,
int sqlType,
int precision) throws SQLException, Exception {
getAdapter().bindParameter(statement, object, pos, sqlType, precision);
}
public String tableTypeForTable() {
return getAdapter().tableTypeForTable();
}
public String tableTypeForView() {
return getAdapter().tableTypeForView();
}
/**
* @deprecated since 1.2 this method is deprecated in DbAdapter interface.
*/
public boolean shouldRunBatchQuery(
DataNode node,
Connection con,
BatchQuery query,
OperationObserver delegate) throws SQLException, Exception {
return getAdapter().shouldRunBatchQuery(node, con, query, delegate);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy