예제 #1
0
        public PredicateStep ParsePredicates(string query)
        {
            var predicates = new List <string>();


            List <string> queryParts = SplitOnSeparatorsExceptQuotesAndParantheses(query, new char[] { ' ', '\r', '\n' });

            var whereClauseIndex = queryParts.IndexOf("where");

            int?operatorIndex = null;

            if (whereClauseIndex != -1)
            {
                string firstPredicate = queryParts[whereClauseIndex + 0] + " " +
                                        queryParts[whereClauseIndex + 1] + " " +
                                        queryParts[whereClauseIndex + 2] + " " +
                                        queryParts[whereClauseIndex + 3];

                predicates.Add(firstPredicate);

                operatorIndex = whereClauseIndex + 4;

                HashSet <string> andOrOps = new HashSet <string> {
                    "or", "and"
                };

                while (operatorIndex < queryParts.Count() && andOrOps.Contains(queryParts[(int)operatorIndex].ToLower()))
                {
                    string currentPredicate = queryParts[(int)operatorIndex + 0] + " " +
                                              queryParts[(int)operatorIndex + 1] + " " +
                                              queryParts[(int)operatorIndex + 2] + " " +
                                              queryParts[(int)operatorIndex + 3];

                    predicates.Add(currentPredicate);

                    operatorIndex += 4;
                }
            }

            PredicateStep predicateStep = new PredicateStep
            {
                Predicates    = predicates,
                HasPredicates = true,
                OperatorIndex = operatorIndex,
                QueryParts    = queryParts
            };

            return(predicateStep);
        }
예제 #2
0
        public List <List <IComparable> > RunQuery(string query)
        {
            var tableName = _selectParser.GetTableName(query);

            var tableDef = _schemaFetcher.GetTableDefinition(tableName);

            List <SelectColumnDto> columns = _selectParser.GetColumns(query);

            IEnumerable <SelectColumnDto> selects = tableDef.ColumnDefinitions
                                                    .Select(x => new SelectColumnDto(x)).OrderBy(x => x.Index).ToList();

            foreach (var select in selects)
            {
                if (columns.Select(x => x.ColumnName).Contains(select.ColumnName) || columns.First().ColumnName == "*")
                {
                    select.IsInSelect = true;

                    SelectColumnDto firstMatchingColumn = columns.FirstOrDefault(x => x.ColumnName == select.ColumnName);

                    if (firstMatchingColumn != null)
                    {
                        select.AggregateFunction = firstMatchingColumn.AggregateFunction;
                    }
                }
            }

            PredicateStep predicateStep = _selectParser.ParsePredicates(query);

            predicateStep = _selectParser.GetPredicateTrailers(predicateStep, query);

            var predicateOperations = _predicateParser.BuildPredicateOperations(tableDef, predicateStep.Predicates);

            var readTransaction = new ReadTransaction
            {
                TableDefinition     = tableDef,
                Selects             = selects,
                PredicateOperations = predicateOperations
            };

            var rows = _lockManager.ProcessReadTransaction(readTransaction).Rows;

            if (predicateStep.PredicateTrailer != null && predicateStep.PredicateTrailer.Any())
            {
                rows = ApplyGroupByOperation(selects, predicateStep, rows);
                rows = ProcessPostPredicateOrderBy(selects, predicateStep, rows);
            }

            return(rows);
        }
예제 #3
0
        public PredicateStep GetPredicateTrailers(PredicateStep predicateStep, string query)
        {
            int startTrailingPredicate = predicateStep.OperatorIndex == null?
                                         IndexOfTableName(query, GetTableName(query)) + 1 : (int)predicateStep.OperatorIndex;

            List <string> predicateTrailersUnparsed = string.Join(' ',
                                                                  predicateStep.QueryParts.GetRange(startTrailingPredicate, predicateStep.QueryParts.Count() - startTrailingPredicate))
                                                      .ToLower()
                                                      .Split(new[] { " ", ",", "by" }, StringSplitOptions.RemoveEmptyEntries)
                                                      .Where(x => !string.IsNullOrEmpty(x)).ToList();

            predicateStep.PredicateTrailer = ParsePredicateTrailers(predicateTrailersUnparsed);

            return(predicateStep);
        }
예제 #4
0
        private List <List <IComparable> > ApplyGroupByOperation(IEnumerable <SelectColumnDto> selects, PredicateStep predicateStep, List <List <IComparable> > rows)
        {
            Func <IComparable,
                  List <List <IComparable> >,
                  IEnumerable <KeyValuePair <int,
                                             Func <List <IComparable>, IComparable> > >,
                  List <IComparable> > processGrouping = ReturnGroupedList;


            //first, group by
            var groupByClause = predicateStep.PredicateTrailer.Where(x => x.Contains("group")).FirstOrDefault();

            if (groupByClause == null)
            {
                return(rows);
            }

            var groupParts = groupByClause.Split(' ');

            if (groupParts.Count() > 2)
            {
                throw new Exception(ErrorMessages.One_Column_Max_In_Group_By);
            }

            string groupingColumn = groupParts[1].ToLower();

            selects = selects.Where(x => x.IsInSelect);

            int groupColumnIndex = selects.Select(x => x.ColumnName.ToLower()).ToList().IndexOf(groupingColumn);

            var columnIndexToAggregateFunction = selects.Select((x, i) => new KeyValuePair <int, Func <List <IComparable>, IComparable> >(i, x.AggregateFunction)).ToList();

            var groupings = rows.GroupBy(x => x[groupColumnIndex]);

            var aggregatedRows = new List <List <IComparable> >();


            foreach (var grouping in groupings)
            {
                List <List <IComparable> > groupingValues = grouping.Select(x => x).ToList();

                List <IComparable> groupedRow = ReturnGroupedList(grouping.Key, groupingValues, columnIndexToAggregateFunction);

                aggregatedRows.Add(groupedRow);
            }

            return(aggregatedRows);
        }
예제 #5
0
        private List <List <IComparable> > ProcessPostPredicateOrderBy(IEnumerable <SelectColumnDto> selects, PredicateStep predicateStep, List <List <IComparable> > rows)
        {
            //first, group by
            var orderByClause = predicateStep.PredicateTrailer.FirstOrDefault(x => x.Contains("order"));

            if (orderByClause == null)
            {
                return(rows);
            }

            var orderParts = orderByClause.Split(' ');

            //storing an inenumerable in a temporary list and then adding the "then by"
            //clause does not work. changes to an ienumerable are not guaranteed to persist
            switch (orderParts.Count())
            {
            case 2:
                var select = selects.Where(x => x.ColumnName == orderParts[1]).FirstOrDefault();
                rows = rows.OrderBy(x => x[select.Index]).ToList();
                break;

            case 3:
                var selectCase2   = selects.Where(x => x.ColumnName == orderParts[1]).FirstOrDefault();
                var selectCase2_2 = selects.Where(x => x.ColumnName == orderParts[2]).FirstOrDefault();
                rows = rows.OrderBy(x => x[selectCase2.Index]).ThenBy(x => x[selectCase2_2.Index]).ToList();
                break;

            case 4:
                var selectCase3   = selects.Where(x => x.ColumnName == orderParts[1]).FirstOrDefault();
                var selectCase3_2 = selects.Where(x => x.ColumnName == orderParts[2]).FirstOrDefault();
                var selectCase3_3 = selects.Where(x => x.ColumnName == orderParts[3]).FirstOrDefault();
                rows = rows.OrderBy(x => x[selectCase3.Index]).ThenBy(x => x[selectCase3_2.Index]).
                       ThenBy(x => x[selectCase3_3.Index]).ToList();
                break;

            default:
                throw new Exception(ErrorMessages.Three_Column_Max_In_Order_By);
            }

            return(rows);
        }
예제 #6
0
        private object RunUpdateStatement(string sql)
        {
            List <KeyValuePair <string, string> > columnToValue = _updateParser.GetUpdates(sql);

            var tableName = _updateParser.GetTableName(sql);

            var tableDef = _schemaFetcher.GetTableDefinition(tableName);

            PredicateStep predicateStep = _updateParser.ParsePredicates(sql);

            var predicateOperations = _predicateParser.BuildPredicateOperations(tableDef, predicateStep.Predicates);

            var selects = tableDef.ColumnDefinitions
                          .Select(x => new SelectColumnDto(x)).OrderBy(x => x.Index).ToList();

            selects.ForEach(x => x.IsInSelect = true);

            var readTransaction = new ReadTransaction
            {
                TableDefinition     = tableDef,
                Selects             = selects,
                PredicateOperations = predicateOperations
            };

            var selectData = _lockManager.ProcessReadTransaction(readTransaction);

            var columnDefs = new List <ColumnDefinition>();

            foreach (var col in columnToValue)
            {
                var colDef = tableDef.ColumnDefinitions.Where(x => x.ColumnName.ToLower() == col.Key).Single();

                columnDefs.Add(colDef);
            }

            Dictionary <int, IComparable> indexToValue = new Dictionary <int, IComparable>();

            foreach (var columnNameToValue in columnToValue)
            {
                var colDef = tableDef.ColumnDefinitions.Single(x => x.ColumnName.ToLower() == columnNameToValue.Key);

                indexToValue[colDef.Index] = _stringParser.ConvertToType(columnNameToValue.Value, colDef.Type);
            }

            foreach (var colDef in columnDefs)
            {
                foreach (var row in selectData.Rows)
                {
                    row[colDef.Index] = indexToValue[colDef.Index];
                }
            }

            //each row is updated as its own transaction - not ideal for update - not atomic
            for (int i = 0; i < selectData.Rows.Count; i++)
            {
                var writeTransaction = new WriteTransaction
                {
                    Data              = selectData.Rows[i].ToArray(),
                    TableDefinition   = tableDef,
                    AddressToWriteTo  = selectData.RowLocations[i],
                    Query             = sql,
                    UpdateObjectCount = false
                };

                _lockManager.ProcessWriteTransaction(writeTransaction);
            }

            return(new object());
        }