/** * Retrieve a record (=row) * @param dbfHeader dBase meta info * @param recordNumber starts with 1 * @return the String with the complete record * or null if the record is marked as deleted * @see tinySQLTable#GetCol */ public String GetRecord(java.io.RandomAccessFile ff, DBFHeader dbfHeader, int recordNumber) //throws tinySQLException { if (recordNumber < 1) { throw new TinySQLException("Internal error - current record number < 1"); } try { // seek the starting offset of the current record, // as indicated by recordNumber ff.seek(dbfHeader.headerLength + (recordNumber - 1) * dbfHeader.recordLength); // fully read a byte array out to the length of // the record. byte[] b = new byte[dbfHeader.recordLength]; ff.readFully(b); // make it into a String String record = new java.lang.StringJ(b, Utils.encode); // remove deleted records if (DBFFileTable.isDeleted(record)) { return(null); } return(record); } catch (Exception e) { throw new TinySQLException(e.getMessage()); } }
//throws IOException { /** * Opens the given file for reading, assuming the specified * encoding for file names. * * @param f the archive. * @param encoding the encoding to use for file names, use null * for the platform's default encoding * @param useUnicodeExtraFields whether to use InfoZIP Unicode * Extra Fields (if present) to set the file names. * * @throws IOException if an error occurs while reading the file. */ public ZipFile(java.io.File f, String encoding, bool useUnicodeExtraFields) //throws IOException { this.OFFSET_COMPARATOR = new IAC_OFFSET_COMPARATOR(this); this.encoding = encoding; this.zipEncoding = ZipEncodingHelper.getZipEncoding(encoding); this.useUnicodeExtraFields = useUnicodeExtraFields; archive = new java.io.RandomAccessFile(f, "r"); bool success = false; try { java.util.Map <ZipArchiveEntry, IAC_NameAndComment> entriesWithoutUTF8Flag = populateFromCentralDirectory(); resolveLocalFileHeaderData(entriesWithoutUTF8Flag); success = true; } finally { if (!success) { try { archive.close(); } catch (java.io.IOException) { // swallow, throw the original exception instead } } } }
/* * Opens a file as <i>ZIP-archive</i>. "mode" must be {@code OPEN_READ} or * {@code OPEN_DELETE} . The latter sets the "delete on exit" flag through a * file. * * @param file * the ZIP file to read. * @param mode * the mode of the file open operation. * @throws IOException * if an {@code IOException} occurs. */ public ZipFile(java.io.File file, int mode) //throws IOException { { fileName = file.getPath(); if (mode != OPEN_READ && mode != (OPEN_READ | OPEN_DELETE)) { throw new java.lang.IllegalArgumentException(); } /* java.lang.SecurityManager security = java.lang.SystemJ.getSecurityManager(); * if (security != null) { * security.checkRead(fileName); * }*/ if ((mode & OPEN_DELETE) != 0) { /* if (security != null) { * security.checkDelete(fileName); * }*/ fileToDeleteOnClose = file; // file.deleteOnExit(); } else { fileToDeleteOnClose = null; } mRaf = new java.io.RandomAccessFile(fileName, "r"); readCentralDir(); }
/** * 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()); } }
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(); }
/** * Create new dBase file and write the first 32 bytes<br> * the file remains opened * @return file handle with read/write access */ public java.io.RandomAccessFile create(String dataDir, String tableName ) //throws tinySQLException { this.tableName = tableName; try { // make the data directory, if it needs to be make // mkDataDirectory(dataDir); // perform an implicit drop table. // dropTable(dataDir, tableName); String fullPath = dataDir + java.io.File.separator + tableName + DBFFileTable.dbfExtension; java.io.RandomAccessFile ff = new java.io.RandomAccessFile(fullPath, "rw"); write(ff); // ftbl.close(); return(ff); } catch (Exception e) { throw new TinySQLException(e.getMessage()); } }
/* * 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()); } }
/* * Closes this ZIP file. This method is idempotent. * * @throws IOException * if an IOException occurs. */ public void close() // throws IOException { { java.io.RandomAccessFile raf = mRaf; if (raf != null) // Only close initialized instances { lock (raf) { mRaf = null; raf.close(); } if (fileToDeleteOnClose != null) { new java.io.File(fileName).delete(); /*AccessController.doPrivileged(new PrivilegedAction<Object>() { * public Object run() { * new File(fileName).delete(); * return null; * } * });*/ // fileToDeleteOnClose.delete(); fileToDeleteOnClose = null; } } }
internal const int RESERVED_INDEX = 12; // 12-31 /** * Constructs a DBFHeader, read the data from file <br> * You need to supply an open file handle to read from * @param ff open file handle for read access */ internal DBFHeader(java.io.RandomAccessFile ff) //throws tinySQLException { try { ff.seek(FLAG_INDEX); file_type = Utils.fixByte(ff.readByte()); // get the last update date file_update_year = Utils.fixByte(ff.readByte()); file_update_month = Utils.fixByte(ff.readByte()); file_update_day = Utils.fixByte(ff.readByte()); // a byte array to hold little-endian long data // byte[] b = new byte[4]; // read that baby in... // ff.readFully(b); // convert the byte array into a long (really a double) // 4-7 number of records numRecords = (int)Utils.vax_to_long(b); // a byte array to hold little-endian short data // b = new byte[2]; // get the data position (where it starts in the file) // 8-9 Length of header ff.readFully(b); headerLength = Utils.vax_to_short(b); // find out the length of the data portion // 10-11 Length of Record ff.readFully(b); recordLength = Utils.vax_to_short(b); // calculate the number of fields // numFields = (int)(headerLength - 33) / 32; // skip the next 20 bytes - looks like this is not needed... //ff.skipBytes(20); // 12-31 reserved Utils.log("HEADER=" + this.toString()); } catch (Exception e) { throw new TinySQLException(e.getMessage()); } }
/* * Read a four-byte int in little-endian order. */ internal static long readIntLE(java.io.RandomAccessFile raf) //throws IOException { int b0 = raf.read(); int b1 = raf.read(); int b2 = raf.read(); int b3 = raf.read(); if (b3 < 0) { throw new java.io.EOFException(); //Messages.getString("archive.3B")); } return(b0 | (b1 << 8) | (b2 << 16) | (b3 << 24)); // ATTENTION: DOES SIGN EXTENSION: IS THIS WANTED? }
/** * Update the header (index 10-11) with the length of one record * @param recordLength Length of one data record (row) */ public void setRecordLength(java.io.RandomAccessFile ff, int recordLength) //throws tinySQLException { this.recordLength = recordLength; try { ff.seek(DBFHeader.LENGTH_OF_REC_INDEX); ff.write(Utils.shortToLittleEndian((short)recordLength)); } catch (Exception e) { throw new TinySQLException(e.getMessage()); } }
/** * Update the header (index 4-7) with the new number of records <br> * This is the static variant (use it if you don't want to obtain * a DBFHeader instance * @param New number of records */ public static void writeNumRecords(java.io.RandomAccessFile ff, int numRecords) //throws tinySQLException { try { byte[] b = Utils.intToLittleEndian(numRecords); ff.seek(NUMBER_OF_REC_INDEX); ff.write(b); } catch (Exception e) { throw new TinySQLException(e.getMessage()); } }
/** * Update the header (index 8-9) with the new number of records * @param numFields number of columns (used to calculate header length) */ public void setHeaderLength(java.io.RandomAccessFile ff, int numFields)// throws tinySQLException { this.numFields = numFields; try { int headerLength = (DBFHeader.BULK_SIZE + 1) + numFields * DBFHeader.BULK_SIZE; ff.seek(DBFHeader.LENGTH_OF_HEADER_INDEX); ff.write(Utils.shortToLittleEndian((short)headerLength)); } catch (Exception e) { throw new TinySQLException(e.getMessage()); } }
/** * Update the header (index 10-11) with the length of one record * @param recordLength Length of one data record (row) */ public void setReserved(java.io.RandomAccessFile ff) //throws tinySQLException { try { ff.seek(DBFHeader.RESERVED_INDEX); byte[] reserved = Utils.forceToSize(null, DBFHeader.BULK_SIZE - DBFHeader.RESERVED_INDEX, (byte)0); ff.write(reserved); // padding with \0! } catch (Exception e) { throw new TinySQLException(e.getMessage()); } }
public void setTimestamp(java.io.RandomAccessFile ff) //throws tinySQLException { try { java.util.Calendar cal = java.util.Calendar.getInstance(); cal.setTime(new java.util.Date()); int dd = cal.get(java.util.Calendar.DAY_OF_MONTH); int mm = cal.get(java.util.Calendar.MONTH) + 1; int yy = cal.get(java.util.Calendar.YEAR); yy = yy % 100; // Y2K problem: only 2 digits ff.seek(DATE_INDEX); ff.write(yy); ff.write(mm); ff.write(dd); } catch (Exception e) { throw new TinySQLException(e.getMessage()); } }
long record_length; // length of a record /** * * Constructs a textFileTable. This is only called by getTable() * in textFile.java. * * @param dDir data directory * @param table_name the name of the table * */ internal TextFileTable(String dDir, String table_name) { //throws tinySQLException { dataDir = dDir; // set the data directory table = table_name; // set the table name // attempt to open the file in read/write mode // try { ftbl = new java.io.RandomAccessFile(dataDir + "/" + table_name, "rw"); } catch (Exception) { throw new TinySQLException("Could not open the file " + table + "."); } // read in the table definition // readColumnInfo(); }
/** * Creates a new ZIP OutputStream writing to a File. Will use * random access if possible. * @param file the file to zip to * @throws IOException on error */ public ZipArchiveOutputStream(java.io.File file) //throws IOException { java.io.OutputStream o = null; java.io.RandomAccessFile _raf = null; try { _raf = new java.io.RandomAccessFile(file, "rw"); _raf.setLength(0); } catch (java.io.IOException) { if (_raf != null) { try { _raf.close(); } catch (java.io.IOException) { // ignore } _raf = null; } o = new java.io.FileOutputStream(file); } outJ = o; raf = _raf; }
/* * Returns an input stream on the data of the specified {@code ZipEntry}. * * @param entry * the ZipEntry. * @return an input stream of the data contained in the {@code ZipEntry}. * @throws IOException * if an {@code IOException} occurs. * @throws IllegalStateException if this ZIP file has been closed. */ public java.io.InputStream getInputStream(ZipEntry entry) // throws IOException { /* * Make sure this ZipEntry is in this Zip file. We run it through * the name lookup. */ { entry = getEntry(entry.getName()); if (entry == null) { return(null); } /* * Create a ZipInputStream at the right part of the file. */ java.io.RandomAccessFile raf = mRaf; lock (raf) { // We don't know the entry data's start position. All we have is the // position of the entry's local header. At position 28 we find the // length of the extra data. In some cases this length differs from // the one coming in the central header. RAFStream rafstrm = new RAFStream(raf, entry.mLocalHeaderRelOffset + 28); int localExtraLenOrWhatever = ler.readShortLE(rafstrm); // Skip the name and this "extra" data or whatever it is: rafstrm.skip(entry.nameLen + localExtraLenOrWhatever); rafstrm.mLength = rafstrm.mOffset + entry.compressedSize; if (entry.compressionMethod == ZipEntry.DEFLATED) { int bufSize = java.lang.Math.max(1024, (int)java.lang.Math.min(entry.getSize(), 65535L)); return(new ZipInflaterInputStream(rafstrm, new Inflater(true), bufSize, entry)); } else { return(rafstrm); } } }
/* * Retrieve a column's string value from the given row and given colName * @param ff the file handle * @param colName the column name * @param the wanted record (starts with 1) * @see tinySQLTable#GetCol * * @author Thomas Morgner <*****@*****.**> This function retrieves a * row, perhaps the name should changed to reflect the new function. */ public static String _GetCol(java.io.RandomAccessFile ff, DBFHeader dbfHeader, int currentRow) //throws TinySQLException { try { /* * Seek the starting offset of the current record, * as indicated by currentRow */ ff.seek(dbfHeader.headerLength + (currentRow - 1) * dbfHeader.recordLength); /* * Fully read a byte array out to the length of the record and convert * it into a String. */ byte[] b = new byte[dbfHeader.recordLength]; ff.readFully(b); return(new java.lang.StringJ(b, Utils.encode)); // "Cp437" } catch (Exception e) { throw new TinySQLException(e.getMessage()); } }
/** * write the first 32 bytes to file */ public void write(java.io.RandomAccessFile ff) //throws tinySQLException { try { //----------------------------- // write out the primary header ff.seek(FLAG_INDEX); ff.writeByte((byte)0x03); setTimestamp(ff); // set current date YY MM DD (dBase is not Y2K save) setNumRecords(ff, 0); setHeaderLength(ff, numFields); setRecordLength(ff, recordLength); setReserved(ff); } catch (Exception e) { throw new TinySQLException(e.getMessage()); } }
/** * Creates a new ZIP OutputStream filtering the underlying stream. * @param out the outputstream to zip */ public ZipArchiveOutputStream(java.io.OutputStream output) { this.outJ = output; this.raf = null; }
/* * 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()); } }
/* * Checks whether the row is deleted. */ public static bool isDeleted(java.io.RandomAccessFile ff, DBFHeader dbfHeader, int currentRow) //throws TinySQLException { char del = _GetCol(ff, dbfHeader, currentRow).charAt(0); // "_DELETED" return(del == RECORD_IS_DELETED); }
/** * Update the header (index 4-7) with the new number of records * @param New number of records */ public void setNumRecords(java.io.RandomAccessFile ff, int numRecords) //throws tinySQLException { this.numRecords = numRecords; writeNumRecords(ff, numRecords); }
/** * 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()); } }
/** * 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()); } }
/** * * 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()); } }
public RAFStream(java.io.RandomAccessFile raf, long pos) //throws IOException { { mSharedRaf = raf; mOffset = pos; mLength = raf.length(); }