in core/src/main/java/com/jetbrains/youtrackdb/internal/core/sql/SQLHelper.java [103:319]
public static Object parseValue(
String iValue, final CommandContext context,
boolean resolveContextVariables,
@Nullable SchemaClass schemaClass,
@Nullable SchemaProperty schemaProperty, @Nullable PropertyTypeInternal propertyType,
@Nullable PropertyTypeInternal parentProperty) {
if (iValue == null) {
return null;
}
if (propertyType == null && schemaProperty != null) {
propertyType = PropertyTypeInternal.convertFromPublicType(schemaProperty.getType());
}
iValue = iValue.trim();
Object fieldValue = VALUE_NOT_PARSED;
var session = context.getDatabaseSession();
if (iValue.isEmpty()) {
return iValue;
}
if (iValue.charAt(0) == '\'' && iValue.charAt(iValue.length() - 1) == '\''
|| iValue.charAt(0) == '\"'
&& iValue.charAt(iValue.length() - 1) == '\"')
// STRING
{
fieldValue = IOUtils.getStringContent(iValue);
} else if (iValue.charAt(0) == StringSerializerHelper.LIST_BEGIN
&& iValue.charAt(iValue.length() - 1) == StringSerializerHelper.LIST_END) {
// COLLECTION/ARRAY
final var items =
StringSerializerHelper.smartSplit(
iValue.substring(1, iValue.length() - 1), StringSerializerHelper.RECORD_SEPARATOR);
List<Object> coll;
if (propertyType != null) {
if (propertyType.isMultiValue()) {
if (propertyType.isLink()) {
//noinspection rawtypes,unchecked
coll = (List) session.newLinkList();
} else {
coll = session.newEmbeddedList();
}
} else {
throw new IllegalArgumentException(
"Value is a list but property is not a collection : " + iValue);
}
} else {
coll = session.newEmbeddedList();
}
if (schemaProperty != null) {
var linkedType = PropertyTypeInternal.convertFromPublicType(schemaProperty.getLinkedType());
var linkedClass = schemaProperty.getLinkedClass();
for (var item : items) {
coll.add(parseValue(item, context, resolveContextVariables,
linkedClass,
null, linkedType, propertyType));
}
} else {
for (var item : items) {
coll.add(parseValue(item, context, resolveContextVariables, null, null, null,
null));
}
}
fieldValue = coll;
} else if (iValue.charAt(0) == StringSerializerHelper.MAP_BEGIN
&& iValue.charAt(iValue.length() - 1) == StringSerializerHelper.MAP_END) {
// map or entity
if (schemaClass != null) {
Entity entity;
if (parentProperty != null) {
if (parentProperty.isEmbedded()) {
entity = session.newEmbeddedEntity(schemaClass);
} else if (parentProperty.isLink()) {
entity = session.newEntity(schemaClass);
} else {
throw new IllegalArgumentException(
"Property is not a link or embedded : " + parentProperty);
}
} else {
entity = session.newEntity(schemaClass);
}
fieldValue = JSONSerializerJackson.INSTANCE.fromString(session, iValue, (RecordAbstract) entity);
} else {
final var items =
StringSerializerHelper.smartSplit(
iValue.substring(1, iValue.length() - 1), StringSerializerHelper.RECORD_SEPARATOR);
Map<String, Object> map;
if (propertyType != null) {
if (propertyType.isMultiValue()) {
if (propertyType.isLink()) {
//noinspection unchecked,rawtypes
map = (Map) session.newLinkMap();
} else {
map = session.newEmbeddedMap();
}
} else {
throw new IllegalArgumentException(
"Value is a map but property is not a collection : " + iValue);
}
} else {
map = session.newEmbeddedMap();
}
for (var item : items) {
final var parts =
StringSerializerHelper.smartSplit(item, StringSerializerHelper.ENTRY_SEPARATOR);
if (parts.size() != 2) {
throw new CommandSQLParsingException(context.getDatabaseSession().getDatabaseName(),
"Map found but entries are not defined as <key>:<value>");
}
Object key;
Object value;
if (schemaProperty != null) {
var linkedType = PropertyTypeInternal.convertFromPublicType(
schemaProperty.getLinkedType());
var linkedClass = schemaProperty.getLinkedClass();
key = parseValue(parts.get(0), context, resolveContextVariables,
null,
null, PropertyTypeInternal.STRING, propertyType);
value = parseValue(parts.get(1), context, resolveContextVariables,
linkedClass,
null, linkedType, propertyType);
} else {
key = parseValue(parts.get(0), context, resolveContextVariables,
null, null, null, null);
value = parseValue(parts.get(1), context, resolveContextVariables,
null, null, null, null);
}
if (VALUE_NOT_PARSED == value) {
value = new SQLPredicate(context, parts.get(1)).evaluate(context);
}
if (value instanceof String) {
value = StringSerializerHelper.decode(value.toString());
}
map.put(key.toString(), value);
}
if (map.containsKey(EntityHelper.ATTRIBUTE_TYPE))
// entity
{
Entity entity;
if (parentProperty != null) {
if (parentProperty.isEmbedded()) {
entity = session.newEmbeddedEntity();
} else if (parentProperty.isLink()) {
entity = session.newEntity();
} else {
throw new IllegalArgumentException(
"Property is not a link or embedded : " + parentProperty);
}
} else {
entity = session.newEntity();
}
fieldValue = JSONSerializerJackson.INSTANCE.fromString(session, iValue, (RecordAbstract) entity);
} else {
fieldValue = map;
}
}
} else if (iValue.charAt(0) == StringSerializerHelper.EMBEDDED_BEGIN
&& iValue.charAt(iValue.length() - 1) == StringSerializerHelper.EMBEDDED_END) {
// SUB-COMMAND
throw new UnsupportedOperationException();
} else if (RecordIdInternal.isA(iValue))
// RID
{
fieldValue = RecordIdInternal.fromString(iValue.trim(), false);
} 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 var func = SQLHelper.getFunction(context.getDatabaseSession(), null,
iValue);
if (func != null) {
fieldValue = func.execute(null, null, null, context);
}
} else if (resolveContextVariables && iValue.charAt(0) == '$') {
fieldValue = context.getVariable(iValue);
} else {
final var v = parseStringNumber(iValue);
if (v != null) {
fieldValue = v;
}
}
}
return fieldValue;
}