/** * Opens this database. The database should be opened after construction. or reopened by the * close(int closemode) method during a "shutdown compact". Closes the log if there is an error. */ void reopen() { boolean isNew = false; setState(DATABASE_OPENING); try { nameManager = new HsqlNameManager(this); granteeManager = new GranteeManager(this); userManager = new UserManager(this); schemaManager = new SchemaManager(this); persistentStoreCollection = new PersistentStoreCollectionDatabase(this); isReferentialIntegrity = true; sessionManager = new SessionManager(this); collation = collation.newDatabaseInstance(); dbInfo = DatabaseInformation.newDatabaseInformation(this); txManager = new TransactionManager2PL(this); lobManager.createSchema(); sessionManager.getSysLobSession().setSchema(SqlInvariants.LOBS_SCHEMA); schemaManager.setSchemaChangeTimestamp(); schemaManager.createSystemTables(); // completed metadata logger.open(); isNew = logger.isNewDatabase; if (isNew) { String username = urlProperties.getProperty("user", "SA"); String password = urlProperties.getProperty("password", ""); userManager.createFirstUser(username, password); schemaManager.createPublicSchema(); logger.checkpoint(false); } lobManager.open(); dbInfo.setWithContent(true); checkpointRunner = new CheckpointRunner(); timeoutRunner = new TimeoutRunner(); } catch (Throwable e) { logger.close(Database.CLOSEMODE_IMMEDIATELY); logger.releaseLock(); setState(DATABASE_SHUTDOWN); clearStructures(); DatabaseManager.removeDatabase(this); if (!(e instanceof HsqlException)) { e = Error.error(ErrorCode.GENERAL_ERROR, e); } logger.logSevereEvent("could not reopen database", e); throw (HsqlException) e; } setState(DATABASE_ONLINE); }
/** * 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); }
/** * Translates the legacy default database form: database=... to the 1.7.2 form: database.0=... * * @param p The properties object upon which to perform the translation */ public static void translateDefaultDatabaseProperty(HsqlProperties p) { if (p == null) { return; } String defaultdb = p.getProperty(SC_KEY_DATABASE); if (defaultdb != null) { p.setProperty(SC_KEY_DATABASE + ".0", defaultdb); } }
/** * Translates null or zero length value for address key to the special value * ServerConstants.SC_DEFAULT_ADDRESS which causes ServerSockets to be constructed without * specifying an InetAddress. * * @param p The properties object upon which to perform the translation */ public static void translateAddressProperty(HsqlProperties p) { if (p == null) { return; } String address = p.getProperty(SC_KEY_ADDRESS); if (StringUtil.isEmpty(address)) { p.setProperty(SC_KEY_ADDRESS, SC_DEFAULT_ADDRESS); } }
/** * Retrieves a new HsqlProperties object, if possible, loaded from the specified file. * * @param path the file's path, without the .properties extention (which is added automatically) * @return a new properties object loaded from the specified file */ public static HsqlProperties getPropertiesFromFile(String path) { if (StringUtil.isEmpty(path)) { return null; } HsqlProperties p = new HsqlProperties(path); try { p.load(); } catch (Exception e) { } return p; }
/** * Opens this database. The database should be opened after construction. or reopened by the * close(int closemode) method during a "shutdown compact". Closes the log if there is an error. */ void reopen() throws HsqlException { boolean isNew; setState(DATABASE_OPENING); try { databaseProperties = new HsqlDatabaseProperties(this); isNew = !DatabaseURL.isFileBasedDatabaseType(sType) || !databaseProperties.checkFileExists(); if (isNew && urlProperties.isPropertyTrue("ifexists")) { throw Trace.error(Trace.DATABASE_NOT_EXISTS, sName); } databaseProperties.load(); databaseProperties.setURLProperties(urlProperties); compiledStatementManager.reset(); nameManager = new HsqlNameManager(); granteeManager = new GranteeManager(this); userManager = new UserManager(this); hAlias = Library.getAliasMap(); schemaManager = new SchemaManager(this); bReferentialIntegrity = true; sessionManager = new SessionManager(this); txManager = new TransactionManager(this); collation = new Collation(); dbInfo = DatabaseInformation.newDatabaseInformation(this); databaseProperties.setDatabaseVariables(); if (DatabaseURL.isFileBasedDatabaseType(sType)) { logger.openLog(this); } if (isNew) { sessionManager .getSysSession() .sqlExecuteDirectNoPreChecks("CREATE USER SA PASSWORD \"\" ADMIN"); logger.synchLogForce(); } dbInfo.setWithContent(true); } catch (Throwable e) { logger.closeLog(Database.CLOSEMODE_IMMEDIATELY); logger.releaseLock(); setState(DATABASE_SHUTDOWN); clearStructures(); DatabaseManager.removeDatabase(this); if (!(e instanceof HsqlException)) { e = Trace.error(Trace.GENERAL_ERROR, e.toString()); } throw (HsqlException) e; } setState(DATABASE_ONLINE); }
/** * Tranlates unspecified no_system_exit property to false, the default typically required when a * Server is started from the command line. * * @param p The properties object upon which to perform the translation */ public static void translateDefaultNoSystemExitProperty(HsqlProperties p) { if (p == null) { return; } p.setPropertyIfNotExists(SC_KEY_NO_SYSTEM_EXIT, "false"); }
/** * Constructs a new Database object. * * @param type is the type of the database: "mem:", "file:", "res:" * @param path is the given path to the database files * @param canonicalPath is the 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 canonicalPath, HsqlProperties props) { setState(Database.DATABASE_SHUTDOWN); this.databaseType = type; this.path = path; this.canonicalPath = canonicalPath; this.urlProperties = props; if (databaseType == DatabaseURL.S_RES) { filesInJar = true; filesReadOnly = true; } logger = new Logger(this); shutdownOnNoConnection = urlProperties.isPropertyTrue(HsqlDatabaseProperties.url_shutdown); recoveryMode = urlProperties.getIntegerProperty(HsqlDatabaseProperties.url_recover, 0); lobManager = new LobManager(this); }
@Override protected void before() throws Throwable { super.before(); File hsqlHome = new File("target/temporary/hsqldb/" + name); if (hsqlHome.exists()) { hsqlHome.delete(); } hsqlHome.mkdirs(); String dbHome = "file:" + hsqlHome.getAbsolutePath(); HsqlProperties p = new HsqlProperties(); p.setProperty("server.database.0", dbHome); p.setProperty("server.dbname.0", name); p.setProperty("server.port", port); server = new Server(); server.setProperties(p); server.setLogWriter(new PrintWriter(System.out)); server.setErrWriter(new PrintWriter(System.err)); server.start(); }
public static void main(String[] arg) { boolean webserver; String driver = "org.hsqldb.jdbcDriver"; String url; String user; String password; int port; String defaulturl; String shutdownarg; if (arg.length > 0) { String p = arg[0]; if ((p != null) && p.startsWith("-?")) { printHelp(); return; } } HsqlProperties props = HsqlProperties.argArrayToProps(arg, "server"); webserver = props.isPropertyTrue("server.webserver", false); defaulturl = webserver ? "jdbc:hsqldb:http://localhost" : "jdbc:hsqldb:hsql://localhost"; int defaultport = webserver ? 80 : 9001; port = props.getIntegerProperty("server.port", defaultport); url = props.getProperty("server.url", defaulturl + ":" + port); user = props.getProperty("server.user", "sa"); password = props.getProperty("server.password", ""); shutdownarg = props.getProperty("server.shutdownarg", ""); try { Class.forName(driver); // Load the driver Connection connection = DriverManager.getConnection(url, user, password); Statement statement = connection.createStatement(); // can use SHUTDOWN COMPACT or SHUTDOWN IMMEDIATELY statement.execute("SHUTDOWN " + shutdownarg); } catch (ClassNotFoundException cnfe) { System.err.println(cnfe); // Driver not found } catch (SQLException sqle) { System.err.println(sqle); // error connection to database } }
/** * Specifically, this opens a mem-only DB, populates it, starts a HyperSQL Server to server it, * and opens network JDBC Connection "netConn" to it, * * <p>Invoked before each test*() invocation by JUnit. */ protected void setUp() { try { Connection setupConn = DriverManager.getConnection("jdbc:hsqldb:mem:test", "SA", ""); setupConn.setAutoCommit(false); Statement st = setupConn.createStatement(); st.executeUpdate("SET PASSWORD 'sapwd'"); populate(st); st.close(); setupConn.commit(); setupConn.close(); } catch (SQLException se) { throw new RuntimeException("Failed to set up in-memory database", se); } try { server = new Server(); HsqlProperties properties = new HsqlProperties(); if (System.getProperty("VERBOSE") == null) { server.setLogWriter(null); server.setErrWriter(null); } else { properties.setProperty("server.silent", "false"); properties.setProperty("server.trace", "true"); } properties.setProperty("server.database.0", "mem:test"); properties.setProperty("server.dbname.0", ""); properties.setProperty("server.port", AbstractTestOdbc.portString); server.setProperties(properties); server.start(); try { Thread.sleep(1000); } catch (InterruptedException ie) { } } catch (Exception e) { throw new RuntimeException("Failed to set up in-memory database", e); } if (server.getState() != ServerConstants.SERVER_STATE_ONLINE) { throw new RuntimeException("Server failed to start up"); } try { netConn = DriverManager.getConnection("jdbc:odbc:" + dsnName, "SA", "sapwd"); // netConn.setAutoCommit(false); } catch (SQLException se) { if (se.getMessage().indexOf("No suitable driver") > -1) { throw new RuntimeException( "You must install the native library for Sun's jdbc:odbc " + "JDBC driver"); } if (se.getMessage().indexOf("Data source name not found") > -1) { throw new RuntimeException( "You must configure ODBC DSN '" + dsnName + "' (you may change the name and/or port by setting Java " + "system properties 'test.hsqlodbc.port' or " + "'test.hsqlodbc.dsnname'"); } throw new RuntimeException("Failed to set up JDBC/ODBC network connection", se); } }
public void testHsqldbUrls() { HsqlProperties props; DatabaseURL.parseURL( "JDBC:hsqldb:hsql://myhost:1777/mydb;filepath=c:/myfile/database/db", true, false); DatabaseURL.parseURL("JDBC:hsqldb:../data/mydb.db", true, false); DatabaseURL.parseURL("JDBC:hsqldb:../data/mydb.db;ifexists=true", true, false); DatabaseURL.parseURL("JDBC:hsqldb:HSQL://localhost:9000/mydb", true, false); DatabaseURL.parseURL( "JDBC:hsqldb:Http://localhost:8080/servlet/org.hsqldb.Servlet/mydb;get_column_names=true", true, false); DatabaseURL.parseURL("JDBC:hsqldb:Http://localhost/servlet/org.hsqldb.Servlet/", true, false); DatabaseURL.parseURL("JDBC:hsqldb:hsql://myhost", true, false); props = DatabaseURL.parseURL( "jdbc:hsqldb:res://com.anorg.APath;hsqldb.crypt_provider=org.crypt.Provider", true, false); assertEquals(props.getProperty("hsqldb.crypt_provider"), "org.crypt.Provider"); assertEquals(props.getProperty("database"), "//com.anorg.APath"); System.setProperty("mypath", "/opt/mydir"); props = DatabaseURL.parseURL("jdbc:hsqldb:file:${mypath}/mydata", true, false); assertEquals("/opt/mydir/mydata", props.getProperty("database")); props = DatabaseURL.parseURL( "JDBC:hsqldb:hsql://localhost:9000/mydb;file:data/hsqldb/XYZTEST;hsqldb.default_table_type=cached", true, false); }
/** * Initializes this jdbcResultSetMetaData object from the specified Result and HsqlProperties * objects. * * @param r the Result object from which to initialize this jdbcResultSetMetaData object * @param props the HsqlProperties object from which to initialize this jdbcResultSetMetaData * object * @throws SQLException if a database access error occurs */ void init(Result r, HsqlProperties props) throws SQLException { jdbcColumnMetaData cmd; int type; Result.ResultMetaData rmd; if (r == null) { throw Util.sqlException(Trace.GENERAL_ERROR, Trace.JDBC_NO_RESULT_SET, null); } if (r.mode != ResultConstants.DATA) { // implied: columnCount = 0; return; } columnCount = r.getColumnCount(); // fredt - props is null for internal connections, so always use the default behaviour in this // case useColumnName = props == null ? true : props.isPropertyTrue("get_column_name"); columnMetaData = new jdbcColumnMetaData[columnCount]; rmd = r.metaData; for (int i = 0; i < columnCount; i++) { cmd = new jdbcColumnMetaData(); columnMetaData[i] = cmd; // Typically, these null checks are not needed, but as // above, it is not _guaranteed_ that these values // will be non-null. So, it is better to do the work // here than have to perform checks and conversions later. cmd.catalogName = rmd.catalogNames[i] == null ? "" : rmd.catalogNames[i]; cmd.schemaName = rmd.schemaNames[i] == null ? "" : rmd.schemaNames[i]; cmd.tableName = rmd.tableNames[i] == null ? "" : rmd.tableNames[i]; cmd.columnName = rmd.colNames[i] == null ? "" : rmd.colNames[i]; cmd.columnLabel = rmd.colLabels[i] == null ? "" : rmd.colLabels[i]; cmd.columnType = rmd.colTypes[i]; cmd.columnTypeName = Types.getTypeString(cmd.columnType); cmd.isWritable = rmd.isWritable[i]; cmd.isReadOnly = !cmd.isWritable; // default: cmd.isDefinitelyWritable = false; cmd.isAutoIncrement = rmd.isIdentity[i]; cmd.isNullable = rmd.colNullable[i]; type = cmd.columnType; cmd.columnClassName = rmd.classNames[i]; if (cmd.columnClassName == null || cmd.columnClassName.length() == 0) { cmd.columnClassName = Types.getColStClsName(type); } // Some tools, such as PowerBuilder, require that (for char and // varchar types, at any rate) getMaxDisplaySize returns a value // _at least_ as large as the length of the longest value in this // column of the result set, or else an internal error will occur // at retrieve time the instant a longer value is fetched. // // org.hsqldb.Types has been patched to retrieve, by default, either // a large-but-reasonable value or a value defined through system // properties that is expected to be unlikely to cause problems in // the majority of cases. if (Types.acceptsPrecisionCreateParam(type)) { if (rmd.colSizes[i] == 0) { cmd.columnDisplaySize = Types.getMaxDisplaySize(type); } else { cmd.columnDisplaySize = rmd.colSizes[i]; if (Types.acceptsScaleCreateParam(type)) { if (rmd.colScales[i] != 0) { cmd.columnDisplaySize += (1 + rmd.colScales[i]); } } } } else { cmd.columnDisplaySize = Types.getMaxDisplaySize(type); } if (Types.isNumberType(type) && Types.acceptsPrecisionCreateParam(type)) { cmd.precision = rmd.colSizes[i]; if (cmd.precision == 0) { cmd.precision = Types.getPrecision(type); } } else { cmd.precision = Types.getPrecision(type); } // Without a non-zero scale value, some (legacy only?) tools will // simply truncate digits to the right of the decimal point when // retrieving values from the result set. The measure below can // help, but currently only as long as one is connected to an // embedded instance at design time, not via a network connection. if (Types.acceptsScaleCreateParam(type)) { cmd.scale = rmd.colScales[i]; } Boolean iua = Types.isUnsignedAttribute(type); cmd.isSigned = iua != null && !iua.booleanValue(); Boolean ics = Types.isCaseSensitive(type); cmd.isCaseSensitive = ics != null && ics.booleanValue(); cmd.isSearchable = Types.isSearchable(type); } }
/** * Retrieves a new default properties object for a server of the specified protocol * * @return a new default properties object */ public static HsqlProperties newDefaultProperties(int protocol) { HsqlProperties p = new HsqlProperties(); p.setProperty(SC_KEY_AUTORESTART_SERVER, SC_DEFAULT_SERVER_AUTORESTART); p.setProperty(SC_KEY_ADDRESS, SC_DEFAULT_ADDRESS); p.setProperty(SC_KEY_DATABASE + "." + 0, SC_DEFAULT_DATABASE); p.setProperty(SC_KEY_DBNAME + "." + 0, ""); p.setProperty(SC_KEY_NO_SYSTEM_EXIT, SC_DEFAULT_NO_SYSTEM_EXIT); boolean isTls = SC_DEFAULT_TLS; try { isTls = System.getProperty("javax.net.ssl.keyStore") != null; } catch (Exception e) { } p.setProperty(SC_KEY_PORT, getDefaultPort(protocol, isTls)); p.setProperty(SC_KEY_SILENT, SC_DEFAULT_SILENT); p.setProperty(SC_KEY_TLS, isTls); p.setProperty(SC_KEY_TRACE, SC_DEFAULT_TRACE); p.setProperty(SC_KEY_WEB_DEFAULT_PAGE, SC_DEFAULT_WEB_PAGE); p.setProperty(SC_KEY_WEB_ROOT, SC_DEFAULT_WEB_ROOT); return p; }