http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/DefaultJdbc2JavaTypeMapper.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/DefaultJdbc2JavaTypeMapper.java b/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/DefaultJdbc2JavaTypeMapper.java deleted file mode 100644 index de9e02d..0000000 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/DefaultJdbc2JavaTypeMapper.java +++ /dev/null @@ -1,282 +0,0 @@ -/***************************************************************** - * 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.access.loader.mapper; - -import org.apache.cayenne.dba.TypesMapping; -import org.apache.cayenne.map.DbAttribute; -import org.apache.cayenne.util.Util; - -import java.io.Serializable; -import java.math.BigInteger; -import java.sql.Types; -import java.util.Calendar; -import java.util.HashMap; -import java.util.Map; -import java.util.SortedSet; -import java.util.TreeSet; - -/** - * @since 4.0. - */ -public class DefaultJdbc2JavaTypeMapper implements Jdbc2JavaTypeMapper { - - // Never use "-1" or any other normal integer, since there - // is a big chance it is being reserved in java.sql.Types - public static final int NOT_DEFINED = Integer.MAX_VALUE; - - // char constants for Java data types - public static final String JAVA_LONG = "java.lang.Long"; - public static final String JAVA_BYTES = "byte[]"; - public static final String JAVA_BOOLEAN = "java.lang.Boolean"; - public static final String JAVA_STRING = "java.lang.String"; - public static final String JAVA_SQLDATE = "java.sql.Date"; - public static final String JAVA_UTILDATE = "java.util.Date"; - public static final String JAVA_BIGDECIMAL = "java.math.BigDecimal"; - public static final String JAVA_DOUBLE = "java.lang.Double"; - public static final String JAVA_FLOAT = "java.lang.Float"; - public static final String JAVA_INTEGER = "java.lang.Integer"; - public static final String JAVA_SHORT = "java.lang.Short"; - public static final String JAVA_BYTE = "java.lang.Byte"; - public static final String JAVA_TIME = "java.sql.Time"; - public static final String JAVA_TIMESTAMP = "java.sql.Timestamp"; - public static final String JAVA_BLOB = "java.sql.Blob"; - - /** - * Keys: java class names, Values: SQL int type definitions from - * java.sql.Types - */ - private final Map<String, Integer> javaSqlEnum = new HashMap<>(); - - private final Map<DbType, String> mapping = new HashMap<>(); - private final SortedSet<DbType> dbTypes = new TreeSet<>(); - - private Map<String, String> classToPrimitive; - - { - add(Types.BIGINT, JAVA_LONG); - add(Types.BINARY, JAVA_BYTES); - add(Types.BIT, JAVA_BOOLEAN); - add(Types.BOOLEAN, JAVA_BOOLEAN); - add(Types.BLOB, JAVA_BYTES); - add(Types.CLOB, JAVA_STRING); - add(Types.NCLOB, JAVA_STRING); - add(Types.SQLXML, JAVA_STRING); - add(Types.CHAR, JAVA_STRING); - add(Types.NCHAR, JAVA_STRING); - add(Types.DATE, JAVA_UTILDATE); - add(Types.DECIMAL, JAVA_BIGDECIMAL); - add(Types.DOUBLE, JAVA_DOUBLE); - add(Types.FLOAT, JAVA_FLOAT); - add(Types.INTEGER, JAVA_INTEGER); - add(Types.LONGVARCHAR, JAVA_STRING); - add(Types.LONGNVARCHAR, JAVA_STRING); - add(Types.LONGVARBINARY, JAVA_BYTES); - add(Types.NUMERIC, JAVA_BIGDECIMAL); - add(Types.REAL, JAVA_FLOAT); - add(Types.SMALLINT, JAVA_SHORT); - add(Types.TINYINT, JAVA_SHORT); - add(Types.TIME, JAVA_UTILDATE); - add(Types.TIMESTAMP, JAVA_UTILDATE); - add(Types.VARBINARY, JAVA_BYTES); - add(Types.VARCHAR, JAVA_STRING); - add(Types.NVARCHAR, JAVA_STRING); - - javaSqlEnum.put(JAVA_LONG, Types.BIGINT); - javaSqlEnum.put(JAVA_BYTES, Types.BINARY); - javaSqlEnum.put(JAVA_BOOLEAN, Types.BIT); - javaSqlEnum.put(JAVA_STRING, Types.VARCHAR); - javaSqlEnum.put(JAVA_SQLDATE, Types.DATE); - javaSqlEnum.put(JAVA_UTILDATE, Types.DATE); - javaSqlEnum.put(JAVA_TIMESTAMP, Types.TIMESTAMP); - javaSqlEnum.put(JAVA_BIGDECIMAL, Types.DECIMAL); - javaSqlEnum.put(JAVA_DOUBLE, Types.DOUBLE); - javaSqlEnum.put(JAVA_FLOAT, Types.FLOAT); - javaSqlEnum.put(JAVA_INTEGER, Types.INTEGER); - javaSqlEnum.put(JAVA_SHORT, Types.SMALLINT); - javaSqlEnum.put(JAVA_BYTE, Types.SMALLINT); - javaSqlEnum.put(JAVA_TIME, Types.TIME); - javaSqlEnum.put(JAVA_TIMESTAMP, Types.TIMESTAMP); - - // add primitives - javaSqlEnum.put("byte", Types.TINYINT); - javaSqlEnum.put("int", Types.INTEGER); - javaSqlEnum.put("short", Types.SMALLINT); - javaSqlEnum.put("char", Types.CHAR); - javaSqlEnum.put("double", Types.DOUBLE); - javaSqlEnum.put("long", Types.BIGINT); - javaSqlEnum.put("float", Types.FLOAT); - javaSqlEnum.put("boolean", Types.BIT); - - classToPrimitive = new HashMap<>(); - classToPrimitive.put(Byte.class.getName(), "byte"); - classToPrimitive.put(Long.class.getName(), "long"); - classToPrimitive.put(Double.class.getName(), "double"); - classToPrimitive.put(Boolean.class.getName(), "boolean"); - classToPrimitive.put(Float.class.getName(), "float"); - classToPrimitive.put(Short.class.getName(), "short"); - classToPrimitive.put(Integer.class.getName(), "int"); - } - - private Boolean usePrimitives; - - /** - * Returns default java.sql.Types type by the Java type name. - * - * @param className - * Fully qualified Java Class name. - * @return The SQL type or NOT_DEFINED if no type found. - */ - public int getJdbcTypeByJava(DbAttribute attribute, String className) { - if (className == null) { - return NOT_DEFINED; - } - - Integer type = javaSqlEnum.get(className); - if (type != null) { - return type; - } - - // try to load a Java class - some nonstandard mappings may work - try { - return getSqlTypeByJava(attribute, Util.getJavaClass(className)); - } catch (Throwable th) { - return NOT_DEFINED; - } - } - - public void add(int jdbcType, String java) { - add(new DbType(TypesMapping.getSqlNameByType(jdbcType)), java); - } - - @Override - public void add(DbType type, String java) { - mapping.put(type, java); - dbTypes.add(type); - } - - /** - * Guesses a default JDBC type for the Java class. - * - * @since 1.1 - */ - protected int getSqlTypeByJava(DbAttribute attribute, Class<?> javaClass) { - if (javaClass == null) { - return NOT_DEFINED; - } - - // check standard mapping of class and superclasses - Class<?> aClass = javaClass; - while (aClass != null) { - - String name; - - if (aClass.isArray()) { - name = aClass.getComponentType().getName() + "[]"; - } else { - name = aClass.getName(); - } - - Object type = javaSqlEnum.get(name); - if (type != null) { - return ((Number) type).intValue(); - } - - aClass = aClass.getSuperclass(); - } - - // check non-standard JDBC types that are still supported by JPA - if (javaClass.isArray()) { - - Class<?> elementType = javaClass.getComponentType(); - if (Character.class.isAssignableFrom(elementType) || Character.TYPE.isAssignableFrom(elementType)) { - return Types.VARCHAR; - } else if (Byte.class.isAssignableFrom(elementType) || Byte.TYPE.isAssignableFrom(elementType)) { - return Types.VARBINARY; - } - } - - if (Calendar.class.isAssignableFrom(javaClass)) { - return Types.TIMESTAMP; - } - - if (BigInteger.class.isAssignableFrom(javaClass)) { - return Types.BIGINT; - } - - if (Serializable.class.isAssignableFrom(javaClass)) { - // serializable check should be the last one when all other mapping - // attempts failed - return Types.VARBINARY; - } - - return NOT_DEFINED; - } - - /** - * Get the corresponding Java type by its java.sql.Types counterpart. Note - * that this method should be used as a last resort, with explicit mapping - * provided by user used as a first choice, as it can only guess how to map - * certain types, such as NUMERIC, etc. - * - * @return Fully qualified Java type name or null if not found. - */ - @Override - public String getJavaByJdbcType(DbAttribute attribute, int type) { - String jdbcType = TypesMapping.getSqlNameByType(type); - DbType dbType; - if (attribute != null) { - dbType = new DbType(jdbcType, attribute.getMaxLength(), attribute.getAttributePrecision(), - attribute.getScale(), attribute.isMandatory()); - } else { - dbType = new DbType(jdbcType); - } - - String typeName = getJavaByJdbcType(dbType); - - if (usePrimitives != null && usePrimitives) { - String primitive = classToPrimitive.get(typeName); - if (primitive != null) { - return primitive; - } - } - - return typeName; - } - - public String getJavaByJdbcType(DbType type) { - for (DbType t : dbTypes) { - if (t.isCover(type)) { - // because dbTypes sorted by specificity we will take first and - // the most specific matching - // that applicable for attribute - return mapping.get(t); - } - } - - return null; - } - - public Boolean getUsePrimitives() { - return usePrimitives; - } - - public void setUsePrimitives(Boolean usePrimitives) { - this.usePrimitives = usePrimitives; - } -}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/Jdbc2JavaTypeMapper.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/Jdbc2JavaTypeMapper.java b/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/Jdbc2JavaTypeMapper.java deleted file mode 100644 index 160dc4e..0000000 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/loader/mapper/Jdbc2JavaTypeMapper.java +++ /dev/null @@ -1,33 +0,0 @@ -/***************************************************************** - * 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.access.loader.mapper; - -import org.apache.cayenne.map.DbAttribute; - -/** - * @since 4.0. - */ -public interface Jdbc2JavaTypeMapper { - - String getJavaByJdbcType(DbAttribute attribute, int type); - - int getJdbcTypeByJava(DbAttribute attribute, String className); - - void add(DbType type, String java); -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java index a8876f6..cb436e6 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/AutoAdapter.java @@ -33,7 +33,6 @@ 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; @@ -216,11 +215,6 @@ public class AutoAdapter implements DbAdapter { } @Override - public MergerFactory mergerFactory() { - return getAdapter().mergerFactory(); - } - - @Override public void createTableAppendColumn(StringBuffer sqlBuffer, DbAttribute column) { getAdapter().createTableAppendColumn(sqlBuffer, column); } http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java index d72bc31..e89ae4b 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java @@ -29,7 +29,6 @@ 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; @@ -183,11 +182,6 @@ public interface DbAdapter { String tableTypeForView(); /** - * @since 3.0 - */ - MergerFactory mergerFactory(); - - /** * Append the column type part of a "create table" to the given * {@link StringBuffer} * http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java index 57d3430..979b425 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java @@ -36,8 +36,11 @@ import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.di.Inject; import org.apache.cayenne.log.JdbcEventLogger; -import org.apache.cayenne.map.*; -import org.apache.cayenne.merge.MergerFactory; +import org.apache.cayenne.map.DbAttribute; +import org.apache.cayenne.map.DbEntity; +import org.apache.cayenne.map.DbJoin; +import org.apache.cayenne.map.DbRelationship; +import org.apache.cayenne.map.EntityResolver; import org.apache.cayenne.query.Query; import org.apache.cayenne.query.SQLAction; import org.apache.cayenne.query.SelectQuery; @@ -600,13 +603,6 @@ public class JdbcAdapter implements DbAdapter { } /** - * @since 3.0 - */ - public MergerFactory mergerFactory() { - return new MergerFactory(); - } - - /** * @return * @since 4.0 */ http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/PerAdapterProvider.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/PerAdapterProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/PerAdapterProvider.java new file mode 100644 index 0000000..d4b2816 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/PerAdapterProvider.java @@ -0,0 +1,46 @@ +/***************************************************************** + * 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.di.DIRuntimeException; + +import java.util.Map; +import java.util.Objects; + +/** + * An injectable provider that returns a given service in a context of a specific {@link DbAdapter}. + * This allows modules to create adapter-specific extensions without altering DbAdapter API. + * + * @since 4.0 + */ +public class PerAdapterProvider<T> { + + private Map<String, T> perAdapterValues; + private T defaultValue; + + public PerAdapterProvider(Map<String, T> perAdapterValues, T defaultValue) { + this.perAdapterValues = Objects.requireNonNull(perAdapterValues); + this.defaultValue = Objects.requireNonNull(defaultValue); + } + + public T get(DbAdapter adapter) throws DIRuntimeException { + T t = perAdapterValues.get(adapter.unwrap().getClass().getName()); + return t != null ? t : defaultValue; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2Adapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2Adapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2Adapter.java index f71f655..edf8901 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2Adapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2Adapter.java @@ -24,7 +24,12 @@ import org.apache.cayenne.access.DataNode; import org.apache.cayenne.access.translator.ParameterBinding; import org.apache.cayenne.access.translator.select.QualifierTranslator; import org.apache.cayenne.access.translator.select.QueryAssembler; -import org.apache.cayenne.access.types.*; +import org.apache.cayenne.access.types.BooleanType; +import org.apache.cayenne.access.types.ByteArrayType; +import org.apache.cayenne.access.types.CharType; +import org.apache.cayenne.access.types.ExtendedType; +import org.apache.cayenne.access.types.ExtendedTypeFactory; +import org.apache.cayenne.access.types.ExtendedTypeMap; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.JdbcAdapter; @@ -34,7 +39,6 @@ import org.apache.cayenne.dba.TypesMapping; import org.apache.cayenne.di.Inject; import org.apache.cayenne.map.DbAttribute; import org.apache.cayenne.map.DbEntity; -import org.apache.cayenne.merge.MergerFactory; import org.apache.cayenne.query.Query; import org.apache.cayenne.query.SQLAction; import org.apache.cayenne.resource.ResourceLocator; @@ -223,11 +227,6 @@ public class DB2Adapter extends JdbcAdapter { } @Override - public MergerFactory mergerFactory() { - return new DB2MergerFactory(); - } - - @Override public void bindParameter( PreparedStatement statement, ParameterBinding binding) throws SQLException, Exception { http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2MergerFactory.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2MergerFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2MergerFactory.java deleted file mode 100644 index 8ae070d..0000000 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2MergerFactory.java +++ /dev/null @@ -1,49 +0,0 @@ -/***************************************************************** - * 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.db2; - -import org.apache.cayenne.dba.QuotingStrategy; -import org.apache.cayenne.map.DbAttribute; -import org.apache.cayenne.map.DbEntity; -import org.apache.cayenne.merge.MergerFactory; -import org.apache.cayenne.merge.MergerToken; -import org.apache.cayenne.merge.SetColumnTypeToDb; - - -public class DB2MergerFactory extends MergerFactory { - - @Override - public MergerToken createSetColumnTypeToDb( - final DbEntity entity, - DbAttribute columnOriginal, - final DbAttribute columnNew) { - - return new SetColumnTypeToDb(entity, columnOriginal, columnNew) { - - @Override - protected void appendPrefix(StringBuffer sqlBuffer, QuotingStrategy context) { - sqlBuffer.append("ALTER TABLE "); - sqlBuffer.append(context.quotedFullyQualifiedName(entity)); - sqlBuffer.append(" ALTER COLUMN "); - sqlBuffer.append(context.quotedName(columnNew)); - sqlBuffer.append(" SET DATA TYPE "); - } - }; - } -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java index 8a3b462..916eb9e 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java @@ -25,7 +25,12 @@ import org.apache.cayenne.access.translator.ejbql.EJBQLTranslatorFactory; import org.apache.cayenne.access.translator.ejbql.JdbcEJBQLTranslatorFactory; import org.apache.cayenne.access.translator.select.QualifierTranslator; import org.apache.cayenne.access.translator.select.QueryAssembler; -import org.apache.cayenne.access.types.*; +import org.apache.cayenne.access.types.ByteType; +import org.apache.cayenne.access.types.CharType; +import org.apache.cayenne.access.types.ExtendedType; +import org.apache.cayenne.access.types.ExtendedTypeFactory; +import org.apache.cayenne.access.types.ExtendedTypeMap; +import org.apache.cayenne.access.types.ShortType; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.JdbcAdapter; @@ -33,7 +38,6 @@ import org.apache.cayenne.dba.PkGenerator; import org.apache.cayenne.di.Inject; import org.apache.cayenne.map.DbAttribute; import org.apache.cayenne.map.DbEntity; -import org.apache.cayenne.merge.MergerFactory; import org.apache.cayenne.resource.ResourceLocator; import java.sql.PreparedStatement; @@ -44,14 +48,14 @@ import java.util.List; /** * DbAdapter implementation for the <a href="http://db.apache.org/derby/"> Derby RDBMS * </a>. Sample connection settings to use with Derby are shown below. <h3>Embedded</h3> - * + * <p> * <pre> * test-derby.jdbc.url = jdbc:derby:testdb;create=true * test-derby.jdbc.driver = org.apache.derby.jdbc.EmbeddedDriver * </pre> - * + * <p> * <h3>Network Server</h3> - * + * <p> * <pre> * derbynet.jdbc.url = jdbc:derby://localhost/cayenne * derbynet.jdbc.driver = org.apache.derby.jdbc.ClientDriver @@ -103,7 +107,7 @@ public class DerbyAdapter extends JdbcAdapter { /** * Appends SQL for column creation to CREATE TABLE buffer. Only change for Derby is * that " NULL" is not supported. - * + * * @since 1.2 */ @Override @@ -118,7 +122,6 @@ public class DerbyAdapter extends JdbcAdapter { } - sqlBuffer.append(quotingStrategy.quotedName(column)); sqlBuffer.append(' '); @@ -168,7 +171,7 @@ public class DerbyAdapter extends JdbcAdapter { translator.setCaseInsensitive(caseInsensitiveCollations); return translator; } - + /** * @since 3.1 */ @@ -180,11 +183,6 @@ public class DerbyAdapter extends JdbcAdapter { } @Override - public MergerFactory mergerFactory() { - return new DerbyMergerFactory(); - } - - @Override public void bindParameter( PreparedStatement statement, ParameterBinding binding) throws SQLException, Exception { @@ -199,10 +197,14 @@ public class DerbyAdapter extends JdbcAdapter { private int convertNTypes(int sqlType) { switch (sqlType) { - case Types.NCHAR: return Types.CHAR; - case Types.NVARCHAR: return Types.VARCHAR; - case Types.LONGNVARCHAR: return Types.LONGVARCHAR; - case Types.NCLOB: return Types.CLOB; + case Types.NCHAR: + return Types.CHAR; + case Types.NVARCHAR: + return Types.VARCHAR; + case Types.LONGNVARCHAR: + return Types.LONGVARCHAR; + case Types.NCLOB: + return Types.CLOB; default: return sqlType; http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyMergerFactory.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyMergerFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyMergerFactory.java deleted file mode 100644 index 7ce30d4..0000000 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyMergerFactory.java +++ /dev/null @@ -1,86 +0,0 @@ -/***************************************************************** - * 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.derby; - -import java.util.Collections; -import java.util.List; - -import org.apache.cayenne.dba.DbAdapter; -import org.apache.cayenne.dba.QuotingStrategy; -import org.apache.cayenne.map.DbAttribute; -import org.apache.cayenne.map.DbEntity; -import org.apache.cayenne.merge.MergerFactory; -import org.apache.cayenne.merge.MergerToken; -import org.apache.cayenne.merge.SetAllowNullToDb; -import org.apache.cayenne.merge.SetColumnTypeToDb; -import org.apache.cayenne.merge.SetNotNullToDb; - -public class DerbyMergerFactory extends MergerFactory { - - @Override - public MergerToken createSetColumnTypeToDb( - final DbEntity entity, - DbAttribute columnOriginal, - final DbAttribute columnNew) { - - return new SetColumnTypeToDb(entity, columnOriginal, columnNew) { - - @Override - protected void appendPrefix(StringBuffer sqlBuffer, QuotingStrategy context) { - // http://db.apache.org/derby/manuals/reference/sqlj26.html - sqlBuffer.append("ALTER TABLE "); - sqlBuffer.append(context.quotedFullyQualifiedName(entity)); - sqlBuffer.append(" ALTER "); - sqlBuffer.append(context.quotedName(columnNew)); - sqlBuffer.append(" SET DATA TYPE "); - } - }; - } - - @Override - public MergerToken createSetNotNullToDb(DbEntity entity, DbAttribute column) { - return new SetNotNullToDb(entity, column) { - - @Override - public List<String> createSql(DbAdapter adapter) { - QuotingStrategy context = adapter.getQuotingStrategy(); - - return Collections.singletonList("ALTER TABLE " + context.quotedFullyQualifiedName(getEntity()) - + " ALTER COLUMN " + context.quotedName(getColumn()) + " NOT NULL"); - } - - }; - } - - @Override - public MergerToken createSetAllowNullToDb(DbEntity entity, DbAttribute column) { - return new SetAllowNullToDb(entity, column) { - - @Override - public List<String> createSql(DbAdapter adapter) { - QuotingStrategy context = adapter.getQuotingStrategy(); - - return Collections.singletonList("ALTER TABLE " + context.quotedFullyQualifiedName(getEntity()) - + " ALTER COLUMN " + context.quotedName(getColumn()) + " NULL"); - } - - }; - } - -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdAdapter.java index 9146bd5..c88c88f 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdAdapter.java @@ -76,11 +76,7 @@ public class FirebirdAdapter extends JdbcAdapter { map.registerType(new CharType(true, false)); } - - public FirebirdMergerFactory mergerFactory() { - return new FirebirdMergerFactory(); - } - + public void createTableAppendColumn(StringBuffer sqlBuffer, DbAttribute column) { String[] types = externalTypesForJdbcType(column.getType()); http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdMergerFactory.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdMergerFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdMergerFactory.java deleted file mode 100644 index 45f3832..0000000 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdMergerFactory.java +++ /dev/null @@ -1,91 +0,0 @@ -/***************************************************************** - * 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.firebird; - -import java.util.Collections; -import java.util.List; - -import org.apache.cayenne.dba.DbAdapter; -import org.apache.cayenne.dba.QuotingStrategy; -import org.apache.cayenne.map.DbAttribute; -import org.apache.cayenne.map.DbEntity; -import org.apache.cayenne.merge.MergerFactory; -import org.apache.cayenne.merge.MergerToken; -import org.apache.cayenne.merge.AddColumnToDb; -import org.apache.cayenne.merge.DropColumnToDb; -import org.apache.cayenne.merge.SetNotNullToDb; -import org.apache.cayenne.merge.SetAllowNullToDb; - -public class FirebirdMergerFactory extends MergerFactory { - - public MergerToken createDropColumnToDb(DbEntity entity, DbAttribute column) { - return new DropColumnToDb(entity, column) { - public List<String> createSql(DbAdapter adapter) { - QuotingStrategy quoting = adapter.getQuotingStrategy(); - return Collections.singletonList("ALTER TABLE " + quoting.quotedFullyQualifiedName(getEntity()) - + " DROP " + quoting.quotedName(getColumn())); - } - }; - } - - @Override - public MergerToken createSetNotNullToDb(DbEntity entity, DbAttribute column) { - return new SetNotNullToDb(entity, column) { - public List<String> createSql(DbAdapter adapter) { - QuotingStrategy context = adapter.getQuotingStrategy(); - String entityName = context.quotedFullyQualifiedName(getEntity()) ; - String columnName = context.quotedName(getColumn()); - // Firebird doesn't support ALTER TABLE table_name ALTER column_name SET NOT NULL - // but this might be achived by modyfication of system tables - return Collections.singletonList(String.format("UPDATE RDB$RELATION_FIELDS SET RDB$NULL_FLAG = 1 "+ - "WHERE RDB$FIELD_NAME = '%s' AND RDB$RELATION_NAME = '%s'", columnName, entityName)); - } - }; - } - - @Override - public MergerToken createSetAllowNullToDb(DbEntity entity, DbAttribute column) { - return new SetAllowNullToDb(entity, column) { - public List<String> createSql(DbAdapter adapter) { - QuotingStrategy context = adapter.getQuotingStrategy(); - String entityName = context.quotedFullyQualifiedName(getEntity()) ; - String columnName = context.quotedName(getColumn()); - // Firebird doesn't support ALTER TABLE table_name ALTER column_name DROP NOT NULL - // but this might be achived by modyfication system tables - return Collections.singletonList(String.format("UPDATE RDB$RELATION_FIELDS SET RDB$NULL_FLAG = NULL "+ - " WHERE RDB$FIELD_NAME = '%s' AND RDB$RELATION_NAME = '%s'", columnName, entityName)); - } - }; - } - - - public MergerToken createAddColumnToDb(DbEntity entity, DbAttribute column) { - return new AddColumnToDb(entity, column) { - protected void appendPrefix(StringBuffer sqlBuffer, QuotingStrategy context) { - sqlBuffer.append("ALTER TABLE "); - sqlBuffer.append(context.quotedFullyQualifiedName(getEntity())); - sqlBuffer.append(" ADD "); - sqlBuffer.append(context.quotedName(getColumn())); - sqlBuffer.append(" "); - } - }; - } - -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2Adapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2Adapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2Adapter.java index 768d466..0d99869 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2Adapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2Adapter.java @@ -27,7 +27,6 @@ import org.apache.cayenne.dba.JdbcAdapter; import org.apache.cayenne.dba.PkGenerator; import org.apache.cayenne.di.Inject; import org.apache.cayenne.map.DbAttribute; -import org.apache.cayenne.merge.MergerFactory; import org.apache.cayenne.resource.ResourceLocator; import java.util.List; @@ -57,11 +56,6 @@ public class H2Adapter extends JdbcAdapter { } @Override - public MergerFactory mergerFactory() { - return new H2MergerFactory(); - } - - @Override public void createTableAppendColumn(StringBuffer sqlBuffer, DbAttribute column) { super.createTableAppendColumn(sqlBuffer, column); http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2MergerFactory.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2MergerFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2MergerFactory.java deleted file mode 100644 index 6ec19aa..0000000 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2MergerFactory.java +++ /dev/null @@ -1,83 +0,0 @@ -/***************************************************************** - * 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.h2; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.apache.cayenne.dba.DbAdapter; -import org.apache.cayenne.dba.QuotingStrategy; -import org.apache.cayenne.map.DbAttribute; -import org.apache.cayenne.map.DbEntity; -import org.apache.cayenne.merge.MergerFactory; -import org.apache.cayenne.merge.MergerToken; -import org.apache.cayenne.merge.SetAllowNullToDb; -import org.apache.cayenne.merge.SetColumnTypeToDb; -import org.apache.cayenne.merge.SetPrimaryKeyToDb; - -/** - * @since 3.0 - */ -public class H2MergerFactory extends MergerFactory { - - @Override - public MergerToken createSetColumnTypeToDb(final DbEntity entity, DbAttribute columnOriginal, - final DbAttribute columnNew) { - return new SetColumnTypeToDb(entity, columnOriginal, columnNew) { - - @Override - protected void appendPrefix(StringBuffer sqlBuffer, QuotingStrategy context) { - sqlBuffer.append("ALTER TABLE "); - sqlBuffer.append(context.quotedFullyQualifiedName(entity)); - sqlBuffer.append(" ALTER "); - sqlBuffer.append(context.quotedName(columnNew)); - sqlBuffer.append(" "); - } - }; - } - - @Override - public MergerToken createSetAllowNullToDb(DbEntity entity, DbAttribute column) { - return new SetAllowNullToDb(entity, column) { - - @Override - public List<String> createSql(DbAdapter adapter) { - return Collections.singletonList("ALTER TABLE " + getEntity().getFullyQualifiedName() - + " ALTER COLUMN " + getColumn().getName() + " SET NULL"); - } - - }; - } - - @Override - public MergerToken createSetPrimaryKeyToDb(DbEntity entity, Collection<DbAttribute> primaryKeyOriginal, - Collection<DbAttribute> primaryKeyNew, String detectedPrimaryKeyName) { - return new SetPrimaryKeyToDb(entity, primaryKeyOriginal, primaryKeyNew, detectedPrimaryKeyName) { - - @Override - protected void appendDropOriginalPrimaryKeySQL(DbAdapter adapter, List<String> sqls) { - sqls.add("ALTER TABLE " + adapter.getQuotingStrategy().quotedFullyQualifiedName(getEntity()) - + " DROP PRIMARY KEY"); - } - - }; - } -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBAdapter.java index 6cfcaa5..96c5c0b 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBAdapter.java @@ -33,7 +33,6 @@ import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.map.DbJoin; 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; @@ -225,10 +224,4 @@ public class HSQLDBAdapter extends JdbcAdapter { super.createTableAppendColumn(sqlBuffer, column); } } - - @Override - public MergerFactory mergerFactory() { - return new HSQLMergerFactory(); - } - } http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLMergerFactory.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLMergerFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLMergerFactory.java deleted file mode 100644 index e972b15..0000000 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLMergerFactory.java +++ /dev/null @@ -1,83 +0,0 @@ -/***************************************************************** - * 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.hsqldb; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.apache.cayenne.dba.DbAdapter; -import org.apache.cayenne.dba.QuotingStrategy; -import org.apache.cayenne.map.DbAttribute; -import org.apache.cayenne.map.DbEntity; -import org.apache.cayenne.merge.MergerFactory; -import org.apache.cayenne.merge.MergerToken; -import org.apache.cayenne.merge.SetAllowNullToDb; -import org.apache.cayenne.merge.SetColumnTypeToDb; -import org.apache.cayenne.merge.SetPrimaryKeyToDb; - -public class HSQLMergerFactory extends MergerFactory { - - @Override - public MergerToken createSetColumnTypeToDb(final DbEntity entity, DbAttribute columnOriginal, - final DbAttribute columnNew) { - - return new SetColumnTypeToDb(entity, columnOriginal, columnNew) { - - @Override - protected void appendPrefix(StringBuffer sqlBuffer, QuotingStrategy context) { - sqlBuffer.append("ALTER TABLE "); - sqlBuffer.append(context.quotedFullyQualifiedName(entity)); - sqlBuffer.append(" ALTER "); - sqlBuffer.append(context.quotedName(columnNew)); - sqlBuffer.append(" "); - } - }; - } - - @Override - public MergerToken createSetAllowNullToDb(DbEntity entity, DbAttribute column) { - return new SetAllowNullToDb(entity, column) { - - @Override - public List<String> createSql(DbAdapter adapter) { - QuotingStrategy context = adapter.getQuotingStrategy(); - - return Collections.singletonList("ALTER TABLE " + context.quotedFullyQualifiedName(getEntity()) - + " ALTER COLUMN " + context.quotedName(getColumn()) + " NULL"); - } - - }; - } - - @Override - public MergerToken createSetPrimaryKeyToDb(DbEntity entity, Collection<DbAttribute> primaryKeyOriginal, - Collection<DbAttribute> primaryKeyNew, String detectedPrimaryKeyName) { - return new SetPrimaryKeyToDb(entity, primaryKeyOriginal, primaryKeyNew, detectedPrimaryKeyName) { - - @Override - protected void appendDropOriginalPrimaryKeySQL(DbAdapter adapter, List<String> sqls) { - sqls.add("ALTER TABLE " + adapter.getQuotingStrategy().quotedFullyQualifiedName(getEntity()) - + " DROP PRIMARY KEY"); - } - - }; - } - -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresAdapter.java index d9aee83..dc94bae 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresAdapter.java @@ -37,7 +37,6 @@ import org.apache.cayenne.dba.TypesMapping; import org.apache.cayenne.di.Inject; import org.apache.cayenne.map.DbAttribute; 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; @@ -121,11 +120,6 @@ public class IngresAdapter extends JdbcAdapter { } @Override - public MergerFactory mergerFactory() { - return new IngresMergerFactory(); - } - - @Override public void createTableAppendColumn(StringBuffer buf, DbAttribute at) { String[] types = externalTypesForJdbcType(at.getType()); http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresMergerFactory.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresMergerFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresMergerFactory.java deleted file mode 100644 index f8da652..0000000 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresMergerFactory.java +++ /dev/null @@ -1,226 +0,0 @@ -/***************************************************************** - * 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.ingres; - -import java.util.Collections; -import java.util.List; - -import org.apache.cayenne.dba.DbAdapter; -import org.apache.cayenne.dba.QuotingStrategy; -import org.apache.cayenne.dba.TypesMapping; -import org.apache.cayenne.map.DbAttribute; -import org.apache.cayenne.map.DbEntity; -import org.apache.cayenne.map.DbJoin; -import org.apache.cayenne.map.DbRelationship; -import org.apache.cayenne.merge.AddRelationshipToDb; -import org.apache.cayenne.merge.DropColumnToDb; -import org.apache.cayenne.merge.DropRelationshipToDb; -import org.apache.cayenne.merge.MergerFactory; -import org.apache.cayenne.merge.MergerToken; -import org.apache.cayenne.merge.SetAllowNullToDb; -import org.apache.cayenne.merge.SetColumnTypeToDb; -import org.apache.cayenne.merge.SetNotNullToDb; - -public class IngresMergerFactory extends MergerFactory { - - @Override - public MergerToken createSetColumnTypeToDb(final DbEntity entity, DbAttribute columnOriginal, - final DbAttribute columnNew) { - - return new SetColumnTypeToDb(entity, columnOriginal, columnNew) { - - @Override - protected void appendPrefix(StringBuffer sqlBuffer, QuotingStrategy context) { - sqlBuffer.append("ALTER TABLE "); - sqlBuffer.append(context.quotedFullyQualifiedName(entity)); - sqlBuffer.append(" ALTER COLUMN "); - sqlBuffer.append(context.quotedName(columnNew)); - sqlBuffer.append(" "); - } - }; - } - - @Override - public MergerToken createDropColumnToDb(DbEntity entity, DbAttribute column) { - return new DropColumnToDb(entity, column) { - - @Override - public List<String> createSql(DbAdapter adapter) { - StringBuilder buf = new StringBuilder(); - QuotingStrategy context = adapter.getQuotingStrategy(); - buf.append("ALTER TABLE "); - buf.append(context.quotedFullyQualifiedName(getEntity())); - buf.append(" DROP COLUMN "); - buf.append(context.quotedName(getColumn())); - buf.append(" RESTRICT "); - - return Collections.singletonList(buf.toString()); - } - - }; - } - - @Override - public MergerToken createAddRelationshipToDb(DbEntity entity, final DbRelationship rel) { - return new AddRelationshipToDb(entity, rel) { - @Override - public List<String> createSql(DbAdapter adapter) { - if (!rel.isToMany() && rel.isToPK() && !rel.isToDependentPK()) { - - DbEntity source = (DbEntity) rel.getSourceEntity(); - QuotingStrategy context = adapter.getQuotingStrategy(); - StringBuilder buf = new StringBuilder(); - StringBuilder refBuf = new StringBuilder(); - - buf.append("ALTER TABLE "); - buf.append(context.quotedFullyQualifiedName(source)); - - // requires the ADD CONSTRAINT statement - buf.append(" ADD CONSTRAINT "); - String name = "U_" + rel.getSourceEntity().getName() + "_" - + (long) (System.currentTimeMillis() / (Math.random() * 100000)); - - buf.append(context.quotedIdentifier(rel.getSourceEntity(), name)); - buf.append(" FOREIGN KEY ("); - - boolean first = true; - for (DbJoin join : rel.getJoins()) { - if (!first) { - buf.append(", "); - refBuf.append(", "); - } else - first = false; - - buf.append(context.quotedSourceName(join)); - refBuf.append(context.quotedTargetName(join)); - } - - buf.append(") REFERENCES "); - buf.append(context.quotedFullyQualifiedName((DbEntity) rel.getTargetEntity())); - buf.append(" ("); - buf.append(refBuf.toString()); - buf.append(')'); - - // also make sure we delete dependent FKs - buf.append(" ON DELETE CASCADE"); - - String fksql = buf.toString(); - - if (fksql != null) { - return Collections.singletonList(fksql); - } - } - - return Collections.emptyList(); - - } - }; - } - - @Override - public MergerToken createSetNotNullToDb(DbEntity entity, DbAttribute column) { - return new SetNotNullToDb(entity, column) { - - @Override - public List<String> createSql(DbAdapter adapter) { - - /* - * TODO: we generate this query as in ingres db documentation, - * but unfortunately ingres don't support it - */ - - StringBuilder sqlBuffer = new StringBuilder(); - - QuotingStrategy context = adapter.getQuotingStrategy(); - - sqlBuffer.append("ALTER TABLE "); - sqlBuffer.append(getEntity().getFullyQualifiedName()); - sqlBuffer.append(" ALTER COLUMN "); - sqlBuffer.append(context.quotedName(getColumn())); - sqlBuffer.append(" "); - sqlBuffer.append(adapter.externalTypesForJdbcType(getColumn().getType())[0]); - - if (adapter.typeSupportsLength(getColumn().getType()) && getColumn().getMaxLength() > 0) { - sqlBuffer.append("("); - sqlBuffer.append(getColumn().getMaxLength()); - sqlBuffer.append(")"); - } - - sqlBuffer.append(" NOT NULL"); - - return Collections.singletonList(sqlBuffer.toString()); - } - - }; - } - - @Override - public MergerToken createSetAllowNullToDb(DbEntity entity, DbAttribute column) { - return new SetAllowNullToDb(entity, column) { - - @Override - public List<String> createSql(DbAdapter adapter) { - StringBuilder sqlBuffer = new StringBuilder(); - QuotingStrategy context = adapter.getQuotingStrategy(); - sqlBuffer.append("ALTER TABLE "); - sqlBuffer.append(context.quotedFullyQualifiedName(getEntity())); - sqlBuffer.append(" ALTER COLUMN "); - sqlBuffer.append(context.quotedName(getColumn())); - sqlBuffer.append(" "); - sqlBuffer.append(adapter.externalTypesForJdbcType(getColumn().getType())[0]); - - if (adapter.typeSupportsLength(getColumn().getType()) && getColumn().getMaxLength() > 0) { - sqlBuffer.append("("); - sqlBuffer.append(getColumn().getMaxLength()); - sqlBuffer.append(")"); - } - - sqlBuffer.append(" WITH NULL"); - - return Collections.singletonList(sqlBuffer.toString()); - } - - }; - } - - @Override - public MergerToken createDropRelationshipToDb(final DbEntity entity, DbRelationship rel) { - - return new DropRelationshipToDb(entity, rel) { - - @Override - public List<String> createSql(DbAdapter adapter) { - String fkName = getFkName(); - - if (fkName == null) { - return Collections.emptyList(); - } - - StringBuilder buf = new StringBuilder(); - buf.append("ALTER TABLE "); - buf.append(adapter.getQuotingStrategy().quotedFullyQualifiedName(getEntity())); - buf.append(" DROP CONSTRAINT "); - buf.append(fkName); - buf.append(" CASCADE "); - - return Collections.singletonList(buf.toString()); - } - }; - } -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java index 961f653..1ecac8a 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java @@ -27,16 +27,23 @@ import org.apache.cayenne.access.translator.ejbql.JdbcEJBQLTranslatorFactory; 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.*; +import org.apache.cayenne.access.types.ByteArrayType; +import org.apache.cayenne.access.types.CharType; +import org.apache.cayenne.access.types.ExtendedType; +import org.apache.cayenne.access.types.ExtendedTypeFactory; +import org.apache.cayenne.access.types.ExtendedTypeMap; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; -import org.apache.cayenne.dba.*; +import org.apache.cayenne.dba.DefaultQuotingStrategy; +import org.apache.cayenne.dba.JdbcAdapter; +import org.apache.cayenne.dba.PkGenerator; +import org.apache.cayenne.dba.QuotingStrategy; +import org.apache.cayenne.dba.TypesMapping; import org.apache.cayenne.di.Inject; 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; @@ -45,7 +52,13 @@ import org.apache.cayenne.resource.ResourceLocator; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Types; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; /** * DbAdapter implementation for <a href="http://www.mysql.com">MySQL RDBMS</a>. @@ -378,11 +391,6 @@ public class MySQLAdapter extends JdbcAdapter { } } - @Override - public MergerFactory mergerFactory() { - return new MySQLMergerFactory(); - } - final class PKComparator implements Comparator<DbAttribute> { public int compare(DbAttribute a1, DbAttribute a2) { http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLMergerFactory.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLMergerFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLMergerFactory.java deleted file mode 100644 index 43f4b55..0000000 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLMergerFactory.java +++ /dev/null @@ -1,157 +0,0 @@ -/***************************************************************** - * 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.mysql; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.apache.cayenne.dba.DbAdapter; -import org.apache.cayenne.dba.QuotingStrategy; -import org.apache.cayenne.map.DbAttribute; -import org.apache.cayenne.map.DbEntity; -import org.apache.cayenne.map.DbRelationship; -import org.apache.cayenne.merge.DropRelationshipToDb; -import org.apache.cayenne.merge.MergerFactory; -import org.apache.cayenne.merge.MergerToken; -import org.apache.cayenne.merge.SetAllowNullToDb; -import org.apache.cayenne.merge.SetColumnTypeToDb; -import org.apache.cayenne.merge.SetNotNullToDb; -import org.apache.cayenne.merge.SetPrimaryKeyToDb; - -public class MySQLMergerFactory extends MergerFactory { - - @Override - public MergerToken createSetNotNullToDb( - final DbEntity entity, - final DbAttribute column) { - return new SetNotNullToDb(entity, column) { - - @Override - public List<String> createSql(DbAdapter adapter) { - StringBuffer sqlBuffer = new StringBuffer(); - - QuotingStrategy context = adapter.getQuotingStrategy(); - - sqlBuffer.append("ALTER TABLE "); - sqlBuffer.append(context.quotedFullyQualifiedName(getEntity())); - sqlBuffer.append(" CHANGE "); - sqlBuffer.append(context.quotedName(getColumn())); - sqlBuffer.append(" "); - adapter.createTableAppendColumn(sqlBuffer, column); - - return Collections.singletonList(sqlBuffer.toString()); - } - - }; - } - - @Override - public MergerToken createSetAllowNullToDb( - final DbEntity entity, - final DbAttribute column) { - return new SetAllowNullToDb(entity, column) { - - @Override - public List<String> createSql(DbAdapter adapter) { - StringBuffer sqlBuffer = new StringBuffer(); - - QuotingStrategy context = adapter.getQuotingStrategy(); - - sqlBuffer.append("ALTER TABLE "); - sqlBuffer.append(context.quotedFullyQualifiedName(getEntity())); - sqlBuffer.append(" CHANGE "); - sqlBuffer.append(context.quotedName(getColumn())); - sqlBuffer.append(" "); - adapter.createTableAppendColumn(sqlBuffer, column); - - return Collections.singletonList(sqlBuffer.toString()); - } - - }; - } - - @Override - public MergerToken createSetColumnTypeToDb( - final DbEntity entity, - DbAttribute columnOriginal, - final DbAttribute columnNew) { - - return new SetColumnTypeToDb(entity, columnOriginal, columnNew) { - - @Override - protected void appendPrefix(StringBuffer sqlBuffer, QuotingStrategy context) { - // http://dev.mysql.com/tech-resources/articles/mysql-cluster-50.html - sqlBuffer.append("ALTER TABLE "); - sqlBuffer.append(context.quotedFullyQualifiedName(entity)); - sqlBuffer.append(" MODIFY "); - sqlBuffer.append(context.quotedName(columnNew)); - sqlBuffer.append(" "); - } - - }; - } - - @Override - public MergerToken createDropRelationshipToDb( - final DbEntity entity, - DbRelationship rel) { - - return new DropRelationshipToDb(entity, rel) { - - @Override - public List<String> createSql(DbAdapter adapter) { - String fkName = getFkName(); - - if (fkName == null) { - return Collections.emptyList(); - } - QuotingStrategy context = adapter.getQuotingStrategy(); - - // http://dev.mysql.com/tech-resources/articles/mysql-cluster-50.html - return Collections.singletonList("ALTER TABLE " + context.quotedFullyQualifiedName(entity) + " DROP FOREIGN KEY " + fkName); - } - }; - } - - @Override - public MergerToken createSetPrimaryKeyToDb( - DbEntity entity, - Collection<DbAttribute> primaryKeyOriginal, - Collection<DbAttribute> primaryKeyNew, - String detectedPrimaryKeyName) { - return new SetPrimaryKeyToDb( - entity, - primaryKeyOriginal, - primaryKeyNew, - detectedPrimaryKeyName) { - - @Override - protected void appendDropOriginalPrimaryKeySQL( - DbAdapter adapter, - List<String> sqls) { - sqls.add("ALTER TABLE " - + adapter.getQuotingStrategy() - .quotedFullyQualifiedName(getEntity()) - + " DROP PRIMARY KEY"); - } - - }; - } -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/2f7b1d53/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseAdapter.java index c4a50db..a426332 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseAdapter.java @@ -39,7 +39,6 @@ import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.map.DbJoin; import org.apache.cayenne.map.DbRelationship; import org.apache.cayenne.map.EntityResolver; -import org.apache.cayenne.merge.MergerFactory; import org.apache.cayenne.query.SelectQuery; import org.apache.cayenne.resource.ResourceLocator; @@ -53,251 +52,245 @@ import java.util.List; /** * DbAdapter implementation for <a href="http://www.openbase.com">OpenBase</a>. * Sample connection settings to use with OpenBase are shown below: - * + * <p> * <pre> * openbase.jdbc.username = test * openbase.jdbc.password = secret * openbase.jdbc.url = jdbc:openbase://serverhostname/cayenne * openbase.jdbc.driver = com.openbase.jdbc.ObDriver * </pre> - * + * * @since 1.1 */ public class OpenBaseAdapter extends JdbcAdapter { - public OpenBaseAdapter(@Inject RuntimeProperties runtimeProperties, - @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List<ExtendedType> defaultExtendedTypes, - @Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes, - @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { - super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator); - - // init defaults - this.setSupportsUniqueConstraints(false); - } - - /** - * @since 4.0 - */ - @Override - public SelectTranslator getSelectTranslator(SelectQuery<?> query, EntityResolver entityResolver) { - return new OpenBaseSelectTranslator(query, this, entityResolver); - } - - @Override - protected void configureExtendedTypes(ExtendedTypeMap map) { - super.configureExtendedTypes(map); - - // Byte handling doesn't work on read... - // need special converter - map.registerType(new OpenBaseByteType()); - - map.registerType(new OpenBaseCharType()); - } - - @Override - public DbAttribute buildAttribute(String name, String typeName, int type, int size, int scale, boolean allowNulls) { - - // OpenBase makes no distinction between CHAR and VARCHAR - // so lets use VARCHAR, since it seems more generic - if (type == Types.CHAR) { - type = Types.VARCHAR; - } - - return super.buildAttribute(name, typeName, type, size, scale, allowNulls); - } - - /** - * Returns word "go". - */ - @Override - public String getBatchTerminator() { - return "go"; - } - - /** - * Returns null, since views are not yet supported in openbase. - */ - @Override - public String tableTypeForView() { - // TODO: according to OpenBase docs views *ARE* supported. - return null; - } - - /** - * Returns OpenBase-specific translator for queries. - */ - @Override - public QualifierTranslator getQualifierTranslator(QueryAssembler queryAssembler) { - return new OpenBaseQualifierTranslator(queryAssembler); - } - - /** - * Creates and returns a primary key generator. Overrides superclass - * implementation to return an instance of OpenBasePkGenerator that uses - * built-in multi-server primary key generation. - */ - @Override - protected PkGenerator createPkGenerator() { - return new OpenBasePkGenerator(this); - } - - /** - * Returns a SQL string that can be used to create database table - * corresponding to <code>ent</code> parameter. - */ - @Override - public String createTable(DbEntity ent) { - - StringBuilder buf = new StringBuilder(); - - buf.append("CREATE TABLE "); - buf.append(quotingStrategy.quotedFullyQualifiedName(ent)); - buf.append(" ("); - - // columns - Iterator<DbAttribute> it = ent.getAttributes().iterator(); - boolean first = true; - while (it.hasNext()) { - if (first) { - first = false; - } else { - buf.append(", "); - } - - DbAttribute at = it.next(); - - // attribute may not be fully valid, do a simple check - if (at.getType() == TypesMapping.NOT_DEFINED) { - throw new CayenneRuntimeException("Undefined type for attribute '" + ent.getFullyQualifiedName() + "." - + at.getName() + "'."); - } - - String[] types = externalTypesForJdbcType(at.getType()); - if (types == null || types.length == 0) { - throw new CayenneRuntimeException("Undefined type for attribute '" + ent.getFullyQualifiedName() + "." - + at.getName() + "': " + at.getType()); - } - - String type = types[0]; - buf.append(quotingStrategy.quotedName(at)).append(' ').append(type); - - // append size and precision (if applicable) - if (typeSupportsLength(at.getType())) { - int len = at.getMaxLength(); - int scale = TypesMapping.isDecimal(at.getType()) ? at.getScale() : -1; - - // sanity check - if (scale > len) { - scale = -1; - } - - if (len > 0) { - buf.append('(').append(len); - - if (scale >= 0) { - buf.append(", ").append(scale); - } - - buf.append(')'); - } - } - - if (at.isMandatory()) { - buf.append(" NOT NULL"); - } else { - buf.append(" NULL"); - } - } - - buf.append(')'); - return buf.toString(); - } - - /** - * Returns a SQL string that can be used to create a foreign key constraint - * for the relationship. - */ - @Override - public String createFkConstraint(DbRelationship rel) { - StringBuilder buf = new StringBuilder(); - - // OpendBase Specifics is that we need to create a constraint going - // from destination to source for this to work... - - DbEntity sourceEntity = (DbEntity) rel.getSourceEntity(); - DbEntity targetEntity = (DbEntity) rel.getTargetEntity(); - String toMany = (!rel.isToMany()) ? "'1'" : "'0'"; - - // TODO: doesn't seem like OpenBase supports compound joins... - // need to doublecheck that - - int joinsLen = rel.getJoins().size(); - if (joinsLen == 0) { - throw new CayenneRuntimeException("Relationship has no joins: " + rel.getName()); - } else if (joinsLen > 1) { - // ignore extra joins - } - - DbJoin join = rel.getJoins().get(0); - - buf.append("INSERT INTO _SYS_RELATIONSHIP (").append("dest_table, dest_column, source_table, source_column, ") - .append("block_delete, cascade_delete, one_to_many, operator, relationshipName").append(") VALUES ('") - .append(sourceEntity.getFullyQualifiedName()).append("', '").append(join.getSourceName()) - .append("', '").append(targetEntity.getFullyQualifiedName()).append("', '") - .append(join.getTargetName()).append("', 0, 0, ").append(toMany).append(", '=', '") - .append(rel.getName()).append("')"); - - return buf.toString(); - } - - // OpenBase JDBC driver has trouble reading "integer" as byte - // this converter addresses such problem - static class OpenBaseByteType extends ByteType { - - OpenBaseByteType() { - super(true); - } - - @Override - public Object materializeObject(ResultSet rs, int index, int type) throws Exception { - - // read value as int, and then narrow it down - int val = rs.getInt(index); - return (rs.wasNull()) ? null : Byte.valueOf((byte) val); - } - - @Override - public Object materializeObject(CallableStatement rs, int index, int type) throws Exception { - - // read value as int, and then narrow it down - int val = rs.getInt(index); - return (rs.wasNull()) ? null : Byte.valueOf((byte) val); - } - } - - static class OpenBaseCharType extends CharType { - - OpenBaseCharType() { - super(false, true); - } - - @Override - public void setJdbcObject(PreparedStatement st, Object val, int pos, int type, int precision) throws Exception { - - // These to types map to "text"; and when setting "text" as object - // OB assumes that the object is the actual CLOB... weird - if (type == Types.CLOB || type == Types.LONGVARCHAR) { - st.setString(pos, (String) val); - } else { - super.setJdbcObject(st, val, pos, type, precision); - } - } - } - - @Override - public MergerFactory mergerFactory() { - return new OpenBaseMergerFactory(); - } - + public OpenBaseAdapter(@Inject RuntimeProperties runtimeProperties, + @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List<ExtendedType> defaultExtendedTypes, + @Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes, + @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> extendedTypeFactories, + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { + super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator); + + // init defaults + this.setSupportsUniqueConstraints(false); + } + + /** + * @since 4.0 + */ + @Override + public SelectTranslator getSelectTranslator(SelectQuery<?> query, EntityResolver entityResolver) { + return new OpenBaseSelectTranslator(query, this, entityResolver); + } + + @Override + protected void configureExtendedTypes(ExtendedTypeMap map) { + super.configureExtendedTypes(map); + + // Byte handling doesn't work on read... + // need special converter + map.registerType(new OpenBaseByteType()); + + map.registerType(new OpenBaseCharType()); + } + + @Override + public DbAttribute buildAttribute(String name, String typeName, int type, int size, int scale, boolean allowNulls) { + + // OpenBase makes no distinction between CHAR and VARCHAR + // so lets use VARCHAR, since it seems more generic + if (type == Types.CHAR) { + type = Types.VARCHAR; + } + + return super.buildAttribute(name, typeName, type, size, scale, allowNulls); + } + + /** + * Returns word "go". + */ + @Override + public String getBatchTerminator() { + return "go"; + } + + /** + * Returns null, since views are not yet supported in openbase. + */ + @Override + public String tableTypeForView() { + // TODO: according to OpenBase docs views *ARE* supported. + return null; + } + + /** + * Returns OpenBase-specific translator for queries. + */ + @Override + public QualifierTranslator getQualifierTranslator(QueryAssembler queryAssembler) { + return new OpenBaseQualifierTranslator(queryAssembler); + } + + /** + * Creates and returns a primary key generator. Overrides superclass + * implementation to return an instance of OpenBasePkGenerator that uses + * built-in multi-server primary key generation. + */ + @Override + protected PkGenerator createPkGenerator() { + return new OpenBasePkGenerator(this); + } + + /** + * Returns a SQL string that can be used to create database table + * corresponding to <code>ent</code> parameter. + */ + @Override + public String createTable(DbEntity ent) { + + StringBuilder buf = new StringBuilder(); + + buf.append("CREATE TABLE "); + buf.append(quotingStrategy.quotedFullyQualifiedName(ent)); + buf.append(" ("); + + // columns + Iterator<DbAttribute> it = ent.getAttributes().iterator(); + boolean first = true; + while (it.hasNext()) { + if (first) { + first = false; + } else { + buf.append(", "); + } + + DbAttribute at = it.next(); + + // attribute may not be fully valid, do a simple check + if (at.getType() == TypesMapping.NOT_DEFINED) { + throw new CayenneRuntimeException("Undefined type for attribute '" + ent.getFullyQualifiedName() + "." + + at.getName() + "'."); + } + + String[] types = externalTypesForJdbcType(at.getType()); + if (types == null || types.length == 0) { + throw new CayenneRuntimeException("Undefined type for attribute '" + ent.getFullyQualifiedName() + "." + + at.getName() + "': " + at.getType()); + } + + String type = types[0]; + buf.append(quotingStrategy.quotedName(at)).append(' ').append(type); + + // append size and precision (if applicable) + if (typeSupportsLength(at.getType())) { + int len = at.getMaxLength(); + int scale = TypesMapping.isDecimal(at.getType()) ? at.getScale() : -1; + + // sanity check + if (scale > len) { + scale = -1; + } + + if (len > 0) { + buf.append('(').append(len); + + if (scale >= 0) { + buf.append(", ").append(scale); + } + + buf.append(')'); + } + } + + if (at.isMandatory()) { + buf.append(" NOT NULL"); + } else { + buf.append(" NULL"); + } + } + + buf.append(')'); + return buf.toString(); + } + + /** + * Returns a SQL string that can be used to create a foreign key constraint + * for the relationship. + */ + @Override + public String createFkConstraint(DbRelationship rel) { + StringBuilder buf = new StringBuilder(); + + // OpendBase Specifics is that we need to create a constraint going + // from destination to source for this to work... + + DbEntity sourceEntity = (DbEntity) rel.getSourceEntity(); + DbEntity targetEntity = (DbEntity) rel.getTargetEntity(); + String toMany = (!rel.isToMany()) ? "'1'" : "'0'"; + + // TODO: doesn't seem like OpenBase supports compound joins... + // need to doublecheck that + + int joinsLen = rel.getJoins().size(); + if (joinsLen == 0) { + throw new CayenneRuntimeException("Relationship has no joins: " + rel.getName()); + } else if (joinsLen > 1) { + // ignore extra joins + } + + DbJoin join = rel.getJoins().get(0); + + buf.append("INSERT INTO _SYS_RELATIONSHIP (").append("dest_table, dest_column, source_table, source_column, ") + .append("block_delete, cascade_delete, one_to_many, operator, relationshipName").append(") VALUES ('") + .append(sourceEntity.getFullyQualifiedName()).append("', '").append(join.getSourceName()) + .append("', '").append(targetEntity.getFullyQualifiedName()).append("', '") + .append(join.getTargetName()).append("', 0, 0, ").append(toMany).append(", '=', '") + .append(rel.getName()).append("')"); + + return buf.toString(); + } + + // OpenBase JDBC driver has trouble reading "integer" as byte + // this converter addresses such problem + static class OpenBaseByteType extends ByteType { + + OpenBaseByteType() { + super(true); + } + + @Override + public Object materializeObject(ResultSet rs, int index, int type) throws Exception { + + // read value as int, and then narrow it down + int val = rs.getInt(index); + return (rs.wasNull()) ? null : Byte.valueOf((byte) val); + } + + @Override + public Object materializeObject(CallableStatement rs, int index, int type) throws Exception { + + // read value as int, and then narrow it down + int val = rs.getInt(index); + return (rs.wasNull()) ? null : Byte.valueOf((byte) val); + } + } + + static class OpenBaseCharType extends CharType { + + OpenBaseCharType() { + super(false, true); + } + + @Override + public void setJdbcObject(PreparedStatement st, Object val, int pos, int type, int precision) throws Exception { + + // These to types map to "text"; and when setting "text" as object + // OB assumes that the object is the actual CLOB... weird + if (type == Types.CLOB || type == Types.LONGVARCHAR) { + st.setString(pos, (String) val); + } else { + super.setJdbcObject(st, val, pos, type, precision); + } + } + } }