Beispiel #1
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);
        }
 /**
  *
  * Constructs a tinySQLResultSet; requires a TsResultSet object
  * @param result the TsResultSet object
  *
  */
 public TinySQLResultSetMetaData(TsResultSet result)
 {
     tsql = result;
 }
Beispiel #3
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);
        }
Beispiel #4
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);
        }
Beispiel #5
0
        /**
         * Gets a description of table columns available in
         * the specified catalog.
         *
         * <P>Only column descriptions matching the catalog, schema, table
         * and column name criteria are returned.  They are ordered by
         * TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.
         *
         * <P>Each column description has the following columns:
         *  <OL>
         *  <LI><B>TABLE_CAT</B> String => table catalog (may be null)
         *  <LI><B>TABLE_SCHEM</B> String => table schema (may be null)sRow record = new TsRow();
         *
         *  <LI><B>TABLE_NAME</B> String => table name
         *  <LI><B>COLUMN_NAME</B> String => column name
         *  <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
         *  <LI><B>TYPE_NAME</B> String => Data source dependent type name,
         *  for a UDT the type name is fully qualified
         *  <LI><B>COLUMN_SIZE</B> int => column size.  For char or date
         *      types this is the maximum number of characters, for numeric or
         *      decimal types this is precision.
         *  <LI><B>BUFFER_LENGTH</B> is not used.
         *  <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits
         *  <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
         *  <LI><B>NULLABLE</B> int => is NULL allowed?
         *      <UL>
         *      <LI> columnNoNulls - might not allow NULL values
         *      <LI> columnNullable - definitely allows NULL values
         *      <LI> columnNullableUnknown - nullability unknown
         *      </UL>
         *  <LI><B>REMARKS</B> String => comment describing column (may be null)
         *  <LI><B>COLUMN_DEF</B> String => default value (may be null)
         *  <LI><B>SQL_DATA_TYPE</B> int => unused
         *  <LI><B>SQL_DATETIME_SUB</B> int => unused
         *  <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
         *       maximum number of bytes in the column
         *  <LI><B>ORDINAL_POSITION</B> int => index of column in table
         *      (starting at 1)
         *  <LI><B>IS_NULLABLE</B> String => "NO" means column definitely
         *      does not allow NULL values; "YES" means the column might
         *      allow NULL values.  An empty string means nobody knows.
         *  </OL>
         *
         * @param catalog a catalog name; "" retrieves those without a
         * catalog; null means drop catalog name from the selection criteria
         * @param schemaPattern a schema name pattern; "" retrieves those
         * without a schema
         * @param tableNamePattern a table name pattern
         * @param columnNamePattern a column name pattern
         * @return ResultSet - each row is a column description
         * @exception SQLException if a database access error occurs
         * @see #getSearchStringEscape
         */
        public override java.sql.ResultSet getColumns(String catalog, String schemaPattern,
                                                      String tableNamePattern, String columnNamePattern)
        {
            int    i;
            String columnNameKey;

            try
            {
                String dataDir = getDataDir();

                Utils.log("Entering getColumns(tableNamePattern='" + tableNamePattern + "')");

                if (dataDir == null)
                {
                    return(null);
                }

                java.sql.ResultSet tableRs = getTables(catalog, schemaPattern, tableNamePattern, null);

                TsResultSet jrs = new TsResultSet();

                TsColumn jsc = new TsColumn("TABLE_CAT");
                jsc.type = java.sql.Types.CHAR;
                jsc.size = 9;
                jrs.addColumn(jsc);

                jsc      = new TsColumn("TABLE_SCHEM");
                jsc.type = java.sql.Types.CHAR;
                jsc.size = 11;
                jrs.addColumn(jsc);

                jsc      = new TsColumn("TABLE_NAME");
                jsc.type = java.sql.Types.CHAR;
                jsc.size = 10;
                jrs.addColumn(jsc);

                jsc      = new TsColumn("COLUMN_NAME");
                jsc.type = java.sql.Types.CHAR;
                jsc.size = 11;
                jrs.addColumn(jsc);

                jsc      = new TsColumn("DATA_TYPE");
                jsc.type = java.sql.Types.INTEGER;
                jsc.size = 6;
                jrs.addColumn(jsc);

                jsc      = new TsColumn("TYPE_NAME");
                jsc.type = java.sql.Types.CHAR;
                jsc.size = 9;
                jrs.addColumn(jsc);

                jsc      = new TsColumn("COLUMN_SIZE");
                jsc.type = java.sql.Types.INTEGER;
                jsc.size = 8;
                jrs.addColumn(jsc);

                jsc      = new TsColumn("BUFFER_LENGTH");
                jsc.type = java.sql.Types.INTEGER;
                jsc.size = 8;
                jrs.addColumn(jsc);

                jsc      = new TsColumn("DECIMAL_DIGITS");
                jsc.type = java.sql.Types.INTEGER;
                jsc.size = 8;
                jrs.addColumn(jsc);

                jsc      = new TsColumn("NUM_PREC_RADIX");
                jsc.type = java.sql.Types.INTEGER;
                jsc.size = 8;
                jrs.addColumn(jsc);

                jsc      = new TsColumn("NULLABLE");
                jsc.type = java.sql.Types.INTEGER;
                jsc.size = 8;
                jrs.addColumn(jsc);

                jsc      = new TsColumn("REMARKS");
                jsc.type = java.sql.Types.CHAR;
                jsc.size = 128;
                jrs.addColumn(jsc);

                jsc      = new TsColumn("COLUMN_DEF");
                jsc.type = java.sql.Types.CHAR;
                jsc.size = 128;
                jrs.addColumn(jsc);

                jsc      = new TsColumn("SQL_DATA_TYPE");
                jsc.type = java.sql.Types.INTEGER;
                jsc.size = 128;
                jrs.addColumn(jsc);

                //      Several parameters missing.

                jsc      = new TsColumn("IS_NULLABLE");
                jsc.type = java.sql.Types.CHAR;
                jsc.size = 3;
                jrs.addColumn(jsc);

                while (tableRs.next())
                { // process each DBF file and extract column info ...
                    String tableName = tableRs.getString("TABLE_NAME");

                    DBFFileTable tbl;
                    try
                    {
                        tbl = new DBFFileTable(dataDir, tableName);
                    }
                    catch (Exception)
                    {
                        continue; // ignore buggy and empty (zero byte size) DBF files
                    }

                    Utils.log("Accessing column info for table " + tableName);

                    java.util.Hashtable <Object, Object> column_info = tbl.column_info;
                    for (i = 0; i < tbl.columnNameKeys.size(); i++)
                    {
                        columnNameKey = (String)tbl.columnNameKeys.elementAt(i);
                        TsColumn tsc = (TsColumn)column_info.get(columnNameKey);
                        // process each column of the current table ...
                        TsRow record = new TsRow();
                        record.put("TABLE_CAT", "");
                        record.put("TABLE_SCHEM", "");
                        record.put("TABLE_NAME", tableName);
                        record.put("COLUMN_NAME", TinySQLGlobals.getLongName(tsc.name));
                        record.put("DATA_TYPE", new java.lang.Integer(tsc.type).toString());
                        record.put("TYPE_NAME", DBFFile.typeToLiteral(tsc.type).toString());
                        record.put("COLUMN_SIZE", new java.lang.Integer(tsc.size).toString());
                        record.put("DECIMAL_DIGITS", new java.lang.Integer(tsc.decimalPlaces).toString());
                        int nullable = columnNoNulls;
                        if (tsc.notNull == true)
                        {
                            nullable = columnNullable;
                        }
                        record.put("NULLABLE", new java.lang.Integer(nullable).toString());
                        record.put("REMARKS", "noRemarks");
                        String defaultVal = tsc.defaultVal;
                        if (defaultVal == null)
                        {
                            defaultVal = "";
                        }
                        record.put("COLUMN_DEF", defaultVal);
                        String isNullable = "NO";
                        if (tsc.notNull == true)
                        {
                            isNullable = "YES";
                        }
                        record.put("IS_NULLABLE", isNullable);

                        /*
                         *          Suppress any sorting of the ResultSet.  Column Metadata should
                         *          be presented in the order the columns exist in the dBase header.
                         */

                        jrs.addRow(record, false);
                    }

                    tbl.close();
                    tbl = null;
                }

                return(new TinySQLResultSet(jrs, (TinySQLStatement)null));
            }
            catch (Exception)
            {
                return(null);
            }
        }
Beispiel #6
0
        /*
         * Gets a description of tables available in a catalog.
         *
         * Only table descriptions matching the catalog, schema, table
         * name and type criteria are returned.  They are ordered by
         * TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
         *
         * Each table description has the following columns:
         *
         * TABLE_CAT String => table catalog (may be null)
         * TABLE_SCHEM String => table schema (may be null)
         * TABLE_NAME String => table name
         * TABLE_TYPE String => table type.  Typical types are "TABLE",
         *      "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
         *      "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
         * REMARKS String => explanatory comment on the table
         *
         * Note: Some databases may not return information for
         * all tables.
         *
         * @param catalog a catalog name; "" retrieves those without a
         * catalog; null means drop catalog name from the selection criteria
         * THIS VALUE IS IGNORED
         * @param schemaPattern THIS VALUE IS IGNORED
         * @param tableNamePattern a table name pattern, ´null´ or "%" delivers all
         *                         token will be handled as substrings
         * @param types a list of table types to include; null returns all DBF types
         *              only "TABLE" is supported, others like "VIEW", "SYSTEM TABLE", "SEQUENCE"
         *              are ignored.
         * @return ResultSet - each row is a table description
         * @exception SQLException if a database access error occurs
         * @see #getSearchStringEscape
         *
         * @author Thomas Morgner <*****@*****.**> Fill all needed columns, or some query tools will crash :(
         */
        public override java.sql.ResultSet getTables(String catalog, String schemaPattern,
                                                     String tableNamePattern, String[] types)
        {
            String dataDir = getDataDir();
            String tableName;

            java.io.File tableFile;
            TsColumn     jsc;
            int          i, dotAt;

            if (dataDir == null)
            {
                return(null);
            }
            if (types == null)
            {
                types    = new String[1];
                types[0] = "TABLE";
            }
            TsResultSet jrs = new TsResultSet();

            /*
             *    Create the header for the tables ResultSet
             */
            try
            {
                jsc      = new TsColumn("TABLE_CAT");
                jsc.type = java.sql.Types.CHAR;    // CHAR max 254 bytes
                jsc.size = 10;
                jrs.addColumn(jsc);

                jsc      = new TsColumn("TABLE_SCHEM");
                jsc.type = java.sql.Types.CHAR;    // CHAR max 254 bytes
                jsc.size = 10;
                jrs.addColumn(jsc);

                jsc      = new TsColumn("TABLE_NAME");
                jsc.type = java.sql.Types.CHAR;    // CHAR max 254 bytes
                jsc.size = 10;
                jrs.addColumn(jsc);

                jsc            = new TsColumn("TABLE_TYPE");
                jsc.type       = java.sql.Types.CHAR; // CHAR max 254 bytes
                jsc.size       = 40;
                jsc.defaultVal = "TABLE";
                jrs.addColumn(jsc);

                jsc      = new TsColumn("TABLE_REMARKS");
                jsc.type = java.sql.Types.CHAR;    // CHAR max 254 bytes
                jsc.size = 254;
                jrs.addColumn(jsc);

                /*
                 *       Add the MetaData by examining all the DBF files in the current
                 *       directory.
                 */
                for (int itype = 0; itype < types.Length; itype++)
                {
                    String type = types[itype];
                    if (type == null)
                    {
                        continue;
                    }
                    String extension = null;
                    if (type.equalsIgnoreCase("TABLE"))
                    {
                        extension = DBFFileTable.dbfExtension; // ".DBF";
                    }
                    if (extension == null)
                    {
                        continue;
                    }
                    java.util.Vector <Object> vec = Utils.getAllFiles(dataDir, extension);
                    for (i = 0; i < vec.size(); i++)
                    {
                        tableFile = (java.io.File)vec.elementAt(i);
                        tableName = tableFile.getName().toUpperCase();
                        dotAt     = tableName.indexOf(".");
                        if (dotAt > -1)
                        {
                            tableName = tableName.substring(0, dotAt);
                        }
                        if (tableNamePattern == null)
                        {
                            tableNamePattern = "%";
                        }
                        if (tableNamePattern.equals("%") |
                            tableName.equalsIgnoreCase(tableNamePattern))
                        {
                            if (tableName.length() > jsc.size)
                            {
                                jsc.size = tableName.length();
                            }
                            TsRow record = new TsRow();
                            record.put("TABLE_NAME", tableName.toUpperCase());
                            record.put("TABLE_TYPE", "TABLE");
                            jrs.addRow(record);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                java.lang.SystemJ.outJ.println("Unable to create MetaData");
                java.lang.SystemJ.outJ.println(ex.ToString());// ex.printStackTrace(System.out);
            }

            // This Resultset is not created by an statement
            return(new TinySQLResultSet(jrs, (TinySQLStatement)null));
        }
Beispiel #7
0
        /**
         * Gets a description of all the standard SQL types supported by
         * this database. They are ordered by DATA_TYPE and then by how
         * closely the data type maps to the corresponding JDBC SQL type.
         *
         * <P>Each type description has the following columns:
         *  <OL>
         *  <LI><B>TYPE_NAME</B> String => Type name
         *  <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
         *  <LI><B>PRECISION</B> int => maximum precision
         *  <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal
         *      (may be null)
         *  <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal
         *      (may be null)
         *  <LI><B>CREATE_PARAMS</B> String => parameters used in creating
         *      the type (may be null)
         *  <LI><B>NULLABLE</B> short => can you use NULL for this type?
         *      <UL>
         *      <LI> typeNoNulls - does not allow NULL values
         *      <LI> typeNullable - allows NULL values
         *      <LI> typeNullableUnknown - nullability unknown
         *      </UL>
         *  <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?
         *  <LI><B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
         *      <UL>
         *      <LI> typePredNone - No support
         *      <LI> typePredChar - Only supported with WHERE .. LIKE
         *      <LI> typePredBasic - Supported except for WHERE .. LIKE
         *      <LI> typeSearchable - Supported for all WHERE ..
         *      </UL>
         *  <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?
         *  <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?
         *  <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an
         *      auto-increment value?
         *  <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name
         *      (may be null)
         *  <LI><B>MINIMUM_SCALE</B> short => minimum scale supported
         *  <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported
         *  <LI><B>SQL_DATA_TYPE</B> int => unused
         *  <LI><B>SQL_DATETIME_SUB</B> int => unused
         *  <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10
         *  </OL>
         *
         * @return ResultSet - each row is a SQL type description
         * @exception SQLException if a database access error occurs
         */
        public override java.sql.ResultSet getTypeInfo()
        {//throws SQLException {
            TsResultSet jrs = new TsResultSet();

            TsColumn jsc = new TsColumn("TYPE_NAME");

            jsc.type = java.sql.Types.CHAR;
            jsc.size = 10;
            jrs.addColumn(jsc);

            jsc      = new TsColumn("DATA_TYPE");
            jsc.type = java.sql.Types.INTEGER;
            jsc.size = 6;
            jrs.addColumn(jsc);

            jsc      = new TsColumn("PRECISION");
            jsc.type = java.sql.Types.INTEGER;
            jsc.size = 8;
            jrs.addColumn(jsc);

            jsc      = new TsColumn("LITERAL_PREFIX");
            jsc.type = java.sql.Types.CHAR;
            jsc.size = 1;
            jrs.addColumn(jsc);

            jsc      = new TsColumn("LITERAL_SUFFIX");
            jsc.type = java.sql.Types.CHAR;
            jsc.size = 1;
            jrs.addColumn(jsc);

            jsc      = new TsColumn("CREATE_PARAMS");
            jsc.type = java.sql.Types.CHAR;
            jsc.size = 20;
            jrs.addColumn(jsc);

            jsc      = new TsColumn("NULLABLE");
            jsc.type = java.sql.Types.INTEGER;
            jsc.size = 6;
            jrs.addColumn(jsc);

            jsc      = new TsColumn("CASE_SENSITIVE");
            jsc.type = java.sql.Types.BIT;
            jsc.size = 1;
            jrs.addColumn(jsc);

            jsc      = new TsColumn("SEARCHABLE");
            jsc.type = java.sql.Types.INTEGER;
            jsc.size = 6;
            jrs.addColumn(jsc);

            /*
             *  <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?
             *  <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?
             *  <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an
             *      auto-increment value?
             *  <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name
             *      (may be null)
             *  <LI><B>MINIMUM_SCALE</B> short => minimum scale supported
             *  <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported
             *  <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10
             */


            // NOTE: the Hashtable in tsRow expects always a String as its value!
            //       so i use the toString() method here
            //       Perhaps in future the real type should be pushed into the Hashtable?

            TsRow record = new TsRow();

            record.put("TYPE_NAME", DBFFile.typeToLiteral(java.sql.Types.CHAR));    // "CHAR", String
            record.put("DATA_TYPE", new java.lang.Integer(java.sql.Types.CHAR).toString());
            record.put("PRECISION", new java.lang.Integer(254).toString());
            record.put("LITERAL_PREFIX", "\"");
            record.put("LITERAL_SUFFIX", "\"");
            record.put("CREATE_PARAMS", new java.lang.Integer(0).toString());
            record.put("NULLABLE", new java.lang.Integer(typeNullableUnknown).toString());
            record.put("CASE_SENSITIVE", "N");
            record.put("SEARCHABLE", new java.lang.Integer(typePredBasic).toString());
            jrs.addRow(record);

            record = new TsRow();
            record.put("TYPE_NAME", DBFFile.typeToLiteral(java.sql.Types.FLOAT));    // "FLOAT", double
            record.put("DATA_TYPE", new java.lang.Integer(java.sql.Types.FLOAT).toString());
            record.put("PRECISION", new java.lang.Integer(19).toString());
            record.put("LITERAL_PREFIX", emptyString);
            record.put("LITERAL_SUFFIX", emptyString);
            record.put("CREATE_PARAMS", new java.lang.Integer(0).toString());
            record.put("NULLABLE", new java.lang.Integer(typeNullableUnknown).toString());
            record.put("CASE_SENSITIVE", "N");
            record.put("SEARCHABLE", new java.lang.Integer(typePredBasic).toString());
            jrs.addRow(record);

            record = new TsRow();
            record.put("TYPE_NAME", DBFFile.typeToLiteral(java.sql.Types.BIT));     // "CHAR", boolean "YyNnTtFf"
            record.put("DATA_TYPE", new java.lang.Integer(java.sql.Types.BIT).toString());
            record.put("PRECISION", new java.lang.Integer(1).toString());
            record.put("LITERAL_PREFIX", "\"");
            record.put("LITERAL_SUFFIX", "\"");
            record.put("CREATE_PARAMS", new java.lang.Integer(0).toString());
            record.put("NULLABLE", new java.lang.Integer(typeNullableUnknown).toString());
            record.put("CASE_SENSITIVE", "N");
            record.put("SEARCHABLE", new java.lang.Integer(typePredBasic).toString());
            jrs.addRow(record);

            record = new TsRow();
            record.put("TYPE_NAME", DBFFile.typeToLiteral(java.sql.Types.INTEGER));     // "INT", unsigned long
            record.put("DATA_TYPE", new java.lang.Integer(java.sql.Types.INTEGER).toString());
            record.put("PRECISION", new java.lang.Integer(19).toString());
            record.put("LITERAL_PREFIX", emptyString);
            record.put("LITERAL_SUFFIX", emptyString);
            record.put("CREATE_PARAMS", new java.lang.Integer(0).toString());
            record.put("NULLABLE", new java.lang.Integer(typeNullableUnknown).toString());
            record.put("CASE_SENSITIVE", "N");
            record.put("SEARCHABLE", new java.lang.Integer(typePredBasic).toString());
            jrs.addRow(record);

            record = new TsRow();
            record.put("TYPE_NAME", DBFFile.typeToLiteral(java.sql.Types.DATE));     // "DATE", date
            record.put("DATA_TYPE", new java.lang.Integer(java.sql.Types.DATE).toString());
            record.put("PRECISION", new java.lang.Integer(8).toString());
            record.put("LITERAL_PREFIX", "\"");
            record.put("LITERAL_SUFFIX", "\"");
            record.put("CREATE_PARAMS", new java.lang.Integer(0).toString());
            record.put("NULLABLE", new java.lang.Integer(typeNullableUnknown).toString());
            record.put("CASE_SENSITIVE", "N");
            record.put("SEARCHABLE", new java.lang.Integer(typePredBasic).toString());
            jrs.addRow(record);

            return(new TinySQLResultSet(jrs, (TinySQLStatement)null));
        }