// Creates Sensor wrapper private Sensor CreateItem( // Fields of Sensor table Guid SensorId, SensorType SensorType, int BitWidth, PinSide PinSide, string Notation, string Data, string Note // Fields of Circuit table ) { TableSnapshot <CircuitData> tableCircuit = (TableSnapshot <CircuitData>) this.CircuitProject.Table("Circuit"); CircuitData dataCircuit = new CircuitData() { CircuitId = SensorId }; RowId rowIdCircuit = tableCircuit.Insert(ref dataCircuit); SensorData dataSensor = new SensorData() { SensorId = SensorId, SensorType = SensorType, BitWidth = BitWidth, PinSide = PinSide, Notation = Notation, Data = Data, Note = Note, }; return(this.Create(this.Table.Insert(ref dataSensor), rowIdCircuit)); }
// Creates Sound wrapper private Sound CreateItem( // Fields of Sound table Guid SoundId, PinSide PinSide, string Notation, string Note // Fields of Circuit table ) { TableSnapshot <CircuitData> tableCircuit = (TableSnapshot <CircuitData>) this.CircuitProject.Table("Circuit"); CircuitData dataCircuit = new CircuitData() { CircuitId = SoundId }; RowId rowIdCircuit = tableCircuit.Insert(ref dataCircuit); SoundData dataSound = new SoundData() { SoundId = SoundId, PinSide = PinSide, Notation = Notation, Note = Note, }; return(this.Create(this.Table.Insert(ref dataSound), rowIdCircuit)); }
public SqlObject GetValue(int columnOffset, RowId rowid) { if (rowid.ToInt64() != 0) throw new ArgumentOutOfRangeException("rowid"); return values[columnOffset]; }
// Creates CircuitButton wrapper private CircuitButton CreateItem( // Fields of CircuitButton table Guid CircuitButtonId, string Notation, bool IsToggle, PinSide PinSide, bool Inverted, int Width, int Height, string Note // Fields of Circuit table ) { TableSnapshot <CircuitData> tableCircuit = (TableSnapshot <CircuitData>) this.CircuitProject.Table("Circuit"); CircuitData dataCircuit = new CircuitData() { CircuitId = CircuitButtonId }; RowId rowIdCircuit = tableCircuit.Insert(ref dataCircuit); CircuitButtonData dataCircuitButton = new CircuitButtonData() { CircuitButtonId = CircuitButtonId, Notation = Notation, IsToggle = IsToggle, PinSide = PinSide, Inverted = Inverted, Width = Width, Height = Height, Note = Note, }; return(this.Create(this.Table.Insert(ref dataCircuitButton), rowIdCircuit)); }
protected override int CompareToSameType(RowEditBase rowEdit) { // We want to sort by row ID *IN REVERSE* to make sure we delete from the bottom first. // If we delete from the top first, it will change IDs, making all subsequent deletes // off by one or more! return(RowId.CompareTo(rowEdit.RowId) * -1); }
public static void NotNull() { var nullRowId = RowId.Null; var rowId = new RowId(1, 32); Assert.AreNotEqual(rowId, nullRowId); }
public static void ToString(int tableId, long rowNumber, string expected) { var rowId = new RowId(tableId, (int) rowNumber); var s = rowId.ToString(); Assert.AreEqual(expected, s); }
// Creates Splitter wrapper private Splitter CreateItem( // Fields of Splitter table Guid SplitterId, int BitWidth, int PinCount, bool Clockwise // Fields of Circuit table ) { TableSnapshot <CircuitData> tableCircuit = (TableSnapshot <CircuitData>) this.CircuitProject.Table("Circuit"); CircuitData dataCircuit = new CircuitData() { CircuitId = SplitterId }; RowId rowIdCircuit = tableCircuit.Insert(ref dataCircuit); SplitterData dataSplitter = new SplitterData() { SplitterId = SplitterId, BitWidth = BitWidth, PinCount = PinCount, Clockwise = Clockwise, }; return(this.Create(this.Table.Insert(ref dataSplitter), rowIdCircuit)); }
// Creates Constant wrapper private Constant CreateItem( // Fields of Constant table Guid ConstantId, int BitWidth, int Value, PinSide PinSide, string Note // Fields of Circuit table ) { TableSnapshot <CircuitData> tableCircuit = (TableSnapshot <CircuitData>) this.CircuitProject.Table("Circuit"); CircuitData dataCircuit = new CircuitData() { CircuitId = ConstantId }; RowId rowIdCircuit = tableCircuit.Insert(ref dataCircuit); ConstantData dataConstant = new ConstantData() { ConstantId = ConstantId, BitWidth = BitWidth, Value = Value, PinSide = PinSide, Note = Note, }; return(this.Create(this.Table.Insert(ref dataConstant), rowIdCircuit)); }
// Creates CircuitProbe wrapper private CircuitProbe CreateItem( // Fields of CircuitProbe table Guid CircuitProbeId, string Name, string Note // Fields of Circuit table ) { TableSnapshot <CircuitData> tableCircuit = (TableSnapshot <CircuitData>) this.CircuitProject.Table("Circuit"); CircuitData dataCircuit = new CircuitData() { CircuitId = CircuitProbeId }; RowId rowIdCircuit = tableCircuit.Insert(ref dataCircuit); CircuitProbeData dataCircuitProbe = new CircuitProbeData() { CircuitProbeId = CircuitProbeId, Name = Name, Note = Note, }; return(this.Create(this.Table.Insert(ref dataCircuitProbe), rowIdCircuit)); }
// Creates LedMatrix wrapper private LedMatrix CreateItem( // Fields of LedMatrix table Guid LedMatrixId, LedMatrixType MatrixType, LedMatrixCellShape CellShape, int Rows, int Columns, int Colors, string Note // Fields of Circuit table ) { TableSnapshot <CircuitData> tableCircuit = (TableSnapshot <CircuitData>) this.CircuitProject.Table("Circuit"); CircuitData dataCircuit = new CircuitData() { CircuitId = LedMatrixId }; RowId rowIdCircuit = tableCircuit.Insert(ref dataCircuit); LedMatrixData dataLedMatrix = new LedMatrixData() { LedMatrixId = LedMatrixId, MatrixType = MatrixType, CellShape = CellShape, Rows = Rows, Columns = Columns, Colors = Colors, Note = Note, }; return(this.Create(this.Table.Insert(ref dataLedMatrix), rowIdCircuit)); }
// Creates GraphicsArray wrapper private GraphicsArray CreateItem( // Fields of GraphicsArray table Guid GraphicsArrayId, bool WriteOn1, MemoryOnStart OnStart, int DataBitWidth, int BitsPerPixel, int Width, int Height, string Note // Fields of Circuit table ) { TableSnapshot <CircuitData> tableCircuit = (TableSnapshot <CircuitData>) this.CircuitProject.Table("Circuit"); CircuitData dataCircuit = new CircuitData() { CircuitId = GraphicsArrayId }; RowId rowIdCircuit = tableCircuit.Insert(ref dataCircuit); GraphicsArrayData dataGraphicsArray = new GraphicsArrayData() { GraphicsArrayId = GraphicsArrayId, WriteOn1 = WriteOn1, OnStart = OnStart, DataBitWidth = DataBitWidth, BitsPerPixel = BitsPerPixel, Width = Width, Height = Height, Note = Note, }; return(this.Create(this.Table.Insert(ref dataGraphicsArray), rowIdCircuit)); }
public override ValueGetter <RowId> GetIdGetter() { #if (DEBUG) Dictionary <RowId, int> localCache = new Dictionary <RowId, int>(); #endif // We do not change the ID (row to row transform). var getId = _inputCursor.GetIdGetter(); return((ref RowId pos) => { getId(ref pos); if (_shift > 0) { Contracts.Assert(_copy >= 0 && _copy <= _maxReplica); ulong left = pos.Low << _shift; left >>= _shift; left = pos.Low - left; ulong lo = pos.Low << _shift; ulong hi = pos.High << _shift; hi += left >> (64 - _shift); pos = new RowId(lo + (ulong)_copy, hi); #if (DEBUG) if (localCache.ContainsKey(pos)) { throw Contracts.Except("Id already taken: {0}", pos); } #endif } else { Contracts.Assert(_copy == 0); } }); }
// Creates Memory wrapper private Memory CreateItem( // Fields of Memory table Guid MemoryId, bool Writable, bool WriteOn1, MemoryOnStart OnStart, int AddressBitWidth, int DataBitWidth, string Data, string Note // Fields of Circuit table ) { TableSnapshot <CircuitData> tableCircuit = (TableSnapshot <CircuitData>) this.CircuitProject.Table("Circuit"); CircuitData dataCircuit = new CircuitData() { CircuitId = MemoryId }; RowId rowIdCircuit = tableCircuit.Insert(ref dataCircuit); MemoryData dataMemory = new MemoryData() { MemoryId = MemoryId, Writable = Writable, WriteOn1 = WriteOn1, OnStart = OnStart, AddressBitWidth = AddressBitWidth, DataBitWidth = DataBitWidth, Data = Data, Note = Note, }; return(this.Create(this.Table.Insert(ref dataMemory), rowIdCircuit)); }
public static void Set(this ITableCellCache cache, string database, int tableId, int rowNumber, int columnOffset, Field value) { var rowId = new RowId(tableId, rowNumber); var key = new CellKey(database, new CellId(rowId, columnOffset)); cache.Set(new CachedCell(key, value)); }
public static void Remove(this ITableCellCache cache, string database, int tableId, int rowNumber, int columnOffset) { var rowId = new RowId(tableId, rowNumber); var key = new CellKey(database, new CellId(rowId, columnOffset)); cache.Remove(key); }
public static bool TryGetValue(this ITableCellCache cache, string database, int tableId, int rowNumber, int columnOffset, out Field value) { var rowId = new RowId(tableId, rowNumber); var key = new CellKey(database, new CellId(rowId, columnOffset)); return(cache.TryGetValue(key, out value)); }
// Creates LogicalCircuit wrapper private LogicalCircuit CreateItem( // Fields of LogicalCircuit table Guid LogicalCircuitId, string Name, string Notation, string Note, string Category, bool IsDisplay // Fields of Circuit table ) { TableSnapshot <CircuitData> tableCircuit = (TableSnapshot <CircuitData>) this.CircuitProject.Table("Circuit"); CircuitData dataCircuit = new CircuitData() { CircuitId = LogicalCircuitId }; RowId rowIdCircuit = tableCircuit.Insert(ref dataCircuit); LogicalCircuitData dataLogicalCircuit = new LogicalCircuitData() { LogicalCircuitId = LogicalCircuitId, Name = Name, Notation = Notation, Note = Note, Category = Category, IsDisplay = IsDisplay, }; return(this.Create(this.Table.Insert(ref dataLogicalCircuit), rowIdCircuit)); }
//internal void Register() { // foreach(RowId rowId in this.Table.Rows) { // this.FindOrCreate(rowId); // } //} // gets items wrapper by RowId public LogicalCircuit Find(RowId rowId) { if (!rowId.IsEmpty) { return(this.Table.GetField(rowId, LogicalCircuitData.LogicalCircuitField.Field)); } return(null); }
// Constructor public LogicalCircuit(CircuitProject store, RowId rowIdLogicalCircuit, RowId rowIdCircuit) : base(store, rowIdCircuit) { Debug.Assert(!rowIdLogicalCircuit.IsEmpty); this.LogicalCircuitRowId = rowIdLogicalCircuit; // Link back to record. Assuming that a transaction is started this.Table.SetField(this.LogicalCircuitRowId, LogicalCircuitData.LogicalCircuitField.Field, this); this.InitializeLogicalCircuit(); }
//internal void Register() { // foreach(RowId rowId in this.Table.Rows) { // this.FindOrCreate(rowId); // } //} // gets items wrapper by RowId public DevicePin Find(RowId rowId) { if (!rowId.IsEmpty) { return(this.Table.GetField(rowId, DevicePinData.DevicePinField.Field)); } return(null); }
public SqlObject GetValue(int columnOffset, RowId rowid) { TableRow row; if (!rows.TryGetValue(rowid, out row)) return SqlObject.Null; return row.GetValue(columnOffset); }
//internal void Register() { // foreach(RowId rowId in this.Table.Rows) { // this.FindOrCreate(rowId); // } //} // gets items wrapper by RowId public CircuitProbe Find(RowId rowId) { if (!rowId.IsEmpty) { return(this.Table.GetField(rowId, CircuitProbeData.CircuitProbeField.Field)); } return(null); }
// Constructor public GraphicsArray(CircuitProject store, RowId rowIdGraphicsArray, RowId rowIdCircuit) : base(store, rowIdCircuit) { Debug.Assert(!rowIdGraphicsArray.IsEmpty); this.GraphicsArrayRowId = rowIdGraphicsArray; // Link back to record. Assuming that a transaction is started this.Table.SetField(this.GraphicsArrayRowId, GraphicsArrayData.GraphicsArrayField.Field, this); this.InitializeGraphicsArray(); }
//internal void Register() { // foreach(RowId rowId in this.Table.Rows) { // this.FindOrCreate(rowId); // } //} // gets items wrapper by RowId public TextNote Find(RowId rowId) { if (!rowId.IsEmpty) { return(this.Table.GetField(rowId, TextNoteData.TextNoteField.Field)); } return(null); }
// Constructor public Memory(CircuitProject store, RowId rowIdMemory, RowId rowIdCircuit) : base(store, rowIdCircuit) { Debug.Assert(!rowIdMemory.IsEmpty); this.MemoryRowId = rowIdMemory; // Link back to record. Assuming that a transaction is started this.Table.SetField(this.MemoryRowId, MemoryData.MemoryField.Field, this); this.InitializeMemory(); }
//internal void Register() { // foreach(RowId rowId in this.Table.Rows) { // this.FindOrCreate(rowId); // } //} // gets items wrapper by RowId public GraphicsArray Find(RowId rowId) { if (!rowId.IsEmpty) { return(this.Table.GetField(rowId, GraphicsArrayData.GraphicsArrayField.Field)); } return(null); }
//internal void Register() { // foreach(RowId rowId in this.Table.Rows) { // this.FindOrCreate(rowId); // } //} // gets items wrapper by RowId public Constant Find(RowId rowId) { if (!rowId.IsEmpty) { return(this.Table.GetField(rowId, ConstantData.ConstantField.Field)); } return(null); }
//internal void Register() { // foreach(RowId rowId in this.Table.Rows) { // this.FindOrCreate(rowId); // } //} // gets items wrapper by RowId public Project Find(RowId rowId) { if (!rowId.IsEmpty) { return(this.Table.GetField(rowId, ProjectData.ProjectField.Field)); } return(null); }
//internal void Register() { // foreach(RowId rowId in this.Table.Rows) { // this.FindOrCreate(rowId); // } //} // gets items wrapper by RowId public CollapsedCategory Find(RowId rowId) { if (!rowId.IsEmpty) { return(this.Table.GetField(rowId, CollapsedCategoryData.CollapsedCategoryField.Field)); } return(null); }
//internal void Register() { // foreach(RowId rowId in this.Table.Rows) { // this.FindOrCreate(rowId); // } //} // gets items wrapper by RowId public Wire Find(RowId rowId) { if (!rowId.IsEmpty) { return(this.Table.GetField(rowId, WireData.WireField.Field)); } return(null); }
// Constructor public CircuitProbe(CircuitProject store, RowId rowIdCircuitProbe, RowId rowIdCircuit) : base(store, rowIdCircuit) { Debug.Assert(!rowIdCircuitProbe.IsEmpty); this.CircuitProbeRowId = rowIdCircuitProbe; // Link back to record. Assuming that a transaction is started this.Table.SetField(this.CircuitProbeRowId, CircuitProbeData.CircuitProbeField.Field, this); this.InitializeCircuitProbe(); }
// Constructor public Constant(CircuitProject store, RowId rowIdConstant, RowId rowIdCircuit) : base(store, rowIdCircuit) { Debug.Assert(!rowIdConstant.IsEmpty); this.ConstantRowId = rowIdConstant; // Link back to record. Assuming that a transaction is started this.Table.SetField(this.ConstantRowId, ConstantData.ConstantField.Field, this); this.InitializeConstant(); }
//internal void Register() { // foreach(RowId rowId in this.Table.Rows) { // this.FindOrCreate(rowId); // } //} // gets items wrapper by RowId public Memory Find(RowId rowId) { if (!rowId.IsEmpty) { return(this.Table.GetField(rowId, MemoryData.MemoryField.Field)); } return(null); }
public JournalEntry(JournalCommandCode code, long id) : this() { this.code = code; this.id = id; rowid = null; forTable = true; forRow = false; }
public override SqlObject GetValue(int column, RowId row) { OutputExpression outExpr = outputExps[column]; Expression expression = outExpr.expression; // Set the processor stack as necessary processor.UpdateTableRow(row); // Execute the expression and return return QueryProcessor.Result(processor.Execute(expression))[0]; }
public JournalEntry(JournalCommandCode code, RowId rowid) : this() { this.code = code; this.rowid = rowid; id = -1; forTable = false; forRow = true; }
internal TableEventContext(ITable table, TriggerEventType eventType, RowId oldRowId, Row newRow) { if (table == null) throw new ArgumentNullException("table"); Table = table; EventType = eventType; OldRowId = oldRowId; NewRow = newRow; }
public void Delete(RowId rowid) { if (rows.ContainsKey(rowid)) { rows.Remove(rowid); for (int i = rowIndex.Count - 1; i >= 0; i--) { if (rowIndex[i] == rowid) rowIndex.RemoveAt(i); } } }
internal CachedCell(RowId rowId, int columnOffset, DataObject value) { if (rowId.IsNull) throw new ArgumentNullException("rowId"); if (columnOffset < 0) throw new ArgumentOutOfRangeException("columnOffset"); RowId = rowId; ColumnOffset = columnOffset; Value = value; }
public TableRow(ITable table, RowId id) { if (table == null) throw new ArgumentNullException("table"); if (id == null) throw new ArgumentNullException("id"); this.table = table; this.id = id; mutable = (table is IMutableTable); cachedValues = new Dictionary<int, SqlObject>(16); }
public TableRow GetRow(RowId rowid) { if (rowid.ToInt64() != 0) throw new ArgumentOutOfRangeException("rowid"); if (row == null) { row = new TableRow(this, new RowId(0)); for (int i = 0; i < columns.Count; i++) row.SetValue(i, values[i]); } return row; }
internal TriggerEvent(ObjectName triggerName, ObjectName sourceName, TriggerEventType eventType, RowId oldRowId, Row newRow) { if (triggerName == null) throw new ArgumentNullException("triggerName"); if (sourceName == null) throw new ArgumentNullException("sourceName"); TriggerName = triggerName; SourceName = sourceName; TriggerEventType = eventType; OldRowId = oldRowId; NewRow = newRow; }
public override SqlObject GetValue(int columnOffset, RowId rowid) { Init(); int i = TableIndex(rowid, 0, tableIndex.Length); IColumnCollection columns = tableColumns[i]; int col_count = columns.Count; TableName tableName = tableNames[i]; // If no column, return null if (col_count == 0) { // We output the schema and name but the rest of the info is null // for tables with 0 columns if (columnOffset == 0) return tableName.Schema; if (columnOffset == 1) return tableName.Name; return SqlObject.Null; } int seq_no = col_count - (def_index[i] - (int)row_id); TableColumn col_def = columns[seq_no]; switch (columnOffset) { case 0: // schema return columns.getSchema(); case 1: // table return TObject.stringVal(columns.getName()); case 2: // column return TObject.stringVal(col_def.getName()); case 3: // sql_type return TObject.longVal(col_def.getSQLType()); case 4: // type_desc return TObject.stringVal(col_def.getSQLTypeString()); case 5: // size return TObject.longVal(col_def.getSize()); case 6: // scale return TObject.longVal(col_def.getScale()); case 7: // not_null return TObject.booleanVal(col_def.isNotNull()); case 8: // default return TObject.stringVal(col_def.getDefaultExpressionString()); case 9: // store hint return TObject.stringVal(col_def.getStoreHint()); case 10: // seq_no return TObject.longVal(seq_no); default: throw new Error("Column out of bounds."); } }
/// <summary> /// Constructs a new row object for the table given, /// identified by the given <see cref="RowId"/>. /// </summary> /// <param name="table">The table that contains the row.</param> /// <param name="rowId">The unique identifier of the row within the database.</param> /// <exception cref="ArgumentNullException"> /// If the provided <paramref name="table"/> is <c>null</c>. /// </exception> /// <exception cref="ArgumentException"> /// If the <paramref name="table"/> defines any id and this does not /// match the given <paramref name="rowId"/>. /// </exception> public Row(ITable table, RowId rowId) { if (table == null) throw new ArgumentNullException("table"); if (!rowId.IsNull && table.TableInfo.Id >= 0 && table.TableInfo.Id != rowId.TableId) throw new ArgumentException(String.Format("The table ID {0} does not match the identifier specified by the row ID ({1})", table.TableInfo.Id, rowId.TableId)); Table = table; RowId = rowId; }
public override SqlObject[] GetValue(RowId rowid) { SqlObject[] values; if (columns.Length == 1) { // Single value values = new SqlObject[] { table.GetValue(columns[0], rowid) }; } else { // Composite value so create a composite object as the key. int sz = columns.Length; values = new SqlObject[sz]; for (int i = 0; i < sz; ++i) { values[i] = table.GetValue(columns[i], rowid); } } return values; }
public TableRow GetRow(RowId rowid) { // Null value if the rowid is less than 0 if (rowid == null || rowid.ToInt64() < 0) return null; int sz = Columns.Count; TableRow row = new TableRow(this, rowid); for (int i = 0; i < sz; i++) { int tableIndex = columns.IndexOfTable(i); // Adjust the column to the table the column is located int tableColumn = columns.AdjustColumn(i); // Adjust the row by the table RowId tableRow = AdjustRow(rowid.ToInt64(), tableIndex); // Fetch and return the data SqlObject value = tables[tableIndex].GetValue(tableColumn, tableRow); TableColumn column = Columns[i]; row.SetValue(column.Offset, value); } return row; }
public TableRow GetRow(RowId rowid) { TableRow row; return !rows.TryGetValue(rowid, out row) ? null : row; }
public bool RemoveRow(RowId rowId) { throw new NotSupportedException(String.Format("Deleting data from '{0}' is not allowed.", tableInfo.TableName)); }
public bool RowExists(RowId rowid) { return rows.ContainsKey(rowid); }
public void UpdateTableRow(RowId rowid) { rowIdStack[rowIdStack.Count - 1] = rowid; }
public TableRow NewRow() { RowId rowid = new RowId(++rowIdSeq); return new TableRow(this, rowid); }
public void PrefetchValue(int columnOffset, RowId rowid) { }
public override SqlObject[] GetValue(RowId rowid) { // Set the top of stack table row_id processor.UpdateTableRow(rowid); if (columnExps.Length == 1) // If a single part, return Result(processor.DoExecute(columnExps[0])); // TODO: We can clean this up a great deal! We should make // 'DoExecute' produce a table with multiple columns when a // composite function is given. int compParts = columnExps.Length; // If composite, SqlObject[] arr = new SqlObject[compParts]; for (int i = 0; i < compParts; ++i) arr[i] = Result(processor.DoExecute(columnExps[i]))[0]; return arr; }
public override int Compare(RowId rowid, SqlObject[] value) { SqlObject[] val1 = GetValue(rowid); SqlObject[] val2 = value; // Compare until we reach the end of the array. int min_compare = System.Math.Min(val1.Length, val2.Length); for (int i = 0; i < min_compare; ++i) { int c = SqlObject.Compare(val1[i], val2[i]); if (c != 0) { bool rev = ascending[i]; return rev ? c : -c; } } // If the sizes are equal, compare equally, if (val1.Length == val2.Length) return 0; // If val1.length is greater, return +1, else return -1 (val1.length is // less) if (val1.Length > val2.Length) { return 1; } else { return -1; } }
public bool RowExists(RowId rowid) { throw new NotImplementedException(); }
public void PrefetchValue(int columnOffset, RowId rowid) { throw new NotImplementedException(); }
public SqlObject GetValue(int columnOffset, RowId rowid) { throw new NotImplementedException(); }
public TableRow GetRow(RowId rowid) { throw new NotImplementedException(); }
private ITable SortFilter(ITable table, FilterExpression expression) { // The filter operation which is a function that describes the sort terms Expression filterExp = expression.Filter; if (!(filterExp is FunctionExpression)) throw new ArgumentException("Expected a function as argument to the filter."); ITable resultTable = table; // If there's something to sort, if (table.RowCount > 1) { // Get the composite function representing the sort collation, FunctionExpression compositeExp = (FunctionExpression) filterExp; if (!compositeExp.Name.Equals("composite")) throw new ArgumentException("Invalid composite function for sorting."); // The natural ordering of the child Expression naturalChildOrder = GetTableOrderComposite(table); if (naturalChildOrder != null) { if (naturalChildOrder.Equals(compositeExp)) // No sort necessary, already sorted return table; // TODO: test for the reverse condition, which we can optimize // with a reverse row iterator. } int paramCount = compositeExp.Parameters.Count; int termCount = paramCount / 2; IIndexSetDataSource rowIndex; bool naturalOrder = true; // If 1 sort term, if (termCount == 1) { Expression sortExp = (Expression) compositeExp.Parameters[0]; naturalOrder = SqlObject.Equals((SqlObject)compositeExp.Parameters[1], SqlObject.True); // Get the index candidate string indexName = sortExp.IndexCandidate; TableName indexTableName = sortExp.IndexTableName; // Index available? rowIndex = GetIndex(table, indexName); } else { // Multiple terms, // Get the index candidate if there is one string indexName = compositeExp.IndexCandidate; TableName indexTableame = compositeExp.IndexTableName; // Index available? rowIndex = GetIndex(table, indexName); } // If we have an index, if (rowIndex != null) { IRowCursor sortedCursor = rowIndex.Select(SelectableRange.Full); if (!naturalOrder) // Reverse iterator, sortedCursor = new ReverseRowCursor(sortedCursor); SubsetTable sortedTable = new SubsetTable(table, sortedCursor); sortedTable.IndexRequestFallthrough = true; // Set the order composite function the describes how the subset is // naturally sorted. sortedTable.OrderComposite = (Expression) compositeExp.Clone(); resultTable = sortedTable; } else { // NOTE: There's lots of directions we can take for optimizing this // sort. For example, if the number of values being sorted meets some // criteria (such as all integers and less than 2 millions values) // then the values being sorted could be read onto the heap and sorted // in memory with a quick sort. // Scan sort, // The working set, IIndex<RowId> workingSet = transaction.CreateTemporaryIndex<RowId>(table.RowCount); // Create the resolver IndexResolver resolver = CreateResolver(table, compositeExp); // Iterator over the source table IRowCursor tableCursor = table.GetRowCursor(); // Wrap in a forward prefetch iterator tableCursor = new PrefetchRowCursor(tableCursor, table); // Use a buffer, RowId[] rowIds = new RowId[128]; while (tableCursor.MoveNext()) { int count = 0; while (tableCursor.MoveNext() && count < 128) { rowIds[count] = tableCursor.Current; ++count; } for (int i = 0; i < count; ++i) { RowId rowid = rowIds[i]; // Get the value, SqlObject[] values = resolver.GetValue(rowid); // Insert the record into sorted order in the working_set workingSet.Insert(values, rowid, resolver); } } // TODO: record 'workingSet' for future resolution. // The result, IRowCursor sortedCursor = new DefaultRowCursor(workingSet.GetCursor()); SubsetTable sortedTable = new SubsetTable(table, sortedCursor); sortedTable.IndexRequestFallthrough = true; // Set the order composite function the describes how the subset is // naturally sorted. sortedTable.OrderComposite = (Expression) compositeExp.Clone(); resultTable = sortedTable; } } return resultTable; }