From c5e711c5a8828db5812d7b8915a85eb84772b280 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Tue, 18 Sep 2007 00:10:43 +0000 Subject: Fix support for char data type when used with an adapter. --- .../carbonado/repo/jdbc/JDBCStorableGenerator.java | 85 +++++++++++----------- .../repo/jdbc/JDBCStorableIntrospector.java | 55 ++++++++++++-- .../carbonado/repo/jdbc/JDBCStorableProperty.java | 21 +++++- .../amazon/carbonado/repo/jdbc/JDBCStorage.java | 17 ++--- 4 files changed, 119 insertions(+), 59 deletions(-) (limited to 'src/main') diff --git a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableGenerator.java b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableGenerator.java index ca8188b..a41eebe 100644 --- a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableGenerator.java +++ b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableGenerator.java @@ -1511,13 +1511,7 @@ class JDBCStorableGenerator { } fromType = propertyType; } else { - Class toClass = psClass; - if (java.sql.Blob.class.isAssignableFrom(toClass)) { - toClass = com.amazon.carbonado.lob.Blob.class; - } else if (java.sql.Clob.class.isAssignableFrom(toClass)) { - toClass = com.amazon.carbonado.lob.Clob.class; - } - Method adaptMethod = adapter.findAdaptMethod(property.getType(), toClass); + Method adaptMethod = property.getAppliedAdapterFromMethod(); TypeDesc adaptType = TypeDesc.forClass(adaptMethod.getReturnType()); if (mode != INITIAL_VERSION) { // Invoke special inherited protected method that gets the field @@ -1945,48 +1939,14 @@ class JDBCStorableGenerator { StorablePropertyAdapter adapter = property.getAppliedAdapter(); if (adapter == null) { TypeDesc propertyType = TypeDesc.forClass(property.getType()); - - if (resultSetType == TypeDesc.STRING && - propertyType.toPrimitiveType() == TypeDesc.CHAR) - { - // Special case for converting String to character. - - Label charWasNull = null; - if (property.isNullable()) { - charWasNull = b.createLabel(); - LocalVariable temp = b.createLocalVariable(null, resultSetType); - b.storeLocal(temp); - b.loadLocal(temp); - b.ifNullBranch(charWasNull, true); - b.loadLocal(temp); - } - - b.loadConstant(0); - b.invokeVirtual(String.class.getName(), "charAt", - TypeDesc.CHAR, new TypeDesc[] {TypeDesc.INT}); - b.convert(TypeDesc.CHAR, propertyType); - - if (charWasNull != null) { - Label skipNull = b.createLabel(); - b.branch(skipNull); - - charWasNull.setLocation(); - b.loadNull(); - - skipNull.setLocation(); - } - } else { - b.convert(resultSetType, propertyType); - } - + convertFromResultSet(b, property, resultSetType, propertyType); wasNull.setLocation(); // Set protected field directly, since no adapter. b.storeField(superType, property.getName(), propertyType); } else { - Method adaptMethod = adapter.findAdaptMethod - (resultSetType.toClass(), property.getType()); + Method adaptMethod = property.getAppliedAdapterToMethod(); TypeDesc adaptType = TypeDesc.forClass(adaptMethod.getParameterTypes()[0]); - b.convert(resultSetType, adaptType); + convertFromResultSet(b, property, resultSetType, adaptType); wasNull.setLocation(); // Invoke special inherited protected method that invokes the // adapter and sets the field. Method was generated by StorableGenerator. @@ -1997,6 +1957,43 @@ class JDBCStorableGenerator { } } + private void convertFromResultSet(CodeBuilder b, + JDBCStorableProperty property, + TypeDesc resultSetType, + TypeDesc toType) + { + if (resultSetType == TypeDesc.STRING && toType.toPrimitiveType() == TypeDesc.CHAR) { + // Special case for converting String to character. + + Label charWasNull = null; + if (property.isNullable()) { + charWasNull = b.createLabel(); + LocalVariable temp = b.createLocalVariable(null, resultSetType); + b.storeLocal(temp); + b.loadLocal(temp); + b.ifNullBranch(charWasNull, true); + b.loadLocal(temp); + } + + b.loadConstant(0); + b.invokeVirtual(String.class.getName(), "charAt", + TypeDesc.CHAR, new TypeDesc[] {TypeDesc.INT}); + b.convert(TypeDesc.CHAR, toType); + + if (charWasNull != null) { + Label skipNull = b.createLabel(); + b.branch(skipNull); + + charWasNull.setLocation(); + b.loadNull(); + + skipNull.setLocation(); + } + } else { + b.convert(resultSetType, toType); + } + } + private Map, Class> generateLobLoaders() throws SupportException { diff --git a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableIntrospector.java b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableIntrospector.java index 27c0b13..dacb02f 100644 --- a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableIntrospector.java +++ b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableIntrospector.java @@ -362,7 +362,9 @@ public class JDBCStorableIntrospector extends StorableIntrospector { autoIncrement, accessInfo.mResultSetGet, accessInfo.mPreparedStatementSet, - accessInfo.getAdapter()); + accessInfo.getAdapter(), + accessInfo.getAdapterFromMethod(), + accessInfo.getAdapterToMethod()); break findName; } @@ -531,12 +533,13 @@ public class JDBCStorableIntrospector extends StorableIntrospector { for (Method toMethod : toMethods) { Class fromType = toMethod.getParameterTypes()[0]; // Verify that reverse adapt method exists as well... - if (adapter.findAdaptMethod(property.getType(), fromType) != null) { + Method fromMethod = adapter.findAdaptMethod(property.getType(), fromType); + if (fromMethod != null) { // ...and try to get access info for fromType. info = getAccessInfo (fromType, dataType, dataTypeName, columnSize, decimalDigits); if (info != null) { - info.setAdapter(adapter); + info.setAdapter(adapter, fromMethod, toMethod); return info; } } @@ -914,6 +917,8 @@ public class JDBCStorableIntrospector extends StorableIntrospector { // Is null if no adapter needed. private StorablePropertyAdapter mAdapter; + private Method mAdapterFromMethod; + private Method mAdapterToMethod; AccessInfo(String suffix, Class actualClass) { try { @@ -929,8 +934,18 @@ public class JDBCStorableIntrospector extends StorableIntrospector { return mAdapter; } - void setAdapter(StorablePropertyAdapter adapter) { + void setAdapter(StorablePropertyAdapter adapter, Method fromMethod, Method toMethod) { mAdapter = adapter; + mAdapterFromMethod = fromMethod; + mAdapterToMethod = toMethod; + } + + Method getAdapterFromMethod() { + return mAdapterFromMethod; + } + + Method getAdapterToMethod() { + return mAdapterToMethod; } } @@ -1122,6 +1137,8 @@ public class JDBCStorableIntrospector extends StorableIntrospector { private final Method mResultSetGet; private final Method mPreparedStatementSet; private final StorablePropertyAdapter mAdapter; + private final Method mAdapterFromMethod; + private final Method mAdapterToMethod; private final Integer mColumnSize; private final Integer mDecimalDigits; private final Integer mCharOctetLength; @@ -1139,7 +1156,9 @@ public class JDBCStorableIntrospector extends StorableIntrospector { boolean autoIncrement, Method resultSetGet, Method preparedStatementSet, - StorablePropertyAdapter adapter) + StorablePropertyAdapter adapter, + Method adapterFromMethod, + Method adapterToMethod) { mMainProperty = mainProperty; mColumnName = columnInfo.columnName; @@ -1148,11 +1167,27 @@ public class JDBCStorableIntrospector extends StorableIntrospector { mResultSetGet = resultSetGet; mPreparedStatementSet = preparedStatementSet; mAdapter = adapter; + mAdapterFromMethod = adapterFromMethod; + mAdapterToMethod = adapterToMethod; mColumnSize = columnInfo.columnSize; mDecimalDigits = columnInfo.decimalDigits; mCharOctetLength = columnInfo.charOctetLength; mOrdinalPosition = columnInfo.ordinalPosition; mAutoIncrement = autoIncrement; + + if (adapterToMethod != null) { + if (!getType().isAssignableFrom(adapterToMethod.getReturnType())) { + throw new IllegalArgumentException + ("Illegal adapter \"to\" method: " + adapterToMethod); + } + } + + if (adapterFromMethod != null) { + if (!adapterFromMethod.getParameterTypes()[0].isAssignableFrom(getType())) { + throw new IllegalArgumentException + ("Illegal adapter \"from\" method: " + adapterFromMethod); + } + } } JProperty(StorableProperty mainProperty) { @@ -1163,6 +1198,8 @@ public class JDBCStorableIntrospector extends StorableIntrospector { mResultSetGet = null; mPreparedStatementSet = null; mAdapter = null; + mAdapterFromMethod = null; + mAdapterToMethod = null; mColumnSize = null; mDecimalDigits = null; mCharOctetLength = null; @@ -1327,6 +1364,14 @@ public class JDBCStorableIntrospector extends StorableIntrospector { return mAdapter; } + public Method getAppliedAdapterFromMethod() { + return mAdapterFromMethod; + } + + public Method getAppliedAdapterToMethod() { + return mAdapterToMethod; + } + public Integer getColumnSize() { return mColumnSize; } diff --git a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableProperty.java b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableProperty.java index c86895a..824e0fc 100644 --- a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableProperty.java +++ b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorableProperty.java @@ -94,10 +94,29 @@ public interface JDBCStorableProperty extends StorableProper * Returns the adapter that needs to be applied to properties returned from * ResultSets and set into PreparedStatements. Is null if not needed. * - * @return null if property is unsupported or if not needed. + * @return null if property is unsupported or if adapter not needed. */ StorablePropertyAdapter getAppliedAdapter(); + /** + * Returns the applied adapter method for converting from this property's + * actual type. The method's single argument type is the same as for this + * property. + * + * @return null if property is unsupported or if adapter not needed. + * @since 1.2 + */ + Method getAppliedAdapterFromMethod(); + + /** + * Returns the applied adapter method for converting to this property's + * actual type. The method's return type is the same as for this property. + * + * @return null if property is unsupported or if adapter not needed. + * @since 1.2 + */ + Method getAppliedAdapterToMethod(); + /** * The column size is either the maximum number of characters or the * numeric precision. diff --git a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorage.java b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorage.java index 19a6bab..a45c90a 100644 --- a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorage.java +++ b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorage.java @@ -484,15 +484,9 @@ class JDBCStorage extends StandardQueryFactory JDBCStorableProperty jProperty = mRepository.getJDBCStorableProperty(property); - Method psSetMethod = jProperty.getPreparedStatementSetMethod(); - mPreparedStatementSetMethods[i] = psSetMethod; - - StorablePropertyAdapter adapter = jProperty.getAppliedAdapter(); - if (adapter != null) { - Class toType = psSetMethod.getParameterTypes()[1]; - mAdapterMethods[i] = adapter.findAdaptMethod(jProperty.getType(), toType); - mAdapterInstances[i] = adapter.getAdapterInstance(); - } + mPreparedStatementSetMethods[i] = jProperty.getPreparedStatementSetMethod(); + mAdapterMethods[i] = jProperty.getAppliedAdapterFromMethod(); + mAdapterInstances[i] = jProperty.getAppliedAdapter(); } } @@ -671,6 +665,11 @@ class JDBCStorage extends StandardQueryFactory value = adapter.invoke(adapterInstances[ordinal], value); } + // Special case for converting character to String. + if (value != null && value instanceof Character) { + value = String.valueOf((Character) value); + } + psSetMethods[ordinal].invoke(ps, psOrdinal, value); psOrdinal++; } -- cgit v1.2.3