/** * Method declaration * * * @param c * @param t * * @return * * @throws Exception */ private int[] processColumnList(Tokenizer c, Table t) { ArrayList v = new ArrayList(); c.getThis("("); while (true) { v.Add(c.getstring()); string sToken = c.getstring(); if (sToken.Equals(")")) { break; } if (!sToken.Equals(",")) { throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken); } } int s = v.Count; int[] col = new int[s]; for (int i = 0; i < s; i++) { col[i] = t.getColumnNr((string)v[i]); } return(col); }
/** * Method declaration * * * @param c * @param channel * * @return * * @throws Exception */ private Result processDrop(Tokenizer c, Channel channel) { channel.checkReadWrite(); channel.checkAdmin(); string sToken = c.getstring(); if (sToken.Equals("TABLE")) { sToken = c.getstring(); if (sToken.Equals("IF")) { sToken = c.getstring(); // EXISTS sToken = c.getstring(); // <table> dropTable(sToken, true); } else { dropTable(sToken, false); } channel.commit(); } else if (sToken.Equals("USER")) { aAccess.dropUser(c.getstringToken()); } else if (sToken.Equals("INDEX")) { sToken = c.getstring(); if (!c.wasLongName()) { throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken); } string table = c.getLongNameFirst(); string index = c.getLongNameLast(); Table t = getTable(table, channel); t.checkDropIndex(index); Table tn = t.moveDefinition(index); tn.moveData(t); dropTable(table); linkTable(tn); channel.commit(); } else { throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken); } return(new Result()); }
/** * Method declaration * * * @param c * @param channel * @param grant * * @return * * @throws Exception */ private Result processGrantOrRevoke(Tokenizer c, Channel channel, bool grant) { channel.checkReadWrite(); channel.checkAdmin(); int right = 0; string sToken; do { string sRight = c.getstring(); right |= Access.getRight(sRight); sToken = c.getstring(); } while (sToken.Equals(",")); if (!sToken.Equals("ON")) { throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken); } string table = c.getstring(); if (table.Equals("CLASS")) { // object is saved as 'CLASS "java.lang.Math"' // tables like 'CLASS "xy"' should not be created table += " \"" + c.getstring() + "\""; } else { getTable(table, channel); // to make sure the table exists } c.getThis("TO"); string user = c.getstringToken(); // string command; if (grant) { aAccess.grant(user, table, right); // command = "GRANT"; } else { aAccess.revoke(user, table, right); // command = "REVOKE"; } return(new Result()); }
/** * Method declaration * * * @param c * @param channel * @param name * @param t * * @throws Exception */ private void addForeignKeyOn(Tokenizer c, Channel channel, string name, Table t) { int[] col = processColumnList(c, t); c.getThis("REFERENCES"); Table t2 = getTable(c.getstring(), channel); int[] col2 = processColumnList(c, t2); if (t.getIndexForColumns(col) == null) { createIndex(channel, t, col, "SYSTEM_FOREIGN_KEY_" + name, false); } if (t2.getIndexForColumns(col2) == null) { createIndex(channel, t2, col2, "SYSTEM_REFERENCE_" + name, false); } t.addConstraint(new Constraint(Constraint.FOREIGN_KEY, t2, t, col2, col)); t2.addConstraint(new Constraint(Constraint.MAIN, t2, t, col2, col)); }
/** * Method declaration * * * @param c * @param channel * * @return * * @throws Exception */ private Result processRollback(Tokenizer c, Channel channel) { string sToken = c.getstring(); if (!sToken.Equals("WORK")) { c.back(); } channel.rollback(); return(new Result()); }
/** * Method declaration * * * @param c * * @return * * @throws Exception */ private bool processTrueOrFalse(Tokenizer c) { string sToken = c.getstring(); if (sToken.Equals("TRUE")) { return(true); } else if (sToken.Equals("FALSE")) { return(false); } else { throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken); } }
/** * Method declaration * * * @param c * @param channel * * @return * * @throws Exception */ private Result processScript(Tokenizer c, Channel channel) { string sToken = c.getstring(); if (c.wasValue()) { sToken = (string)c.getAsValue(); Log.scriptToFile(this, sToken, true, channel); return(new Result()); } else { c.back(); // try to script all: drop, insert; but no positions for cached tables return(getScript(true, true, false, channel)); } }
/** * Method declaration * * * @param c * @param channel * * @return * * @throws Exception */ private Result processShutdown(Tokenizer c, Channel channel) { channel.checkAdmin(); // don't disconnect system user; need it to save database for (int i = 1; i < cChannel.Count; i++) { Channel d = (Channel)cChannel[i]; if (d != null) { d.disconnect(); } } cChannel.Clear(); string token = c.getstring(); if (token.Equals("IMMEDIATELY")) { close(-1); } else if (token.Equals("COMPACT")) { close(1); } else { c.back(); close(0); } processDisconnect(c, channel); return(new Result()); }
/** * Method declaration * * * @param c * @param channel * @param cached * * @throws Exception */ private void processCreateTable(Tokenizer c, Channel channel, bool cached) { Table t; string sToken = c.getName(); if (cached && lLog != null) { t = new Table(this, true, sToken, true); } else { t = new Table(this, true, sToken, false); } c.getThis("("); int primarykeycolumn = -1; int column = 0; bool constraint = false; while (true) { bool identity = false; sToken = c.getstring(); if (sToken.Equals("CONSTRAINT") || sToken.Equals("PRIMARY") || sToken.Equals("FOREIGN") || sToken.Equals("UNIQUE")) { c.back(); constraint = true; break; } string sColumn = sToken; int iType = Column.getTypeNr(c.getstring()); if (iType == Column.VARCHAR && bIgnoreCase) { iType = Column.VARCHAR_IGNORECASE; } sToken = c.getstring(); if (iType == Column.DOUBLE && sToken.Equals("PRECISION")) { sToken = c.getstring(); } if (sToken.Equals("(")) { // overread length do { sToken = c.getstring(); } while (!sToken.Equals(")")); sToken = c.getstring(); } bool nullable = true; if (sToken.Equals("NULL")) { sToken = c.getstring(); } else if (sToken.Equals("NOT")) { c.getThis("NULL"); nullable = false; sToken = c.getstring(); } if (sToken.Equals("IDENTITY")) { identity = true; Trace.check(primarykeycolumn == -1, Trace.SECOND_PRIMARY_KEY, sColumn); sToken = c.getstring(); primarykeycolumn = column; } if (sToken.Equals("PRIMARY")) { c.getThis("KEY"); Trace.check(identity || primarykeycolumn == -1, Trace.SECOND_PRIMARY_KEY, sColumn); primarykeycolumn = column; sToken = c.getstring(); } t.addColumn(sColumn, iType, nullable, identity); if (sToken.Equals(")")) { break; } if (!sToken.Equals(",")) { throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken); } column++; } if (primarykeycolumn != -1) { t.createPrimaryKey(primarykeycolumn); } else { t.createPrimaryKey(); } if (constraint) { int i = 0; while (true) { sToken = c.getstring(); string name = "SYSTEM_CONSTRAINT" + i; i++; if (sToken.Equals("CONSTRAINT")) { name = c.getstring(); sToken = c.getstring(); } if (sToken.Equals("PRIMARY")) { c.getThis("KEY"); addUniqueConstraintOn(c, channel, name, t); } else if (sToken.Equals("UNIQUE")) { addUniqueConstraintOn(c, channel, name, t); } else if (sToken.Equals("FOREIGN")) { c.getThis("KEY"); addForeignKeyOn(c, channel, name, t); } sToken = c.getstring(); if (sToken.Equals(")")) { break; } if (!sToken.Equals(",")) { throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken); } } } channel.commit(); linkTable(t); }
/** * Method declaration * * * @param c * @param channel * * @return * * @throws Exception */ private Result processCreate(Tokenizer c, Channel channel) { channel.checkReadWrite(); channel.checkAdmin(); string sToken = c.getstring(); if (sToken.Equals("TABLE")) { processCreateTable(c, channel, false); } else if (sToken.Equals("MEMORY")) { c.getThis("TABLE"); processCreateTable(c, channel, false); } else if (sToken.Equals("CACHED")) { c.getThis("TABLE"); processCreateTable(c, channel, true); } else if (sToken.Equals("USER")) { string u = c.getstringToken(); c.getThis("PASSWORD"); string p = c.getstringToken(); bool admin; if (c.getstring().Equals("ADMIN")) { admin = true; } else { admin = false; } aAccess.createUser(u, p, admin); } else if (sToken.Equals("ALIAS")) { string name = c.getstring(); sToken = c.getstring(); Trace.check(sToken.Equals("FOR"), Trace.UNEXPECTED_TOKEN, sToken); sToken = c.getstring(); hAlias.Add(name, sToken); } else { bool unique = false; if (sToken.Equals("UNIQUE")) { unique = true; sToken = c.getstring(); } if (!sToken.Equals("INDEX")) { throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken); } string name = c.getName(); c.getThis("ON"); Table t = getTable(c.getstring(), channel); addIndexOn(c, channel, name, t, unique); } return(new Result()); }
/** * Method declaration * * * @param statement * @param channel * * @return */ public Result execute(string statement, Channel channel) { if (Trace.TRACE) { Trace.trace(statement); } Tokenizer c = new Tokenizer(statement); Parser p = new Parser(this, c, channel); Result rResult = new Result(); try { if (lLog != null && lLog.cCache != null) { lLog.cCache.cleanUp(); } if (Trace.ASSERT) { Trace.assert(!channel.isNestedTransaction()); } Trace.check(channel != null, Trace.ACCESS_IS_DENIED); Trace.check(!bShutdown, Trace.DATABASE_IS_SHUTDOWN); while (true) { int begin = c.getPosition(); bool script = false; string sToken = c.getstring(); if (sToken.Equals("")) { break; } else if (sToken.Equals("SELECT")) { rResult = p.processSelect(); } else if (sToken.Equals("INSERT")) { rResult = p.processInsert(); } else if (sToken.Equals("UPDATE")) { rResult = p.processUpdate(); } else if (sToken.Equals("DELETE")) { rResult = p.processDelete(); } else if (sToken.Equals("ALTER")) { rResult = p.processAlter(); } else if (sToken.Equals("CREATE")) { rResult = processCreate(c, channel); script = true; } else if (sToken.Equals("DROP")) { rResult = processDrop(c, channel); script = true; } else if (sToken.Equals("GRANT")) { rResult = processGrantOrRevoke(c, channel, true); script = true; } else if (sToken.Equals("REVOKE")) { rResult = processGrantOrRevoke(c, channel, false); script = true; } else if (sToken.Equals("CONNECT")) { rResult = processConnect(c, channel); } else if (sToken.Equals("DISCONNECT")) { rResult = processDisconnect(c, channel); } else if (sToken.Equals("SET")) { rResult = processSet(c, channel); script = true; } else if (sToken.Equals("SCRIPT")) { rResult = processScript(c, channel); } else if (sToken.Equals("COMMIT")) { rResult = processCommit(c, channel); script = true; } else if (sToken.Equals("ROLLBACK")) { rResult = processRollback(c, channel); script = true; } else if (sToken.Equals("SHUTDOWN")) { rResult = processShutdown(c, channel); } else if (sToken.Equals("CHECKPOINT")) { rResult = processCheckpoint(channel); } else if (sToken.Equals("CALL")) { rResult = p.processCall(); } else if (sToken.Equals(";")) { // ignore } else { throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken); } if (script && lLog != null) { int end = c.getPosition(); lLog.write(channel, c.getPart(begin, end)); } } } catch (Exception e) { rResult = new Result(Trace.getMessage(e) + " in statement [" + statement + "]"); } return(rResult); }
/** * Method declaration * * * @param c * @param channel * * @return * * @throws Exception */ private Result processSet(Tokenizer c, Channel channel) { string sToken = c.getstring(); if (sToken.Equals("PASSWORD")) { channel.checkReadWrite(); channel.setPassword(c.getstringToken()); } else if (sToken.Equals("READONLY")) { channel.commit(); channel.setReadOnly(processTrueOrFalse(c)); } else if (sToken.Equals("LOGSIZE")) { channel.checkAdmin(); int i = Int32.FromString(c.getstring()); if (lLog != null) { lLog.setLogSize(i); } } else if (sToken.Equals("IGNORECASE")) { channel.checkAdmin(); bIgnoreCase = processTrueOrFalse(c); } else if (sToken.Equals("MAXROWS")) { int i = Int32.FromString(c.getstring()); channel.setMaxRows(i); } else if (sToken.Equals("AUTOCOMMIT")) { channel.setAutoCommit(processTrueOrFalse(c)); } else if (sToken.Equals("TABLE")) { channel.checkReadWrite(); channel.checkAdmin(); Table t = getTable(c.getstring(), channel); c.getThis("INDEX"); c.getstring(); t.setIndexRoots((string)c.getAsValue()); } else if (sToken.Equals("REFERENCIAL_INTEGRITY") || sToken.Equals("REFERENTIAL_INTEGRITY")) { channel.checkAdmin(); bReferentialIntegrity = processTrueOrFalse(c); } else if (sToken.Equals("WRITE_DELAY")) { channel.checkAdmin(); bool delay = processTrueOrFalse(c); if (lLog != null) { lLog.setWriteDelay(delay); } } else { throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken); } return(new Result()); }
/** * 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; }