⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbffile.java

📁 TinySQL是一个轻量级的纯java数据库引擎
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        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);
          System.out.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
      File f = new File(tmppath);
      if (f.exists())
         f.delete();

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

    } catch (Exception e) {
      throw new tinySQLException(e.getMessage());
    }
  }


  /*
   * Rename columns
   *
   * ALTER TABLE table RENAME war TO peace
   */
  void AlterTableRenameCol (String tableName, String oldColname, String newColname)
    throws tinySQLException
  {
    String fullpath = dataDir + File.separator + tableName + dbfFileTable.dbfExtension;
    try {
      RandomAccessFile ftbl = new 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());
    }

  }

  /**
   *
   * Return a tinySQLTable object, given a table name.
   *
   * @param tableName
   * @see tinySQL#getTable
   *
   */
  tinySQLTable getTable (String tableName) throws tinySQLException 
  {
     int i,tableIndex;
     tinySQLTable nextTable;
     tableIndex = Integer.MIN_VALUE;
     if ( tinySQLGlobals.DEBUG ) System.out.println("Trying to create table"
     + " object for " + tableName);
     for ( i = 0; i < tableList.size(); i++ )
     {
        nextTable = (tinySQLTable)tableList.elementAt(i);
        if ( nextTable.table.equals(tableName) )
        {
           if ( nextTable.isOpen() )
           {
              if ( tinySQLGlobals.DEBUG )
                 System.out.println("Found in cache " + nextTable.toString());
              return nextTable;
           }
           tableIndex = i;
           break;
        }
     }
     if ( tableIndex == Integer.MIN_VALUE )
     {
        tableList.addElement(new dbfFileTable(dataDir,tableName));
        nextTable = (tinySQLTable)tableList.lastElement();
        if ( tinySQLGlobals.DEBUG ) System.out.println("Add to cache "
        + nextTable.toString());
        return (tinySQLTable)tableList.lastElement(); 
     } else {
        tableList.setElementAt(new dbfFileTable(dataDir,tableName),tableIndex);
        nextTable = (tinySQLTable)tableList.elementAt(tableIndex);
        if ( tinySQLGlobals.DEBUG ) System.out.println("Update in cache "
        + nextTable.toString());
        return (tinySQLTable)tableList.elementAt(tableIndex); 
     }
  }

  /**
   *
   * The DBF File class provides read-only access to DBF
   * files, so this baby should throw an exception.
   *
   * @param fname table name
   * @see tinySQL#DropTable
   *
   */
  void DropTable (String fname) throws tinySQLException {
    DBFHeader.dropTable(dataDir, fname);
  }
  /**
  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
  */
  static tsColumn readColdef(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.
      boolean clear = false;
      int i = 0;
      while ((i < 11) && (b[i] != 0))
      {
      	i++;
      }
      while (i < 11)
      {
      	b[i] = 0;
      	i++;
      }
      String colName = (new String(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 String(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 ) 
         System.out.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());
    }
  }

  /**
  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(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 == Types.CHAR || coldef.type == Types.VARCHAR || coldef.type == Types.LONGVARCHAR)
      	type = "C";
      else
      if (coldef.type == Types.NUMERIC || coldef.type == Types.INTEGER || 
          coldef.type == Types.TINYINT || coldef.type == Types.SMALLINT ||
          coldef.type == Types.BIGINT  || coldef.type == Types.FLOAT || 
          coldef.type == Types.DOUBLE  || coldef.type == Types.REAL)
      	type = "N";
      else
      if (coldef.type == Types.BIT)
      	type = "L";
      else
      if (coldef.type == 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());
    }
  }


  /**
  'C' Char (max 254 bytes)
  'N' '-.0123456789' (max 19 bytes)
  'L' 'YyNnTtFf?' (1 byte)
  'M' 10 digit .DBT block number
  'D' 8 digit YYYYMMDD
  *
  * Uses java.sql.Types as key
  */
  static String typeToLiteral(int type)
  {
    if (type == Types.CHAR) return "CHAR";
    if (type == Types.VARCHAR) return "VARCHAR";
    if (type == Types.FLOAT) return "FLOAT";
    if (type == Types.NUMERIC) return "NUMERIC";
    if (type == Types.INTEGER) return "INT";
    if (type == Types.BIT) return "BIT";
    if (type == Types.BINARY) return "BINARY";
    if (type == Types.DATE) return "DATE";
    return "CHAR"; // fallback
  }


  /**
  'C' Char (max 254 bytes)
  'N' '-.0123456789' (max 19 bytes)
  'L' 'YyNnTtFf?' (1 byte)
  'M' 10 digit .DBT block number
  'D' 8 digit YYYYMMDD
  */
  static int typeToSQLType(String type)
  {
    if (type.equals("C")) return java.sql.Types.CHAR;
    if (type.equals("N")) return java.sql.Types.FLOAT;
    if (type.equals("I")) return java.sql.Types.INTEGER;
    if (type.equals("L")) return java.sql.Types.CHAR;
    if (type.equals("M")) return java.sql.Types.INTEGER;
    if (type.equals("D")) return java.sql.Types.DATE;
    return java.sql.Types.CHAR; // fallback
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -