/** * Constructs a new Database object. * * @param type is the type of the database: "mem", "file", "res" * @param path is the fiven path to the database files * @param name is the combination of type and canonical path * @param props property overrides placed on the connect URL * @exception HsqlException if the specified name and path combination is illegal or unavailable, * or the database files the name and path resolves to are in use by another process */ Database(String type, String path, String name, HsqlProperties props) throws HsqlException { urlProperties = props; setState(Database.DATABASE_SHUTDOWN); sName = name; sType = type; sPath = path; if (sType == DatabaseURL.S_RES) { filesInJar = true; filesReadOnly = true; } // does not need to be done more than once try { classLoader = getClass().getClassLoader(); } catch (Exception e) { // strict security policy: just use the system/boot loader classLoader = null; } // [email protected] - changed to file access api String fileaccess_class_name = (String) urlProperties.getProperty("fileaccess_class_name"); if (fileaccess_class_name != null) { String storagekey = urlProperties.getProperty("storage_key"); try { Class fileAccessClass = null; try { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); fileAccessClass = classLoader.loadClass(fileaccess_class_name); } catch (ClassNotFoundException e) { fileAccessClass = Class.forName(fileaccess_class_name); } Constructor constructor = fileAccessClass.getConstructor(new Class[] {Object.class}); fileaccess = (FileAccess) constructor.newInstance(new Object[] {storagekey}); isStoredFileAccess = true; } catch (Exception e) { throw Trace.error(Trace.INVALID_FILE_ACCESS_CLASS, new Object[] {e.toString()}); } } else { fileaccess = FileUtil.getDefaultInstance(); } shutdownOnNoConnection = urlProperties.getProperty("shutdown", "false").equals("true"); logger = new Logger(); compiledStatementManager = new CompiledStatementManager(this); }
/** Closes the source file and deletes it if it is not read-only. */ void purge() throws HsqlException { if (rFile == null) { return; } try { if (readOnly) { close(); } else { rFile.close(); rFile = null; FileUtil.delete(sName); } } catch (Exception e) { throw Trace.error( Trace.FILE_IO_ERROR, Trace.TextCache_purging_file_error, new Object[] {sName, e}); } }
/** * Writes newly created rows to disk. In the current implentation, such rows have already been * saved, so this method just removes a source file that has no rows. */ void close() throws HsqlException { if (rFile == null) { return; } try { saveAll(); boolean empty = (rFile.length() <= NL.length()); rFile.close(); rFile = null; if (empty && !readOnly) { FileUtil.delete(sName); } } catch (Exception e) { throw Trace.error( Trace.FILE_IO_ERROR, Trace.TextCache_closing_file_error, new Object[] {sName, e}); } }
/** Writes out all the rows to a new file without fragmentation. */ public void defrag() throws HsqlException { if (cacheReadonly) { return; } if (fileFreePosition == INITIAL_FREE_POS) { return; } try { boolean wasNio = dataFile.wasNio(); DataFileDefrag dfd = new DataFileDefrag(database, this, fileName); dfd.process(); close(false); Trace.printSystemOut("closed old cache"); // first attemp to delete fa.removeElement(fileName); if (wasNio) { System.gc(); if (fa.isStreamElement(fileName)) { fa.removeElement(fileName); if (fa.isStreamElement(fileName)) { fa.renameElement(fileName, fileName + ".old"); File oldfile = new File(fileName + ".old"); FileUtil.deleteOnExit(oldfile); } } } // [email protected] - change to file access api fa.renameElement(fileName + ".new", fileName); backup(); database .getProperties() .setProperty("hsqldb.cache_version", HsqlDatabaseProperties.VERSION_STRING_1_7_0); database.getProperties().save(); initParams(); cache = new Cache(this); open(cacheReadonly); dfd.updateTableIndexRoots(); Trace.printSystemOut("opened cache"); } catch (Exception e) { database.logger.appLog.logContext(e); throw new HsqlException(e, Trace.getMessage(Trace.GENERAL_IO_ERROR), Trace.GENERAL_IO_ERROR); /* Trace.error(Trace.FILE_IO_ERROR, Trace.DataFileCache_defrag, new Object[] { e, fileName }); */ } }