/* * Delete rows which match a where clause. */ private void DeleteStatement(String tableName, TinySQLWhere wc) //throws TinySQLException { TinySQLTable jtbl; java.util.Hashtable <Object, Object> tables; String columnName, columnString, whereStatus; java.util.Enumeration <Object> cols; /* * Create a table object and put it in the Hashtable. */ jtbl = getTable(tableName); tables = new java.util.Hashtable <Object, Object>(); tables.put(tableName, jtbl); /* * Process each row in the table ignoring deleted rows. */ jtbl.GoTop(); while (jtbl.NextRecord()) { if (!jtbl.isDeleted()) { cols = jtbl.column_info.keys(); whereStatus = "TRUE"; while (cols.hasMoreElements()) { columnName = jtbl.table + "->" + jtbl.tableAlias + "." + (String)cols.nextElement(); columnString = jtbl.GetCol(columnName); /* * Check the status of the where clause for each column value. */ if (wc != (TinySQLWhere)null) { whereStatus = wc.evaluate(columnName, columnString); } if (whereStatus.equals("FALSE")) { break; } } if (whereStatus.equals("TRUE")) { jtbl.DeleteRow(); } if (wc != (TinySQLWhere)null) { wc.clearValues(jtbl.table + "->" + jtbl.tableAlias); } } } jtbl.close(); }
public TsResultSet(TinySQLWhere w, TinySQL dbeng) { dbengine = dbeng; windowStart = 0; whereC = w; rows = new java.util.Vector <Object>(); rsColumns = new java.util.Vector <Object>(); selectColumns = new java.util.Vector <Object>(); orderByColumns = new java.util.Vector <Object>(); tables = new java.util.Vector <Object>(); }
/* * Execute an SQL Select Statement */ protected virtual TsResultSet SelectStatement(java.util.Hashtable <Object, Object> t, java.util.Vector <Object> c, TinySQLWhere w, String ot, bool distinct, Object stmt) //throws TinySQLException { java.util.Hashtable <Object, Object> tables; java.util.Vector <Object> tableList; TsResultSet jrs; TsColumn columnObject; int i; /* * Instantiate a new, empty tsResultSet */ jrs = new TsResultSet(w, this); groupFunctions = new java.util.Hashtable <Object, Object>(); try { jrs.setFetchSize(((TinySQLStatement)stmt).getFetchSize()); jrs.setType(((TinySQLStatement)stmt).getResultSetType()); } catch (java.sql.SQLException) { Utils.log("Caught SQLException while setting Fetchsize and ResultSetType"); Utils.log(" This event is (should be) impossible!"); } tables = t; tableList = (java.util.Vector <Object>)tables.get("TABLE_SELECT_ORDER"); /* * Add the column objects to the ResultSet. */ for (i = 0; i < c.size(); i++) { columnObject = (TsColumn)c.elementAt(i); /* * The column object is now added to the ResultSet */ jrs.addColumn(columnObject); if (debug) { java.lang.SystemJ.outJ.println("Adding " + columnObject.contextToString() + " column " + newLine + columnObject.toString() + newLine); } } jrs.setState(1, tables, ot, distinct); contSelectStatement(jrs); return(jrs); }
public TinySQLParser(java.io.InputStream sqlInput, TinySQL inputEngine) //throws TinySQLException { java.io.StreamTokenizer st; FieldTokenizer ft; java.io.Reader r; String nextToken, upperField, nextField, keyWord = (String)null; java.lang.StringBuffer cmdBuffer, inputSQLBuffer; int lastIndex, keyIndex; r = new java.io.BufferedReader(new java.io.InputStreamReader(sqlInput)); dbEngine = inputEngine; actionList = new java.util.Vector <Object>(); columnList = new java.util.Vector <Object>(); columns = new java.util.Vector <Object>(); columnAliasList = new java.util.Vector <Object>(); contextList = new java.util.Vector <Object>(); valueList = new java.util.Vector <Object>(); tableName = (String)null; whereClause = (TinySQLWhere)null; /* * The tableList is a list of table names, in the optimal order * in which they should be scanned for the SELECT phrase. * The java.util.Hashtable<Object,Object> tables contains table objects keyed by table * alias and name. */ tableList = new java.util.Vector <Object>(); tables = new java.util.Hashtable <Object, Object>(); tables.put("TABLE_SELECT_ORDER", tableList); try { st = new java.io.StreamTokenizer(r); st.eolIsSignificant(false); st.wordChars('\'', '}'); st.wordChars('?', '?'); st.wordChars('"', '.'); st.ordinaryChars('0', '9'); st.wordChars('0', '9'); cmdBuffer = new java.lang.StringBuffer(); inputSQLBuffer = new java.lang.StringBuffer(); while (st.nextToken() != java.io.StreamTokenizer.TT_EOF) { if (st.ttype == java.io.StreamTokenizer.TT_WORD) { nextToken = st.sval.trim(); } else { continue; } if (inputSQLBuffer.length() > 0) { inputSQLBuffer.append(" "); } inputSQLBuffer.append(nextToken); } ft = new FieldTokenizer(inputSQLBuffer.toString(), ' ', false); while (ft.hasMoreFields()) { nextField = ft.nextField(); upperField = nextField.toUpperCase(); if (statementType == (String)null) { statementType = upperField; lastIndex = getKeywordIndex(statementType, statementType); if (lastIndex != 0) { throwException(9); } keyWord = statementType; } else { keyIndex = getKeywordIndex(statementType, upperField); if (keyIndex < 0) { if (cmdBuffer.length() > 0) { cmdBuffer.append(" "); } cmdBuffer.append(nextField); } else { setPhrase(keyWord, cmdBuffer.toString()); cmdBuffer = new java.lang.StringBuffer(); keyWord = upperField; if (TinySQLGlobals.PARSER_DEBUG) { java.lang.SystemJ.outJ.println("Found keyword " + keyWord); } } } } if (keyWord != (String)null) { setPhrase(keyWord, cmdBuffer.toString()); } addAction(); if (TinySQLGlobals.PARSER_DEBUG) { java.lang.SystemJ.outJ.println("SQL:" + inputSQLBuffer.toString()); } } catch (Exception ex) { if (TinySQLGlobals.DEBUG) { java.lang.SystemJ.outJ.println(ex.StackTrace); //ex.printStackTrace(java.lang.SystemJ.outJ); } throw new TinySQLException(ex.getMessage()); } }
/* * This method sets up particular phrase elements for the SQL command. * Examples would be a list of selected columns and tables for a SELECT * statement, or a list of column definitions for a CREATE TABLE * statement. These phrase elements will be added to the action list * once the entire statement has been parsed. */ public void setPhrase(String inputKeyWord, String inputString) //throws TinySQLException { String nextField, upperField, fieldString, tempString, columnName, columnAlias; java.lang.StringBuffer concatBuffer; FieldTokenizer ft1, ft2, ft3; TsColumn createColumn; /* * Handle compound keywords. */ if (inputString == (String)null) { lastKeyWord = inputKeyWord; return; } else if (inputString.trim().length() == 0) { lastKeyWord = inputKeyWord; return; } if (TinySQLGlobals.PARSER_DEBUG) { java.lang.SystemJ.outJ.println("setPhrase " + inputString); } ft1 = new FieldTokenizer(inputString, ',', false); while (ft1.hasMoreFields()) { nextField = ft1.nextField().trim(); if (TinySQLGlobals.PARSER_DEBUG) { java.lang.SystemJ.outJ.println(inputKeyWord + " field is " + nextField); } upperField = nextField.toUpperCase(); if (inputKeyWord.equals("SELECT")) { /* * Check for the keyword DISTINCT */ if (nextField.toUpperCase().startsWith("DISTINCT")) { distinct = true; nextField = nextField.substring(9).trim(); } /* * Check for and set column alias. */ ft2 = new FieldTokenizer(nextField, ' ', false); columnName = ft2.getField(0); columnAlias = (String)null; /* * A column alias can be preceded by the keyword AS which will * be ignored by tinySQL. */ if (ft2.countFields() == 2) { columnAlias = ft2.getField(1); } else if (ft2.countFields() == 3) { columnAlias = ft2.getField(2); } /* * Check for column concatenation using the | symbol */ ft2 = new FieldTokenizer(columnName, '|', false); if (ft2.countFields() > 1) { concatBuffer = new java.lang.StringBuffer("CONCAT("); while (ft2.hasMoreFields()) { if (concatBuffer.length() > 7) { concatBuffer.append(","); } concatBuffer.append(ft2.nextField()); } columnName = concatBuffer.toString() + ")"; } columnList.addElement(columnName); columnAliasList.addElement(columnAlias); contextList.addElement(inputKeyWord); } else if (inputKeyWord.equals("TABLE")) { /* * If the input keyword is TABLE, update the statement type to be a * compound type such as CREATE_TABLE, DROP_TABLE, or ALTER_TABLE. */ if (!statementType.equals("INSERT")) { statementType = statementType + "_TABLE"; } if (statementType.equals("CREATE_TABLE")) { /* * Parse out the column definition. */ ft2 = new FieldTokenizer(nextField, '(', false); if (ft2.countFields() != 2) { throwException(1); } tableName = ft2.getField(0); fieldString = ft2.getField(1); ft2 = new FieldTokenizer(fieldString, ',', false); while (ft2.hasMoreFields()) { tempString = ft2.nextField(); createColumn = parseColumnDefn(tempString); if (createColumn != (TsColumn)null) { columnList.addElement(createColumn); } } } else if (statementType.equals("DROP_TABLE")) { /* * Handle dropping of non-existent tables */ tableName = upperField; try { validateTable(upperField, true); } catch (Exception) { throw new TinySQLException("Table " + tableName + " does not exist."); } } else { tableName = upperField; validateTable(upperField, true); } } else if (inputKeyWord.equals("BY")) { /* * Set up Group by and Order by columns. */ if (lastKeyWord == (String)null) { throwException(6); } else { ft3 = new FieldTokenizer(upperField, ' ', false); columnList.addElement(ft3.getField(0)); if (ft3.countFields() == 2) { /* * ASC or DESC are the only allowable directives after GROUP BY */ if (ft3.getField(1).startsWith("ASC") | ft3.getField(1).startsWith("DESC")) { orderType = ft3.getField(1); } else { throwException(7); } } if (lastKeyWord.equals("ORDER")) { defaultOrderBy = false; } contextList.addElement(lastKeyWord); } } else if (inputKeyWord.equals("DROP")) { /* * Parse list of columns to be dropped. */ statementType = "ALTER_DROP"; ft2 = new FieldTokenizer(upperField, ' ', false); while (ft2.hasMoreFields()) { columnList.addElement(UtilString.removeQuotes(ft2.nextField())); } } else if (inputKeyWord.equals("RENAME")) { /* * Parse old and new column name. */ statementType = "ALTER_RENAME"; ft2 = new FieldTokenizer(upperField, ' ', false); oldColumnName = ft2.getField(0); newColumnName = ft2.getField(1); if (newColumnName.equals("TO") & ft2.countFields() == 3) { newColumnName = ft2.getField(2); } if (newColumnName.length() > 11) { newColumnName = TinySQLGlobals.getShortName(newColumnName); } } else if (inputKeyWord.equals("ADD")) { /* * Parse definition of columns to be added. */ statementType = "ALTER_ADD"; createColumn = parseColumnDefn(nextField); if (createColumn != (TsColumn)null) { columnList.addElement(createColumn); } } else if (inputKeyWord.equals("FROM")) { /* * Check for valid table */ tableName = upperField; validateTable(tableName); } else if (inputKeyWord.equals("INTO")) { ft2 = new FieldTokenizer(nextField, '(', false); if (ft2.countFields() != 2) { throwException(3); } tableName = ft2.getField(0).toUpperCase(); validateTable(tableName); fieldString = ft2.getField(1).toUpperCase(); ft2 = new FieldTokenizer(fieldString, ',', false); while (ft2.hasMoreFields()) { tempString = UtilString.removeQuotes(ft2.nextField()); columnList.addElement(tempString); contextList.addElement(inputKeyWord); } } else if (inputKeyWord.equals("VALUES")) { ft2 = new FieldTokenizer(nextField, '(', false); fieldString = ft2.getField(0); ft2 = new FieldTokenizer(fieldString, ',', false); while (ft2.hasMoreFields()) { tempString = UtilString.removeQuotes(ft2.nextField()); tempString = UtilString.replaceAll(tempString, "''", "'"); valueList.addElement(tempString); } } else if (inputKeyWord.equals("UPDATE")) { tableName = nextField.toUpperCase(); validateTable(tableName); } else if (inputKeyWord.equals("SET")) { /* * Parse the update column name/value pairs */ ft2 = new FieldTokenizer(nextField, '=', false); if (ft2.countFields() != 2) { throwException(4); } columnList.addElement(ft2.getField(0)); contextList.addElement(inputKeyWord); valueList.addElement(UtilString.removeQuotes(ft2.getField(1))); } else if (inputKeyWord.equals("WHERE")) { whereClause = new TinySQLWhere(nextField, tables); } else if (!inputKeyWord.equals("TABLE")) { throwException(10); } } lastKeyWord = inputKeyWord; }
/* * Support function for restartable queries. Continue to * read the query result. The current state is taken from * tsResultSet. Proceed until maxFetchSize has reached. */ protected internal virtual void contSelectStatement(TsResultSet jrs) //throws TinySQLException { /* * The table scan here is an iterative tree expansion, similar to * the algorithm shown in the outline example in Chapter 5. */ String columnName, columnString, whereStatus, tableAndAlias; bool addOK; int i; int level = jrs.getLevel(); TinySQLTable jtbl; TsColumn updateColumn; java.util.Hashtable <Object, Object> tables = jrs.getTableState(); TinySQLWhere wc = jrs.getWhereClause(); /* * Create a hashtable to enumerate the tables to be scanned and initialize * with the first table name. */ java.util.Hashtable <Object, Object> tbl_list = new java.util.Hashtable <Object, Object>(); java.util.Vector <Object> t = (java.util.Vector <Object>)tables.get("TABLE_SELECT_ORDER"); String current = (String)t.elementAt(0); tbl_list.put(current, new java.lang.Integer(1)); /* * Create a row object; this is added to the ResultSet. */ TsRow record = new TsRow(); java.util.Vector <Object> resultSet = new java.util.Vector <Object>(); /* * Keep retrieving rows until we run out of rows to process. */ while (level > 0) { bool levelFound = false; /* * Find an item within the tbl_list which has the same level as the * one we're on. */ java.util.Enumeration <Object> keys = tbl_list.keys(); while (keys.hasMoreElements()) { /* * Get the next element in the "to be processed" * Hashtable, and find out its level, storing this * value in currLevel. */ String hashkey = (String)keys.nextElement(); int currLevel = ((java.lang.Integer)tbl_list.get(hashkey)).intValue(); /* * As soon as an element is found whose level is equal to the * one currently being processed, grab it's primary key (the hashkey), * flag levelfound, and break! */ if (currLevel == level) { current = hashkey; levelFound = true; break; } } bool haveRecord = false; // did we get a record or not? /* * If a table was found at the current level, then we should * try to get another row from it. */ if (levelFound) { /* * Get the current table */ jtbl = (TinySQLTable)tables.get(current); tableAndAlias = jtbl.table + "->" + jtbl.tableAlias; if (TinySQLGlobals.WHERE_DEBUG) { java.lang.SystemJ.outJ.println("Processing level " + level + " table " + tableAndAlias + "\n"); } /* * The following code is the start of setting up simple indexes * for tinySQL. The concept involves creating a new tinySQLCondition * class, instances of which will be created by tinySQLWhere. At least * initially only conditions that are equal to a constant will be * considered. One of these conditions will be stored inside the * dbfFileTable object. Calls to NextRecord would then have to add * logic to check to see if an index exists. The presence of a * complete index would be indicated by a counter that was equal * to the number of rows in the table. In that case a single get * would deliver the record numbers required for the where condition. * The NextRecord function would return these record numbers in * sequence. If the index did not exist then new values in the * index Hashtable would be created. None of this code has been * developed or implemented, let alone tested. * * * if ( wc != (tinySQLWhere)null ) * jtbl.setIndexCondition(wc.getIndexCondition(tableAndAlias)); */ if (performDebug) { java.lang.SystemJ.outJ.println("Selecting records from " + jtbl.table); } /* * Skip to the next undeleted record; at some point, * this will run out of records, and found will be false. */ bool found = false; while (jtbl.NextRecord()) { /* * Clear the column values for this table before starting * to process the next row. */ for (i = 0; i < jrs.numcols(); i++) { updateColumn = jrs.columnAtIndex(i, true); updateColumn.clear(tableAndAlias); } if (wc != (TinySQLWhere)null) { wc.clearValues(tableAndAlias); } if (!jtbl.isDeleted()) { /* * Evaluate the where clause for each column in the table. If * it is false, skip to the next row. Otherwise, add the * column value to the output record. */ java.util.Enumeration <Object> cols = jtbl.column_info.keys(); found = true; whereStatus = "TRUE"; while (cols.hasMoreElements()) { columnName = tableAndAlias + "." + (String)cols.nextElement(); columnString = jtbl.GetCol(columnName); if (wc != (TinySQLWhere)null) { whereStatus = wc.evaluate(columnName, columnString); if (whereStatus.equals("FALSE")) { /* * This column value caused the where clause to * be FALSE. Go to the next row in the table. */ found = false; break; } } /* * Update the ResultSet tsColumn values */ jrs.updateColumns(columnName, columnString); } /* * If no where condition has evaluated to false then this * record is a candidate for output. Break to the next table * in this case for further WHERE processing. */ if (found) { break; } } } if (found) { if (TinySQLGlobals.DEBUG) { java.lang.SystemJ.outJ.println("Build candidate record."); } for (i = 0; i < jrs.numcols(); i++) { updateColumn = jrs.columnAtIndex(i, true); /* * Evaluate all functions before adding the * column to the output record. */ updateColumn.updateFunctions(); columnString = updateColumn.getString(); if (updateColumn.isNotNull()) { record.put(updateColumn.name, columnString); } else { record.remove(updateColumn.name); } } if (performDebug) { java.lang.SystemJ.outJ.println("Record is " + record.toString()); } /* * If the table we are processing is not the last in * the list, then we should increment level and loop to the top. */ if (level < t.size()) { /* * Increment level */ level++; /* * Add the next table in the list of tables to * the tbl_list, the Hashtable of "to be processed" tables. */ String next_tbl = (String)t.elementAt(level - 1); tbl_list.put(next_tbl, new java.lang.Integer(level)); } else { /* * If the table that was just processed is the last in * the list, then we have drilled down to the bottom; * all columns have values, and we can add it to the * result set. The next time through, the program * will try to read another row at this level; if it's * found, only columns for the table being read will * be overwritten in the tsRow. * * Columns for the other table will be left alone, and * another row will be added to the result set. Here * is the essence of the Cartesian Product which is * being built here. */ haveRecord = true; } } else { /* * We didn't find any more records at this level. * Reset the record pointer to the top of the table, * and decrement level. We have hit end of file here. */ if (wc != (TinySQLWhere)null) { wc.clearValues(tableAndAlias); } level--; jtbl.GoTop(); } } else { /* * No tables were found at this level; back up a level * and see if there's any up there. */ level--; } /* * If we got a record, then add it to the result set. */ if (haveRecord) { /* * If group functions are involved, add records only after a break, * which is defined as a change in all of the group columns. * Otherwise, update the current record. */ if (jrs.isGrouped()) { if (groupBreak) { addOK = jrs.addRow((TsRow)record.clone()); if (addOK == false) { jrs.setLevel(level); return; } groupBreak = false; } else { jrs.updateRow((TsRow)record.clone()); } } else { /* * No group functions are involved. Just add the record. */ addOK = jrs.addRow((TsRow)record.clone()); if (addOK == false) { jrs.setLevel(level); return; } } } } /* * Close all the tables */ for (i = 0; i < t.size(); i++) { jtbl = (TinySQLTable)tables.get((String)t.elementAt(i)); jtbl.close(); } /* * return a result set */ jrs.setLevel(0); }
/* * * Read SQL Statements from the SQLStream, and * return a result set for the last SQL Statement * executed. * * @returns the ResultSet or null, if no result set was created * @exception TinySQLException * */ protected virtual TsResultSet sql(Object s) //throws TinySQLException { /* * Build the ResultSet */ TsResultSet rs = null; TinySQLTable jtbl; TinySQLPreparedStatement pstmt = (TinySQLPreparedStatement)null; bool distinct = false; java.util.Vector <Object> actions, columns, columnDefs, values; String actionType, orderType, tableName, statementType, byteString; java.util.Hashtable <Object, Object> h, selectTables; byte[] bStream; java.io.ByteArrayInputStream st; int i; String actionString; groupBreak = false; statementType = s.getClass().getName(); try { /* * Instantiate a new parser object which reads from the SQLStream. This * should probably be changed to a String at some point. Note that * parsing is only done once for a PreparedStatement. */ actions = (java.util.Vector <Object>)null; if (statementType.endsWith("tinySQLPreparedStatement")) { pstmt = (TinySQLPreparedStatement)s; pstmt.updateActions(actions); actions = pstmt.getActions(); byteString = pstmt.getSQLString(); bStream = (byte[])null; if (pstmt.getSQLString() != (String)null) { bStream = pstmt.getSQLString().getBytes(); } } else if (statementType.endsWith("tinySQLStatement")) { bStream = ((TinySQLStatement)s).getSQLString().getBytes(); } else { throw new TinySQLException("Unknown statement type" + statementType); } if (actions == (java.util.Vector <Object>)null) { st = new java.io.ByteArrayInputStream(bStream); SQLStream = (java.io.InputStream)st; TinySQLParser tinyp = new TinySQLParser(SQLStream, this); TinySQLGlobals.writeLongNames(); actions = tinyp.getActions(); if (statementType.endsWith("tinySQLPreparedStatement")) { pstmt.updateActions(actions); } } /* * The actions Vector consists of a list of Hashtables. Each of these * action Hashtables contains elements required for a particular SQL * statement. The following elements are used for various actions; * * Type Name Description * * String tableName The name of the affected table for * CREATE,INSERT,UPDATE,DELETE actions. * * Hashtable selectTables Hashtable of tables in a SELECT action. * * Vector columns A list of column names used by the * the action. * * Vector columnContexts A list of Strings indicating the context * for the elements in the columns Vector. * Values can be SELECT,ORDER,GROUP. * * Vector columnDefs A list of column objects used by the * CREATE TABLE and ALTER TABLE ADD actions. * * Vector values A list of String values used in INSERT * and UPDATE actions. * * String oldColumnName Old column name for the * ALTER TABLE RENAME action. * * String newColumnName New column name for the * ALTER TABLE RENAME action. * * String orderType Type or ORDER BY - ASC or DESC. * * String distinct Distinct rows only - TRUE or NULL * * tinySQLWhere whereClause An object containing the where clause * which can be updated and queried. */ for (i = 0; i < actions.size(); i++) { h = (java.util.Hashtable <Object, Object>)actions.elementAt(i); actionType = (String)h.get("TYPE"); if (TinySQLGlobals.DEBUG) { java.lang.SystemJ.outJ.println("Action: " + actionType); } /* * Many actions have a table specification. If this one, build * a table object to update the where clause if there is one. */ tableName = (String)h.get("TABLE"); wc = (TinySQLWhere)h.get("WHERE"); if (tableName != (String)null & !actionType.equals("DROP_TABLE") & !actionType.equals("CREATE_TABLE") & !actionType.equals("INSERT") & !actionType.startsWith("ALTER")) { jtbl = getTable(tableName); /* * For prepared statements, store any table objects that * are created so that they can be explicitly closed when * the statement processing is complete. */ if (statementType.endsWith("tinySQLPreparedStatement")) { pstmt.addTable(jtbl); } } actionString = UtilString.actionToString(h); if (debug) { java.lang.SystemJ.outJ.println("ACTION: " + actionString); } if (actionType.equals("UPDATE")) { /* * SQL UPDATE */ columns = (java.util.Vector <Object>)h.get("COLUMNS"); values = (java.util.Vector <Object>)h.get("VALUES"); UpdateStatement(tableName, columns, values, wc); } else if (actionType.equals("DELETE")) { /* * SQL DELETE */ DeleteStatement(tableName, wc); } else if (actionType.equals("SELECT")) { /* * SQL SELECT */ selectTables = (java.util.Hashtable <Object, Object>)h.get("TABLES"); columns = (java.util.Vector <Object>)h.get("COLUMNS"); orderType = (String)h.get("ORDER_TYPE"); if ((String)h.get("DISTINCT") != (String)null) { distinct = true; } rs = SelectStatement(selectTables, columns, wc, orderType, distinct, s); } else if (actionType.equals("INSERT")) { /* * SQL INSERT */ columns = (java.util.Vector <Object>)h.get("COLUMNS"); values = (java.util.Vector <Object>)h.get("VALUES"); InsertStatement(statementType, tableName, columns, values); } else if (actionType.equals("CREATE_TABLE")) { /* * SQL CREATE TABLE * * CREATE TABLE User(user_oid NUMBER(8) NOT NULL, * userType VARCHAR(80) DEFAULT '-' NOT NULL, * PRIMARY KEY (user_oid)) * * -> DEFAULT / NOT NULL / PRIMARY KEY is not supported * */ columnDefs = (java.util.Vector <Object>)h.get("COLUMN_DEF"); CreateTable(tableName, columnDefs); } else if (actionType.equals("ALTER_ADD")) { /* * SQL ALTER TABLE ADD */ columnDefs = (java.util.Vector <Object>)h.get("COLUMN_DEF"); AlterTableAddCol(tableName, columnDefs); } else if (actionType.equals("ALTER_DROP")) { /* * SQL ALTER TABLE DROP */ columns = (java.util.Vector <Object>)h.get("COLUMNS"); AlterTableDropCol(tableName, columns); } else if (actionType.equals("ALTER_RENAME")) { /* * SQL ALTER TABLE RENAME */ String oldColumnName = (String)h.get("OLD_COLUMN"); String newColumnName = (String)h.get("NEW_COLUMN"); AlterTableRenameCol(tableName, oldColumnName, newColumnName); } else if (actionType.equals("DROP_TABLE")) { /* * SQL DROP TABLE */ DropTable(tableName); } else { java.lang.SystemJ.outJ.println("Unrecognized action " + actionType); } } } catch (java.lang.Throwable e) { if (TinySQLGlobals.EX_DEBUG) { e.printStackTrace(java.lang.SystemJ.outJ); } throw new TinySQLException(e.getMessage()); } return(rs); }
/* * The constructor builds a Where clause object from the input string. */ public TinySQLWhere(String whereString, java.util.Hashtable <Object, Object> tableDefs) //throws tinySQLException { FieldTokenizer ft; java.util.Vector <Object> whereConditions; TsColumn leftColumn, rightColumn; Object whereObj; java.lang.StringBuffer fieldBuffer; String nextField, upperField, wherePhrase, comp, left, right, andOr, lastWord; java.util.Vector <Object> whereCondition; String[] comparisons = { "<=", "=<", ">=", "=>", "=", "<>", "!=", ">", "<", "LIKE", "NOT LIKE", "IS" }; String[] fields, keepFields; bool inBrackets = false, foundFunction = false; int i, j, foundKeyWord, foundComp, startAt, foundAnd, foundOr, keepCount; /* * The whereClauseList is a Vector containing pointers to whereCondition * Vectors or tinySQLWhere objects. */ whereConditions = new java.util.Vector <Object>(); whereClauseList = new java.util.Vector <Object>(); /* * Identify any phrases that are contained within brackets. Note that * the FieldTokenizer will catch function definitions as well as * subPhrases so there has to be additional logic to reconstruct * the functions. */ ft = new FieldTokenizer(whereString, '(', true); fields = ft.getFields(); keepFields = new String[fields.Length]; lastWord = "NULL"; fieldBuffer = new java.lang.StringBuffer(); foundFunction = false; keepCount = 0; for (i = 0; i < fields.Length; i++) { keepFields[i] = ""; if (fields[i].equals("(")) { /* * If this is a known function reconstruct the function definition * and save the entire string. */ foundFunction = Utils.isFunctionName(lastWord); if (foundFunction) { fieldBuffer.append("("); } else { if (fieldBuffer.length() > 0) { keepFields[keepCount] = fieldBuffer.toString(); keepCount++; fieldBuffer.delete(0, fieldBuffer.length()); } keepFields[keepCount] = "("; keepCount++; } } else if (fields[i].equals(")")) { if (foundFunction) { fieldBuffer.append(") "); foundFunction = false; } else { if (fieldBuffer.length() > 0) { keepFields[keepCount] = fieldBuffer.toString(); keepCount++; fieldBuffer.delete(0, fieldBuffer.length()); } keepFields[keepCount] = ")"; keepCount++; } } else { fieldBuffer.append(fields[i]); } lastWord = fields[i].substring(fields[i].lastIndexOf(" ") + 1); } /* * Keep last subPhrase */ if (fieldBuffer.length() > 0) { keepFields[keepCount] = fieldBuffer.toString(); keepCount++; } for (i = 0; i < keepCount; i++) { if (TinySQLGlobals.WHERE_DEBUG) { java.lang.SystemJ.outJ.println("keepFields[" + i + "]=" + keepFields[i]); } nextField = keepFields[i]; upperField = nextField.toUpperCase(); if (nextField.equals("(")) { whereObj = (Object)null; inBrackets = true; } else if (nextField.equals(")")) { inBrackets = false; whereObj = (Object)null; } else if (inBrackets) { whereObj = new TinySQLWhere(nextField, tableDefs); whereConditions.addElement(whereObj); } else { /* * Look for AND/OR keywords - if none are found process the * entire string. */ andOr = "AND"; startAt = 0; while (startAt < upperField.length()) { if (upperField.startsWith("AND ")) { foundAnd = 0; } else { foundAnd = upperField.indexOf(" AND", startAt); /* * Make sure this is not just part of a longer string. */ if (foundAnd > -1 & foundAnd < upperField.length() - 4) { if (upperField.charAt(foundAnd + 4) != ' ') { foundAnd = -1; } } } if (upperField.startsWith("OR ")) { foundOr = 0; } else { foundOr = upperField.indexOf(" OR", startAt); if (foundOr > -1 & foundOr < upperField.length() - 3) { if (upperField.charAt(foundOr + 3) != ' ') { foundOr = -1; } } } foundKeyWord = upperField.length(); if (foundAnd > -1) { foundKeyWord = foundAnd; } if (foundOr > -1 & foundOr < foundKeyWord) { foundKeyWord = foundOr; andOr = "OR"; } if (foundKeyWord == 0) { startAt = andOr.length() + 1; foundKeyWord = upperField.length(); } wherePhrase = nextField.substring(startAt, foundKeyWord); if (TinySQLGlobals.WHERE_DEBUG) { java.lang.SystemJ.outJ.println("Where phrase is " + wherePhrase); } if (foundKeyWord < upperField.length() - 4) { andOr = upperField.substring(foundKeyWord + 1, foundKeyWord + 3); } /* * Build a whereCondition Vector. The elements are * as follows: * 0 - left column object * 1 - comparison * 2 - right column object * 3 - status * * The status values indicate which parts of the where * condition have been set. */ whereCondition = new java.util.Vector <Object>(); for (j = 0; j < comparisons.Length; j++) { comp = comparisons[j]; foundComp = wherePhrase.toUpperCase().indexOf(comp); if (foundComp > -1) { left = wherePhrase.substring(0, foundComp).trim(); leftColumn = new TsColumn(left, tableDefs, "WHERE"); whereCondition.addElement(leftColumn); whereCondition.addElement(comp); right = wherePhrase.substring(foundComp + comp.length()).trim(); if (comp.equals("IS")) { right = "'" + right.toUpperCase() + "'"; } rightColumn = new TsColumn(right, tableDefs, "WHERE"); whereCondition.addElement(rightColumn); if (leftColumn.isConstant & rightColumn.isConstant) { whereCondition.addElement("BOTH"); } else if (leftColumn.isConstant) { whereCondition.addElement("LEFT"); } else if (rightColumn.isConstant) { whereCondition.addElement("RIGHT"); } else { whereCondition.addElement("UNKNOWN"); } break; } } whereConditions.addElement(whereCondition); /* * If this condition and the previous one are joined by an * AND keyword, add the condition to the existing Vector. * For an OR keyword, create a new entry in the whereClauseList. */ if (andOr.equals("OR")) { whereClauseList.addElement(whereConditions); whereConditions = new java.util.Vector <Object>(); } startAt = foundKeyWord + andOr.length() + 2; } } } /* * Add the last where condition to the list. */ if (whereConditions.size() > 0) { whereClauseList.addElement(whereConditions); } if (TinySQLGlobals.WHERE_DEBUG) { java.lang.SystemJ.outJ.println("Where clause is \n" + toString()); } }