// PLAN
if (record instanceof ODocument) {
final Map<String, Integer> fetchPlan = OFetchHelper.buildFetchPlan(fetchPlanString);
final Set<ODocument> recordsToSend = new HashSet<ODocument>();
OFetchHelper.fetch((ODocument) record, record, fetchPlan, null, 0, -1, new OFetchListener() {
@Override
public int size() {
return recordsToSend.size();
}
// ADD TO THE SET OF OBJECTS TO SEND
@Override
public Object fetchLinked(final ODocument iRoot, final Object iUserObject, final String iFieldName,
final Object iLinked) {
if (iLinked instanceof ODocument) {
if (((ODocument) iLinked).getIdentity().isValid())
return recordsToSend.add((ODocument) iLinked) ? iLinked : null;
return null;
} else if (iLinked instanceof Collection<?>)
return recordsToSend.addAll((Collection<? extends ODocument>) iLinked) ? iLinked : null;
else if (iLinked instanceof Map<?, ?>)
return recordsToSend.addAll(((Map<String, ? extends ODocument>) iLinked).values()) ? iLinked : null;
else
throw new IllegalArgumentException("Unrecognized type while fetching records: " + iLinked);
}
});
// SEND RECORDS TO LOAD IN CLIENT CACHE
for (ODocument doc : recordsToSend) {
if (doc.getIdentity().isValid()) {
channel.writeByte((byte) 2); // CLIENT CACHE
// RECORD. IT ISN'T PART OF THE RESULT SET
writeIdentifiable(doc);
}
}
}
}
}
} finally {
channel.releaseExclusiveLock();
}
}
channel.writeByte((byte) 0); // NO MORE RECORDS
break;
}
case OChannelBinaryProtocol.REQUEST_RECORD_CREATE: {
data.commandInfo = "Create record";
final ORecordId rid = new ORecordId(channel.readShort(), ORID.CLUSTER_POS_INVALID);
final byte[] buffer = channel.readBytes();
final byte recordType = channel.readByte();
final ORecordInternal<?> record = Orient.instance().getRecordFactoryManager().newInstance(connection.database, recordType);
record.fill(connection.database, rid, 0, buffer, true);
connection.database.save(record);
channel.acquireExclusiveLock();
try {
sendOk(lastClientTxId);
channel.writeLong(record.getIdentity().getClusterPosition());
} finally {
channel.releaseExclusiveLock();
}
break;
}
case OChannelBinaryProtocol.REQUEST_RECORD_UPDATE: {
data.commandInfo = "Update record";
final ORecordId rid = channel.readRID();
final byte[] buffer = channel.readBytes();
final int version = channel.readInt();
final byte recordType = channel.readByte();
final ORecordInternal<?> newRecord = Orient.instance().getRecordFactoryManager().newInstance(connection.database, recordType);
newRecord.fill(connection.database, rid, version, buffer, true);
if (((OSchemaProxy) connection.database.getMetadata().getSchema()).getIdentity().equals(rid))
// || ((OIndexManagerImpl) connection.database.getMetadata().getIndexManager()).getDocument().getIdentity().equals(rid)) {
throw new OSecurityAccessException("Can't update internal record " + rid);
final ORecordInternal<?> currentRecord;
if (newRecord instanceof ODocument) {
currentRecord = connection.database.load(rid);
if (currentRecord == null)
throw new ORecordNotFoundException(rid.toString());
final ODocument doc = (ODocument) currentRecord;
doc.merge((ODocument) newRecord, false, false);
} else
currentRecord = newRecord;
currentRecord.setVersion(version);
connection.database.save(currentRecord);
if (currentRecord.getIdentity().toString().equals(connection.database.getStorage().getConfiguration().indexMgrRecordId)) {
// FORCE INDEX MANAGER UPDATE. THIS HAPPENS FOR DIRECT CHANGES FROM REMOTE LIKE IN GRAPH
connection.database.getMetadata().getIndexManager().reload();
}
channel.acquireExclusiveLock();
try {
sendOk(lastClientTxId);
channel.writeInt(currentRecord.getVersion());
} finally {
channel.releaseExclusiveLock();
}
break;
}
case OChannelBinaryProtocol.REQUEST_RECORD_DELETE: {
data.commandInfo = "Delete record";
ORecordInternal<?> record = connection.database.load(channel.readRID());
record.setVersion(channel.readInt());
record.delete();
channel.acquireExclusiveLock();
try {
sendOk(lastClientTxId);
channel.writeByte((byte) 1);
} finally {
channel.releaseExclusiveLock();
}
break;
}
case OChannelBinaryProtocol.REQUEST_COUNT: {
data.commandInfo = "Count cluster records";
final String clusterName = channel.readString();
final long size = connection.database.countClusterElements(clusterName);
channel.acquireExclusiveLock();
try {
sendOk(lastClientTxId);
channel.writeLong(size);
} finally {
channel.releaseExclusiveLock();
}
break;
}
case OChannelBinaryProtocol.REQUEST_COMMAND: {
data.commandInfo = "Execute remote command";
final boolean asynch = channel.readByte() == 'a';
final OCommandRequestText command = (OCommandRequestText) OStreamSerializerAnyStreamable.INSTANCE.fromStream(
connection.database, channel.readBytes());
final OQuery<?> query = (OQuery<?>) (command instanceof OQuery<?> ? command : null);
data.commandDetail = command.getText();
channel.acquireExclusiveLock();
try {
if (asynch) {
// ASYNCHRONOUS
final StringBuilder empty = new StringBuilder();
final Set<ODocument> recordsToSend = new HashSet<ODocument>();
final int txId = lastClientTxId;
final Map<String, Integer> fetchPlan = query != null ? OFetchHelper.buildFetchPlan(query.getFetchPlan()) : null;
command.setResultListener(new OCommandResultListener() {
@Override
public boolean result(final Object iRecord) {
if (empty.length() == 0)
try {
sendOk(txId);
empty.append("-");
} catch (IOException e1) {
}
try {
channel.writeByte((byte) 1); // ONE MORE RECORD
writeIdentifiable((ORecordInternal<?>) iRecord);
if (fetchPlan != null && iRecord instanceof ODocument) {
OFetchHelper.fetch((ODocument) iRecord, iRecord, fetchPlan, null, 0, -1, new OFetchListener() {
@Override
public int size() {
return recordsToSend.size();
}