|
|
There is a built-in security system using users, passwords and access rights. There exists by default a 'System Administrator' with the user name 'sa' and the password '' (empty password). This special user can create new users, drop users and grant and revoke access rights for tables or stored procedures to other users. The general users can only change their own password and connect as another user. All this user administration can be done by SQL scripts (GRANT, REVOKE). Access can be granted also to PUBLIC.
Identity (autoincrement) column type
Identity columns can be used to serve as automatic unique row identifier for a table. When a new row is added to the table and the identity column is not inserted (or a NULL value is inserted), then HSQLDB provides a unique, incremental value for the column. The identity column is automatically the primary key of the table. Only one identity column can be created per table. In HSQLDB, any value can be used for updating or inserting in an identity column provided it does not violate the primary key constraint.
HSQLDB supports extensive system tables that are build dynamically when a query is made to them. These tables provide database metadata. The names of the tables are 'SYSTEM_' followed by the corresponding JDBC DatabaseMetaData method. For example the methode 'getColumns(...)' queries the table 'SYSTEM_COLUMNS'. There are several other system tables reporting on database tables, indexes, primary keys, foreign keys etc.
Readonly connection and database support
Connections can be set to readonly using the command SET READONLY [TRUE|FALSE] or using the method Connection.setReadOnly(boolean readonly). Additionally the whole database can be put in read-only mode by manually adding the line 'readonly=true' to the .properties file. All connections are then automatically readonly. The database files will then be opened in readonly mode, and it is thus possible to create a CD with this database. Other variations, allow modifiable readonly database (changes are discarded at shutdown) or inclusion of a database in the application JAR.
Selecting big results / Scanning big tables
One limitation of HSQLDB is that it currently does not support server side cursors. This means the result of a query must always fit in memory, otherwise an OutOfMemory error occurs. In the rare situation that a huge resultsets must be processed, then the following workaround can be used:
Limit the ResultSet using Statement.setMaxRows(1024), and select multiple 'smaller' blocks. If the table is for example 'CREATE TABLE Test(Id INT IDENTITY PRIMARY KEY, Name VARCHAR)' then the first block can be selected using 'SELECT * FROM Test ORDER BY Id' and the next block using 'SELECT * FROM Test WHERE Id>(biggest_id) ORDER BY Id' until no more records are returned. Don't forget to switch of the limit using setMaxRows(0).
The database file should grow automatically, empty space (after deleting records) should be reused automatically, and the file should shrink finally if data is deleted.
In HSQLDB, not all of these features are currently implemented for the .data file. In most cases empty space (caused by deleted records) is reused, because a list of 1024 free blocks is kept. But this list is lost when the database is closed. In one case (DROP TABLE) the space is not reclaimed.
To shrink all files to the minimum size, use the SQL command 'CHECKPOINT DEFRAG' and continue using the database or use 'SHUTDOWN COMPACT' when closing the database. It is a good idea to run this command also before creating a read-only database.
Java Stored Procedures / Functions
Stored procedures are Java functions that are called directly from the SQL language or using an alias. Calling Java functions (directly or using the alias) requires that the Java class can be reached by the database (server). User defined stored procedures / functions must be places where the database server runs. For HSQLDB, stored procedures and functions are equal. The syntax for calling functions and stored procedures (inside a SELECT statement for example) is:
SELECT Value, "java.lang.Math.sqrt"(Value) AS SQRT FROM Test
It can be called also without the SELECT, using the command CALL. This makes more sense for 'Stored Procedures' but works for functions, too:
CALL "java.lang.Math.sqrt"(2.0)
The package must be provided, and the name must be written as one word, and inside " because otherwise it is converted to uppercase (and not found).
An alias can be created using the command CREATE ALIAS:
CREATE ALIAS SQRT FOR "java.lang.Math.sqrt"
When an alias is defined, then the function can be called additionally using this alias:
CALL SQRT(2.0)
SELECT Value, SQRT(Value) AS SQRT FROM Test
This are the rules when creating user defined functions / stored procedures:
There is also a security mechanism provided: Access to each class can be granted / revoked to a user:
GRANT ALL ON "java.lang.Math" TO PUBLIC
By default, all users have access to java.lang.Math and org.hsqldb1.Library.
This text is based on HypersonicSQL documentation, updated
to reflect the latest version of HSQLDB