public class SQLKVDatabase extends Object implements KVDatabase
KVDatabase
implementations.
Key watches are not supported.
Modifier and Type | Field and Description |
---|---|
protected DataSource |
dataSource |
static String |
DEFAULT_KEY_COLUMN_NAME
Default key column name ("kv_key").
|
static String |
DEFAULT_TABLE_NAME
Default table name ("KV").
|
static String |
DEFAULT_VALUE_COLUMN_NAME
Default value column name ("kv_value").
|
protected IsolationLevel |
isolationLevel
The default transaction isolation level.
|
protected String |
keyColumnName
The name of the key column.
|
protected Logger |
log |
static String |
OPTION_ISOLATION
Option key for
createTransaction(Map) . |
protected String |
tableName
The name of the key/value table.
|
protected String |
valueColumnName
The name of the value column.
|
Constructor and Description |
---|
SQLKVDatabase() |
Modifier and Type | Method and Description |
---|---|
protected void |
beginTransaction(Connection connection)
Open a new SQL transaction on the given
Connection . |
protected void |
configureConnection(Connection connection)
Configure a newly created
Connection . |
String |
createGetAllStatement(boolean reverse)
Create an SQL statement that reads all of the key and value columns (in that order), possibly reversed.
|
String |
createGetAtLeastStatement(boolean reverse)
Create an SQL statement that reads the key and value columns (in that order) associated
with the smallest key greater than or equal to
?1 , if any. |
String |
createGetAtMostStatement(boolean reverse)
Create an SQL statement that reads the key and value columns (in that order)
associated with the greatest key strictly less than
?1 , if any. |
String |
createGetRangeStatement(boolean reverse)
Create an SQL statement that reads the key and value columns (in that order) associated with all keys
in the range
?1 (inclusive) to ?2 (exclusive), possibly reversed. |
String |
createGetStatement()
Create an SQL statement that reads the value column associated with key
?1 . |
String |
createPutStatement()
Create an SQL statement that inserts the key/value pair with key
?1 and value ?2
A row with key ?1 may already exist; if so, the value should be updated to
?2 (if syntax requires it, the value may be updated to ?3 instead;
?3 , if it exists, will be set to the same value as ?2 ). |
String |
createRemoveAllStatement()
Create an SQL statement that deletes all rows.
|
String |
createRemoveAtLeastStatement()
Create an SQL statement that deletes all rows with keys greater than or equal to
?1 . |
String |
createRemoveAtMostStatement()
Create an SQL statement that deletes all rows with keys strictly less than
?1 . |
String |
createRemoveRangeStatement()
Create an SQL statement that deletes all rows with keys in the range
?1 (inclusive}
to ?2 (exclusive). |
String |
createRemoveStatement()
Create an SQL statement that deletes the row associated with key
?1 , if any. |
protected SQLKVTransaction |
createSQLKVTransaction(Connection connection)
Create a new
SQLKVTransaction for a new transaction given the specified Connection . |
SQLKVTransaction |
createTransaction()
Create a new transaction.
|
SQLKVTransaction |
createTransaction(Map<String,?> options)
Create a new transaction.
|
protected Connection |
createTransactionConnection()
Create a
Connection for a new transaction. |
DataSource |
getDataSource()
Get the
DataSource used with this instance. |
IsolationLevel |
getIsolationLevel()
Get the default transaction isolation level.
|
protected IsolationLevel |
getIsolationLevel(Map<String,?> options)
Extract the
IsolationLevel , if any, from the transaction options. |
String |
getKeyColumnName()
Get the name of the column containing keys.
|
String |
getTableName()
Get the name of the table containing keys and values.
|
String |
getValueColumnName()
Get the name of the column containing values.
|
protected void |
initializeDatabaseIfNecessary(Connection connection)
Perform any required database initialization.
|
boolean |
isRollbackForReadOnly()
Get whether to rollback read-only transactions.
|
String |
limitSingleRow(String sql)
Modify the given SQL statement so that only one row is returned.
|
protected void |
postBeginTransaction(Connection connection)
Subclass hook invoked just after opening a new SQL transaction.
|
protected void |
preBeginTransaction(Connection connection)
Subclass hook invoked just before opening a new SQL transaction.
|
String |
quote(String name)
Enquote a table or column name as necessary.
|
void |
setDataSource(DataSource dataSource)
Configure the
DataSource used with this instance. |
void |
setIsolationLevel(IsolationLevel isolationLevel)
Configure the default transaction isolation level.
|
void |
setKeyColumnName(String keyColumnName)
Configure the name of the column containing keys.
|
void |
setRollbackForReadOnly(boolean rollbackForReadOnly)
Configure whether to rollback read-only transactions.
|
void |
setTableName(String tableName)
Set the name of the key/value table.
|
void |
setValueColumnName(String valueColumnName)
Configure the name of the column containing values.
|
void |
start()
Start this instance.
|
void |
stop()
Stop this instance.
|
KVTransactionException |
wrapException(SQLKVTransaction transaction,
SQLException e)
Wrap the given
SQLException in the appropriate KVTransactionException . |
public static final String DEFAULT_TABLE_NAME
public static final String DEFAULT_KEY_COLUMN_NAME
public static final String DEFAULT_VALUE_COLUMN_NAME
public static final String OPTION_ISOLATION
createTransaction(Map)
. Value should be an IsolationLevel
instance,
or the name()
thereof.protected DataSource dataSource
protected String valueColumnName
protected IsolationLevel isolationLevel
IsolationLevel.SERIALIZABLE
.protected final Logger log
public DataSource getDataSource()
DataSource
used with this instance.DataSource
public void setDataSource(DataSource dataSource)
DataSource
used with this instance.
Required property.
dataSource
- access to the underlying databasepublic String getTableName()
Default value is "KV".
public void setTableName(String tableName)
tableName
- the name of the key/value tableIllegalArgumentException
- if table
is nullpublic String getKeyColumnName()
Default value is "kv_key".
public void setKeyColumnName(String keyColumnName)
keyColumnName
- the name of the key columnIllegalArgumentException
- if keyColumnName
is nullpublic String getValueColumnName()
Default value is "kv_value".
public void setValueColumnName(String valueColumnName)
valueColumnName
- the name of the value columnIllegalArgumentException
- if valueColumnName
is nullpublic IsolationLevel getIsolationLevel()
This may be overridden on a per-transaction basis; see getIsolationLevel(Map)
.
Default value is IsolationLevel.SERIALIZABLE
.
public void setIsolationLevel(IsolationLevel isolationLevel)
isolationLevel
- isolation levelIllegalArgumentException
- if isolationLevel
is nullpublic boolean isRollbackForReadOnly()
If true, read-only transactions will be rolled back on commit. If false, mutations during read-only transactions will be captured in memory and not written to the database, and the underlying SQL transaction committed on commit. Some implementations require the latter in order to guarantee up-to-date reads within the transaction.
Default value is true.
public void setRollbackForReadOnly(boolean rollbackForReadOnly)
rollbackForReadOnly
- true to use rollback when committing a read-only transaction.isRollbackForReadOnly()
@PostConstruct public void start()
KVDatabase
This method is idempotent: if this instance is already started, nothing happens.
Whether an instance that has been started and stopped can be restarted is implementation-dependent.
start
in interface KVDatabase
@PreDestroy public void stop()
KVDatabase
This method is idempotent: if this instance has not been started, or is already stopped, nothing happens.
stop
in interface KVDatabase
protected void initializeDatabaseIfNecessary(Connection connection) throws SQLException
The implementation in SQLKVDatabase
does nothing. Subclasses will
typically invoke CREATE TABLE ... IF NOT EXISTS
here, etc.
connection
- open database connection (will be closed by the caller of this method)SQLException
- if an error occurspublic SQLKVTransaction createTransaction(Map<String,?> options)
The implementation in SQLKVDatabase
invokes createTransactionConnection()
to get a Connection
for the new transaction, then invokes these methods in order:
createTransaction
in interface KVDatabase
options
- optional transaction options; may be nullKVDatabaseException
- if an unexpected error occursIllegalStateException
- if no DataSource
is configuredpublic SQLKVTransaction createTransaction()
The implementation in SQLKVDatabase
invokes createTransaction(null)
(i.e., with no options) and returns the result.
createTransaction
in interface KVDatabase
KVDatabaseException
- if an unexpected error occursIllegalStateException
- if no DataSource
is configuredprotected IsolationLevel getIsolationLevel(Map<String,?> options)
IsolationLevel
, if any, from the transaction options.
The implementation in SQLKVDatabase
supports an IsolationLevel
under the key OPTION_ISOLATION
;
also, the IsolationLevel
may be configured by the Spring
PermazenTransactionManager
, for example, using the
@Transactional
annotation.
options
- transaction optionsprotected Connection createTransactionConnection() throws SQLException
Connection
for a new transaction.
The implementation in SQLKVDatabase
invokes DataSource.getConnection()
on the
configured DataSource
, and then deletates to
configureConnection()
to perform any required configuration
of the new Connection
.
Connection
SQLException
- if an error occursprotected void configureConnection(Connection connection) throws SQLException
Connection
.
The implementation in SQLKVDatabase
does nothing.
connection
- newly created Connection
SQLException
- if an error occursprotected void preBeginTransaction(Connection connection) throws SQLException
The implementation in SQLKVDatabase
does nothing. Note: subclasses must ensure the transaction is
configured for the IsolationLevel
configured on this instance.
connection
- the Connection
for a new transactionSQLException
- if an error occurscreateSQLKVTransaction()
protected void beginTransaction(Connection connection) throws SQLException
Connection
.
The implementation in SQLKVDatabase
invokes Connection.setAutoCommit(false)
.
connection
- the Connection
for a new transactionSQLException
- if an error occurscreateSQLKVTransaction()
protected void postBeginTransaction(Connection connection) throws SQLException
The implementation in SQLKVDatabase
does nothing. Note: subclasses must ensure the transaction is
configured for the IsolationLevel
configured on this instance.
connection
- the Connection
for a new transactionSQLException
- if an error occurscreateSQLKVTransaction()
protected SQLKVTransaction createSQLKVTransaction(Connection connection) throws SQLException
SQLKVTransaction
for a new transaction given the specified Connection
.
There will already be an SQL transaction open on connection
.
The implementation in SQLKVDatabase
just invokes
new SQLKVTransaction(this, connection)
.
connection
- the Connection
for a new transactionSQLException
- if an error occurspublic String createGetStatement()
?1
.public String createGetAtLeastStatement(boolean reverse)
?1
, if any.reverse
- true to return rows in descending key order, false to return rows in ascending key orderpublic String createGetAtMostStatement(boolean reverse)
?1
, if any.reverse
- true to return rows in descending key order, false to return rows in ascending key orderpublic String createGetRangeStatement(boolean reverse)
?1
(inclusive) to ?2
(exclusive), possibly reversed.reverse
- true to return rows in descending key order, false to return rows in ascending key orderpublic String createGetAllStatement(boolean reverse)
reverse
- true to return rows in descending key order, false to return rows in ascending key orderpublic String createPutStatement()
?1
and value ?2
A row with key ?1
may already exist; if so, the value should be updated to
?2
(if syntax requires it, the value may be updated to ?3
instead;
?3
, if it exists, will be set to the same value as ?2
).public String createRemoveStatement()
?1
, if any.
Note that the key may or may not exist prior to this method being invoked.public String createRemoveRangeStatement()
?1
(inclusive}
to ?2
(exclusive).public String createRemoveAtLeastStatement()
?1
.public String createRemoveAtMostStatement()
?1
.public String createRemoveAllStatement()
public String limitSingleRow(String sql)
This is an optional method; returning statement
unmodified is acceptable, but subclasses may
be able to improve efficiency by modifying the SQL statement in a vendor-specific manner to only return one row.
The implementation in SQLKVDatabase
returns its parameter unchanged.
sql
- SQL statementpublic String quote(String name)
The implementation in SQLKVDatabase
returns its parameter unchanged.
name
- table or column namename
enquoted as necessary for this database typeIllegalArgumentException
- if name
is nullpublic KVTransactionException wrapException(SQLKVTransaction transaction, SQLException e)
SQLException
in the appropriate KVTransactionException
.transaction
- the SQLKVTransaction
in which the exception occurede
- SQL exceptionKVTransactionException
with chained exception e
NullPointerException
- if e
is nullCopyright © 2022. All rights reserved.