/// <summary> /// Constructor using only the Main Table. /// </summary> /// <param name="type"></param> /// <param name="table"></param> /// <param name="col"></param> public Constraint(ConstraintType type, Table table, int[] col) { _type = type; _mainTable = table; _mainColumns = col; _len = col.Length; }
private Table tTable; // null: memory row; otherwise: cached table #endregion Fields #region Constructors public Row(Table table, object[] o) { tTable = table; int index = tTable.IndexCount; nFirstIndex = new Node(this, 0); Node n = nFirstIndex; for (int i = 1; i < index; i++) { n.nNext = new Node(this, i); n = n.nNext; } oData = o; if (tTable != null && tTable.cCache != null) { LastAccess = CurrentAccess++; // todo: 32 bytes overhead for each index + iSize, iPos Size = 8 + Column.GetSize(o, tTable) + 16 * tTable.IndexCount; //((iSize + 7) / 8) * 8; // align to 8 byte blocks tTable.cCache.Add(this); } Changed = true; }
/// <summary> /// Default constructor. /// </summary> /// <param name="t"></param> /// <param name="alias"></param> /// <param name="outerjoin"></param> public TableFilter(Table t, string alias, bool outerjoin) { tTable = t; iIndex = null; sAlias = alias != null ? alias : t.Name; bOuterJoin = outerjoin; oEmptyData = tTable.NewRow; }
private string GetColumnList(Table table, int[] col, int len) { StringBuilder a = new StringBuilder(); a.Append("("); for (int i = 0; i < len; i++) { a.Append('"'); a.Append(table.GetColumnName(col[i])); a.Append('"'); if (i < len - 1) { a.Append(","); } } return a.Append(")").ToString(); }
/// <summary> /// Add an insert transaction to the current transaction list. /// </summary> /// <param name="table"></param> /// <param name="row"></param> internal void AddTransactionInsert(Table table, object[] row) { TracingHelper.Check(!_closed, TracingHelper.CONNECTION_IS_CLOSED); if (!_autoCommit) { Transaction t = new Transaction(false, table, row); _transaction.Add(t); } }
public Table MoveDefinition(string withoutIndex) { Table tn = new Table(dDatabase, true, Name, IsCached); for (int i = 0; i < ColumnCount; i++) { tn.AddColumn(GetColumn(i)); } // todo: there should be nothing special with the primary key! if (iVisibleColumns < iColumnCount) { tn.CreatePrimaryKey(); } else { tn.CreatePrimaryKey(PrimaryIndex.Columns[0]); } Index idx = null; while (true) { idx = GetNextIndex(idx); if (idx == null) { break; } if (withoutIndex != null && idx.Name.Equals(withoutIndex)) { continue; } if (idx == PrimaryIndex) { continue; } tn.CreateIndex(idx); } for (int i = 0; i < iConstraintCount; i++) { Constraint c = (Constraint) vConstraint[i]; c.ReplaceTable(this, tn); } tn.vConstraint = vConstraint; return tn; }
public void MoveData(Table from) { Index index = from.PrimaryIndex; Node n = index.First(); while (n != null) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } object[] o = n.GetData(); InsertNoCheck(o, null); n = index.Next(n); } index = PrimaryIndex; n = index.First(); while (n != null) { if (TracingHelper.StopEnabled) { TracingHelper.Stop(); } object[] o = n.GetData(); from.DeleteNoCheck(o, null); n = index.Next(n); } }
/// <summary> /// Process ALTER TABLE statements. /// /// ALTER TABLE tableName ADD COLUMN columnName columnType; /// ALTER TABLE tableName DELETE COLUMN columnName; /// </summary> /// <remarks> /// The only change I've made to Sergio's original code was /// changing the insert's to call insertNoCheck to bypass the trigger /// mechanism that is a part of hsqldb 1.60 and beyond. - Mark Tutt /// </remarks> /// <returns></returns> public Result ProcessAlter() { tTokenizer.GetThis ("TABLE"); string token = tTokenizer.GetString (); cChannel.CheckReadWrite (); // cChannel.check(token,Access.ALTER); --> Accessul nu-l inca controleaza... string tName = token; string swap = tName + "SWAP"; // nimicirea swapului... dDatabase.Execute ("DROP TABLE " + swap, cChannel); Table initialTable = dDatabase.GetTable (token, cChannel); int count = 0; token = tTokenizer.GetString (); if (token.Equals ("ADD")) { token = tTokenizer.GetString (); if (token.Equals ("COLUMN")) { Table swapTable = new Table (dDatabase, true, swap, initialTable.IsCached); // copiem coloanele (fara date) din tabelul initial in swap for (int i = 0; i < initialTable.ColumnCount; i++) { Column aColumn = initialTable.GetColumn (i); swapTable.AddColumn (aColumn); } // end Of copiem coloanele... // aflam daca are PrimaryKey & o cream... string cName = tTokenizer.GetString (); string cType = tTokenizer.GetString (); ColumnType iType = Column.GetColumnType (cType); string sToken = cType; // int primarykeycolumn = -1; bool identity = false; int column = initialTable.ColumnCount + 1; // !-- // stolen from CREATE TABLE... string sColumn = cName; if (iType == ColumnType.VarChar && dDatabase.IsIgnoreCase) { iType = ColumnType.VarCharIgnoreCase; } sToken = tTokenizer.GetString (); if (iType == ColumnType.DbDouble && sToken.Equals ("PRECISION")) { sToken = tTokenizer.GetString (); } if (sToken.Equals ("(")) { // overread length do { sToken = tTokenizer.GetString (); } while (!sToken.Equals (")")); sToken = tTokenizer.GetString (); } // !-- bool nullable = true; if (sToken.Equals ("NULL")) { sToken = tTokenizer.GetString (); } else if (sToken.Equals ("NOT")) { tTokenizer.GetThis ("NULL"); nullable = false; sToken = tTokenizer.GetString (); } /* * if(sToken.Equals("IDENTITY")) { * identity=true; * Trace.check(primarykeycolumn==-1,Trace.SECOND_PRIMARY_KEY,sColumn); * sToken=tTokenizer.getstring(); * primarykeycolumn=column; * } * * if(sToken.Equals("PRIMARY")) { * tTokenizer.getThis("KEY"); * Trace.check(identity || primarykeycolumn==-1, * Trace.SECOND_PRIMARY_KEY,sColumn); * primarykeycolumn=column; * //sToken=tTokenizer.getstring(); * } * //end of STOLEN... */ swapTable.AddColumn (cName, iType, nullable, identity); // under construction... if (initialTable.ColumnCount < initialTable.InternalColumnCount) { swapTable.CreatePrimaryKey (); } else { swapTable.CreatePrimaryKey (initialTable.PrimaryIndex.Columns [0]); } // endof PrimaryKey... // sa ne farimam cu indicii... ;-(( Index idx = null; while (true) { idx = initialTable.GetNextIndex (idx); if (idx == null) { break; } if (idx == initialTable.PrimaryIndex) { continue; } swapTable.CreateIndex (idx); } // end of Index... cChannel.Commit (); dDatabase.LinkTable (swapTable); Tokenizer tmpTokenizer = new Tokenizer ("SELECT * FROM " + tName); Parser pp = new Parser (dDatabase, tmpTokenizer, cChannel); string ff = tmpTokenizer.GetString (); if (!initialTable.IsEmpty) { Record n = ((Result)pp.ProcessSelect ()).Root; do { object[] row = swapTable.NewRow; object[] row1 = n.Data; for (int i = 0; i < initialTable.ColumnCount; i++) { row [i] = row1 [i]; } swapTable.InsertNoCheck (row, cChannel); n = n.Next; } while (n != null); } dDatabase.Execute ("DROP TABLE " + tName, cChannel); // cream tabelul vechi cu proprietatile celui nou... initialTable = new Table (dDatabase, true, tName, swapTable.IsCached); for (int i = 0; i < swapTable.ColumnCount; i++) { Column aColumn = swapTable.GetColumn (i); initialTable.AddColumn (aColumn); } if (swapTable.ColumnCount < swapTable.InternalColumnCount) { initialTable.CreatePrimaryKey (); } else { initialTable.CreatePrimaryKey (swapTable.PrimaryIndex.Columns [0]); } // endof PrimaryKey... // sa ne farimam cu indicii... ;-(( idx = null; while (true) { idx = swapTable.GetNextIndex (idx); if (idx == null) { break; } if (idx == swapTable.PrimaryIndex) { continue; } initialTable.CreateIndex (idx); } // end of Index... cChannel.Commit (); dDatabase.LinkTable (initialTable); // end of cream... // copiem datele din swap in tabel... tmpTokenizer = new Tokenizer ("SELECT * FROM " + swap); pp = new Parser (dDatabase, tmpTokenizer, cChannel); ff = tmpTokenizer.GetString (); if (!swapTable.IsEmpty) { Record n = ((Result)pp.ProcessSelect ()).Root; do { object[] row = initialTable.NewRow; object[] row1 = n.Data; for (int i = 0; i < swapTable.ColumnCount; i++) { row [i] = row1 [i]; } initialTable.InsertNoCheck (row, cChannel); n = n.Next; } while (n != null); // end of copiem... } dDatabase.Execute ("DROP TABLE " + swap, cChannel); count = 4; } else { throw TracingHelper.Error (TracingHelper.UnexpectedToken, token); } } else if (token.Equals ("DELETE")) { token = tTokenizer.GetString (); if (token.Equals ("COLUMN")) { Table swapTable = new Table (dDatabase, true, swap, initialTable.IsCached); string cName = tTokenizer.GetString (); int undesired = initialTable.GetColumnNumber (cName); for (int i = 0; i < initialTable.ColumnCount; i++) { Column aColumn = initialTable.GetColumn (i); if (i != undesired) { swapTable.AddColumn (aColumn); } } int pKey = -1; // !-- if (initialTable.ColumnCount < initialTable.InternalColumnCount) { swapTable.CreatePrimaryKey (); } else { int[] cols = initialTable.PrimaryIndex.Columns; pKey = cols [0]; if ((cols [0] > undesired) || (cols [0] + cols.Length < undesired)) { if (undesired < initialTable.PrimaryIndex.Columns [0]) { // reindexarea... for (int i = 0; i < cols.Length; i++) { cols [i]--; } // endOf reindexarea... } // MT: This initially wouldn't compile, missing the array index on cols[] swapTable.CreatePrimaryKey (cols [0]); } else { swapTable.CreatePrimaryKey (); } } // endof PrimaryKey... // sa ne farimam cu indicii... ;-(( Index idx = null; while (true) { idx = initialTable.GetNextIndex (idx); if (idx == null) { break; } if (idx == initialTable.PrimaryIndex) { continue; } bool flag = true; int[] cols = idx.Columns; for (int i = 0; i < cols.Length; i++) { if (cols [i] == undesired) { flag = false; } } if (flag) { Index tIdx; for (int i = 0; i < cols.Length; i++) { if (cols [i] > undesired) { cols [i]--; } } tIdx = new Index (idx.Name, idx.Columns, idx.ColumnType, idx.IsUnique); swapTable.CreateIndex (tIdx); } } // !-- cChannel.Commit (); dDatabase.LinkTable (swapTable); Tokenizer tmpTokenizer = new Tokenizer ("SELECT * FROM " + tName); Parser pp = new Parser (dDatabase, tmpTokenizer, cChannel); string ff = tmpTokenizer.GetString (); if (!initialTable.IsEmpty) { Record n = ((Result)pp.ProcessSelect ()).Root; do { object[] row = swapTable.NewRow; object[] row1 = n.Data; int j = 0; for (int i = 0; i < initialTable.ColumnCount; i++) { if (i != undesired) { row [j] = row1 [i]; j++; } } swapTable.InsertNoCheck (row, cChannel); n = n.Next; } while (n != null); } dDatabase.Execute ("DROP TABLE " + tName, cChannel); // cream tabelul vechi cu proprietatile celui nou... initialTable = new Table (dDatabase, true, tName, swapTable.IsCached); for (int i = 0; i < swapTable.ColumnCount; i++) { Column aColumn = swapTable.GetColumn (i); initialTable.AddColumn (aColumn); } // !-- if (swapTable.ColumnCount < swapTable.InternalColumnCount) { initialTable.CreatePrimaryKey (); } else { initialTable.CreatePrimaryKey (swapTable.PrimaryIndex.Columns [0]); } // endof PrimaryKey... // sa ne farimam cu indicii... ;-(( idx = null; while (true) { idx = swapTable.GetNextIndex (idx); if (idx == null) { break; } if (idx == swapTable.PrimaryIndex) { continue; } initialTable.CreateIndex (idx); } // end of Index... // !-- cChannel.Commit (); dDatabase.LinkTable (initialTable); // end of cream... // copiem datele din swap in tabel... tmpTokenizer = new Tokenizer ("SELECT * FROM " + swap); pp = new Parser (dDatabase, tmpTokenizer, cChannel); ff = tmpTokenizer.GetString (); if (!swapTable.IsEmpty) { Record n = ((Result)pp.ProcessSelect ()).Root; do { object[] row = initialTable.NewRow; object[] row1 = n.Data; for (int i = 0; i < swapTable.ColumnCount; i++) { row [i] = row1 [i]; } initialTable.InsertNoCheck (row, cChannel); n = n.Next; } while (n != null); // end of copiem... } dDatabase.Execute ("DROP TABLE " + swap, cChannel); count = 3; } else { throw TracingHelper.Error (TracingHelper.UnexpectedToken, token); } count = 3; } Result r = new Result (); r.SetUpdateCount (count); return r; }
internal void LinkTable(Table table) { string name = table.Name; for (int i = 0; i < _table.Count; i++) { Table o = (Table)_table[i]; if (o.Name.Equals(name)) { throw TracingHelper.Error(TracingHelper.TABLE_ALREADY_EXISTS, name); } } _table.Add(table); }
/// <summary> /// Write column data to file. /// </summary> /// <param name="writer"></param> /// <param name="data"></param> /// <param name="table"></param> internal static void WriteData(BinaryWriter writer, object[] data, Table table) { int len = table.InternalColumnCount; ColumnType[] type = new ColumnType[len]; for (int i = 0; i < len; i++) { type[i] = table.GetType(i); } WriteData(writer, len, type, data); }
internal Row(Table t, BinaryReader din, int pos, Row before) { tTable = t; int index = tTable.IndexCount; Pos = pos; nFirstIndex = new Node(this, din, 0); Node n = nFirstIndex; for (int i = 1; i < index; i++) { n.nNext = new Node(this, din, i); n = n.nNext; } int l = tTable.InternalColumnCount; oData = Column.ReadData(din, l); int iCurrent = din.ReadInt32(); LogHelper.Publish( String.Format("Row read with {0} columns. Row read position from file: {1}. Current position: {2}.", oData.Length, iCurrent, Pos ), LogEntryType.Debug ); TracingHelper.Check(iCurrent == Pos, TracingHelper.INPUTSTREAM_ERROR); Insert(before); LastAccess = CurrentAccess++; }
private void ProcessCreateTable(Tokenizer tokenizer, Channel channel, bool cached) { Table t; string sToken = tokenizer.GetName(); if (cached && _log != null) { t = new Table(this, true, sToken, true); } else { t = new Table(this, true, sToken, false); } tokenizer.GetThis("("); int primarykeycolumn = -1; int column = 0; bool constraint = false; while (true) { bool identity = false; sToken = tokenizer.GetString(); if (sToken.Equals("CONSTRAINT") || sToken.Equals("PRIMARY") || sToken.Equals("FOREIGN") || sToken.Equals("UNIQUE")) { tokenizer.Back(); constraint = true; break; } string sColumn = sToken; ColumnType iType = Column.GetColumnType(tokenizer.GetString()); if (iType == ColumnType.VarChar && _ignoreCase) { iType = ColumnType.VarCharIgnoreCase; } sToken = tokenizer.GetString(); if (iType == ColumnType.DbDouble && sToken.Equals("PRECISION")) { sToken = tokenizer.GetString(); } if (sToken.Equals("(")) { // overread length do { sToken = tokenizer.GetString(); } while (!sToken.Equals(")")); sToken = tokenizer.GetString(); } bool nullable = true; if (sToken.Equals("NULL")) { sToken = tokenizer.GetString(); } else if (sToken.Equals("NOT")) { tokenizer.GetThis("NULL"); nullable = false; sToken = tokenizer.GetString(); } if (sToken.Equals("IDENTITY")) { identity = true; TracingHelper.Check(primarykeycolumn == -1, TracingHelper.SECOND_PRIMARY_KEY, sColumn); sToken = tokenizer.GetString(); primarykeycolumn = column; } if (sToken.Equals("PRIMARY")) { tokenizer.GetThis("KEY"); TracingHelper.Check(identity || primarykeycolumn == -1, TracingHelper.SECOND_PRIMARY_KEY, sColumn); primarykeycolumn = column; sToken = tokenizer.GetString(); } t.AddColumn(sColumn, iType, nullable, identity); if (sToken.Equals(")")) { break; } if (!sToken.Equals(",")) { throw TracingHelper.Error(TracingHelper.UnexpectedToken, sToken); } column++; } if (primarykeycolumn != -1) { t.CreatePrimaryKey(primarykeycolumn); } else { t.CreatePrimaryKey(); } if (constraint) { int i = 0; while (true) { sToken = tokenizer.GetString(); string name = "SYSTEM_CONSTRAINT" + i; i++; if (sToken.Equals("CONSTRAINT")) { name = tokenizer.GetString(); sToken = tokenizer.GetString(); } if (sToken.Equals("PRIMARY")) { tokenizer.GetThis("KEY"); AddUniqueConstraintOn(tokenizer, channel, name, t); } else if (sToken.Equals("UNIQUE")) { AddUniqueConstraintOn(tokenizer, channel, name, t); } else if (sToken.Equals("FOREIGN")) { tokenizer.GetThis("KEY"); AddForeignKeyOn(tokenizer, channel, name, t); } sToken = tokenizer.GetString(); if (sToken.Equals(")")) { break; } if (!sToken.Equals(",")) { throw TracingHelper.Error(TracingHelper.UnexpectedToken, sToken); } } } channel.Commit(); LinkTable(t); }
/// <summary> /// Replaces the main or reference table with a new one. /// </summary> /// <param name="oldTable"></param> /// <param name="newTable"></param> internal void ReplaceTable(Table oldTable, Table newTable) { if (oldTable == _mainTable) { _mainTable = newTable; } else if (oldTable == _refTable) { _refTable = newTable; } else { TracingHelper.Assert(false, "could not replace"); } }
private int[] ProcessColumnList(Tokenizer tokenizer, Table table) { ArrayList v = new ArrayList(); tokenizer.GetThis("("); while (true) { v.Add(tokenizer.GetString()); string sToken = tokenizer.GetString(); if (sToken.Equals(")")) { break; } if (!sToken.Equals(",")) { throw TracingHelper.Error(TracingHelper.UnexpectedToken, sToken); } } int s = v.Count; int[] col = new int[s]; for (int i = 0; i < s; i++) { col[i] = table.GetColumnNumber((string) v[i]); } return col; }
private void CreateIndex(Channel channel, Table t, int[] col, string name, bool unique) { channel.Commit(); if (t.IsEmpty) { t.CreateIndex(col, name, unique); } else { Table tn = t.MoveDefinition(null); tn.CreateIndex(col, name, unique); tn.MoveData(t); DropTable(t.Name); LinkTable(tn); } }
private void AddUniqueConstraintOn(Tokenizer tokenizer, Channel channel, string name, Table table) { int[] col = ProcessColumnList(tokenizer, table); CreateIndex(channel, table, col, name, true); table.AddConstraint(new Constraint(ConstraintType.Unique, table, col)); }
private void AddIndexOn(Tokenizer tokenizer, Channel channel, string name, Table table, bool unique) { int[] col = ProcessColumnList(tokenizer, table); CreateIndex(channel, table, col, name, unique); }
private void AddForeignKeyOn(Tokenizer tokenizer, Channel channel, string name, Table table) { int[] col = ProcessColumnList(tokenizer, table); tokenizer.GetThis("REFERENCES"); Table t2 = GetTable(tokenizer.GetString(), channel); int[] col2 = ProcessColumnList(tokenizer, t2); if (table.GetIndexForColumns(col) == null) { CreateIndex(channel, table, col, "SYSTEM_FOREIGN_KEY_" + name, false); } if (t2.GetIndexForColumns(col2) == null) { CreateIndex(channel, t2, col2, "SYSTEM_REFERENCE_" + name, false); } table.AddConstraint(new Constraint(ConstraintType.ForeignKey, t2, table, col2, col)); t2.AddConstraint(new Constraint(ConstraintType.Main, t2, table, col2, col)); }
/// <summary> /// GetRow method declaration. /// This method reads a Row object from the cache. /// </summary> /// <param name="pos">Offset of the requested Row in the cache</param> /// <param name="table">Table this Row belongs to</param> /// <returns>The Row object as read from the cache.</returns> public Row GetRow(int pos, Table table) { int k = pos & MASK; Row r = _rowData[k]; Row start = r; while (r != null) { if (TracingHelper.StopEnabled) TracingHelper.Stop(); int p = r.Pos; if (p == pos) return r; else if ((p & MASK) != k) break; r = r.Next; if (r == start) break; } Row before = _rowData[k]; if (before == null) { before = _rowFirst; } try { LogHelper.Publish( String.Format("Retrieving row at position: {0}.", pos ), LogEntryType.Debug ); _fileStream.Seek(pos, SeekOrigin.Begin); BinaryReader b = new BinaryReader(_fileStream); int size = b.ReadInt32(); byte[] buffer = new byte[size]; buffer = b.ReadBytes(size); LogHelper.Publish( String.Format("Row Size: {0}. Retrieved {1} bytes.", size, buffer.Length ), LogEntryType.Debug ); MemoryStream bin = new MemoryStream(buffer); BinaryReader din = new BinaryReader(bin, System.Text.Encoding.Unicode); r = new Row(table, din, pos, before); r.Size = size; } catch (IOException e) { #if !POCKETPC Console.WriteLine(e.StackTrace); #endif throw TracingHelper.Error(TracingHelper.FILE_IO_ERROR, "reading: " + e); } _cacheSize++; _rowData[k] = r; _rowFirst = r; return r; }
/// <summary> /// Constructor using Main and Reference Table. /// </summary> /// <param name="type"></param> /// <param name="main"></param> /// <param name="child"></param> /// <param name="columnMain"></param> /// <param name="columnRef"></param> public Constraint(ConstraintType type, Table main, Table child, int[] columnMain, int[] columnRef) { _type = type; _mainTable = main; _refTable = child; _mainColumns = columnMain; _refColumns = columnRef; _len = columnMain.Length; if (TracingHelper.AssertEnabled) { TracingHelper.Assert(columnMain.Length == columnRef.Length); } _mainData = _mainTable.NewRow; _refData = _refTable.NewRow; _mainIndex = _mainTable.GetIndexForColumns(columnMain); _refIndex = _refTable.GetIndexForColumns(columnRef); }
private TableFilter ParseTableFilter(bool outerjoin) { string token = tTokenizer.GetString (); Table t = null; if (token.Equals ("(")) { tTokenizer.GetThis ("SELECT"); Select s = ParseSelect (); Result r = s.GetResult (0, null); // it's not a problem that this table has not a unique name t = new Table (dDatabase, false, "SYSTEM_SUBQUERY", false); tTokenizer.GetThis (")"); t.AddColumns (r); t.CreatePrimaryKey (); // subquery creation can't fail because of violation of primary key t.Insert (r, cChannel); } else { cChannel.Check (token, AccessType.Select); t = dDatabase.GetTable (token, cChannel); } string sAlias = null; token = tTokenizer.GetString (); if (token.Equals ("AS")) { sAlias = tTokenizer.GetName (); } else if (tTokenizer.WasName) { sAlias = token; } else { tTokenizer.Back (); } return new TableFilter (t, sAlias, outerjoin); }
public Result ProcessSelect() { Select select = ParseSelect (); if (select.sIntoTable == null) { // [email protected] begin changes from 1.50 // return select.getResult(cChannel.getMaxRows()); return select.GetResult (select.limitStart, select.limitCount, cChannel); // [email protected] end changes from 1.50 } else { Result r = select.GetResult (0, cChannel); Table t = new Table (dDatabase, true, select.sIntoTable, false); t.AddColumns (r); t.CreatePrimaryKey (); // SELECT .. INTO can't fail because of violation of primary key t.Insert (r, cChannel); dDatabase.LinkTable (t); int i = r.Size; r = new Result (); r.SetUpdateCount (i); return r; } }
/// <summary> /// Gets the size of the stored data. /// </summary> /// <param name="data"></param> /// <param name="table"></param> /// <returns></returns> internal static int GetSize(object[] data, Table table) { int l = data.Length; ColumnType[] type = new ColumnType[l]; for (int i = 0; i < l; i++) { type[i] = table.GetType(i); } return GetSize(data, l, type); }
public Transaction(bool delete, Table table, object[] row) { _delete = delete; _table = table; _row = row; }