public void Dispose() { foreach (var dbreader in TableReaders) { dbreader.Dispose(); } TableReaders.Clear(); }
/// <summary> /// execute query to get result rows /// </summary> /// <returns></returns> public IEnumerable <object[]> Rows() { //only for one table for now var table = Query.Tables.First(); var handler = TableReaders.FirstOrDefault(r => r.Table.Name == table.Name); var collection = Enumerable.Empty <int>(); if (!Query.Where.Defined) { //no WHERE, ALL table //return the full table rows //later mix all tables according to FROM tables and SELECT rows var type = handler.GetType(); var method = type.GetMethod(nameof(DbTableDataReader.Rows), BindingFlags.Instance | BindingFlags.NonPublic); MethodInfo genMethod = method.MakeGenericMethod(handler.Table.Type); //get first key var key = handler.Table.Columns.FirstOrDefault(c => c.Key); collection = (IEnumerable <int>)genMethod.Invoke(handler, new object[] { key }); } else { //filtered table collection = ExecuteWhere(Query.Where.Root as DbQuery.ExpressionOperator); } //TOP if (Query.Select.Top > 0) { collection = collection.Take(Query.Select.Top); } //process collection of offsets if (Query.Select.IsFunction) { RowCount = 1; //query functions contains only one column in SELECT var column = SelectIndexColumns.Columns.First(); var valueType = column.Type; if (Query.Select.Function == TokenType.COUNT) { //Enumerable.Count() returns an int yield return(new object[] { collection.Count() }); } else { if (!valueType.IsNumeric()) { throw new ArgumentException($"function {Query.Select.Function} column type must be numeric"); } MethodInfo method = this.GetType().GetMethod(nameof(ExecuteFunction), BindingFlags.Instance | BindingFlags.NonPublic); MethodInfo genMethod = method.MakeGenericMethod(Type.GetType($"System.{valueType}")); var result = genMethod.Invoke(this, new object[] { handler, valueType, collection }); yield return(new object[] { result }); } } else { //output all rows filtered or not RowCount = 0; foreach (var offset in collection) { RowCount++; yield return(handler.ReadRecord(offset)); } } }