diff options
4 files changed, 119 insertions, 59 deletions
| 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<S extends Storable> {              }
              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<S extends Storable> {              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<S extends Storable> {          }
      }
 +    private void convertFromResultSet(CodeBuilder b,
 +                                      JDBCStorableProperty<S> 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<JDBCStorableProperty<S>, 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<S> 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,11 +94,30 @@ public interface JDBCStorableProperty<S extends Storable> 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<S extends Storable> extends StandardQueryFactory<S>                  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<S extends Storable> extends StandardQueryFactory<S>                          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++;
                  }
 | 
