public static IEnumerable <QueryCondition> ParseQueryConditions(this string query) { var stringSpan = new StringSpan(query); stringSpan.MoveToTheNextStartOfString(); while (!stringSpan.Eof) { var fieldName = stringSpan.ReadNextString(); var operation = stringSpan.ReadOperation(); if (operation == QueryOperation.In) { var value = stringSpan.ReadInValues(); yield return(new QueryCondition { FieldName = fieldName, Values = value.ToArray(), Operation = operation }); } else { var value = stringSpan.ReadNextString(); yield return(new QueryCondition { FieldName = fieldName, Values = value.ToSingleArray(), Operation = operation }); } stringSpan.MoveToTheNextStartOfString(); if (stringSpan.Eof) { break; } var logicalOperator = stringSpan.ReadNextString(); if (logicalOperator.ToLower() != "and") { throw new Exception("Only and logical operation is supported for a while"); } } }
private static IEnumerable <string> ReadInValues(this StringSpan stringSpan) { stringSpan.MoveToTheNextStartOfString(); var arrayIsOpened = stringSpan.CurrentChar == '['; if (!arrayIsOpened) { throw new Exception("Invalid int operation at position: " + stringSpan.PositionStart); } stringSpan.MoveStartPosition(1); stringSpan.SyncEndWithStart(); while (!stringSpan.Eof) { var value = stringSpan.ReadNextStringFromArray(); yield return(value); stringSpan.SyncStartWithEnd(); if (stringSpan.CurrentChar <= ' ') { stringSpan.MoveToTheNextStartOfString(); stringSpan.SyncEndWithStart(); } if (stringSpan.CurrentChar == ']') { stringSpan.MoveStartPosition(1); stringSpan.SyncEndWithStart(); break; } if (stringSpan.CurrentChar != ',') { stringSpan.MoveStartPosition(EscapeSequence, c => c == ',' || c == ']'); } stringSpan.MoveStartPosition(1); stringSpan.SyncEndWithStart(); } }
private static string ReadNextString(this StringSpan stringSpan) { stringSpan.MoveToTheNextStartOfString(); var isString = stringSpan.CurrentChar == CharToEscape; if (isString) { stringSpan.MoveEndPosition(EscapeSequence, c => c == CharToEscape, 1); stringSpan.MoveEndPosition(1); return(stringSpan.GetCurrentValue(EscapeSequence, StringToEscape)); } stringSpan.MoveEndPosition(EscapeSequence, c => c <= ' '); return(stringSpan.GetCurrentValue()); }