diff options
Diffstat (limited to 'src/main/java/com/amazon')
3 files changed, 91 insertions, 0 deletions
diff --git a/src/main/java/com/amazon/carbonado/gen/CodeBuilderUtil.java b/src/main/java/com/amazon/carbonado/gen/CodeBuilderUtil.java index 82be9f2..f25d6f1 100644 --- a/src/main/java/com/amazon/carbonado/gen/CodeBuilderUtil.java +++ b/src/main/java/com/amazon/carbonado/gen/CodeBuilderUtil.java @@ -579,6 +579,42 @@ public class CodeBuilderUtil {      }
      /**
 +     * Generates code to push a blank value to the stack. For objects, it is
 +     * null, and for primitive types it is zero or false.
 +     */
 +    public static void blankValue(CodeBuilder b, TypeDesc type) {
 +        switch (type.getTypeCode()) {
 +        default:
 +            b.loadNull();
 +            break;
 +
 +        case TypeDesc.BYTE_CODE:
 +        case TypeDesc.CHAR_CODE:
 +        case TypeDesc.SHORT_CODE:
 +        case TypeDesc.INT_CODE:
 +            b.loadConstant(0);
 +            break;
 +
 +        case TypeDesc.BOOLEAN_CODE:
 +            b.loadConstant(false);
 +            break;
 +
 +        case TypeDesc.LONG_CODE:
 +            b.loadConstant(0L);
 +            break;
 +
 +        case TypeDesc.FLOAT_CODE:
 +            b.loadConstant(0.0f);
 +            break;
 +
 +        case TypeDesc.DOUBLE_CODE:
 +
 +            b.loadConstant(0.0);
 +            break;
 +        }
 +    }
 +
 +    /**
       * Determines which overloaded "with" method on Query should be bound to.
       */
      public static TypeDesc bindQueryParam(Class clazz) {
 diff --git a/src/main/java/com/amazon/carbonado/gen/MasterStorableGenerator.java b/src/main/java/com/amazon/carbonado/gen/MasterStorableGenerator.java index 82d8c7a..21af6cf 100644 --- a/src/main/java/com/amazon/carbonado/gen/MasterStorableGenerator.java +++ b/src/main/java/com/amazon/carbonado/gen/MasterStorableGenerator.java @@ -403,12 +403,16 @@ public final class MasterStorableGenerator<S extends Storable> {              Label tryStart = addEnterTransaction(b, INSERT_OP, txnVar);
 +            LocalVariable wasVersionInitVar = null;
              if (mFeatures.contains(MasterFeature.VERSIONING)) {
                  if (!mInfo.getVersionProperty().isDerived()) {
                      // Only set if uninitialized.
                      b.loadThis();
                      b.invokeVirtual(StorableGenerator.IS_VERSION_INITIALIZED_METHOD_NAME,
                                      TypeDesc.BOOLEAN, null);
 +                    wasVersionInitVar = b.createLocalVariable(null, TypeDesc.BOOLEAN);
 +                    b.storeLocal(wasVersionInitVar);
 +                    b.loadLocal(wasVersionInitVar);
                      Label isInitialized = b.createLabel();
                      b.ifZeroComparisonBranch(isInitialized, "!=");
                      addAdjustVersionProperty(b, null, 1);
 @@ -535,6 +539,23 @@ public final class MasterStorableGenerator<S extends Storable> {              b.loadThis();
              b.invokeVirtual(DO_TRY_INSERT_MASTER_METHOD_NAME, TypeDesc.BOOLEAN, null);
 +
 +            if (wasVersionInitVar != null) {
 +                // Decide if version property needs to rollback to uninitialized.
 +
 +                b.dup();
 +                Label noRollback = b.createLabel();
 +                // Don't rollback if insert succeeded.
 +                b.ifZeroComparisonBranch(noRollback, "!=");
 +
 +                b.loadLocal(wasVersionInitVar);
 +                // Rollback only if version was automatically set.
 +                b.ifZeroComparisonBranch(noRollback, "!=");
 +                unsetVersionProperty(b);
 +
 +                noRollback.setLocation();
 +            }
 +
              addNormalizationRollback(b, doTryStart, unnormalized);
              if (tryStart == null) {
 @@ -1080,6 +1101,32 @@ public final class MasterStorableGenerator<S extends Storable> {          b.invoke(versionProperty.getWriteMethod());
      }
 +    /**
 +     * Sets the version property to its initial uninitialized state.
 +     */
 +    private void unsetVersionProperty(CodeBuilder b) throws SupportException {
 +        StorableProperty<?> property = mInfo.getVersionProperty();
 +
 +        // Set the property state to uninitialized.
 +        {
 +            String stateFieldName =
 +                StorableGenerator.PROPERTY_STATE_FIELD_NAME + (property.getNumber() >> 4);
 +            b.loadThis();
 +            b.loadThis();
 +            b.loadField(stateFieldName, TypeDesc.INT);
 +            int shift = (property.getNumber() & 0xf) * 2;
 +            b.loadConstant(~(StorableGenerator.PROPERTY_STATE_MASK << shift));
 +            b.math(Opcode.IAND);
 +            b.storeField(stateFieldName, TypeDesc.INT);
 +        }
 +
 +        // Zero the property value.
 +        TypeDesc type = TypeDesc.forClass(property.getType());
 +        b.loadThis();
 +        CodeBuilderUtil.blankValue(b, type);
 +        b.storeField(property.getName(), type);
 +    }
 +
      private List<PropertyCopy> addNormalization(CodeBuilder b, boolean forUpdate) {
          List<PropertyCopy> unnormalized = null;
 diff --git a/src/main/java/com/amazon/carbonado/layout/LayoutProperty.java b/src/main/java/com/amazon/carbonado/layout/LayoutProperty.java index a0ce48f..bf35073 100644 --- a/src/main/java/com/amazon/carbonado/layout/LayoutProperty.java +++ b/src/main/java/com/amazon/carbonado/layout/LayoutProperty.java @@ -20,6 +20,7 @@ package com.amazon.carbonado.layout;  import org.cojen.classfile.TypeDesc;
 +import com.amazon.carbonado.FetchException;
  import com.amazon.carbonado.PersistException;
  import com.amazon.carbonado.SupportException;
 @@ -187,6 +188,13 @@ public class LayoutProperty {      void store() throws PersistException {
          if (!mStoredLayoutProperty.tryInsert()) {
 +            StoredLayoutProperty existing = mStoredLayoutProperty.copy();
 +            try {
 +                existing.load();
 +                existing.copyVersionProperty(mStoredLayoutProperty);
 +            } catch (FetchException e) {
 +                throw e.toPersistException();
 +            }
              mStoredLayoutProperty.update();
          }
      }
  | 
