DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
QueryResult.old.cs
Go to the documentation of this file.
1 //
2 // Copyright 2010-2014 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 using System;
17 using System.Collections.Generic;
18 
19 using Deveel.Data.DbSystem;
20 
21 namespace Deveel.Data.Protocol {
22  public sealed class QueryResult : IDisposable {
26  private SqlQuery query;
27 
31  private Table result;
32 
37 
42  private IList<int> rowIndexMap;
43 
48  private readonly bool resultIsSimpleEnum;
49 
53  private readonly int resultRowCount;
54 
58  private int locked;
59 
64  private readonly Dictionary<long, StreamableObject> streamableBlobMap;
65 
66 
72  public QueryResult(SqlQuery query, Table result) {
73  this.query = query;
74  this.result = result;
75  streamableBlobMap = new Dictionary<long, StreamableObject>();
76 
77  resultRowCount = result.RowCount;
78 
79  // HACK: Read the contents of the first row so that we can pick up
80  // any errors with reading, and also to fix the 'uniquekey' bug
81  // that causes a new transaction to be started if 'uniquekey' is
82  // a column and the value is resolved later.
83  IRowEnumerator rowEnum = result.GetRowEnumerator();
84  if (rowEnum.MoveNext()) {
85  int rowIndex = rowEnum.RowIndex;
86  for (int c = 0; c < result.ColumnCount; ++c) {
87  result.GetCell(c, rowIndex);
88  }
89  }
90 
91  // If simple enum, note it here
92  resultIsSimpleEnum = (rowEnum is SimpleRowEnumerator);
93  rowEnum = null;
94 
95  // Build 'row_index_map' if not a simple enum
96  if (!resultIsSimpleEnum) {
97  rowIndexMap = new List<int>(result.RowCount);
98 
99  IRowEnumerator en = result.GetRowEnumerator();
100  while (en.MoveNext()) {
101  rowIndexMap.Add(en.RowIndex);
102  }
103  }
104 
105  // This is a safe operation provides we are shared.
106  // Copy all the TableField columns from the table to our own
107  // QueryResultColumn array, naming each column by what is returned from
108  // the 'GetResolvedVariable' method.
109  int colCount = result.ColumnCount;
110  colDesc = new QueryResultColumn[colCount];
111  for (int i = 0; i < colCount; ++i) {
112  VariableName v = result.GetResolvedVariable(i);
113  string fieldName;
114  if (v.TableName == null) {
115  // This means the column is an alias
116  fieldName = String.Format("@a{0}", v.Name);
117  } else {
118  // This means the column is an schema/table/column reference
119  fieldName = String.Format("@f{0}", v);
120  }
121 
122  colDesc[i] = new QueryResultColumn(fieldName, result.GetColumnInfo(i));
123  }
124 
125  locked = 0;
126  }
127 
134  public StreamableObject GetRef(long id) {
135  StreamableObject reference;
136  if (!streamableBlobMap.TryGetValue(id, out reference))
137  return null;
138 
139  return reference;
140  }
141 
147  public void RemoveRef(long id) {
148  streamableBlobMap.Remove(id);
149  }
150 
154  public void Dispose() {
155  while (locked > 0) {
156  UnlockRoot(-1);
157  }
158  result = null;
159  rowIndexMap = null;
160  colDesc = null;
161  }
162 
172  public TObject GetCellContents(int column, int row) {
173  if (locked <= 0)
174  throw new Exception("Table roots not locked!");
175 
176  int realRow = resultIsSimpleEnum ? row : rowIndexMap[row];
177  TObject tob = result.GetCell(column, realRow);
178 
179  // If this is a large object reference then cache it so a streamable
180  // object can reference it via this result.
181  if (tob.Object is IRef) {
182  var reference = (IRef) tob.Object;
183  streamableBlobMap[reference.Id] =
184  new StreamableObject(reference.Type, reference.RawSize, reference.Id);
185  }
186 
187  return tob;
188  }
189 
193  public int ColumnCount {
194  get { return result.ColumnCount; }
195  }
196 
200  public int RowCount {
201  get { return resultRowCount; }
202  }
203 
207  public QueryResultColumn[] Fields {
208  get { return colDesc; }
209  }
210 
215  public void LockRoot(int key) {
216  result.LockRoot(key);
217  ++locked;
218  }
219 
224  private void UnlockRoot(int key) {
225  result.UnlockRoot(key);
226  --locked;
227  }
228  }
229 }
QueryResult(SqlQuery query, Table result)
Constructs the result set.
readonly int resultRowCount
The number of rows in the result.
readonly Dictionary< long, StreamableObject > streamableBlobMap
A Dictionary of blob_reference_id values to IRef objects used to handle and streamable o...
QueryResultColumn[] colDesc
A set of QueryResultColumn that describes each column in the ResultSet.
void LockRoot(int key)
Locks the root of the result set.
TObject GetCellContents(int column, int row)
Gets the cell contents of the cell at the given row/column.
Table result
The table that is the result.
void RemoveRef(long id)
Removes a IRef that has been cached in this table object by its identifier value. ...
void UnlockRoot(int key)
Unlocks the root of the result set.
readonly bool resultIsSimpleEnum
Set to true if the result table has a SimpleRowEnumerator, therefore guarenteeing we do not need to s...
void Dispose()
Disposes this object.
SqlQuery query
The SqlQuery that was executed to produce this result.
An object that is streamable (such as a long binary object, or a long string object).
StreamableObject GetRef(long id)
Returns a IRef that has been cached in this table object by its identifier value. ...