use of com.orientechnologies.orient.core.record.ORecord in project orientdb by orientechnologies.
the class OStorageRemoteAsynchEventListener method onRequest.
public void onRequest(final byte iRequestCode, final Object obj) {
// Using get status to avoid to check the session.
if (storage.getStatus() == STATUS.CLOSED)
return;
if (iRequestCode == OChannelBinaryProtocol.REQUEST_PUSH_DISTRIB_CONFIG) {
storage.updateClusterConfiguration(null, (byte[]) obj);
if (OLogManager.instance().isDebugEnabled()) {
synchronized (storage.getClusterConfiguration()) {
OLogManager.instance().debug(this, "Received new cluster configuration: %s", storage.getClusterConfiguration().toJSON("prettyPrint"));
}
}
} else if (iRequestCode == OChannelBinaryProtocol.REQUEST_PUSH_LIVE_QUERY) {
byte[] bytes = (byte[]) obj;
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
Integer id = null;
try {
byte what = dis.readByte();
if (what == 'r') {
byte op = dis.readByte();
id = dis.readInt();
final ORecord record = Orient.instance().getRecordFactoryManager().newInstance(dis.readByte());
final int version = readVersion(dis);
final ORecordId rid = readRID(dis);
final byte[] content = readBytes(dis);
ORecordInternal.fill(record, rid, version, content, false);
OLiveResultListener listener = liveQueryListeners.get(id);
if (listener != null) {
listener.onLiveResult(id, new ORecordOperation(record, op));
} else {
OLogManager.instance().warn(this, "Receiving invalid LiveQuery token: " + id);
}
} else if (what == 'u') {
id = dis.readInt();
OLiveResultListener listener = liveQueryListeners.get(id);
listener.onUnsubscribe(id);
}
} catch (IOException e) {
if (id != null) {
OLiveResultListener listener = liveQueryListeners.get(id);
if (listener != null) {
listener.onError(id);
}
}
e.printStackTrace();
}
}
byte op;
}
use of com.orientechnologies.orient.core.record.ORecord in project orientdb by orientechnologies.
the class OStorageRemote method command.
/**
* Execute the command remotely and get the results back.
*/
public Object command(final OCommandRequestText iCommand) {
if (!(iCommand instanceof OSerializableStream))
throw new OCommandExecutionException("Cannot serialize the command to be executed to the server side.");
final boolean live = iCommand instanceof OLiveQuery;
final ODatabaseDocument database = ODatabaseRecordThreadLocal.INSTANCE.get();
return networkOperation(new OStorageRemoteOperation<Object>() {
@Override
public Object execute(final OChannelBinaryAsynchClient network, OStorageRemoteSession session) throws IOException {
Object result = null;
session.commandExecuting = true;
try {
final boolean asynch = iCommand instanceof OCommandRequestAsynch && ((OCommandRequestAsynch) iCommand).isAsynchronous();
try {
beginRequest(network, OChannelBinaryProtocol.REQUEST_COMMAND, session);
if (live) {
network.writeByte((byte) 'l');
} else {
// ASYNC / SYNC
network.writeByte((byte) (asynch ? 'a' : 's'));
}
network.writeBytes(OStreamSerializerAnyStreamable.INSTANCE.toStream(iCommand));
} finally {
endRequest(network);
}
try {
beginResponse(network, session);
// Collection of prefetched temporary record (nested projection record), to refer for avoid garbage collection.
List<ORecord> temporaryResults = new ArrayList<ORecord>();
boolean addNextRecord = true;
if (asynch) {
byte status;
// ASYNCH: READ ONE RECORD AT TIME
while ((status = network.readByte()) > 0) {
final ORecord record = (ORecord) OChannelBinaryProtocol.readIdentifiable(network);
if (record == null)
continue;
switch(status) {
case 1:
// PUT AS PART OF THE RESULT SET. INVOKE THE LISTENER
if (addNextRecord) {
addNextRecord = iCommand.getResultListener().result(record);
database.getLocalCache().updateRecord(record);
}
break;
case 2:
if (record.getIdentity().getClusterId() == -2)
temporaryResults.add(record);
// PUT IN THE CLIENT LOCAL CACHE
database.getLocalCache().updateRecord(record);
}
}
} else {
result = readSynchResult(network, database, temporaryResults);
if (live) {
final ODocument doc = ((List<ODocument>) result).get(0);
final Integer token = doc.field("token");
final Boolean unsubscribe = doc.field("unsubscribe");
if (token != null) {
if (Boolean.TRUE.equals(unsubscribe)) {
if (OStorageRemote.this.asynchEventListener != null)
OStorageRemote.this.asynchEventListener.unregisterLiveListener(token);
} else {
final OLiveResultListener listener = (OLiveResultListener) iCommand.getResultListener();
ODatabaseDocumentInternal current = ODatabaseRecordThreadLocal.INSTANCE.get();
final ODatabaseDocument dbCopy = current.copy();
ORemoteConnectionPool pool = OStorageRemote.this.connectionManager.getPool(network.getServerURL());
OStorageRemote.this.asynchEventListener.registerLiveListener(pool, token, new OLiveResultListener() {
@Override
public void onUnsubscribe(int iLiveToken) {
listener.onUnsubscribe(iLiveToken);
dbCopy.close();
}
@Override
public void onLiveResult(int iLiveToken, ORecordOperation iOp) throws OException {
dbCopy.activateOnCurrentThread();
listener.onLiveResult(iLiveToken, iOp);
}
@Override
public void onError(int iLiveToken) {
listener.onError(iLiveToken);
dbCopy.close();
}
});
}
} else {
throw new OStorageException("Cannot execute live query, returned null token");
}
}
}
if (!temporaryResults.isEmpty()) {
if (result instanceof OBasicResultSet<?>) {
((OBasicResultSet<?>) result).setTemporaryRecordCache(temporaryResults);
}
}
return result;
} finally {
endResponse(network);
}
} finally {
session.commandExecuting = false;
if (iCommand.getResultListener() != null && !live)
iCommand.getResultListener().end();
}
}
}, "Error on executing command: " + iCommand);
}
use of com.orientechnologies.orient.core.record.ORecord in project orientdb by orientechnologies.
the class ODocumentHelper method getFieldValue.
@SuppressWarnings("unchecked")
public static <RET> RET getFieldValue(Object value, final String iFieldName, final OCommandContext iContext) {
if (value == null)
return null;
final int fieldNameLength = iFieldName.length();
if (fieldNameLength == 0)
return (RET) value;
OIdentifiable currentRecord = value instanceof OIdentifiable ? (OIdentifiable) value : null;
int beginPos = iFieldName.charAt(0) == '.' ? 1 : 0;
int nextSeparatorPos = iFieldName.charAt(0) == '.' ? 1 : 0;
boolean firstInChain = true;
do {
char nextSeparator = ' ';
for (; nextSeparatorPos < fieldNameLength; ++nextSeparatorPos) {
nextSeparator = iFieldName.charAt(nextSeparatorPos);
if (nextSeparator == '.' || nextSeparator == '[')
break;
}
final String fieldName;
if (nextSeparatorPos < fieldNameLength)
fieldName = iFieldName.substring(beginPos, nextSeparatorPos);
else {
nextSeparator = ' ';
if (beginPos > 0)
fieldName = iFieldName.substring(beginPos);
else
fieldName = iFieldName;
}
if (nextSeparator == '[') {
if (fieldName != null && fieldName.length() > 0) {
if (currentRecord != null)
value = getIdentifiableValue(currentRecord, fieldName);
else if (value instanceof Map<?, ?>)
value = getMapEntry((Map<String, ?>) value, fieldName);
else if (OMultiValue.isMultiValue(value)) {
final HashSet<Object> temp = new LinkedHashSet<Object>();
for (Object o : OMultiValue.getMultiValueIterable(value, false)) {
if (o instanceof OIdentifiable) {
Object r = getFieldValue(o, iFieldName);
if (r != null)
OMultiValue.add(temp, r);
}
}
value = temp;
}
}
if (value == null)
return null;
else if (value instanceof OIdentifiable)
currentRecord = (OIdentifiable) value;
// final int end = iFieldName.indexOf(']', nextSeparatorPos);
final int end = findClosingBracketPosition(iFieldName, nextSeparatorPos);
if (end == -1)
throw new IllegalArgumentException("Missed closed ']'");
String indexPart = iFieldName.substring(nextSeparatorPos + 1, end);
if (indexPart.length() == 0)
return null;
nextSeparatorPos = end;
if (value instanceof OCommandContext)
value = ((OCommandContext) value).getVariables();
if (value instanceof OIdentifiable) {
final ORecord record = currentRecord != null && currentRecord instanceof OIdentifiable ? ((OIdentifiable) currentRecord).getRecord() : null;
final boolean backtick;
if ((indexPart.startsWith("`") && indexPart.endsWith("`"))) {
indexPart = OIOUtils.getStringContent(indexPart);
backtick = true;
} else
backtick = false;
final Object index = getIndexPart(iContext, indexPart);
final String indexAsString = index != null ? index.toString() : null;
final List<String> indexParts = OStringSerializerHelper.smartSplit(indexAsString, ',', OStringSerializerHelper.DEFAULT_IGNORE_CHARS);
final List<String> indexRanges = OStringSerializerHelper.smartSplit(indexAsString, '-', ' ');
final List<String> indexCondition = OStringSerializerHelper.smartSplit(indexAsString, '=', ' ');
if (backtick || (indexParts.size() == 1 && indexCondition.size() == 1 && indexRanges.size() == 1))
// SINGLE VALUE
value = ((ODocument) record).field(indexAsString);
else if (indexParts.size() > 1) {
// MULTI VALUE
final Object[] values = new Object[indexParts.size()];
for (int i = 0; i < indexParts.size(); ++i) {
values[i] = ((ODocument) record).field(OIOUtils.getStringContent(indexParts.get(i)));
}
value = values;
} else if (indexRanges.size() > 1) {
// MULTI VALUES RANGE
String from = indexRanges.get(0);
String to = indexRanges.get(1);
final ODocument doc = (ODocument) record;
final String[] fieldNames = doc.fieldNames();
final int rangeFrom = from != null && !from.isEmpty() ? Integer.parseInt(from) : 0;
final int rangeTo = to != null && !to.isEmpty() ? Math.min(Integer.parseInt(to), fieldNames.length - 1) : fieldNames.length - 1;
final Object[] values = new Object[rangeTo - rangeFrom + 1];
for (int i = rangeFrom; i <= rangeTo; ++i) values[i - rangeFrom] = doc.field(fieldNames[i]);
value = values;
} else if (!indexCondition.isEmpty()) {
// CONDITION
final String conditionFieldName = indexCondition.get(0);
Object conditionFieldValue = ORecordSerializerStringAbstract.getTypeValue(indexCondition.get(1));
if (conditionFieldValue instanceof String)
conditionFieldValue = OIOUtils.getStringContent(conditionFieldValue);
final Object fieldValue = getFieldValue(currentRecord, conditionFieldName);
if (conditionFieldValue != null && fieldValue != null)
conditionFieldValue = OType.convert(conditionFieldValue, fieldValue.getClass());
if (fieldValue == null && !conditionFieldValue.equals("null") || fieldValue != null && !fieldValue.equals(conditionFieldValue))
value = null;
}
} else if (value instanceof Map<?, ?>) {
final boolean backtick;
if ((indexPart.startsWith("`") && indexPart.endsWith("`"))) {
indexPart = OIOUtils.getStringContent(indexPart);
backtick = true;
} else
backtick = false;
final Object index = getIndexPart(iContext, indexPart);
final String indexAsString = index != null ? index.toString() : null;
final List<String> indexParts = OStringSerializerHelper.smartSplit(indexAsString, ',', OStringSerializerHelper.DEFAULT_IGNORE_CHARS);
final List<String> indexRanges = OStringSerializerHelper.smartSplit(indexAsString, '-', ' ');
if (!allIntegers(indexRanges)) {
indexRanges.clear();
indexRanges.add(indexAsString);
}
final List<String> indexCondition = OStringSerializerHelper.smartSplit(indexAsString, '=', ' ');
final Map<String, ?> map = (Map<String, ?>) value;
if (backtick || (indexParts.size() == 1 && indexCondition.size() == 1 && indexRanges.size() == 1))
// SINGLE VALUE
value = map.get(index);
else if (indexParts.size() > 1) {
// MULTI VALUE
final Object[] values = new Object[indexParts.size()];
for (int i = 0; i < indexParts.size(); ++i) {
values[i] = map.get(OIOUtils.getStringContent(indexParts.get(i)));
}
value = values;
} else if (indexRanges.size() > 1) {
// MULTI VALUES RANGE
String from = indexRanges.get(0);
String to = indexRanges.get(1);
final List<String> fieldNames = new ArrayList<String>(map.keySet());
final int rangeFrom = from != null && !from.isEmpty() ? Integer.parseInt(from) : 0;
final int rangeTo = to != null && !to.isEmpty() ? Math.min(Integer.parseInt(to), fieldNames.size() - 1) : fieldNames.size() - 1;
final Object[] values = new Object[rangeTo - rangeFrom + 1];
for (int i = rangeFrom; i <= rangeTo; ++i) values[i - rangeFrom] = map.get(fieldNames.get(i));
value = values;
} else if (!indexCondition.isEmpty()) {
// CONDITION
final String conditionFieldName = indexCondition.get(0);
Object conditionFieldValue = ORecordSerializerStringAbstract.getTypeValue(indexCondition.get(1));
if (conditionFieldValue instanceof String)
conditionFieldValue = OIOUtils.getStringContent(conditionFieldValue);
final Object fieldValue = map.get(conditionFieldName);
if (conditionFieldValue != null && fieldValue != null)
conditionFieldValue = OType.convert(conditionFieldValue, fieldValue.getClass());
if (fieldValue == null && !conditionFieldValue.equals("null") || fieldValue != null && !fieldValue.equals(conditionFieldValue))
value = null;
}
} else if (OMultiValue.isMultiValue(value)) {
// MULTI VALUE
final Object index = getIndexPart(iContext, indexPart);
final String indexAsString = index != null ? index.toString() : null;
final List<String> indexParts = OStringSerializerHelper.smartSplit(indexAsString, ',');
final List<String> indexRanges = OStringSerializerHelper.smartSplit(indexAsString, '-');
final List<String> indexCondition = OStringSerializerHelper.smartSplit(indexAsString, '=', ' ');
if (isFieldName(indexAsString)) {
// SINGLE VALUE
if (value instanceof Map<?, ?>)
value = getMapEntry((Map<String, ?>) value, index);
else if (Character.isDigit(indexAsString.charAt(0)))
value = OMultiValue.getValue(value, Integer.parseInt(indexAsString));
else
// FILTER BY FIELD
value = getFieldValue(value, indexAsString, iContext);
} else if (isListOfNumbers(indexParts)) {
// MULTI VALUES
final Object[] values = new Object[indexParts.size()];
for (int i = 0; i < indexParts.size(); ++i) values[i] = OMultiValue.getValue(value, Integer.parseInt(indexParts.get(i)));
if (indexParts.size() > 1) {
value = values;
} else {
value = values[0];
}
} else if (isListOfNumbers(indexRanges)) {
// MULTI VALUES RANGE
String from = indexRanges.get(0);
String to = indexRanges.get(1);
final int rangeFrom = from != null && !from.isEmpty() ? Integer.parseInt(from) : 0;
final int rangeTo = to != null && !to.isEmpty() ? Math.min(Integer.parseInt(to), OMultiValue.getSize(value) - 1) : OMultiValue.getSize(value) - 1;
int arraySize = rangeTo - rangeFrom + 1;
if (arraySize < 0) {
arraySize = 0;
}
final Object[] values = new Object[arraySize];
for (int i = rangeFrom; i <= rangeTo; ++i) values[i - rangeFrom] = OMultiValue.getValue(value, i);
value = values;
} else {
// CONDITION
OSQLPredicate pred = new OSQLPredicate(indexAsString);
final HashSet<Object> values = new LinkedHashSet<Object>();
for (Object v : OMultiValue.getMultiValueIterable(value)) {
if (v instanceof OIdentifiable) {
Object result = pred.evaluate((OIdentifiable) v, (ODocument) ((OIdentifiable) v).getRecord(), iContext);
if (Boolean.TRUE.equals(result)) {
values.add(v);
}
} else if (v instanceof Map) {
ODocument doc = new ODocument().fromMap((Map<String, ? extends Object>) v);
Object result = pred.evaluate(doc, doc, iContext);
if (Boolean.TRUE.equals(result)) {
values.add(v);
}
}
}
if (values.isEmpty())
// RETURNS NULL
value = values;
else if (values.size() == 1)
// RETURNS THE SINGLE ODOCUMENT
value = values.iterator().next();
else
// RETURNS THE FILTERED COLLECTION
value = values;
}
}
} else {
if (fieldName.length() == 0) {
// NO FIELD NAME: THIS IS THE CASE OF NOT USEFUL . AFTER A ] OR .
beginPos = ++nextSeparatorPos;
continue;
}
if (fieldName.startsWith("$"))
value = iContext.getVariable(fieldName);
else if (fieldName.contains("(")) {
boolean executedMethod = false;
if (!firstInChain && fieldName.endsWith("()")) {
OSQLMethod method = OSQLEngine.getInstance().getMethod(fieldName.substring(0, fieldName.length() - 2));
if (method != null) {
value = method.execute(value, currentRecord, iContext, value, new Object[] {});
executedMethod = true;
}
}
if (!executedMethod) {
value = evaluateFunction(value, fieldName, iContext);
}
} else {
final List<String> indexCondition = OStringSerializerHelper.smartSplit(fieldName, '=', ' ');
if (indexCondition.size() == 2) {
final String conditionFieldName = indexCondition.get(0);
Object conditionFieldValue = ORecordSerializerStringAbstract.getTypeValue(indexCondition.get(1));
if (conditionFieldValue instanceof String)
conditionFieldValue = OIOUtils.getStringContent(conditionFieldValue);
value = filterItem(conditionFieldName, conditionFieldValue, value);
} else if (currentRecord != null) {
// GET THE LINKED OBJECT IF ANY
value = getIdentifiableValue(currentRecord, fieldName);
if (value != null && value instanceof ORecord && ((ORecord) value).getInternalStatus() == STATUS.NOT_LOADED)
// RELOAD IT
((ORecord) value).reload();
} else if (value instanceof Map<?, ?>)
value = getMapEntry((Map<String, ?>) value, fieldName);
else if (OMultiValue.isMultiValue(value)) {
final Set<Object> values = new LinkedHashSet<Object>();
for (Object v : OMultiValue.getMultiValueIterable(value, false)) {
final Object item;
if (v instanceof OIdentifiable)
item = getIdentifiableValue((OIdentifiable) v, fieldName);
else if (v instanceof Map)
item = ((Map<?, ?>) v).get(fieldName);
else
item = null;
if (item != null)
if (item instanceof Collection<?>)
values.addAll((Collection<? extends Object>) item);
else
values.add(item);
}
if (values.isEmpty())
value = null;
else
value = values;
} else
return null;
}
}
if (value instanceof OIdentifiable)
currentRecord = (OIdentifiable) value;
else
currentRecord = null;
beginPos = ++nextSeparatorPos;
firstInChain = false;
} while (nextSeparatorPos < fieldNameLength && value != null);
return (RET) value;
}
use of com.orientechnologies.orient.core.record.ORecord in project orientdb by orientechnologies.
the class ODocumentHelper method filterItem.
@SuppressWarnings("unchecked")
protected static Object filterItem(final String iConditionFieldName, final Object iConditionFieldValue, final Object iValue) {
if (iValue instanceof OIdentifiable) {
final ORecord rec = ((OIdentifiable) iValue).getRecord();
if (rec instanceof ODocument) {
final ODocument doc = (ODocument) rec;
Object fieldValue = doc.field(iConditionFieldName);
if (iConditionFieldValue == null)
return fieldValue == null ? doc : null;
fieldValue = OType.convert(fieldValue, iConditionFieldValue.getClass());
if (fieldValue != null && fieldValue.equals(iConditionFieldValue))
return doc;
}
} else if (iValue instanceof Map<?, ?>) {
final Map<String, ?> map = (Map<String, ?>) iValue;
Object fieldValue = getMapEntry(map, iConditionFieldName);
fieldValue = OType.convert(fieldValue, iConditionFieldValue.getClass());
if (fieldValue != null && fieldValue.equals(iConditionFieldValue))
return map;
}
return null;
}
use of com.orientechnologies.orient.core.record.ORecord in project orientdb by orientechnologies.
the class OCommandExecutorSQLSelect method executeSearchRecord.
protected boolean executeSearchRecord(final OIdentifiable id, final OCommandContext iContext, boolean callHooks) {
if (id == null)
return false;
final ORID identity = id.getIdentity();
if (uniqueResult != null) {
if (uniqueResult.containsKey(identity))
return true;
if (identity.isValid())
uniqueResult.put(identity, identity);
}
if (!checkInterruption())
return false;
final LOCKING_STRATEGY contextLockingStrategy = iContext.getVariable("$locking") != null ? (LOCKING_STRATEGY) iContext.getVariable("$locking") : null;
final LOCKING_STRATEGY localLockingStrategy = contextLockingStrategy != null ? contextLockingStrategy : lockingStrategy;
if (localLockingStrategy != null && !(localLockingStrategy == LOCKING_STRATEGY.DEFAULT || localLockingStrategy == LOCKING_STRATEGY.NONE || localLockingStrategy == LOCKING_STRATEGY.EXCLUSIVE_LOCK || localLockingStrategy == LOCKING_STRATEGY.SHARED_LOCK))
throw new IllegalStateException("Unsupported locking strategy " + localLockingStrategy);
if (localLockingStrategy == LOCKING_STRATEGY.SHARED_LOCK) {
id.lock(false);
if (id instanceof ORecord) {
final ORecord record = (ORecord) id;
record.reload(null, true, false);
}
} else if (localLockingStrategy == LOCKING_STRATEGY.EXCLUSIVE_LOCK) {
id.lock(true);
if (id instanceof ORecord) {
final ORecord record = (ORecord) id;
record.reload(null, true, false);
}
}
ORecord record = null;
try {
if (!(id instanceof ORecord)) {
record = getDatabase().load(id.getIdentity(), null, !isUseCache());
if (id instanceof OContextualRecordId && ((OContextualRecordId) id).getContext() != null) {
Map<String, Object> ridContext = ((OContextualRecordId) id).getContext();
for (String key : ridContext.keySet()) {
context.setVariable(key, ridContext.get(key));
}
}
} else {
record = (ORecord) id;
}
iContext.updateMetric("recordReads", +1);
if (record == null)
// SKIP IT
return true;
if (ORecordInternal.getRecordType(record) != ODocument.RECORD_TYPE && checkSkipBlob())
// SKIP binary records in case of projection.
return true;
iContext.updateMetric("documentReads", +1);
iContext.setVariable("current", record);
if (filter(record, iContext)) {
if (callHooks) {
((ODatabaseDocumentInternal) getDatabase()).callbackHooks(ORecordHook.TYPE.BEFORE_READ, record);
((ODatabaseDocumentInternal) getDatabase()).callbackHooks(ORecordHook.TYPE.AFTER_READ, record);
}
if (parallel) {
try {
applyGroupBy(record, iContext);
resultQueue.put(new AsyncResult(record, iContext));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
tmpQueueOffer.incrementAndGet();
} else {
applyGroupBy(record, iContext);
if (!handleResult(record, iContext)) {
// LIMIT REACHED
return false;
}
}
}
} finally {
if (localLockingStrategy != null && record != null && record.isLocked()) {
// CONTEXT LOCK: lock must be released (no matter if filtered or not)
if (localLockingStrategy == LOCKING_STRATEGY.EXCLUSIVE_LOCK || localLockingStrategy == LOCKING_STRATEGY.SHARED_LOCK) {
record.unlock();
}
}
}
return true;
}
Aggregations