use of com.orientechnologies.orient.core.record.ORecord in project orientdb by orientechnologies.
the class OAbstractPaginatedStorage method commit.
public List<ORecordOperation> commit(final OTransaction clientTx, Runnable callback) {
checkOpeness();
checkLowDiskSpaceFullCheckpointRequestsAndBackgroundDataFlushExceptions();
txBegun.incrementAndGet();
final ODatabaseDocumentInternal databaseRecord = (ODatabaseDocumentInternal) clientTx.getDatabase();
final OIndexManagerProxy indexManager = databaseRecord.getMetadata().getIndexManager();
final TreeMap<String, OTransactionIndexChanges> indexesToCommit = getSortedIndexEntries(clientTx);
final Map<ORecordOperation, Integer> clusterOverrides = new IdentityHashMap<ORecordOperation, Integer>();
databaseRecord.getMetadata().makeThreadLocalSchemaSnapshot();
if (OLogManager.instance().isDebugEnabled())
OLogManager.instance().debug(this, "%d Committing transaction %d on database '%s' (items=%d)...", Thread.currentThread().getId(), clientTx.getId(), databaseRecord.getName(), clientTx.getEntryCount());
final Iterable<ORecordOperation> entries = (Iterable<ORecordOperation>) clientTx.getAllRecordEntries();
final TreeMap<Integer, OCluster> clustersToLock = new TreeMap<Integer, OCluster>();
final Set<ORecordOperation> newRecords = new TreeSet<ORecordOperation>(new Comparator<ORecordOperation>() {
@Override
public int compare(final ORecordOperation o1, final ORecordOperation o2) {
return o1.getRecord().getIdentity().compareTo(o2.getRecord().getIdentity());
}
});
for (ORecordOperation txEntry : entries) {
if (txEntry.type == ORecordOperation.CREATED || txEntry.type == ORecordOperation.UPDATED) {
final ORecord record = txEntry.getRecord();
if (record instanceof ODocument)
((ODocument) record).validate();
}
if (txEntry.type == ORecordOperation.UPDATED || txEntry.type == ORecordOperation.DELETED) {
final int clusterId = txEntry.getRecord().getIdentity().getClusterId();
clustersToLock.put(clusterId, getClusterById(clusterId));
} else if (txEntry.type == ORecordOperation.CREATED) {
newRecords.add(txEntry);
final ORecord record = txEntry.getRecord();
final ORID rid = record.getIdentity();
int clusterId = rid.getClusterId();
if (record.isDirty() && clusterId == ORID.CLUSTER_ID_INVALID && record instanceof ODocument) {
// TRY TO FIX CLUSTER ID TO THE DEFAULT CLUSTER ID DEFINED IN SCHEMA CLASS
final OImmutableClass class_ = ODocumentInternal.getImmutableSchemaClass(((ODocument) record));
if (class_ != null) {
clusterId = class_.getClusterForNewInstance((ODocument) record);
clusterOverrides.put(txEntry, clusterId);
}
}
clustersToLock.put(clusterId, getClusterById(clusterId));
}
}
final List<ORecordOperation> result = new ArrayList<ORecordOperation>();
final List<Lock[]> indexKeyLockList = new ArrayList<Lock[]>(indexesToCommit.size());
stateLock.acquireReadLock();
try {
try {
try {
checkOpeness();
lockIndexKeys(indexManager, indexesToCommit, indexKeyLockList);
makeStorageDirty();
startStorageTx(clientTx);
lockClusters(clustersToLock);
lockRidBags(clustersToLock, indexesToCommit);
lockIndexes(indexesToCommit);
Map<ORecordOperation, OPhysicalPosition> positions = new IdentityHashMap<ORecordOperation, OPhysicalPosition>();
for (ORecordOperation txEntry : newRecords) {
ORecord rec = txEntry.getRecord();
if (rec.isDirty()) {
ORecordId rid = (ORecordId) rec.getIdentity().copy();
ORecordId oldRID = rid.copy();
final Integer clusterOverride = clusterOverrides.get(txEntry);
final int clusterId = clusterOverride == null ? rid.getClusterId() : clusterOverride;
final OCluster cluster = getClusterById(clusterId);
OPhysicalPosition ppos = cluster.allocatePosition(ORecordInternal.getRecordType(rec));
rid.setClusterId(cluster.getId());
if (rid.getClusterPosition() > -1) {
// RECORD HAVING A HIGHER CLUSTER POSITION
while (rid.getClusterPosition() > ppos.clusterPosition) {
ppos = cluster.allocatePosition(ORecordInternal.getRecordType(rec));
}
if (rid.getClusterPosition() != ppos.clusterPosition)
throw new OConcurrentCreateException(rid, new ORecordId(rid.getClusterId(), ppos.clusterPosition));
}
positions.put(txEntry, ppos);
rid.setClusterPosition(ppos.clusterPosition);
clientTx.updateIdentityAfterCommit(oldRID, rid);
}
}
for (ORecordOperation txEntry : entries) {
commitEntry(txEntry, positions.get(txEntry));
result.add(txEntry);
}
commitIndexes(indexesToCommit);
endStorageTx();
OTransactionAbstract.updateCacheFromEntries(clientTx, entries, true);
txCommit.incrementAndGet();
} catch (IOException ioe) {
makeRollback(clientTx, ioe);
} catch (RuntimeException e) {
makeRollback(clientTx, e);
} finally {
unlockIndexKeys(indexesToCommit, indexKeyLockList);
transaction.set(null);
}
} finally {
databaseRecord.getMetadata().clearThreadLocalSchemaSnapshot();
}
} finally {
stateLock.releaseReadLock();
}
if (OLogManager.instance().isDebugEnabled())
OLogManager.instance().debug(this, "%d Committed transaction %d on database '%s' (result=%s)", Thread.currentThread().getId(), clientTx.getId(), databaseRecord.getName(), result);
return result;
}
use of com.orientechnologies.orient.core.record.ORecord in project orientdb by orientechnologies.
the class HookReadTest method testSelectChangedInHook.
@Test
public void testSelectChangedInHook() {
database.registerHook(new ORecordHook() {
@Override
public void onUnregister() {
}
@Override
public RESULT onTrigger(TYPE iType, ORecord iRecord) {
if (iType == TYPE.AFTER_READ)
((ODocument) iRecord).field("read", "test");
return RESULT.RECORD_CHANGED;
}
@Override
public DISTRIBUTED_EXECUTION_MODE getDistributedExecutionMode() {
return null;
}
});
database.save(new ODocument("TestClass"));
List<ODocument> res = database.query(new OSQLSynchQuery<Object>("select from TestClass"));
assertEquals(res.get(0).field("read"), "test");
}
use of com.orientechnologies.orient.core.record.ORecord in project orientdb by orientechnologies.
the class ODatabaseDocumentSaveClusterTest method testSaveCluster.
@Test
public void testSaveCluster() {
OClass clazz = db.getMetadata().getSchema().createClass("test");
int res = db.addCluster("test_one");
clazz.addCluster("test_one");
ORecord saved = db.save(new ODocument("test"), "test_one");
Assert.assertEquals(saved.getIdentity().getClusterId(), res);
}
use of com.orientechnologies.orient.core.record.ORecord in project orientdb by orientechnologies.
the class HookSaveTest method testCreatedBackLinkedInHook.
@Test
public void testCreatedBackLinkedInHook() {
database.registerHook(new ORecordHook() {
@Override
public void onUnregister() {
}
@Override
public RESULT onTrigger(TYPE iType, ORecord iRecord) {
if (iType != TYPE.BEFORE_CREATE)
return RESULT.RECORD_NOT_CHANGED;
ODocument doc = (ODocument) iRecord;
if (doc.containsField("test"))
return RESULT.RECORD_NOT_CHANGED;
ODocument doc1 = new ODocument();
doc1.field("test", "value");
doc.field("testNewLinkedRecord", doc1);
doc1.field("backLink", doc);
return RESULT.RECORD_CHANGED;
}
@Override
public DISTRIBUTED_EXECUTION_MODE getDistributedExecutionMode() {
return null;
}
});
ODocument doc = database.save(new ODocument("test"));
ODocument newRef = doc.field("testNewLinkedRecord");
assertNotNull(newRef);
assertNotNull(newRef.getIdentity().isPersistent());
}
use of com.orientechnologies.orient.core.record.ORecord in project orientdb by orientechnologies.
the class HookSaveTest method testCreatedLinkedInHook.
@Test
public void testCreatedLinkedInHook() {
database.registerHook(new ORecordHook() {
@Override
public void onUnregister() {
}
@Override
public RESULT onTrigger(TYPE iType, ORecord iRecord) {
if (iType != TYPE.BEFORE_CREATE)
return RESULT.RECORD_NOT_CHANGED;
ODocument doc = (ODocument) iRecord;
if (doc.containsField("test"))
return RESULT.RECORD_NOT_CHANGED;
ODocument doc1 = new ODocument();
doc1.field("test", "value");
doc.field("testNewLinkedRecord", doc1);
return RESULT.RECORD_CHANGED;
}
@Override
public DISTRIBUTED_EXECUTION_MODE getDistributedExecutionMode() {
return null;
}
});
ODocument doc = database.save(new ODocument("test"));
ODocument newRef = doc.field("testNewLinkedRecord");
assertNotNull(newRef);
assertNotNull(newRef.getIdentity().isPersistent());
}
Aggregations