return;
final ORecordId rid = (ORecordId) iRecord.getIdentity();
if (rid == null)
throw new ODatabaseException(
"Can't create record because it has no identity. Probably is not a regular record or contains projections of fields rather than a full record");
if (iRecord.getDatabase() == null)
iRecord.setDatabase(this);
try {
boolean wasNew = rid.isNew();
// STREAM.LENGTH == 0 -> RECORD IN STACK: WILL BE SAVED AFTER
byte[] stream = iRecord.toStream();
boolean isNew = rid.isNew();
if (isNew)
// NOTIFY IDENTITY HAS CHANGED
iRecord.onBeforeIdentityChanged(rid);
else if (stream.length == 0)
// ALREADY CREATED AND WAITING FOR THE RIGHT UPDATE (WE'RE IN A GRAPH)
return;
if (isNew && rid.clusterId < 0)
rid.clusterId = iClusterName != null ? getClusterIdByName(iClusterName) : getDefaultClusterId();
if (stream != null && stream.length > 0) {
if (wasNew) {
// CHECK ACCESS ON CLUSTER
checkSecurity(ODatabaseSecurityResources.CLUSTER, ORole.PERMISSION_CREATE, iClusterName, rid.clusterId);
if (callbackHooks(TYPE.BEFORE_CREATE, iRecord))
// RECORD CHANGED IN TRIGGER, REACQUIRE IT
stream = iRecord.toStream();
} else {
// CHECK ACCESS ON CLUSTER
checkSecurity(ODatabaseSecurityResources.CLUSTER, ORole.PERMISSION_UPDATE, iClusterName, rid.clusterId);
if (callbackHooks(TYPE.BEFORE_UPDATE, iRecord))
// RECORD CHANGED IN TRIGGER, REACQUIRE IT
stream = iRecord.toStream();
}
if (!iRecord.isDirty()) {
// RECORD SAVED DURING PREVIOUS STREAMING PHASE: THIS HAPPENS FOR CIRCULAR REFERENCED RECORDS
// ADD/UPDATE IT IN CACHE IF IT'S ACTIVE
getLevel1Cache().updateRecord(iRecord);
return;
}
}
// GET THE LATEST VERSION. IT COULD CHANGE BECAUSE THE RECORD COULD BE BEEN LINKED FROM OTHERS
final int realVersion = iVersion == -1 || !mvcc ? -1 : iRecord.getVersion();
// SAVE IT
final long result = underlying.save(rid, stream, realVersion, iRecord.getRecordType());
if (isNew) {
// UPDATE INFORMATION: CLUSTER ID+POSITION
iRecord.fill(iRecord.getDatabase(), rid, 0, stream, stream == null || stream.length == 0);
// NOTIFY IDENTITY HAS CHANGED
iRecord.onAfterIdentityChanged(iRecord);
} else {
// UPDATE INFORMATION: VERSION
iRecord.fill(iRecord.getDatabase(), rid, (int) result, stream, stream == null || stream.length == 0);
}
if (stream != null && stream.length > 0)
callbackHooks(wasNew ? TYPE.AFTER_CREATE : TYPE.AFTER_UPDATE, iRecord);
// ADD/UPDATE IT IN CACHE IF IT'S ACTIVE
getLevel1Cache().updateRecord(iRecord);
} catch (OException e) {
// RE-THROW THE EXCEPTION
throw e;
} catch (Throwable t) {
// WRAP IT AS ODATABASE EXCEPTION
throw new ODatabaseException("Error on saving record in cluster #" + iRecord.getIdentity().getClusterId(), t);
}
}