DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
QueryResult.cs
Go to the documentation of this file.
1 //
2 // Copyright 2010-2015 Deveel
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 using System;
18 using System.Collections.Generic;
19 using System.Resources;
20 
21 using Deveel.Data.Sql;
22 using Deveel.Data.Sql.Tables;
23 
24 namespace Deveel.Data.Protocol {
25  public sealed class QueryResult : IDisposable {
27 
28  private bool resultIsSimpleEnum;
29  private IList<int> rowIndexMap;
30 
31  private int locked;
32 
33  internal QueryResult(SqlQuery query, ITable result) {
34  Query = query;
35  Result = result;
36  FormColumns(Result);
37 
38  locked = 0;
39  }
40 
41  private void FormColumns(ITable result) {
42  // HACK: Read the contents of the first row so that we can pick up
43  // any errors with reading, and also to fix the 'uniquekey' bug
44  // that causes a new transaction to be started if 'uniquekey' is
45  // a column and the value is resolved later.
46  var columnCount = result.TableInfo.ColumnCount;
47  using (var rowEnum = result.GetEnumerator()) {
48  if (rowEnum.MoveNext()) {
49  int rowIndex = rowEnum.Current.RowId.RowNumber;
50  for (int c = 0; c < columnCount; ++c) {
51  result.GetValue(rowIndex, c);
52  }
53  }
54 
55  // If simple enum, note it here
56  resultIsSimpleEnum = (rowEnum is SimpleRowEnumerator);
57  }
58 
59  // Build 'row_index_map' if not a simple enum
60  if (!resultIsSimpleEnum) {
61  rowIndexMap = new List<int>(result.RowCount);
62 
63  var en = result.GetEnumerator();
64  while (en.MoveNext()) {
65  rowIndexMap.Add(en.Current.RowId.RowNumber);
66  }
67  }
68 
69  // This is a safe operation provides we are shared.
70  // Copy all the TableField columns from the table to our own
71  // QueryResultColumn array, naming each column by what is returned from
72  // the 'GetResolvedVariable' method.
73  int colCount = result.TableInfo.ColumnCount;
74  columns = new QueryResultColumn[colCount];
75  for (int i = 0; i < colCount; ++i) {
76  var v = result.GetResolvedColumnName(i);
77  string fieldName;
78  if (v.ParentName == null) {
79  // This means the column is an alias
80  fieldName = String.Format("@a{0}", v.Name);
81  } else {
82  // This means the column is an schema/table/column reference
83  fieldName = String.Format("@f{0}", v);
84  }
85 
86  columns[i] = new QueryResultColumn(fieldName, result.TableInfo[i]);
87  }
88  }
89 
90  public SqlQuery Query { get; private set; }
91 
92  public ITable Result { get; private set; }
93 
94  public int RowCount {
95  get { return Result.RowCount; }
96  }
97 
98  public int ColumnCount {
99  get { return Result.TableInfo.ColumnCount; }
100  }
101 
102  public QueryResultColumn GetColumn(int columnOffset) {
103  if (columnOffset < 0 || columnOffset >= ColumnCount)
104  throw new ArgumentOutOfRangeException("columnOffset");
105 
106  return columns[columnOffset];
107  }
108 
109  public void LockRoot() {
110  Result.Lock();
111  locked++;
112  }
113 
114  public void Release() {
115  Result.Release();
116  --locked;
117  }
118 
119  public void Dispose() {
120  if (locked > 0) {
121  Release();
122  }
123 
124  Result = null;
125  Query = null;
126  columns = null;
127  rowIndexMap = null;
128  }
129 
130  public DataObject GetValue(int rowIndex, int columnIndex) {
131  if (locked <= 0)
132  throw new Exception("Table roots not locked!");
133 
134  int realRow = resultIsSimpleEnum ? rowIndex : rowIndexMap[rowIndex];
135  var obj = Result.GetValue(realRow, columnIndex);
136 
137  // TODO: support large object references
138 
139  return obj;
140  }
141  }
142 }
Defines the contract to access the data contained into a table of a database.
Definition: ITable.cs:40
DataObject GetValue(int rowIndex, int columnIndex)
Definition: QueryResult.cs:130
QueryResultColumn GetColumn(int columnOffset)
Definition: QueryResult.cs:102
DataObject GetValue(long rowNumber, int columnOffset)
Gets a single cell within the table that is located at the given column offset and row...
int locked
Incremented when we Lock roots.
Definition: QueryResult.cs:31
QueryResultColumn[] columns
Definition: QueryResult.cs:26
Represents a dynamic object that encapsulates a defined SqlType and a compatible constant ISqlObject ...
Definition: DataObject.cs:35
TableInfo TableInfo
Gets the metadata information of the table, used to resolve the column sources.
Definition: ITable.cs:47
int RowCount
Gets the total number of rows in the table.
Definition: ITable.cs:52
QueryResult(SqlQuery query, ITable result)
Definition: QueryResult.cs:33
IList< int > rowIndexMap
The IList that contains the row index into the table for each row of the result.
Definition: QueryResult.cs:29
int ColumnCount
Gets a count of the columns defined by this object.
Definition: TableInfo.cs:159
void FormColumns(ITable result)
Definition: QueryResult.cs:41