use of com.orientechnologies.orient.core.sql.filter.OSQLPredicate 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 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 (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 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, '=', ' ');
final Map<String, ?> map = (Map<String, ?>) value;
if (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);
}
}
}
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.sql.filter.OSQLPredicate in project orientdb by orientechnologies.
the class OSQLFunctionRuntime method execute.
/**
* Execute a function.
*
* @param iCurrentRecord
* Current record
* @param iCurrentResult
* TODO
* @param iContext
* @return
*/
public Object execute(final Object iThis, final OIdentifiable iCurrentRecord, final Object iCurrentResult, final OCommandContext iContext) {
// RESOLVE VALUES USING THE CURRENT RECORD
for (int i = 0; i < configuredParameters.length; ++i) {
runtimeParameters[i] = configuredParameters[i];
if (configuredParameters[i] instanceof OSQLFilterItemField) {
runtimeParameters[i] = ((OSQLFilterItemField) configuredParameters[i]).getValue(iCurrentRecord, iCurrentResult, iContext);
} else if (configuredParameters[i] instanceof OSQLFunctionRuntime)
runtimeParameters[i] = ((OSQLFunctionRuntime) configuredParameters[i]).execute(iThis, iCurrentRecord, iCurrentResult, iContext);
else if (configuredParameters[i] instanceof OSQLFilterItemVariable) {
runtimeParameters[i] = ((OSQLFilterItemVariable) configuredParameters[i]).getValue(iCurrentRecord, iCurrentResult, iContext);
} else if (configuredParameters[i] instanceof OCommandSQL) {
try {
runtimeParameters[i] = ((OCommandSQL) configuredParameters[i]).setContext(iContext).execute();
} catch (OCommandExecutorNotFoundException e) {
// TRY WITH SIMPLE CONDITION
final String text = ((OCommandSQL) configuredParameters[i]).getText();
final OSQLPredicate pred = new OSQLPredicate(text);
runtimeParameters[i] = pred.evaluate(iCurrentRecord instanceof ORecord ? (ORecord) iCurrentRecord : null, (ODocument) iCurrentResult, iContext);
// REPLACE ORIGINAL PARAM
configuredParameters[i] = pred;
}
} else if (configuredParameters[i] instanceof OSQLPredicate)
runtimeParameters[i] = ((OSQLPredicate) configuredParameters[i]).evaluate(iCurrentRecord.getRecord(), (iCurrentRecord instanceof ODocument ? (ODocument) iCurrentResult : null), iContext);
else if (configuredParameters[i] instanceof String) {
if (configuredParameters[i].toString().startsWith("\"") || configuredParameters[i].toString().startsWith("'"))
runtimeParameters[i] = OIOUtils.getStringContent(configuredParameters[i]);
}
}
if (function.getMaxParams() == -1 || function.getMaxParams() > 0) {
if (runtimeParameters.length < function.getMinParams() || (function.getMaxParams() > -1 && runtimeParameters.length > function.getMaxParams()))
throw new OCommandExecutionException("Syntax error: function '" + function.getName() + "' needs " + (function.getMinParams() == function.getMaxParams() ? function.getMinParams() : function.getMinParams() + "-" + function.getMaxParams()) + " argument(s) while has been received " + runtimeParameters.length);
}
final Object functionResult = function.execute(iThis, iCurrentRecord, iCurrentResult, runtimeParameters, iContext);
if (functionResult instanceof OAutoConvertToRecord)
// FORCE AVOIDING TO CONVERT IN RECORD
((OAutoConvertToRecord) functionResult).setAutoConvertToRecord(false);
return transformValue(iCurrentRecord, iContext, functionResult);
}
use of com.orientechnologies.orient.core.sql.filter.OSQLPredicate in project orientdb by orientechnologies.
the class OSQLHelper method parseValue.
/**
* Convert fields from text to real value. Supports: String, RID, Boolean, Float, Integer and NULL.
*
* @param iValue
* Value to convert.
* @return The value converted if recognized, otherwise VALUE_NOT_PARSED
*/
public static Object parseValue(String iValue, final OCommandContext iContext) {
if (iValue == null)
return null;
iValue = iValue.trim();
Object fieldValue = VALUE_NOT_PARSED;
if (iValue.startsWith("'") && iValue.endsWith("'") || iValue.startsWith("\"") && iValue.endsWith("\""))
// STRING
fieldValue = OStringSerializerHelper.decode(OIOUtils.getStringContent(iValue));
else if (iValue.charAt(0) == OStringSerializerHelper.LIST_BEGIN && iValue.charAt(iValue.length() - 1) == OStringSerializerHelper.LIST_END) {
// COLLECTION/ARRAY
final List<String> items = OStringSerializerHelper.smartSplit(iValue.substring(1, iValue.length() - 1), OStringSerializerHelper.RECORD_SEPARATOR);
final List<Object> coll = new ArrayList<Object>();
for (String item : items) {
coll.add(parseValue(item, iContext));
}
fieldValue = coll;
} else if (iValue.charAt(0) == OStringSerializerHelper.MAP_BEGIN && iValue.charAt(iValue.length() - 1) == OStringSerializerHelper.MAP_END) {
// MAP
final List<String> items = OStringSerializerHelper.smartSplit(iValue.substring(1, iValue.length() - 1), OStringSerializerHelper.RECORD_SEPARATOR);
final Map<Object, Object> map = new HashMap<Object, Object>();
for (String item : items) {
final List<String> parts = OStringSerializerHelper.smartSplit(item, OStringSerializerHelper.ENTRY_SEPARATOR);
if (parts == null || parts.size() != 2)
throw new OCommandSQLParsingException("Map found but entries are not defined as <key>:<value>");
Object key = OStringSerializerHelper.decode(parseValue(parts.get(0), iContext).toString());
Object value = parseValue(parts.get(1), iContext);
if (VALUE_NOT_PARSED == value) {
value = new OSQLPredicate(parts.get(1)).evaluate(iContext);
}
map.put(key, value);
}
if (map.containsKey(ODocumentHelper.ATTRIBUTE_TYPE))
// IT'S A DOCUMENT
// TODO: IMPROVE THIS CASE AVOIDING DOUBLE PARSING
fieldValue = new ODocument().fromJSON(iValue);
else
fieldValue = map;
} else if (iValue.charAt(0) == OStringSerializerHelper.EMBEDDED_BEGIN && iValue.charAt(iValue.length() - 1) == OStringSerializerHelper.EMBEDDED_END) {
// SUB-COMMAND
fieldValue = new OCommandSQL(iValue.substring(1, iValue.length() - 1));
((OCommandSQL) fieldValue).getContext().setParent(iContext);
} else if (ORecordId.isA(iValue))
// RID
fieldValue = new ORecordId(iValue.trim());
else {
if (iValue.equalsIgnoreCase("null"))
// NULL
fieldValue = null;
else if (iValue.equalsIgnoreCase("not null"))
// NULL
fieldValue = NOT_NULL;
else if (iValue.equalsIgnoreCase("defined"))
// NULL
fieldValue = DEFINED;
else if (iValue.equalsIgnoreCase("true"))
// BOOLEAN, TRUE
fieldValue = Boolean.TRUE;
else if (iValue.equalsIgnoreCase("false"))
// BOOLEAN, FALSE
fieldValue = Boolean.FALSE;
else if (iValue.startsWith("date(")) {
final OSQLFunctionRuntime func = OSQLHelper.getFunction(null, iValue);
if (func != null) {
fieldValue = func.execute(null, null, null, iContext);
}
} else {
final Object v = parseStringNumber(iValue);
if (v != null)
fieldValue = v;
}
}
return fieldValue;
}
use of com.orientechnologies.orient.core.sql.filter.OSQLPredicate in project orientdb by orientechnologies.
the class OCommandExecutorScript method getValue.
private Object getValue(final String iValue, final ODatabaseDocument db) {
Object lastResult = null;
boolean recordResultSet = true;
if (iValue.equalsIgnoreCase("NULL"))
lastResult = null;
else if (iValue.startsWith("[") && iValue.endsWith("]")) {
// ARRAY - COLLECTION
final List<String> items = new ArrayList<String>();
OStringSerializerHelper.getCollection(iValue, 0, items);
final List<Object> result = new ArrayList<Object>(items.size());
for (int i = 0; i < items.size(); ++i) {
String item = items.get(i);
result.add(getValue(item, db));
}
lastResult = result;
checkIsRecordResultSet(lastResult);
} else if (iValue.startsWith("{") && iValue.endsWith("}")) {
// MAP
final Map<String, String> map = OStringSerializerHelper.getMap(iValue);
final Map<Object, Object> result = new HashMap<Object, Object>(map.size());
for (Map.Entry<String, String> entry : map.entrySet()) {
// KEY
String stringKey = entry.getKey();
if (stringKey == null)
continue;
stringKey = stringKey.trim();
Object key;
if (stringKey.startsWith("$"))
key = getContext().getVariable(stringKey);
else
key = stringKey;
if (OMultiValue.isMultiValue(key) && OMultiValue.getSize(key) == 1)
key = OMultiValue.getFirstValue(key);
// VALUE
String stringValue = entry.getValue();
if (stringValue == null)
continue;
stringValue = stringValue.trim();
Object value;
if (stringValue.toString().startsWith("$"))
value = getContext().getVariable(stringValue);
else
value = stringValue;
result.put(key, value);
}
lastResult = result;
checkIsRecordResultSet(lastResult);
} else if (iValue.startsWith("\"") && iValue.endsWith("\"") || iValue.startsWith("'") && iValue.endsWith("'")) {
lastResult = new OContextVariableResolver(context).parse(OIOUtils.getStringContent(iValue));
checkIsRecordResultSet(lastResult);
} else if (iValue.startsWith("(") && iValue.endsWith(")"))
lastResult = executeCommand(iValue.substring(1, iValue.length() - 1), db);
else {
lastResult = new OSQLPredicate(iValue).evaluate(context);
}
// END OF THE SCRIPT
return lastResult;
}
use of com.orientechnologies.orient.core.sql.filter.OSQLPredicate in project orientdb by orientechnologies.
the class TraverseTest method traverseAPIandSQLIterating.
@Test
public void traverseAPIandSQLIterating() {
int cycles = 0;
for (OIdentifiable id : new OTraverse().target(database.browseClass("Movie").iterator()).predicate(new OSQLPredicate("$depth <= 2"))) {
cycles++;
}
Assert.assertTrue(cycles > 0);
}
Aggregations