blob: a8876f60e4af39c093e3b7997a1867d657530503 [file] [log] [blame]
/*****************************************************************
* 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 org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.access.DataNode;
import org.apache.cayenne.access.translator.ParameterBinding;
import org.apache.cayenne.access.translator.ejbql.EJBQLTranslatorFactory;
import org.apache.cayenne.access.translator.select.QualifierTranslator;
import org.apache.cayenne.access.translator.select.QueryAssembler;
import org.apache.cayenne.access.translator.select.SelectTranslator;
import org.apache.cayenne.access.types.ExtendedTypeMap;
import org.apache.cayenne.di.Provider;
import org.apache.cayenne.log.JdbcEventLogger;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbRelationship;
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.merge.MergerFactory;
import org.apache.cayenne.query.Query;
import org.apache.cayenne.query.SQLAction;
import org.apache.cayenne.query.SelectQuery;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Collection;
/**
* 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
*/
public class AutoAdapter implements DbAdapter {
protected Provider<DbAdapter> adapterProvider;
protected PkGenerator pkGenerator;
protected JdbcEventLogger logger;
/**
* The actual adapter that is delegated methods execution.
*/
volatile DbAdapter adapter;
/**
* Creates an {@link AutoAdapter} based on a delegate adapter obtained via
* "adapterProvider".
*
* @since 3.1
*/
public AutoAdapter(Provider<DbAdapter> adapterProvider, JdbcEventLogger logger) {
if (adapterProvider == null) {
throw new CayenneRuntimeException("Null adapterProvider");
}
this.adapterProvider = adapterProvider;
this.logger = logger;
}
/**
* 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;
}
/**
* Loads underlying DbAdapter delegate.
*/
protected DbAdapter loadAdapter() {
return adapterProvider.get();
}
/**
* @since 4.0
*/
@Override
public SelectTranslator getSelectTranslator(SelectQuery<?> query, EntityResolver entityResolver) {
return getAdapter().getSelectTranslator(query, entityResolver);
}
@Override
public String getBatchTerminator() {
return getAdapter().getBatchTerminator();
}
@Override
public QualifierTranslator getQualifierTranslator(QueryAssembler queryAssembler) {
return getAdapter().getQualifierTranslator(queryAssembler);
}
@Override
public SQLAction getAction(Query query, DataNode node) {
return getAdapter().getAction(query, node);
}
@Override
public boolean supportsUniqueConstraints() {
return getAdapter().supportsUniqueConstraints();
}
@Override
public boolean supportsCatalogsOnReverseEngineering() {
return getAdapter().supportsCatalogsOnReverseEngineering();
}
@Override
public boolean supportsGeneratedKeys() {
return getAdapter().supportsGeneratedKeys();
}
@Override
public boolean supportsBatchUpdates() {
return getAdapter().supportsBatchUpdates();
}
@Override
public boolean typeSupportsLength(int type) {
return getAdapter().typeSupportsLength(type);
}
@Override
public Collection<String> dropTableStatements(DbEntity table) {
return getAdapter().dropTableStatements(table);
}
@Override
public String createTable(DbEntity entity) {
return getAdapter().createTable(entity);
}
@Override
public String createUniqueConstraint(DbEntity source, Collection<DbAttribute> columns) {
return getAdapter().createUniqueConstraint(source, columns);
}
@Override
public String createFkConstraint(DbRelationship rel) {
return getAdapter().createFkConstraint(rel);
}
@Override
public String[] externalTypesForJdbcType(int type) {
return getAdapter().externalTypesForJdbcType(type);
}
@Override
public ExtendedTypeMap getExtendedTypes() {
return getAdapter().getExtendedTypes();
}
/**
* Returns a primary key generator.
*/
@Override
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;
}
@Override
public DbAttribute buildAttribute(String name, String typeName, int type, int size, int precision,
boolean allowNulls) {
return getAdapter().buildAttribute(name, typeName, type, size, precision, allowNulls);
}
@Override
public void bindParameter(PreparedStatement statement, ParameterBinding parameterBinding)
throws SQLException, Exception {
getAdapter().bindParameter(statement, parameterBinding);
}
@Override
public String tableTypeForTable() {
return getAdapter().tableTypeForTable();
}
@Override
public String tableTypeForView() {
return getAdapter().tableTypeForView();
}
@Override
public MergerFactory mergerFactory() {
return getAdapter().mergerFactory();
}
@Override
public void createTableAppendColumn(StringBuffer sqlBuffer, DbAttribute column) {
getAdapter().createTableAppendColumn(sqlBuffer, column);
}
/**
* @deprecated since 4.0
*/
@Deprecated
@Override
public QuotingStrategy getQuotingStrategy(boolean isQuoteStrategy) {
return getAdapter().getQuotingStrategy(isQuoteStrategy);
}
/**
* @since 4.0
*/
@Override
public QuotingStrategy getQuotingStrategy() {
return getAdapter().getQuotingStrategy();
}
/**
* @since 4.0
*/
@Override
public DbAdapter unwrap() {
return getAdapter();
}
/**
* @since 4.0
*/
@Override
public EJBQLTranslatorFactory getEjbqlTranslatorFactory() {
return getAdapter().getEjbqlTranslatorFactory();
}
}