Example #1
0
  /**
   * Update the record.
   *
   * @param iForceCreate
   * @param iCallback
   */
  public void saveRecord(
      final ORecordInternal<?> iRecord,
      final String iClusterName,
      final OPERATION_MODE iMode,
      boolean iForceCreate,
      final ORecordCallback<? extends Number> iCallback) {
    try {
      database.executeSaveRecord(
          iRecord,
          iClusterName,
          iRecord.getVersion(),
          iRecord.getRecordType(),
          true,
          iMode,
          iForceCreate,
          iCallback);
    } catch (Exception e) {
      // REMOVE IT FROM THE CACHE TO AVOID DIRTY RECORDS
      final ORecordId rid = (ORecordId) iRecord.getIdentity();
      if (rid.isValid()) database.getLevel1Cache().freeRecord(rid);

      if (e instanceof RuntimeException) throw (RuntimeException) e;
      throw new OException(e);
    }
  }
Example #2
0
  /** Deletes the record. */
  public void deleteRecord(final ORecordInternal<?> iRecord, final OPERATION_MODE iMode) {
    if (!iRecord.getIdentity().isPersistent()) return;

    try {
      database.executeDeleteRecord(iRecord, iRecord.getVersion(), true, true, iMode);
    } catch (Exception e) {
      // REMOVE IT FROM THE CACHE TO AVOID DIRTY RECORDS
      final ORecordId rid = (ORecordId) iRecord.getIdentity();
      if (rid.isValid()) database.getLevel1Cache().freeRecord(rid);

      if (e instanceof RuntimeException) throw (RuntimeException) e;
      throw new OException(e);
    }
  }
  public void executeDeleteRecord(final OIdentifiable iRecord, final int iVersion) {
    checkOpeness();
    final ORecordId rid = (ORecordId) iRecord.getIdentity();

    if (rid == null)
      throw new ODatabaseException(
          "Cannot delete record because it has no identity. Probably was created from scratch or contains projections of fields rather than a full record");

    if (!rid.isValid()) return;

    checkSecurity(
        ODatabaseSecurityResources.CLUSTER,
        ORole.PERMISSION_DELETE,
        getClusterNameById(rid.clusterId));

    setCurrentDatabaseinThreadLocal();

    try {
      callbackHooks(TYPE.BEFORE_DELETE, iRecord);

      underlying.delete(rid, iVersion);

      callbackHooks(TYPE.AFTER_DELETE, iRecord);

      // REMOVE THE RECORD FROM 1 AND 2 LEVEL CACHES
      getLevel1Cache().deleteRecord(rid);

    } catch (OException e) {
      // RE-THROW THE EXCEPTION
      throw e;

    } catch (Throwable t) {
      // WRAP IT AS ODATABASE EXCEPTION
      throw new ODatabaseException(
          "Error on deleting record in cluster #" + iRecord.getIdentity().getClusterId(), t);
    }
  }
  private void addRecord(
      final ORecordInternal<?> iRecord, final byte iStatus, final String iClusterName) {
    checkTransaction();

    if ((status == OTransaction.TXSTATUS.COMMITTING)
        && database.getStorage() instanceof OStorageEmbedded) {
      // I'M COMMITTING OR IT'S AN INDEX: BYPASS LOCAL BUFFER
      switch (iStatus) {
        case OTransactionRecordEntry.CREATED:
        case OTransactionRecordEntry.UPDATED:
          database.executeSaveRecord(
              iRecord, iClusterName, iRecord.getVersion(), iRecord.getRecordType());
          break;
        case OTransactionRecordEntry.DELETED:
          database.executeDeleteRecord(iRecord, iRecord.getVersion());
          break;
      }
    } else {
      final ORecordId rid = (ORecordId) iRecord.getIdentity();

      if (!rid.isValid()) {
        // // TODO: NEED IT FOR REAL?
        // // NEW RECORD: CHECK IF IT'S ALREADY IN
        // for (OTransactionRecordEntry entry : recordEntries.values()) {
        // if (entry.getRecord() == iRecord)
        // return;
        // }

        iRecord.onBeforeIdentityChanged(rid);

        // ASSIGN A UNIQUE SERIAL TEMPORARY ID
        if (rid.clusterId == ORID.CLUSTER_ID_INVALID)
          rid.clusterId =
              iClusterName != null
                  ? database.getClusterIdByName(iClusterName)
                  : database.getDefaultClusterId();
        rid.clusterPosition = newObjectCounter--;

        iRecord.onAfterIdentityChanged(iRecord);
      } else
        // REMOVE FROM THE DB'S CACHE
        database.getLevel1Cache().freeRecord(rid);

      OTransactionRecordEntry txEntry = getRecordEntry(rid);

      if (txEntry == null) {
        // NEW ENTRY: JUST REGISTER IT
        txEntry = new OTransactionRecordEntry(iRecord, iStatus, iClusterName);

        recordEntries.put(rid, txEntry);
      } else {
        // UPDATE PREVIOUS STATUS
        txEntry.setRecord(iRecord);

        switch (txEntry.status) {
          case OTransactionRecordEntry.LOADED:
            switch (iStatus) {
              case OTransactionRecordEntry.UPDATED:
                txEntry.status = OTransactionRecordEntry.UPDATED;
                break;
              case OTransactionRecordEntry.DELETED:
                txEntry.status = OTransactionRecordEntry.DELETED;
                break;
            }
            break;
          case OTransactionRecordEntry.UPDATED:
            switch (iStatus) {
              case OTransactionRecordEntry.DELETED:
                txEntry.status = OTransactionRecordEntry.DELETED;
                break;
            }
            break;
          case OTransactionRecordEntry.DELETED:
            break;
          case OTransactionRecordEntry.CREATED:
            switch (iStatus) {
              case OTransactionRecordEntry.DELETED:
                recordEntries.remove(rid);
                break;
            }
            break;
        }
      }
    }
  }
  protected void addRecord(
      final ORecordInternal<?> iRecord, final byte iStatus, final String iClusterName) {
    checkTransaction();

    switch (iStatus) {
      case ORecordOperation.CREATED:
        database.checkSecurity(
            ODatabaseSecurityResources.CLUSTER, ORole.PERMISSION_CREATE, iClusterName);
        database.callbackHooks(TYPE.BEFORE_CREATE, iRecord);
        break;
      case ORecordOperation.LOADED:
        /**
         * Read hooks already invoked in {@link
         * com.orientechnologies.orient.core.db.record.ODatabaseRecordAbstract#executeReadRecord} .
         */
        break;
      case ORecordOperation.UPDATED:
        database.checkSecurity(
            ODatabaseSecurityResources.CLUSTER, ORole.PERMISSION_UPDATE, iClusterName);
        database.callbackHooks(TYPE.BEFORE_UPDATE, iRecord);
        break;
      case ORecordOperation.DELETED:
        database.checkSecurity(
            ODatabaseSecurityResources.CLUSTER, ORole.PERMISSION_DELETE, iClusterName);
        database.callbackHooks(TYPE.BEFORE_DELETE, iRecord);
        break;
    }

    try {
      if (iRecord.getIdentity().isTemporary())
        temp2persistent.put(iRecord.getIdentity().copy(), iRecord);

      if ((status == OTransaction.TXSTATUS.COMMITTING)
          && database.getStorage() instanceof OStorageEmbedded) {

        // I'M COMMITTING: BYPASS LOCAL BUFFER
        switch (iStatus) {
          case ORecordOperation.CREATED:
          case ORecordOperation.UPDATED:
            final ORID oldRid = iRecord.getIdentity().copy();
            database.executeSaveRecord(
                iRecord,
                iClusterName,
                iRecord.getRecordVersion(),
                iRecord.getRecordType(),
                false,
                OPERATION_MODE.SYNCHRONOUS,
                false,
                null,
                null);
            updateIdentityAfterCommit(oldRid, iRecord.getIdentity());
            break;
          case ORecordOperation.DELETED:
            database.executeDeleteRecord(
                iRecord,
                iRecord.getRecordVersion(),
                false,
                false,
                OPERATION_MODE.SYNCHRONOUS,
                false);
            break;
        }

        final ORecordOperation txRecord = getRecordEntry(iRecord.getIdentity());

        if (txRecord == null) {
          // NOT IN TX, SAVE IT ANYWAY
          allEntries.put(iRecord.getIdentity(), new ORecordOperation(iRecord, iStatus));
        } else if (txRecord.record != iRecord) {
          // UPDATE LOCAL RECORDS TO AVOID MISMATCH OF VERSION/CONTENT
          final String clusterName =
              getDatabase().getClusterNameById(iRecord.getIdentity().getClusterId());
          if (!clusterName.equals(OMetadataDefault.CLUSTER_MANUAL_INDEX_NAME)
              && !clusterName.equals(OMetadataDefault.CLUSTER_INDEX_NAME))
            OLogManager.instance()
                .warn(
                    this,
                    "Found record in transaction with the same RID %s but different instance. Probably the record has been loaded from another transaction and reused on the current one: reload it from current transaction before to update or delete it",
                    iRecord.getIdentity());

          txRecord.record = iRecord;
          txRecord.type = iStatus;
        }

      } else {
        final ORecordId rid = (ORecordId) iRecord.getIdentity();

        if (!rid.isValid()) {
          iRecord.onBeforeIdentityChanged(rid);

          // ASSIGN A UNIQUE SERIAL TEMPORARY ID
          if (rid.clusterId == ORID.CLUSTER_ID_INVALID)
            rid.clusterId =
                iClusterName != null
                    ? database.getClusterIdByName(iClusterName)
                    : database.getDefaultClusterId();
          rid.clusterPosition = OClusterPositionFactory.INSTANCE.valueOf(newObjectCounter--);

          iRecord.onAfterIdentityChanged(iRecord);
        } else
          // REMOVE FROM THE DB'S CACHE
          database.getLevel1Cache().freeRecord(rid);

        ORecordOperation txEntry = getRecordEntry(rid);

        if (txEntry == null) {
          if (!(rid.isTemporary() && iStatus != ORecordOperation.CREATED)) {
            // NEW ENTRY: JUST REGISTER IT
            txEntry = new ORecordOperation(iRecord, iStatus);
            recordEntries.put(rid, txEntry);
          }
        } else {
          // UPDATE PREVIOUS STATUS
          txEntry.record = iRecord;

          switch (txEntry.type) {
            case ORecordOperation.LOADED:
              switch (iStatus) {
                case ORecordOperation.UPDATED:
                  txEntry.type = ORecordOperation.UPDATED;
                  break;
                case ORecordOperation.DELETED:
                  txEntry.type = ORecordOperation.DELETED;
                  break;
              }
              break;
            case ORecordOperation.UPDATED:
              switch (iStatus) {
                case ORecordOperation.DELETED:
                  txEntry.type = ORecordOperation.DELETED;
                  break;
              }
              break;
            case ORecordOperation.DELETED:
              break;
            case ORecordOperation.CREATED:
              switch (iStatus) {
                case ORecordOperation.DELETED:
                  recordEntries.remove(rid);
                  break;
              }
              break;
          }
        }
      }

      switch (iStatus) {
        case ORecordOperation.CREATED:
          database.callbackHooks(TYPE.AFTER_CREATE, iRecord);
          break;
        case ORecordOperation.LOADED:
          /**
           * Read hooks already invoked in {@link
           * com.orientechnologies.orient.core.db.record.ODatabaseRecordAbstract#executeReadRecord}.
           */
          break;
        case ORecordOperation.UPDATED:
          database.callbackHooks(TYPE.AFTER_UPDATE, iRecord);
          break;
        case ORecordOperation.DELETED:
          database.callbackHooks(TYPE.AFTER_DELETE, iRecord);
          break;
      }
    } catch (Throwable t) {
      switch (iStatus) {
        case ORecordOperation.CREATED:
          database.callbackHooks(TYPE.CREATE_FAILED, iRecord);
          break;
        case ORecordOperation.UPDATED:
          database.callbackHooks(TYPE.UPDATE_FAILED, iRecord);
          break;
        case ORecordOperation.DELETED:
          database.callbackHooks(TYPE.DELETE_FAILED, iRecord);
          break;
      }

      if (t instanceof RuntimeException) throw (RuntimeException) t;
      else throw new ODatabaseException("Error on saving record " + iRecord.getIdentity(), t);
    }
  }