private Table tTable; // null: memory row; otherwise: cached table #endregion Fields #region Constructors /** * Constructor declaration * * * @param t * @param o */ public Row(Table t, object[] o) { tTable = t; int index = tTable.getIndexCount(); 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) { iLastAccess = iCurrentAccess++; // todo: 32 bytes overhead for each index + iSize, iPos iSize = 8 + Column.getSize(o, tTable) + 16 * tTable.getIndexCount(); //((iSize + 7) / 8) * 8; // align to 8 byte blocks tTable.cCache.add(this); } bChanged = true; }
/** * Constructor declaration * * * @param type * @param t * @param col */ public Constraint(int type, Table t, int[] col) { iType = type; tMain = t; iColMain = col; iLen = col.Length; }
// object[] getCurrent() { // return oCurrentData; // } /** * Constructor declaration * * * @param t * @param alias * @param outerjoin */ public TableFilter(Table t, string alias, bool outerjoin) { tTable = t; iIndex = null; sAlias = alias != null ? alias : t.getName(); bOuterJoin = outerjoin; oEmptyData = tTable.getNewRow(); }
/** * Method declaration * * * @param table * @param row * * @throws Exception */ public void addTransactionDelete(Table table, object[] row) { if (!bAutoCommit) { Transaction t = new Transaction(true, table, row); tTransaction.Add(t); } }
/** * Method declaration * * * @param t * @param col * @param len * * @return */ private string getColumnList(Table t, int[] col, int len) { StringBuilder a = new StringBuilder(); a.Append("("); for (int i = 0; i < len; i++) { a.Append(t.getColumnName(col[i])); if (i < len - 1) { a.Append(","); } } return a.Append(")").ToString(); }
/** * Constructor declaration * * * @param type * @param main * @param ref * @param cmain * @param cref */ public Constraint(int type, Table main, Table child, int[] cmain, int[] cref) { iType = type; tMain = main; tRef = child; iColMain = cmain; iColRef = cref; iLen = cmain.Length; if (Trace.ASSERT) { Trace.assert(cmain.Length == cref.Length); } oMain = tMain.getNewRow(); oRef = tRef.getNewRow(); iMain = tMain.getIndexForColumns(cmain); iRef = tRef.getIndexForColumns(cref); }
/** * Method declaration * * * @param old * @param n * * @throws Exception */ public void replaceTable(Table old, Table n) { if (old == tMain) { tMain = n; } else if (old == tRef) { tRef = n; } else { Trace.assert(false, "could not replace"); } }
/** * Method declaration * * * @return * * @throws Exception */ 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 ); // [email protected] end changes from 1.50 } else { Result r = select.getResult(0); 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.getSize(); r = new Result(); r.iUpdateCount = i; return r; } }
/** * Method declaration * * * @param data * @param t * * @return */ public static int getSize(object[] data, Table t) { int l = data.Length; int[] type = new int[l]; for (int i = 0; i < l; i++) { type[i] = t.getType(i); } return getSize(data, l, type); }
/** * Method declaration * * * @param out * @param data * @param t * * @throws IOException */ public static void writeData(BinaryWriter dout, object[] data, Table t) { int len = t.getInternalColumnCount(); int[] type = new int[len]; for (int i = 0; i < len; i++) { type[i] = t.getType(i); } writeData(dout, len, type, data); }
/** * Method declaration * * * @param withoutindex * * @return * * @throws Exception */ public Table moveDefinition(string withoutindex) { Table tn = new Table(dDatabase, true, getName(), isCached()); for (int i = 0; i < getColumnCount(); i++) { tn.addColumn(getColumn(i)); } // todo: there should be nothing special with the primary key! if (iVisibleColumns < iColumnCount) { tn.createPrimaryKey(); } else { tn.createPrimaryKey(getPrimaryIndex().getColumns()[0]); } Index idx = null; while (true) { idx = getNextIndex(idx); if (idx == null) { break; } if (withoutindex != null && idx.getName().Equals(withoutindex)) { continue; } if (idx == getPrimaryIndex()) { 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; }
/** * Method declaration * * * @param from * * @throws Exception */ public void moveData(Table from) { Index index = from.getPrimaryIndex(); Node n = index.first(); while (n != null) { if (Trace.STOP) { Trace.stop(); } object[] o = n.getData(); insertNoCheck(o, null); n = index.next(n); } index = getPrimaryIndex(); n = index.first(); while (n != null) { if (Trace.STOP) { Trace.stop(); } object[] o = n.getData(); from.deleteNoCheck(o, null); n = index.next(n); } }
// if read from cache /** * Constructor declaration * * * @param t * @param in * @param pos * @param before */ public Row(Table t, BinaryReader din, int pos, Row before) { tTable = t; int index = tTable.getIndexCount(); iPos = 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.getInternalColumnCount(); oData = Column.readData(din, l); int iCurrent = din.ReadInt32(); Trace.check(iCurrent == iPos, Trace.INPUTSTREAM_ERROR); insert(before); iLastAccess = iCurrentAccess++; }
/** * Method declaration * * ALTER TABLE tableName ADD COLUMN columnName columnType; * ALTER TABLE tableName DELETE COLUMN columnName; * * <B>Note: </B>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 * * @return * * @throws Exception */ 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.getColumnCount(); 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(); int iType = Column.getTypeNr(cType); string sToken = cType; // int primarykeycolumn = -1; bool identity = false; int column = initialTable.getColumnCount() + 1; // !-- // stolen from CREATE TABLE... string sColumn = cName; if (iType == Column.VARCHAR && dDatabase.isIgnoreCase()) { iType = Column.VARCHAR_IGNORECASE; } sToken = tTokenizer.getstring(); if (iType == Column.DOUBLE && 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.getColumnCount() < initialTable.getInternalColumnCount()) { swapTable.createPrimaryKey(); } else { swapTable.createPrimaryKey(initialTable.getPrimaryIndex().getColumns()[0]); } // endof PrimaryKey... // sa ne farimam cu indicii... ;-(( Index idx = null; while (true) { idx = initialTable.getNextIndex(idx); if (idx == null) { break; } if (idx == initialTable.getPrimaryIndex()) { 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()).rRoot; do { object[] row = swapTable.getNewRow(); object[] row1 = n.data; for (int i = 0; i < initialTable.getColumnCount(); 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.getColumnCount(); i++) { Column aColumn = swapTable.getColumn(i); initialTable.addColumn(aColumn); } if (swapTable.getColumnCount() < swapTable.getInternalColumnCount()) { initialTable.createPrimaryKey(); } else { initialTable.createPrimaryKey(swapTable.getPrimaryIndex().getColumns()[0]); } // endof PrimaryKey... // sa ne farimam cu indicii... ;-(( idx = null; while (true) { idx = swapTable.getNextIndex(idx); if (idx == null) { break; } if (idx == swapTable.getPrimaryIndex()) { 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()).rRoot; do { object[] row = initialTable.getNewRow(); object[] row1 = n.data; for (int i = 0; i < swapTable.getColumnCount(); 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 Trace.error(Trace.UNEXPECTED_TOKEN, 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.getColumnNr(cName); for (int i = 0; i < initialTable.getColumnCount(); i++) { Column aColumn = initialTable.getColumn(i); if (i != undesired) { swapTable.addColumn(aColumn); } } int pKey = -1; // !-- if (initialTable.getColumnCount() < initialTable.getInternalColumnCount()) { swapTable.createPrimaryKey(); } else { int[] cols = initialTable.getPrimaryIndex().getColumns(); pKey = cols[0]; if ((cols[0] > undesired) || (cols[0] + cols.Length < undesired)) { if (undesired < initialTable.getPrimaryIndex().getColumns()[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.getPrimaryIndex()) { continue; } bool flag = true; int[] cols = idx.getColumns(); 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.getName(), idx.getColumns(), idx.getType(), 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()).rRoot; do { object[] row = swapTable.getNewRow(); object[] row1 = n.data; int j = 0; for (int i = 0; i < initialTable.getColumnCount(); 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.getColumnCount(); i++) { Column aColumn = swapTable.getColumn(i); initialTable.addColumn(aColumn); } // !-- if (swapTable.getColumnCount() < swapTable.getInternalColumnCount()) { initialTable.createPrimaryKey(); } else { initialTable.createPrimaryKey(swapTable.getPrimaryIndex().getColumns()[0]); } // endof PrimaryKey... // sa ne farimam cu indicii... ;-(( idx = null; while (true) { idx = swapTable.getNextIndex(idx); if (idx == null) { break; } if (idx == swapTable.getPrimaryIndex()) { 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()).rRoot; do { object[] row = initialTable.getNewRow(); object[] row1 = n.data; for (int i = 0; i < swapTable.getColumnCount(); 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 Trace.error(Trace.UNEXPECTED_TOKEN, token); } count = 3; } Result r = new Result(); r.iUpdateCount = count; // --> nu tre inca...?? return r; }
/** * Method declaration * * * @param table * @param row * * @throws Exception */ public void addTransactionInsert(Table table, object[] row) { if (!bAutoCommit) { Transaction t = new Transaction(false, table, row); tTransaction.Add(t); } }
/** * Constructor declaration * * * @param delete * @param table * @param row */ public Transaction(bool delete, Table table, object[] row) { bDelete = delete; tTable = table; oRow = row; }
/** * getRow method declaration * <P>This method reads a Row object from the cache. * * @param pos (offset of the requested Row in the cache) * @param t (Table this Row belongs to) * * @return The Row object as read from the cache. * * @throws Exception */ public Row getRow(int pos, Table t) { int k = pos & MASK; Row r = rData[k]; Row start = r; while (r != null) { if (Trace.STOP) { Trace.stop(); } int p = r.iPos; if (p == pos) { return r; } else if ((p & MASK) != k) { break; } r = r.rNext; if (r == start) { break; } } Row before = rData[k]; if (before == null) { before = rFirst; } try { rFile.Seek(pos,SeekOrigin.Begin); BinaryReader b = new BinaryReader(rFile); int size = b.ReadInt32(); byte[] buffer = new byte[size]; buffer = b.ReadBytes(size); MemoryStream bin = new MemoryStream(buffer); BinaryReader din = new BinaryReader(bin); r = new Row(t, din, pos, before); r.iSize = size; } catch (IOException e) { Console.WriteLine(e.StackTrace); throw Trace.error(Trace.FILE_IO_ERROR, "reading: " + e); } // todo: copy & paste here iCacheSize++; rData[k] = r; rFirst = r; return r; }
/** * Method declaration * * * @param outerjoin * * @return * * @throws Exception */ 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); // 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, Access.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); }