use of com.orientechnologies.orient.core.record.ORecord in project orientdb by orientechnologies.
the class ODatabaseDocumentTx method callbackHooks.
/**
* Callback the registered hooks if any.
*
* @param type Hook type. Define when hook is called.
* @param id Record received in the callback
*
* @return True if the input record is changed, otherwise false
*/
public ORecordHook.RESULT callbackHooks(final ORecordHook.TYPE type, final OIdentifiable id) {
if (id == null || hooks.isEmpty() || id.getIdentity().getClusterId() == 0)
return ORecordHook.RESULT.RECORD_NOT_CHANGED;
final ORecordHook.SCOPE scope = ORecordHook.SCOPE.typeToScope(type);
final int scopeOrdinal = scope.ordinal();
ORID identity = id.getIdentity().copy();
if (!pushInHook(identity))
return ORecordHook.RESULT.RECORD_NOT_CHANGED;
try {
final ORecord rec = id.getRecord();
if (rec == null)
return ORecordHook.RESULT.RECORD_NOT_CHANGED;
final OScenarioThreadLocal.RUN_MODE runMode = OScenarioThreadLocal.INSTANCE.getRunMode();
boolean recordChanged = false;
for (ORecordHook hook : hooksByScope[scopeOrdinal]) {
switch(runMode) {
case // NON_DISTRIBUTED OR PROXIED DB
DEFAULT:
if (getStorage().isDistributed() && hook.getDistributedExecutionMode() == ORecordHook.DISTRIBUTED_EXECUTION_MODE.TARGET_NODE)
// SKIP
continue;
// TARGET NODE
break;
case RUNNING_DISTRIBUTED:
if (hook.getDistributedExecutionMode() == ORecordHook.DISTRIBUTED_EXECUTION_MODE.SOURCE_NODE)
continue;
}
final ORecordHook.RESULT res = hook.onTrigger(type, rec);
if (res == ORecordHook.RESULT.RECORD_CHANGED)
recordChanged = true;
else if (res == ORecordHook.RESULT.SKIP_IO)
// SKIP IO OPERATION
return res;
else if (res == ORecordHook.RESULT.SKIP)
// SKIP NEXT HOOKS AND RETURN IT
return res;
else if (res == ORecordHook.RESULT.RECORD_REPLACED)
return res;
}
return recordChanged ? ORecordHook.RESULT.RECORD_CHANGED : ORecordHook.RESULT.RECORD_NOT_CHANGED;
} finally {
popInHook(identity);
}
}
use of com.orientechnologies.orient.core.record.ORecord in project orientdb by orientechnologies.
the class ODatabaseDocumentTx method updateStream.
private byte[] updateStream(final ORecord record) {
ORecordSerializationContext.pullContext();
ODirtyManager manager = ORecordInternal.getDirtyManager(record);
Set<ORecord> newRecords = manager.getNewRecords();
Set<ORecord> updatedRecords = manager.getUpdateRecords();
manager.clearForSave();
if (newRecords != null) {
for (ORecord newRecord : newRecords) {
if (newRecord != record)
getTransaction().saveRecord(newRecord, null, OPERATION_MODE.SYNCHRONOUS, false, null, null);
}
}
if (updatedRecords != null) {
for (ORecord updatedRecord : updatedRecords) {
if (updatedRecord != record)
getTransaction().saveRecord(updatedRecord, null, OPERATION_MODE.SYNCHRONOUS, false, null, null);
}
}
ORecordSerializationContext.pushContext();
ORecordInternal.unsetDirty(record);
record.setDirty();
return record.toStream();
}
use of com.orientechnologies.orient.core.record.ORecord in project orientdb by orientechnologies.
the class ODatabaseDocumentTx method executeDeleteRecord.
/**
* This method is internal, it can be subject to signature change or be removed, do not use.
*
* @Internal
*/
public void executeDeleteRecord(OIdentifiable record, final int iVersion, final boolean iRequired, final OPERATION_MODE iMode, boolean prohibitTombstones) {
checkOpeness();
checkIfActive();
final ORecordId rid = (ORecordId) record.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;
record = record.getRecord();
if (record == null)
return;
checkSecurity(ORule.ResourceGeneric.CLUSTER, ORole.PERMISSION_DELETE, getClusterNameById(rid.getClusterId()));
ORecordSerializationContext.pushContext();
getMetadata().makeThreadLocalSchemaSnapshot();
try {
if (record instanceof ODocument) {
ODocumentInternal.checkClass((ODocument) record, this);
}
try {
// if cache is switched off record will be unreachable after delete.
ORecord rec = record.getRecord();
if (rec != null) {
callbackHooks(ORecordHook.TYPE.BEFORE_DELETE, rec);
if (rec instanceof ODocument)
ORidBagDeleter.deleteAllRidBags((ODocument) rec);
}
final OStorageOperationResult<Boolean> operationResult;
try {
if (prohibitTombstones) {
final boolean result = storage.cleanOutRecord(rid, iVersion, iMode.ordinal(), null);
if (!result && iRequired)
throw new ORecordNotFoundException(rid);
operationResult = new OStorageOperationResult<Boolean>(result);
} else {
final OStorageOperationResult<Boolean> result = storage.deleteRecord(rid, iVersion, iMode.ordinal(), null);
if (!result.getResult() && iRequired)
throw new ORecordNotFoundException(rid);
operationResult = new OStorageOperationResult<Boolean>(result.getResult());
}
if (!operationResult.isMoved() && rec != null)
callbackHooks(ORecordHook.TYPE.AFTER_DELETE, rec);
else if (rec != null)
callbackHooks(ORecordHook.TYPE.DELETE_REPLICATED, rec);
} catch (Exception t) {
callbackHooks(ORecordHook.TYPE.DELETE_FAILED, rec);
throw t;
} finally {
callbackHooks(ORecordHook.TYPE.FINALIZE_DELETION, rec);
}
clearDocumentTracking(rec);
// REMOVE THE RECORD FROM 1 AND 2 LEVEL CACHES
if (!operationResult.isMoved()) {
getLocalCache().deleteRecord(rid);
}
} catch (OException e) {
// RE-THROW THE EXCEPTION
throw e;
} catch (Exception t) {
// WRAP IT AS ODATABASE EXCEPTION
throw OException.wrapException(new ODatabaseException("Error on deleting record in cluster #" + record.getIdentity().getClusterId()), t);
}
} finally {
ORecordSerializationContext.pullContext();
getMetadata().clearThreadLocalSchemaSnapshot();
}
}
use of com.orientechnologies.orient.core.record.ORecord in project orientdb by orientechnologies.
the class ODatabaseDocumentTx method reload.
@Override
public <RET extends ORecord> RET reload(final ORecord record, String fetchPlan, boolean ignoreCache, boolean force) {
checkIfActive();
final ORecord loadedRecord = currentTx.reloadRecord(record.getIdentity(), record, fetchPlan, ignoreCache, force);
if (loadedRecord != null && record != loadedRecord) {
record.fromStream(loadedRecord.toStream());
ORecordInternal.setVersion(record, loadedRecord.getVersion());
} else if (loadedRecord == null) {
throw new ORecordNotFoundException(record.getIdentity());
}
return (RET) record;
}
use of com.orientechnologies.orient.core.record.ORecord in project orientdb by orientechnologies.
the class ODatabaseDocumentTx method executeReadRecords.
/**
* This method is internal, it can be subject to signature change or be removed, do not use.
*
* @Internal
*/
public Set<ORecord> executeReadRecords(final Set<ORecordId> iRids, final boolean ignoreCache) {
checkOpeness();
checkIfActive();
getMetadata().makeThreadLocalSchemaSnapshot();
ORecordSerializationContext.pushContext();
try {
final Set<ORecord> records = new HashSet<ORecord>(iRids.size() > 0 ? iRids.size() : 1);
if (iRids.isEmpty())
return records;
final Collection<ORecordId> rids = new ArrayList<ORecordId>(iRids);
for (Iterator<ORecordId> it = rids.iterator(); it.hasNext(); ) {
final ORecordId rid = it.next();
// SEARCH IN LOCAL TX
ORecord record = getTransaction().getRecord(rid);
if (record == OTransactionRealAbstract.DELETED_RECORD) {
// DELETED IN TX
it.remove();
continue;
}
if (record == null && !ignoreCache)
// SEARCH INTO THE CACHE
record = getLocalCache().findRecord(rid);
if (record != null) {
// FOUND FROM CACHE
records.add(record);
it.remove();
}
}
final Collection<OPair<ORecordId, ORawBuffer>> rawRecords = ((OAbstractPaginatedStorage) storage.getUnderlying()).readRecords(rids);
for (OPair<ORecordId, ORawBuffer> entry : rawRecords) {
// NO SAME RECORD TYPE: CAN'T REUSE OLD ONE BUT CREATE A NEW ONE FOR IT
final ORecord record = Orient.instance().getRecordFactoryManager().newInstance(entry.value.recordType);
ORecordInternal.fill(record, entry.key, entry.value.version, entry.value.buffer, false);
records.add(record);
}
return records;
} finally {
ORecordSerializationContext.pullContext();
getMetadata().clearThreadLocalSchemaSnapshot();
}
}
Aggregations