Search in sources :

Example 11 with ORecord

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;
}
Also used : ORecordOperation(com.orientechnologies.orient.core.db.record.ORecordOperation) ByteArrayInputStream(java.io.ByteArrayInputStream) ORecord(com.orientechnologies.orient.core.record.ORecord) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) OLiveResultListener(com.orientechnologies.orient.core.sql.query.OLiveResultListener) ORecordId(com.orientechnologies.orient.core.id.ORecordId)

Example 12 with ORecord

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);
}
Also used : OIOException(com.orientechnologies.common.io.OIOException) IOException(java.io.IOException) OChannelBinaryAsynchClient(com.orientechnologies.orient.client.binary.OChannelBinaryAsynchClient) OCommandRequestAsynch(com.orientechnologies.orient.core.command.OCommandRequestAsynch) OLiveResultListener(com.orientechnologies.orient.core.sql.query.OLiveResultListener) ODatabaseDocumentInternal(com.orientechnologies.orient.core.db.ODatabaseDocumentInternal) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ORecordOperation(com.orientechnologies.orient.core.db.record.ORecordOperation) ODatabaseDocument(com.orientechnologies.orient.core.db.document.ODatabaseDocument) OLiveQuery(com.orientechnologies.orient.core.sql.query.OLiveQuery) ORecord(com.orientechnologies.orient.core.record.ORecord) OSerializableStream(com.orientechnologies.orient.core.serialization.OSerializableStream) ODocument(com.orientechnologies.orient.core.record.impl.ODocument)

Example 13 with ORecord

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;
}
Also used : OCommandContext(com.orientechnologies.orient.core.command.OCommandContext) OSQLPredicate(com.orientechnologies.orient.core.sql.filter.OSQLPredicate) ORecord(com.orientechnologies.orient.core.record.ORecord) OSQLMethod(com.orientechnologies.orient.core.sql.method.OSQLMethod)

Example 14 with ORecord

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;
}
Also used : ORecord(com.orientechnologies.orient.core.record.ORecord)

Example 15 with ORecord

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;
}
Also used : OContextualRecordId(com.orientechnologies.orient.core.id.OContextualRecordId) ORecord(com.orientechnologies.orient.core.record.ORecord) LOCKING_STRATEGY(com.orientechnologies.orient.core.storage.OStorage.LOCKING_STRATEGY) ORID(com.orientechnologies.orient.core.id.ORID) ODatabaseDocumentInternal(com.orientechnologies.orient.core.db.ODatabaseDocumentInternal)

Aggregations

ORecord (com.orientechnologies.orient.core.record.ORecord)194 ODocument (com.orientechnologies.orient.core.record.impl.ODocument)91 ORecordId (com.orientechnologies.orient.core.id.ORecordId)40 OIdentifiable (com.orientechnologies.orient.core.db.record.OIdentifiable)36 ODatabaseDocumentTx (com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx)27 ORID (com.orientechnologies.orient.core.id.ORID)27 IOException (java.io.IOException)21 OException (com.orientechnologies.common.exception.OException)17 Test (org.junit.Test)16 ODatabaseDocument (com.orientechnologies.orient.core.db.document.ODatabaseDocument)15 ORecordOperation (com.orientechnologies.orient.core.db.record.ORecordOperation)15 ORecordNotFoundException (com.orientechnologies.orient.core.exception.ORecordNotFoundException)15 OClass (com.orientechnologies.orient.core.metadata.schema.OClass)14 OConcurrentModificationException (com.orientechnologies.orient.core.exception.OConcurrentModificationException)10 ArrayList (java.util.ArrayList)9 Map (java.util.Map)9 ONeedRetryException (com.orientechnologies.common.concur.ONeedRetryException)8 ODatabaseDocumentInternal (com.orientechnologies.orient.core.db.ODatabaseDocumentInternal)8 Test (org.testng.annotations.Test)8 OIOException (com.orientechnologies.common.io.OIOException)7