Пример #1
0
        /*
         * 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();
        }
Пример #2
0
 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>();
 }
Пример #3
0
        /*
         * 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);
        }
Пример #4
0
        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());
            }
        }
Пример #5
0
        /*
         * 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;
        }
Пример #6
0
        /*
         * 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);
        }
Пример #7
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);
        }
Пример #8
0
        /*
         * 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());
            }
        }