示例#1
0
        /**
         * Writing a column definition to file<br>
         * NOTE: the file pointer (seek()) must be at the correct position
         * @param ff file handle (correctly positioned)
         * @param coldef struct with column info
         */
        void writeColdef(java.io.RandomAccessFile ff, TsColumn coldef) //throws tinySQLException
        {
            // Utils.log("Writing Field Def: coldef.name=" + coldef.name + ", coldef.type=" + coldef.type + ", cildef.size=" + coldef.size);

            try
            {
                ff.write(Utils.forceToSize(coldef.name,
                                           DBFFileTable.FIELD_TYPE_INDEX - DBFFileTable.FIELD_NAME_INDEX,
                                           (byte)0));

                // Convert the Java.SQL.Type back to a DBase Type and write it
                String type = null;
                if (coldef.type == java.sql.Types.CHAR || coldef.type == java.sql.Types.VARCHAR || coldef.type == java.sql.Types.LONGVARCHAR)
                {
                    type = "C";
                }
                else
                if (coldef.type == java.sql.Types.NUMERIC || coldef.type == java.sql.Types.INTEGER ||
                    coldef.type == java.sql.Types.TINYINT || coldef.type == java.sql.Types.SMALLINT ||
                    coldef.type == java.sql.Types.BIGINT || coldef.type == java.sql.Types.FLOAT ||
                    coldef.type == java.sql.Types.DOUBLE || coldef.type == java.sql.Types.REAL)
                {
                    type = "N";
                }
                else
                if (coldef.type == java.sql.Types.BIT)
                {
                    type = "L";
                }
                else
                if (coldef.type == java.sql.Types.DATE)
                {
                    type = "D";
                }
                else
                {
                    type = "M";
                }

                ff.write(Utils.forceToSize(type,
                                           1,
                                           (byte)0));

                ff.write(Utils.forceToSize(null,
                                           4,
                                           (byte)0)); // imu field (in memory use) 12-15

                ff.write(coldef.size);                // one byte

                ff.write(coldef.decimalPlaces);       // one byte

                ff.write(Utils.forceToSize(null,
                                           DBFHeader.BULK_SIZE - DBFFileTable.FIELD_RESERVED_INDEX,
                                           (byte)0));
            }
            catch (Exception e)
            {
                throw new TinySQLException(e.getMessage());
            }
        }
示例#2
0
        internal override void CreateTable(String tableName, java.util.Vector <Object> v)
        {//    throws IOException, tinySQLException {
            //---------------------------------------------------
            // determin meta data ....
            int numCols      = v.size();
            int recordLength = 1;        // 1 byte for the flag field

            for (int i = 0; i < numCols; i++)
            {
                TsColumn coldef = ((TsColumn)v.elementAt(i));
                recordLength += coldef.size;
            }

            //---------------------------------------------------
            // create the new dBase file ...
            DBFHeader dbfHeader = new DBFHeader(numCols, recordLength);

            java.io.RandomAccessFile ftbl = dbfHeader.create(dataDir, tableName);

            //---------------------------------------------------
            // write out the rest of the columns' definition.
            for (int i = 0; i < v.size(); i++)
            {
                TsColumn coldef = ((TsColumn)v.elementAt(i));
                Utils.log("CREATING COL=" + coldef.name);
                writeColdef(ftbl, coldef);
            }

            ftbl.write((byte)0x0d); // header section ends with CR (carriage return)

            ftbl.close();
        }
示例#3
0
        /*
         * Rename columns
         *
         * ALTER TABLE table RENAME war TO peace
         */
        internal override void AlterTableRenameCol(String tableName, String oldColname, String newColname)
        //throws tinySQLException
        {
            String fullpath = dataDir + java.io.File.separator + tableName + DBFFileTable.dbfExtension;

            try
            {
                java.io.RandomAccessFile ftbl = new java.io.RandomAccessFile(fullpath, "rw");

                DBFHeader dbfHeader = new DBFHeader(ftbl); // read the first 32 bytes ...

                int locn = 0;                              // offset of the current column
                for (int iCol = 1; iCol <= dbfHeader.numFields; iCol++)
                {
                    TsColumn coldef = readColdef(ftbl, tableName, iCol, locn);
                    if (coldef.name.equals(oldColname))
                    {
                        Utils.log("Replacing column name '" + oldColname + "' with '" + newColname + "'");
                        ftbl.seek((iCol - 1) * 32 + 32);
                        ftbl.write(Utils.forceToSize(newColname,
                                                     DBFFileTable.FIELD_TYPE_INDEX - DBFFileTable.FIELD_NAME_INDEX,
                                                     (byte)0));
                        ftbl.close();
                        return;
                    }
                }
                ftbl.close();
                throw new TinySQLException("Renaming of column name '" + oldColname + "' to '" + newColname + "' failed, no column '" + oldColname + "' found");
            }
            catch (Exception e)
            {
                throw new TinySQLException(e.getMessage());
            }
        }
        /**
         *
         * This returns the column name in the form table_name.column_name.
         * @see java.sql.ResultSetMetaData#getColumnLabel
         * @param column the column whose label is wanted
         * @return the fully qualified column name
         *
         */
        public String getColumnLabel(int column)
        {//  throws SQLException {
            // get the column, return its table and name, separated by a '.'
            //
            TsColumn col = tsql.columnAtIndex(column - 1);

            return(col.tableName + "." + col.name);
        }
        /**
         *
         * Gives the column type using the types in java.sql.Types.
         * @see java.sqlTypes
         * @see java.sql.ResultSetMetaData#getColumnType
         * @exception SQLException thrown for any number of reasons
         * @param column the column type information is needed on
         * @return the type as listed in java.sql.Types
         *
         */
        public int getColumnType(int column)
        {//throws SQLException {
            // get the column info object
            //
            TsColumn col = tsql.columnAtIndex(column - 1);

            return(col.type);
        }
        /**
         *
         * Gives the name of the table to which this column belongs.
         * @see java.sql.ResultSetMetaData#getTableName
         * @param column the column of the field this information is needed for
         * @return the table name
         *
         */
        public String getTableName(int column)
        {//  throws SQLException {
            // retrieve the column info and return the table name
            //
            TsColumn col = tsql.columnAtIndex(column - 1);

            return(col.tableName);
        }
示例#7
0
        /*
         * The following function compares this column to the input using
         * a "like" comparison using % as the wildcard.
         */
        public bool like(TsColumn inputColumn) //throws tinySQLException
        {
            FieldTokenizer ft;
            String         nextField, firstField, lastField;
            bool           like;
            int            foundAt;

            if (!Utils.isCharColumn(type) | !Utils.isCharColumn(inputColumn.type))
            {
                throw new TinySQLException("Column " + name + " or "
                                           + inputColumn.name + " is not character.");
            }
            ft         = new FieldTokenizer(inputColumn.stringValue, '%', true);
            like       = true;
            foundAt    = 0;
            firstField = (String)null;
            lastField  = (String)null;
            while (ft.hasMoreFields())
            {
                nextField = ft.nextField();
                lastField = nextField;

                /*
                 *       If the first matching field is not the wildcare character
                 *       then the test field must start with this string.
                 */
                if (firstField == (String)null)
                {
                    firstField = nextField;
                    if (!firstField.equals("%") & !stringValue.startsWith(firstField))
                    {
                        like = false;
                        break;
                    }
                }
                if (!nextField.equals("%"))
                {
                    if (stringValue.indexOf(nextField, foundAt) < 0)
                    {
                        like = false;
                        break;
                    }
                    foundAt = stringValue.indexOf(nextField, foundAt) + 1;
                }
            }
            if (!lastField.equals("%") & !stringValue.endsWith(lastField))
            {
                like = false;
            }
            if (TinySQLGlobals.DEBUG)
            {
                java.lang.SystemJ.outJ.println("Is " + getString() + " like " +
                                               inputColumn.getString() + " ? " + like);
            }
            return(like);
        }
        /**
         *
         * Gives the display size for this column.
         * @see java.sql.ResultSetMetaData#getColumnDisplaySize
         *
         */
        public int getColumnDisplaySize(int column)
        {//throws SQLException {
            // get a column object. Remember, tinySQL uses a column
            // offset of zero, but JDBC columns start numbering at one.
            // That's why there's a -1 in the columnAtIndex invocation.
            //
            TsColumn col = tsql.columnAtIndex(column - 1);

            return(col.size);
        }
示例#9
0
        /*
         * Update a single column.
         *
         * @param column the column name
         * @param value the String value with which update the column
         * @see tinySQLTable#UpdateCol
         *
         */
        public override void UpdateCol(String colName, String value) //throws TinySQLException
        {
            String shortColumnName;

            try
            {
                /*
                 *       If it's the pseudo column _DELETED, return
                 */
                if (colName.equals("_DELETED"))
                {
                    return;
                }

                /*
                 *       Retrieve the TsColumn object which corresponds to this column.
                 */
                shortColumnName = TinySQLGlobals.getShortName(colName);
                TsColumn column = (TsColumn)column_info.get(shortColumnName);
                if (column == null)
                {
                    throw new TinySQLException("Can't update field=" + colName);
                }
                if (Utils.isDateColumn(column.type))
                {
                    /*
                     *          Convert non-blank dates to the standard YYYYMMDD format.
                     */
                    if (value.trim().length() > 0)
                    {
                        value = UtilString.dateValue(value);
                    }
                }

                /*
                 *       Seek the starting offset of the current record,
                 *       as indicated by currentRecordNumber
                 */
                ftbl.seek(dbfHeader.headerLength + (currentRecordNumber - 1) * dbfHeader.recordLength + column.position);

                /*
                 *       Enforce the correct column length, transform to byte and write to file
                 */
                value = Utils.forceToSize(value, column.size, " ");
                byte[] b = value.getBytes(Utils.encode);
                ftbl.write(b);
                dbfHeader.setTimestamp(ftbl);
            }
            catch (Exception e)
            {
                throw new TinySQLException(e.getMessage());
            }
        }
示例#10
0
 /*
  * Extracts a column from the given row. The row is given as a string.
  * If coldef is null, the special delete-flag is returned (Position 0 of a row).
  *
  * @param coldef the column definition, which tells what content to extract from the row
  * @param row the row as an string contains all column data
  * @returns a substring of row.
  */
 public static String getColumn(TsColumn coldef, String row)
 {
     if (row == (String)null)
     {
         java.lang.SystemJ.outJ.println("Row is null");
     }
     else if (row.length() == 0)
     {
         java.lang.SystemJ.outJ.println("Row has 0 length");
     }
     if (coldef == null)
     {
         return(row.substring(0, 1));
     }
     return(row.substring(coldef.position, coldef.position + coldef.size));
 }
示例#11
0
        /*
         * Retrieve a column's string value from the current row.
         *
         * @param column the column name
         * @see tinySQLTable#GetCol
         */
        public override String GetCol(String colName) //throws TinySQLException
        {
            int    foundDot;
            String columnName;

            columnName = colName;
            foundDot   = columnName.indexOf(".");
            if (foundDot > -1)
            {
                columnName = columnName.substring(foundDot + 1);
            }
            TsColumn coldef = (TsColumn)column_info.get(columnName);

            if (currentRowCache == null)
            {
                currentRowCache = _GetCol(ftbl, dbfHeader, currentRecordNumber);
            }

            return(getColumn(coldef, currentRowCache));
        }
示例#12
0
        public void addColumn(TsColumn col)
        {
            int          i;
            bool         addTable;
            TinySQLTable checkTable;

            rsColumns.addElement(col);
            if (col.getContext("SELECT"))
            {
                selectColumns.addElement(col);
            }
            if (col.getContext("ORDER"))
            {
                orderByColumns.addElement(col);
            }
            if (col.isGroupedColumn())
            {
                groupedColumns = true;
            }

            /*
             *    Add the table that this column belongs to if required
             */
            addTable = true;
            if (col.columnTable != (TinySQLTable)null)
            {
                for (i = 0; i < tables.size(); i++)
                {
                    checkTable = (TinySQLTable)tables.elementAt(i);
                    if (checkTable.table.equals(col.columnTable.table))
                    {
                        addTable = false;
                        break;
                    }
                }
                if (addTable)
                {
                    tables.addElement(col.columnTable);
                }
            }
        }
示例#13
0
        /*
         *  Get a column object for the named column.
         */
        public TsColumn getColumn(String colName) //throws TinySQLException
        {
            int    foundDot;
            String columnName;

            columnName = colName;
            foundDot   = columnName.indexOf(".");
            if (foundDot > -1)
            {
                columnName = columnName.substring(foundDot + 1);
            }
            columnName = TinySQLGlobals.getShortName(columnName);
            TsColumn coldef = (TsColumn)column_info.get(columnName);

            if (coldef == (TsColumn)null)
            {
                throw new TinySQLException("Column " + columnName + " does not"
                                           + " exist in table " + table);
            }
            return(coldef);
        }
        /**
         * The name of a given column
         * @see java.sql.ResultSetMetaData#getColumnName
         * @param column the column whose name is wanted
         * @return the name of the requested column
         */
        public String getColumnName(int column)
        {//  throws SQLException {
            // get the column and return its name
            //
            String   columnName;
            int      dotAt;
            TsColumn col = tsql.columnAtIndex(column - 1);

            dotAt      = col.name.indexOf(".");
            columnName = col.name;
            if (dotAt > -1)
            {
                columnName = col.name.substring(dotAt + 1);
            }
            if (col.alias != (String)null)
            {
                if (!col.alias.equals(columnName))
                {
                    return(col.alias);
                }
            }
            columnName = TinySQLGlobals.getLongName(columnName);
            return(columnName);
        }
示例#15
0
        /**
         *
         * Deletes Columns from tableName, given a vector of
         * column definition (tsColumn) arrays.<br>
         *
         * ALTER TABLE table DROP [ COLUMN ] column { RESTRICT | CASCADE }
         *
         * @param tableName the name of the table
         * @param v a Vector containing arrays of column definitions.
         * @see tinySQL#AlterTableDropCol
         *
         */
        internal override void AlterTableDropCol(String tableName, java.util.Vector <Object> v)
        {//throws IOException, tinySQLException {
            // rename the file ...
            String fullpath = dataDir + java.io.File.separator + tableName + DBFFileTable.dbfExtension;
            String tmppath  = dataDir + java.io.File.separator + tableName + "-tmp" + DBFFileTable.dbfExtension;

            if (Utils.renameFile(fullpath, tmppath) == false)
            {
                throw new TinySQLException("ALTER TABLE DROP COL error in renaming " + fullpath);
            }

            try
            {
                // open the old file ...
                java.io.RandomAccessFile ftbl_tmp = new java.io.RandomAccessFile(tmppath, "r");

                // read the first 32 bytes ...
                DBFHeader dbfHeader_tmp = new DBFHeader(ftbl_tmp);

                // read the column info ...
                java.util.Vector <Object> coldef_list = new java.util.Vector <Object>(dbfHeader_tmp.numFields - v.size());
                int locn = 0; // offset of the current column

                nextCol : for (int i = 1; i <= dbfHeader_tmp.numFields; i++)
                {
                    TsColumn coldef = readColdef(ftbl_tmp, tableName, i, locn);

                    // remove the DROP columns from the existing cols ...
                    for (int jj = 0; jj < v.size(); jj++)
                    {
                        String colName = (String)v.elementAt(jj);
                        if (coldef.name.equals(colName))
                        {
                            Utils.log("Dropping " + colName);
                            goto nextCol;
                        }
                    }

                    locn += coldef.size; // increment locn by the length of this field.
                    // Utils.log("Recycling " + coldef.name);
                    coldef_list.addElement(coldef);
                }

                // create the new table ...
                CreateTable(tableName, coldef_list);

                // copy the data from old to new

                // opening new created dBase file ...
                java.io.RandomAccessFile ftbl = new java.io.RandomAccessFile(fullpath, "rw");
                ftbl.seek(ftbl.length()); // go to end of file

                int numRec = 0;
                for (int iRec = 1; iRec <= dbfHeader_tmp.numRecords; iRec++)
                {
                    if (DBFFileTable.isDeleted(ftbl_tmp, dbfHeader_tmp, iRec) == true)
                    {
                        continue;
                    }

                    numRec++;

                    ftbl.write(DBFFileTable.RECORD_IS_NOT_DELETED);  // write flag

                    // Read the whole column into the table's cache
                    String column = DBFFileTable._GetCol(ftbl_tmp, dbfHeader_tmp, iRec);

                    for (int iCol = 0; iCol < coldef_list.size(); iCol++) // write columns
                    {
                        TsColumn coldef = (TsColumn)coldef_list.elementAt(iCol);

                        // Extract column values from cache
                        String value = DBFFileTable.getColumn(coldef, column);
                        java.lang.SystemJ.outJ.println("From cache column value" + value);

                        value = Utils.forceToSize(value, coldef.size, " "); // enforce the correct column length

                        byte[] b = value.getBytes(Utils.encode);            // transform to byte and write to file
                        ftbl.write(b);
                    }
                }

                ftbl_tmp.close();

                // remove temp file
                java.io.File f = new java.io.File(tmppath);
                if (f.exists())
                {
                    f.delete();
                }

                DBFHeader.writeNumRecords(ftbl, numRec);
                ftbl.close();
            }
            catch (Exception e)
            {
                throw new TinySQLException(e.getMessage());
            }
        }
示例#16
0
        /**
         * Reading a column definition from file<br>
         * @param ff file handle (correctly positioned)
         * @param iCol index starts with 1
         * @param locn offset to the current column
         * @return struct with column info
         */
        internal static TsColumn readColdef(java.io.RandomAccessFile ff, String tableName, int iCol, int locn) //throws tinySQLException
        {
            try
            {
                // seek the position of the field definition data.
                // This information appears after the first 32 byte
                // table information, and lives in 32 byte chunks.
                //
                ff.seek((iCol - 1) * 32 + 32);

                // get the column name into a byte array
                //
                byte[] b = new byte[11];
                ff.readFully(b);

                // convert the byte array to a String
                // Seek first 0x00 occurence and strip array after that
                //
                // some C-implementations do not set the remaining bytes
                // after the name to 0x00, so we have to correct this.
                //bool clear = false;
                int i = 0;
                while ((i < 11) && (b[i] != 0))
                {
                    i++;
                }
                while (i < 11)
                {
                    b[i] = 0;
                    i++;
                }
                String colName = (new java.lang.StringJ(b, Utils.encode)).trim();
                // read in the column type which follows the 11 byte column name
                //
                byte[] c = new byte[1];
                c[0] = ff.readByte();
                String ftyp = new java.lang.StringJ(c, Utils.encode);

                // skip four bytes
                //
                ff.skipBytes(4);

                // get field length and precision which are in the two bytes following
                // the column type.
                //
                short flen = Utils.fixByte(ff.readByte()); // 16
                short fdec = Utils.fixByte(ff.readByte()); // 17
                if (ftyp.equals("N") & fdec == 0)
                {
                    ftyp = "I";
                }

                // bytes 18 - 31 are reserved

                // create a new tsColumn object and assign it the
                // attributes of the current field
                //
                if (TinySQLGlobals.DEBUG)
                {
                    java.lang.SystemJ.outJ.println("Try and create tsColumn for " + colName);
                }
                TsColumn column = new TsColumn(colName);

                /*
                 *    The column type is now given as java.sql.Types constant
                 */
                column.type          = typeToSQLType(ftyp);
                column.size          = flen;
                column.decimalPlaces = fdec;
                column.position      = locn + 1; // set the field position to the current
                column.tableName     = tableName;
                return(column);
            }
            catch (Exception e)
            {
                throw new TinySQLException(e.getMessage());
            }
        }
示例#17
0
        /*
         * Parse out the column definition for a CREATE statement.
         */
        public TsColumn parseColumnDefn(String columnDefn) //throws TinySQLException
        {
            TsColumn       createColumn;
            int            i;
            FieldTokenizer ft;
            String         columnName, colTypeStr, colTypeSpec;

            ft = new FieldTokenizer(columnDefn.toUpperCase(), ' ', false);

/*
 *    A column definition must consist of a column name followed by a
 *    column specification.
 */
            if (ft.countFields() < 2)
            {
                throwException(2);
            }
            columnName = ft.getField(0);

/*
 *    Check for quotes around a column name that may contain blanks.
 */
            if (columnName.charAt(0) == '"' &
                columnName.charAt(columnName.length() - 1) == '"')
            {
                columnName = columnName.substring(1, columnName.length() - 1);
            }
            if (columnName.length() > 11)
            {
                columnName = TinySQLGlobals.getShortName(columnName);
            }
            createColumn = new TsColumn(columnName);
            colTypeStr   = "";
            for (i = 1; i < ft.countFields(); i++)
            {
                colTypeStr += ft.getField(1);
            }
            ft                         = new FieldTokenizer(colTypeStr, '(', false);
            colTypeStr                 = ft.getField(0);
            createColumn.size          = 10;
            createColumn.decimalPlaces = 0;
            if (colTypeStr.equals("FLOAT"))
            {
                createColumn.size          = 12;
                createColumn.decimalPlaces = 2;
            }
            colTypeSpec = ft.getField(1);
            if (!colTypeSpec.equals("NULL"))
            {
/*
 *       Parse out the scale and precision if supplied.
 */
                ft = new FieldTokenizer(colTypeSpec, ',', false);
                createColumn.size          = ft.getInt(0, 8);
                createColumn.decimalPlaces = ft.getInt(1, 0);
            }
            createColumn.type = java.lang.Integer.MIN_VALUE;
            for (i = 0; i < colTypeNames.Length; i++)
            {
                if (colTypeStr.equals(colTypeNames[i]))
                {
                    createColumn.type = colTypes[i];
                }
            }
            if (createColumn.type == java.lang.Integer.MIN_VALUE)
            {
                throwException(8);
            }
            if (TinySQLGlobals.PARSER_DEBUG)
            {
                java.lang.SystemJ.outJ.println("Column " + createColumn.name
                                               + ", type is " + createColumn.type + ",size is " + createColumn.size
                                               + ",precision is " + createColumn.decimalPlaces);
            }
            return(createColumn);
        }
示例#18
0
        /*
         * Validate the column specifications by checking against the tables.
         */
        public void validateColumns() //throws TinySQLException
        {
            String       columnName, columnAlias, columnContext;
            TsColumn     columnObject;
            bool         selectStar;
            TinySQLTable jtbl;
            int          i, j;

/*
 *    Check for a column named *
 */
            selectStar = false;
            for (i = 0; i < columnList.size(); i++)
            {
                columnName    = (String)columnList.elementAt(i);
                columnContext = (String)contextList.elementAt(i);
                if (columnName.equals("*"))
                {
                    if (!columnContext.equals("SELECT"))
                    {
                        throw new TinySQLException("* must be a SELECT column.");
                    }
                    selectStar = true;
                    break;
                }
            }
            if (selectStar)
            {
/*
 *       A column * has been found.  Delete the existing list of SELECT
 *       columns and replace by using an enumeration variable to cycle through
 *       the columns in the tables Hashtable.
 */
                for (i = 0; i < columnList.size(); i++)
                {
                    columnContext = (String)contextList.elementAt(i);
                    if (columnContext.equals("SELECT"))
                    {
                        columnList.removeElementAt(i);
                        contextList.removeElementAt(i);
                        columnAliasList.removeElementAt(i);
                    }
                }
                for (i = 0; i < tableList.size(); i++)
                {
                    jtbl = (TinySQLTable)tables.get((String)tableList.elementAt(i));

/*
 *          Expand to all columns.
 */
                    for (j = 0; j < jtbl.columnNameKeys.size(); j++)
                    {
                        columnName = (String)jtbl.columnNameKeys.elementAt(j);
                        columnList.addElement(jtbl.table + "->" + jtbl.tableAlias
                                              + "." + columnName);
                        columnAliasList.addElement(columnName);
                        contextList.addElement("SELECT");
                    }
                }
            }

/*
 *    Build a column object for each selected column.
 */
            if (tables == (java.util.Hashtable <Object, Object>)null)
            {
                java.lang.SystemJ.outJ.println("*****Column validation - no tables defined.");
            }
            for (i = 0; i < columnList.size(); i++)
            {
                columnName    = (String)columnList.elementAt(i);
                columnContext = (String)contextList.elementAt(i);
                columnAlias   = (String)null;
                if (i < columnAliasList.size())
                {
                    columnAlias = (String)columnAliasList.elementAt(i);
                }
                columnObject       = new TsColumn(columnName, tables, columnContext);
                columnObject.alias = UtilString.removeQuotes(columnAlias);
                columns.addElement(columnObject);
            }
        }
示例#19
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);
            }
        }
示例#20
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));
        }
示例#21
0
        /**
         * Creates new Columns in tableName, given a vector of
         * column definition (tsColumn) arrays.<br>
         * It is necessary to copy the whole file to do this task.
         *
         * ALTER TABLE table [ * ] ADD [ COLUMN ] column type
         *
         * @param tableName the name of the table
         * @param v a Vector containing arrays of column definitions.
         * @see tinySQL#AlterTableAddCol
         */
        internal override void AlterTableAddCol(String tableName, java.util.Vector <Object> v)
        {//throws IOException, tinySQLException {
            // rename the file ...
            String fullpath = dataDir + java.io.File.separator + tableName + DBFFileTable.dbfExtension;
            String tmppath  = dataDir + java.io.File.separator + tableName + "_tmp_tmp" + DBFFileTable.dbfExtension;

            if (Utils.renameFile(fullpath, tmppath) == false)
            {
                throw new TinySQLException("ALTER TABLE ADD COL error in renaming " + fullpath);
            }

            try
            {
                // open the old file ...
                java.io.RandomAccessFile ftbl_tmp = new java.io.RandomAccessFile(tmppath, "r");

                // read the first 32 bytes ...
                DBFHeader dbfHeader_tmp = new DBFHeader(ftbl_tmp);

                // read the column info ...
                java.util.Vector <Object> coldef_list = new java.util.Vector <Object>(dbfHeader_tmp.numFields + v.size());
                int locn = 0; // offset of the current column
                for (int i = 1; i <= dbfHeader_tmp.numFields; i++)
                {
                    TsColumn coldef = readColdef(ftbl_tmp, tableName, i, locn);
                    locn += coldef.size; // increment locn by the length of this field.
                    coldef_list.addElement(coldef);
                }

                // add the new column definitions to the existing ...
                for (int jj = 0; jj < v.size(); jj++)
                {
                    coldef_list.addElement(v.elementAt(jj));
                }

                // create the new table ...
                CreateTable(tableName, coldef_list);

                // copy the data from old to new

                // opening new created dBase file ...
                java.io.RandomAccessFile ftbl = new java.io.RandomAccessFile(fullpath, "rw");
                ftbl.seek(ftbl.length()); // go to end of file

                int numRec = 0;
                for (int iRec = 1; iRec <= dbfHeader_tmp.numRecords; iRec++)
                {
                    String str = GetRecord(ftbl_tmp, dbfHeader_tmp, iRec);

                    // Utils.log("Copy of record#" + iRec + " str='" + str + "' ...");

                    if (str == null)
                    {
                        continue;                           // record was marked as deleted, ignore it
                    }
                    ftbl.write(str.getBytes(Utils.encode)); // write original record
                    numRec++;

                    for (int iCol = 0; iCol < v.size(); iCol++) // write added columns
                    {
                        TsColumn coldef = (TsColumn)v.elementAt(iCol);

                        // enforce the correct column length
                        String value = Utils.forceToSize(coldef.defaultVal, coldef.size, " ");

                        // transform to byte and write to file
                        byte[] b = value.getBytes(Utils.encode);
                        ftbl.write(b);
                    }
                }

                ftbl_tmp.close();

                DBFHeader.writeNumRecords(ftbl, numRec);
                ftbl.close();

                Utils.delFile(tmppath);
            }
            catch (Exception e)
            {
                throw new TinySQLException(e.getMessage());
            }
        }
示例#22
0
        /*
         * Returns the decimal places for a column
         */
        public override int ColDec(String colName) //throws TinySQLException
        {
            TsColumn coldef = getColumn(colName);

            return(coldef.decimalPlaces);
        }
        /**
         *
         * What's a column's number of digits to right of decimal?
         *
         */
        public int getScale(int column)
        {//throws SQLException {
            TsColumn col = tsql.columnAtIndex(column - 1);

            return(col.decimalPlaces);
        }
示例#24
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));
        }
        /**
         *
         * What's the column's precision? Use size.
         *
         */
        public int getPrecision(int column)
        {//  throws SQLException {
            TsColumn col = tsql.columnAtIndex(column - 1);

            return(col.size);
        }
示例#26
0
        /*
         * Returns the datatype of a column.
         *
         * @param column name of the column.
         * @see tinySQLTable#ColType
         *
         * @changed to return java.sql.Types
         */
        public override int ColType(String colName) //throws TinySQLException
        {
            TsColumn coldef = getColumn(colName);

            return(coldef.type);
        }
示例#27
0
        /*
         * opens a DBF file. This is based on Pratap Pereira's
         * Xbase.pm perl module
         * @return column definition list (java.util.Hashtable<Object,Object>)
         *
         * @author Thomas Morgner <*****@*****.**> added check for
         * file exists, before the file is opened. Opening a non existing
         * file will create a new file, and we get errors while trying
         * to read the non-existend headers
         */
        java.util.Hashtable <Object, Object> open_dbf() //throws TinySQLException
        {
            try
            {
                java.io.File f = new java.io.File(fullPath);
                if (TinySQLGlobals.DEBUG)
                {
                    java.lang.SystemJ.outJ.println("Try to open  " + f.getAbsolutePath());
                }
                if (!f.exists())
                {
                    throw new TinySQLException("Unable to open " + f.getAbsolutePath()
                                               + " - does not exist. or can't be read.");
                }
                else if (!f.canRead())
                {
                    throw new TinySQLException("Unable to open " + f.getAbsolutePath()
                                               + " - file can't be read (permissions?).");
                }
                if (f.canWrite())
                {
                    ftbl = new java.io.RandomAccessFile(f, "rw");
                }
                else
                {
                    /*
                     *          Open readonly if the file is not writeable. Needed for
                     *          databases on CD-Rom
                     */
                    ftbl = new java.io.RandomAccessFile(f, "r");
                }

                /*
                 *       Read the first 32 bytes ...
                 */
                dbfHeader = new DBFHeader(ftbl);

                /*
                 *       read the column info (each is a 32 byte bulk) ...
                 */
                java.util.Hashtable <Object, Object> coldef_list = new java.util.Hashtable <Object, Object>();
                columnNameKeys = new java.util.Vector <Object>();
                int locn = 0; // offset of the current column
                for (int i = 1; i <= dbfHeader.numFields; i++)
                {
                    TsColumn coldef = DBFFile.readColdef(ftbl, table, i, locn);
                    locn += coldef.size; // increment locn by the length of this field.
                    coldef_list.put(coldef.name, coldef);
                    columnNameKeys.addElement(coldef.name);
                }
                fileOpen = true;
                return(coldef_list);
            }
            catch (Exception e)
            {
                if (TinySQLGlobals.DEBUG)
                {
                    java.lang.SystemJ.err.println(e.ToString());                      // e.printStackTrace();
                }
                throw new TinySQLException(e.getMessage());
            }
        }
示例#28
0
        internal TsColumn(String s, java.util.Hashtable <Object, Object> tableDefs, String inputContext)
        //throws tinySQLException
        {
            FieldTokenizer ft, ftArgs;
            int            j, numericType, nameLength, dotAt, argIndex;
            String         upperName, checkName, nextArg;
            TinySQLTable   jtbl;
            TsColumn       tcol;

            java.util.Vector <Object>      t;
            java.util.Enumeration <Object> col_keys;
            name        = s;
            longName    = name;
            nameLength  = name.length();
            contextList = new java.util.Vector <Object>();
            contextList.addElement(inputContext);
            ft = new FieldTokenizer(name, '(', false);
            if (ft.countFields() == 2)
            {
                /*
                 *       This is a function rather than a simple column or constant
                 */
                functionName = ft.getField(0).toUpperCase();
                if (functionName.equals("COUNT"))
                {
                    type          = java.sql.Types.INTEGER;
                    size          = 10;
                    intValue      = java.lang.Integer.MIN_VALUE;
                    groupedColumn = true;
                }
                else if (functionName.equals("SUM"))
                {
                    type          = java.sql.Types.FLOAT;
                    size          = 10;
                    groupedColumn = true;
                }
                else if (functionName.equals("TO_DATE"))
                {
                    type = java.sql.Types.DATE;
                    size = 10;
                }
                else if (functionName.equals("CONCAT") |
                         functionName.equals("UPPER") |
                         functionName.equals("SUBSTR") |
                         functionName.equals("TRIM"))
                {
                    type = java.sql.Types.CHAR;
                }
                functionArgString = ft.getField(1);
                ftArgs            = new FieldTokenizer(functionArgString, ',', false);
                functionArgs      = new java.util.Vector <Object>();
                argIndex          = 0;
                while (ftArgs.hasMoreFields())
                {
                    nextArg = ftArgs.nextField();
                    tcol    = new TsColumn(nextArg, tableDefs, inputContext);
                    if (tcol.isGroupedColumn())
                    {
                        groupedColumn = true;
                    }

                    /*
                     *          MAX and MIN functions can be either FLOAT or CHAR types
                     *          depending upon the type of the argument.
                     */
                    if (functionName.equals("MAX") | functionName.equals("MIN"))
                    {
                        if (argIndex > 0)
                        {
                            throw new TinySQLException("Function can only have 1 argument");
                        }
                        groupedColumn = true;
                        type          = tcol.type;
                        size          = tcol.size;
                    }
                    else if (functionName.equals("CONCAT"))
                    {
                        type  = java.sql.Types.CHAR;
                        size += tcol.size;
                    }
                    else if (functionName.equals("UPPER"))
                    {
                        type = java.sql.Types.CHAR;
                        size = tcol.size;
                    }
                    else if (functionName.equals("TO_DATE"))
                    {
                        type = java.sql.Types.DATE;
                        size = 10;
                    }
                    else if (functionName.equals("TRIM"))
                    {
                        type = java.sql.Types.CHAR;
                        size = tcol.size;
                    }
                    else if (functionName.equals("SUBSTR"))
                    {
                        type = java.sql.Types.CHAR;
                        if (argIndex == 0 & tcol.type != java.sql.Types.CHAR)
                        {
                            throw new TinySQLException("SUBSTR first argument must be character");
                        }
                        else if (argIndex == 1)
                        {
                            if (tcol.type != java.sql.Types.INTEGER | tcol.intValue < 1)
                            {
                                throw new TinySQLException("SUBSTR second argument "
                                                           + tcol.getString() + " must be integer > 0");
                            }
                        }
                        else if (argIndex == 2)
                        {
                            if (tcol.type != java.sql.Types.INTEGER | tcol.intValue < 1)
                            {
                                throw new TinySQLException("SUBSTR third argument "
                                                           + tcol.getString() + " must be integer > 0");
                            }
                            size = tcol.intValue;
                        }
                    }
                    argIndex++;
                    functionArgs.addElement(tcol);
                }
            }
            else
            {
                /*
                 *       Check for SYSDATE
                 */
                if (name.toUpperCase().equals("SYSDATE"))
                {
                    isConstant = true;
                    type       = java.sql.Types.DATE;
                    size       = 10;
                    notNull    = true;
                    valueSet   = true;
                    //Basties mote: not really SimpleDateFormat needed... - need yyyy-MM-dd
                    // stringValue = fmtyyyyMMdd.format(today.getTime());
                    stringValue = System.DateTime.Today.ToString("yyyy-MM-dd");

                    /*
                     *          Check for a quoted string
                     */
                }
                else if (UtilString.isQuotedString(name))
                {
                    isConstant  = true;
                    type        = java.sql.Types.CHAR;
                    stringValue = UtilString.removeQuotes(name);
                    if (stringValue != (String)null)
                    {
                        size     = stringValue.length();
                        notNull  = true;
                        valueSet = true;
                    }
                }
                else
                {
                    /*
                     *          Check for a numeric constant
                     */
                    numericType = UtilString.getValueType(name);
                    if (numericType == java.sql.Types.INTEGER)
                    {
                        intValue   = java.lang.Integer.valueOf(name).intValue();
                        size       = 10;
                        type       = numericType;
                        isConstant = true;
                        notNull    = true;
                        valueSet   = true;
                    }
                    else if (numericType == java.sql.Types.FLOAT)
                    {
                        floatValue = java.lang.Float.valueOf(name).floatValue();
                        size       = 10;
                        type       = numericType;
                        isConstant = true;
                        notNull    = true;
                        valueSet   = true;
                    }
                    else
                    {
                        /*
                         *             This should be a column name.
                         */
                        columnTable = (TinySQLTable)null;
                        upperName   = name.toUpperCase();
                        if (TinySQLGlobals.DEBUG)
                        {
                            java.lang.SystemJ.outJ.println("Trying to find table for " + upperName);
                        }
                        dotAt = upperName.indexOf(".");
                        if (dotAt > -1)
                        {
                            tableName = upperName.substring(0, dotAt);
                            if (tableDefs != (java.util.Hashtable <Object, Object>)null &
                                tableName.indexOf("->") < 0)
                            {
                                t         = (java.util.Vector <Object>)tableDefs.get("TABLE_SELECT_ORDER");
                                tableName = UtilString.findTableAlias(tableName, t);
                            }
                            upperName = upperName.substring(dotAt + 1);

                            /*
                             *                Check to see if this column name has a short equivalent.
                             */
                            if (upperName.length() > 11)
                            {
                                longName  = name;
                                upperName = TinySQLGlobals.getShortName(upperName);
                            }
                            columnTable = (TinySQLTable)tableDefs.get(tableName);
                        }
                        else if (tableDefs != (java.util.Hashtable <Object, Object>)null)
                        {
                            /*
                             *                Check to see if this column name has a short equivalent.
                             */
                            if (upperName.length() > 11)
                            {
                                longName  = name;
                                upperName = TinySQLGlobals.getShortName(upperName);
                            }

                            /*
                             *                Use an enumeration to go through all of the tables to find
                             *                this column.
                             */
                            t = (java.util.Vector <Object>)tableDefs.get("TABLE_SELECT_ORDER");
                            for (j = 0; j < t.size(); j++)
                            {
                                tableName = (String)t.elementAt(j);
                                jtbl      = (TinySQLTable)tableDefs.get(tableName);
                                col_keys  = jtbl.column_info.keys();

                                /*
                                 *                   Check all columns.
                                 */
                                while (col_keys.hasMoreElements())
                                {
                                    checkName = (String)col_keys.nextElement();
                                    if (checkName.equals(upperName))
                                    {
                                        upperName   = checkName;
                                        columnTable = jtbl;
                                        break;
                                    }
                                }
                                if (columnTable != (TinySQLTable)null)
                                {
                                    break;
                                }
                            }
                        }
                        else
                        {
                            if (TinySQLGlobals.DEBUG)
                            {
                                java.lang.SystemJ.outJ.println("No table definitions.");
                            }
                        }
                        if (columnTable != (TinySQLTable)null)
                        {
                            name = columnTable.table + "->" + columnTable.tableAlias
                                   + "." + upperName;
                            type          = columnTable.ColType(upperName);
                            size          = columnTable.ColSize(upperName);
                            decimalPlaces = columnTable.ColDec(upperName);
                            tableName     = columnTable.table + "->" + columnTable.tableAlias;
                        }
                    }
                }
            }
        }
示例#29
0
        /**
         *
         * Given a tsColumn object, returns its value as a String.
         *
         * @param column the tsColumn object
         *
         */
        public String columnAsString(TsColumn column)
        {
            String outputString, valueString, functionName, argList, nextArg;

            java.lang.StringBuffer functionBuffer;
            FieldTokenizer         ft1, ft2;

            /*
             *    Next try to retrieve as a group function, which will not have a
             *    tablename prefix.
             */
            outputString = (String)get(column.name);
            if (outputString != (String)null)
            {
                return(outputString);
            }
            ft1 = new FieldTokenizer(column.name, '(', false);
            if (ft1.countFields() == 2)
            {
                /*
                 *       The column is a function.  If it is a group function, the value
                 *       will be stored in the record.  Otherwise, the function value
                 *       will be determined here by retrieving and processing all the
                 *       columns in the function arguments.
                 */
                outputString = (String)get(column.name);
                if (outputString != (String)null)
                {
                    return(outputString);
                }
                functionName   = ft1.getField(0);
                argList        = ft1.getField(1);
                ft2            = new FieldTokenizer(argList, ',', false);
                functionBuffer = new java.lang.StringBuffer();

                /*
                 *       Function arguments must consist of table.column names or constants.
                 */
                while (ft2.hasMoreFields())
                {
                    nextArg     = ft2.nextField();
                    valueString = (String)get(nextArg);
                    if (debug)
                    {
                        java.lang.SystemJ.outJ.println("Function " + functionName
                                                       + " argument " + nextArg + " has value " + valueString);
                    }

                    /*
                     *          If the valueString is null then it is a constant rather than
                     *          a database column.  Remove enclosing quotes.
                     */
                    if (valueString == (String)null)
                    {
                        valueString = UtilString.removeQuotes(nextArg);
                    }
                    else
                    {
                        valueString = valueString.trim();
                    }
                    if (functionName.equals("CONCAT"))
                    {
                        functionBuffer.append(valueString);
                    }
                }
                outputString = functionBuffer.toString();
            }
            else if (column.tableName == (String)null)
            {
                /*
                 *       This is a constant.  Return the table name which will be equal to
                 *       the constant value.
                 */
                outputString = UtilString.removeQuotes(column.name);
            }
            else
            {
                /*
                 *       Retrieve as a simple database column.
                 */
                outputString = (String)get(column.tableName + "." + column.name);
                if (Utils.isDateColumn(column.type))
                {
                    /*
                     *          Format dates as DD-MON-YY for output.  Note that the value
                     *          stored in the database may already be in this format because
                     *          of incorrect storage of date strings prior to version 2.3.
                     */
                    try
                    {
                        outputString = UtilString.toStandardDate(outputString);
                    }
                    catch (Exception dateEx)
                    {
                        java.lang.SystemJ.outJ.println(dateEx.getMessage());
                    }
                }
            }
            return(outputString);
        }
示例#30
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());
            }
        }