A JDBC implementation of an object related storage manager.
author: Pierre van Rooden since: MMBase-1.7 version: $Id: DatabaseStorageManager.java,v 1.189 2008/02/18 12:43:17 michiel Exp $
Inner Class :protected static class InputStreamBlob implements Blob
create(MMObjectNode node, MMObjectBuilder builder) This method inserts a new object in a specific builder, and registers the change.
This method makes it easier to implement relational databases, where you may need to update the node
in more than one builder.
Call this method for all involved builders if you use a relational database.
Parameters: node - The node to insert.
delete(MMObjectNode node, MMObjectBuilder builder) Delete a node from a specific builder
This method makes it easier to implement relational databses, where you may need to remove the node
in more than one builder.
getBlobValue(ResultSet result, int index, CoreField field, boolean mayShorten) Retrieve a large binary object (byte array) for a specified object field.
The default method uses
ResultSet.getBytes(int) to obtain text.
Override this method if you want to optimize retrieving large objects,
i.e by using clobs or streams.
Parameters: result - the resultset to retrieve the text from Parameters: index - the index of the text in the resultset, or -1 to retireiv from file (blobs). Parameters: field - the (MMBase) fieldtype.
getBooleanValue(ResultSet result, int index, CoreField field) Retrieve a boolean value for a specified object field.
The default method uses
ResultSet.getBoolean(int) to obtain the date.
Parameters: result - the resultset to retrieve the value from Parameters: index - the index of the value in the resultset Parameters: field - the (MMBase) fieldtype.
getDateTimeValue(ResultSet result, int index, CoreField field) Retrieve a date for a specified object field.
The default method uses
ResultSet.getTimestamp(int) to obtain the date.
Parameters: result - the resultset to retrieve the value from Parameters: index - the index of the value in the resultset Parameters: field - the (MMBase) fieldtype.
getFieldDefinition(CoreField field) Creates a fielddefinition, of the format '[fieldname] [fieldtype] NULL' or
'[fieldname] [fieldtype] NOT NULL' (depending on whether the field is nullable).
getFieldTypeDefinition(CoreField field) Creates a field type definition, of the format '[fieldtype] NULL' or
'[fieldtype] NOT NULL' (depending on whether the field is nullable).
getStringValue(ResultSet result, int index, CoreField field, boolean mayShorten) Retrieve a text for a specified object field.
The default method uses
ResultSet.getString(int) to obtain text.
Override this method if you want to optimize retrieving large texts,
i.e by using clobs or streams.
Parameters: result - the resultset to retrieve the text from Parameters: index - the index of the text in the resultset Parameters: field - the (MMBase) fieldtype.
getValue(ResultSet result, int index, CoreField field, boolean mayShorten) Attempts to return a single field value from the resultset of a query.
Parameters: result - the resultset Parameters: index - the index of the field in the resultset Parameters: field - the expected MMBase field type.
getXMLValue(ResultSet result, int index, CoreField field, boolean mayShorten) Retrieve the XML (as a string) for a specified object field.
The default method uses
ResultSet.getString(int) to obtain text.
Unlike
Override this method if you want to optimize retrieving large texts,
i.e by using clobs or streams.
Parameters: result - the resultset to retrieve the xml from Parameters: index - the index of the xml in the resultset Parameters: field - the (MMBase) fieldtype.
setBinaryValue(PreparedStatement statement, int index, Object objectValue, CoreField field, MMObjectNode node) Store binary data of a field in a prepared statement.
This basic implementation uses a binary stream to set the data.
Null values are stored as NULL if possible, otherwise they are stored as an empty byte-array.
Override this method if you use another way to store binaries (i.e.
protected void
setBooleanValue(PreparedStatement statement, int index, Object value, CoreField field, MMObjectNode node) Store a boolean value of a field in a prepared statement.
The method uses the Casting class to convert to the appropriate value.
Null values are stored as NULL if possible, otherwise they are stored as false
Override this method if you use another way to store booleans
Parameters: statement - the prepared statement Parameters: index - the index of the field in the prepared statement Parameters: value - the data (boolean) to store Parameters: field - the MMBase field, containing meta-information Parameters: node - the node that contains the data.
protected void
setDateTimeValue(PreparedStatement statement, int index, Object value, CoreField field, MMObjectNode node) Store a Date value of a field in a prepared statement.
The method uses the Casting class to convert to the appropriate value.
Null values are stored as NULL if possible, otherwise they are stored as the date 31/12/1969 23:59:59 GMT (-1)
TODO: I think that is -1000, not -1.
Override this method if you use another way to store dates
Parameters: statement - the prepared statement Parameters: index - the index of the field in the prepared statement Parameters: value - the data (date) to store Parameters: field - the MMBase field, containing meta-information Parameters: node - the node that contains the data.
protected void
setListValue(PreparedStatement statement, int index, Object value, CoreField field, MMObjectNode node) Store a List value of a field in a prepared statement.
The method uses the Casting class to convert to the appropriate value.
Null values are stored as NULL if possible, otherwise they are stored as an empty list.
Override this method if you use another way to store lists
Parameters: statement - the prepared statement Parameters: index - the index of the field in the prepared statement Parameters: value - the data (List) to store Parameters: field - the MMBase field, containing meta-information.
protected void
setNodeValue(PreparedStatement statement, int index, Object nodeValue, CoreField field, MMObjectNode node) Store a node value of a field in a prepared statement
Nodes are stored in the database as numeric values.
Since a node value can be a (referential) key (depending on implementation),
Null values should be stored as NULL, not -1.
protected boolean
setNullValue(PreparedStatement statement, int index, Object value, CoreField field, int type) Stores the 'null' value in the statement if appopriate (the value is null or unset, and the
value may indeed be NULL, according to the configuration).
protected void
setNumericValue(PreparedStatement statement, int index, Object value, CoreField field, MMObjectNode node) Store a numeric value of a field in a prepared statement
The method uses the Casting class to convert to the appropriate value.
Null values are stored as NULL if possible, otherwise they are stored as -1.
Override this method if you want to override this behavior.
Parameters: statement - the prepared statement Parameters: index - the index of the field in the prepared statement Parameters: value - the numeric value to store.
setStringValue(PreparedStatement statement, int index, Object objectValue, CoreField field, MMObjectNode node) Store the text value of a field in a prepared statement.
Null values are stored as NULL if possible, otherwise they are stored as an empty string.
If the FORCE_ENCODE_TEXT option is set, text is encoded (using the MMBase encoding) to a byte array
and stored as a binary stream.
Otherwise it uses
PreparedStatement.setString(intString) to set the data.
Override this method if you use another way to store large texts (i.e.
The transaction issolation level to use when starting a transaction.
This value is retrieved from the factory's
Attributes.TRANSACTION_ISOLATION_LEVEL attribute, which is commonly set
to the highest (most secure) transaction isolation level available.
Change this node in the specified builder.
This method makes it easier to implement relational databses, where you may need to update the node
in more than one builder.
Call this method for all involved builders if you use a relational database.
Parameters: node - The node to change Parameters: builder - the builder to store the node throws: StorageException - if an error occurred during change
Checks whether file is readable and existing. Warns if not.
If non-existing it checks older locations.
the file to be used, or null if no existing readable file could be found, also no 'legacy' one.
Commits the change to a node.
If the manager is in a transaction (and supports it), the change is stored in a
DatabaseStorageManager.changes object (to be committed after the transaction ends).
Otherwise it directly commits and broadcasts the changes
Parameters: node - the node to register Parameters: change - the type of change: "n": new, "c": commit, "d": delete, "r" : relation changed
This method inserts a new object in a specific builder, and registers the change.
This method makes it easier to implement relational databases, where you may need to update the node
in more than one builder.
Call this method for all involved builders if you use a relational database.
Parameters: node - The node to insert. The node already needs to have a (new) number assigned Parameters: builder - the builder to store the node throws: StorageException - if an error occurred during creation
(Re)create all constraints and indices that contain a specific field.
You should have an active connection before calling this method.
Parameters: field - the field for which to create indices throws: StorageException - when a database error occurs
Creates a means for the database to pre-create keys with increasing numbers.
A sequence can be a database routine, a number table, or anything else that can be used to create unique numbers.
Keys can be obtained from the sequence by calling
DatabaseStorageManager.createKey() .
throws: StorageException - when the sequence can not be created
Delete a node from a specific builder
This method makes it easier to implement relational databses, where you may need to remove the node
in more than one builder.
Call this method for all involved builders if you use a relational database.
Parameters: node - The node to delete throws: StorageException - if an error occurred during delete
Drop a constraint or index.
You should have an active connection before calling this method.
Parameters: index - the index to drop throws: StorageException - when a database error occurs
Drop all constraints and indices that contain a specific field.
You should have an active connection before calling this method.
Parameters: field - the field for which to drop indices throws: StorageException - when a database error occurs
Executes an update query for given node and fields. This is wrapped in a function because it
is repeatedly called in
DatabaseStorageManager.executeUpdateCheckConnection which in turn is called from
several spots in this class.
since: MMBase-1.7.1
Queries the database metadata to test whether a given table exists.
Parameters: tableName - name of the table to look for throws: StorageException - when the metadata could not be retrieved true if the table exists
Determines if an index exists.
You should have an active connection before calling this method.
Parameters: index - the index to test Parameters: tablename - the tablename to test the index against throws: StorageException - when a database error occurs
Determines if an index exists.
You should have an active connection before calling this method.
Parameters: index - the index to test throws: StorageException - when a database error occurs
Fills a single Node from the resultset of a query.
You can use this method to iterate through a query, creating multiple nodes, provided the resultset still contains
members (that is, result.isAfterLast returns false)
Parameters: node - The MMObjectNode to be filled Parameters: result - the resultset Parameters: builder - the builder to use for creating the node throws: StorageException - if the resultset is exhausted or a database error occurred
Obtains an active connection, opening a new one if needed.
This method sets and then returns the
DatabaseStorageManager.activeConnection member.
If an active connection was allready open, and the manager is in a database transaction, that connection is returned instead.
Otherwise, the connection is closed before a new one is opened.
throws: SQLException - if opening the connection failed
Defines how binary (blob) data files must look like.
Parameters: node - the node the binary data belongs to Parameters: fieldName - the name of the binary field The File where to store or read the binary data
Read a binary (blob) from a field in the database
Parameters: node - the node the binary data belongs to Parameters: field - the binary field An InputStream representing the binary data, null if no binary data was stored, or VALUE_SHORTED, if mayShorten
Read a binary (blob) data file
Parameters: node - the node the binary data belongs to Parameters: field - the binary field the byte array containing the binary data, null if no binary data was stored
Retrieve a large binary object (byte array) for a specified object field.
The default method uses
ResultSet.getBytes(int) to obtain text.
Override this method if you want to optimize retrieving large objects,
i.e by using clobs or streams.
Parameters: result - the resultset to retrieve the text from Parameters: index - the index of the text in the resultset, or -1 to retireiv from file (blobs). Parameters: field - the (MMBase) fieldtype. This value can be null the retrieved data, null if no binary data was stored throws: SQLException - when a database error occurs throws: StorageException - when data is incompatible or the function is not supported
Retrieve a boolean value for a specified object field.
The default method uses
ResultSet.getBoolean(int) to obtain the date.
Parameters: result - the resultset to retrieve the value from Parameters: index - the index of the value in the resultset Parameters: field - the (MMBase) fieldtype. This value can be null the retrieved Boolean value, null if no text was stored throws: SQLException - when a database error occurs throws: StorageException - when data is incompatible or the function is not supported since: MMBase-1.8
Creates an index definition string for a field to be passed when creating a table.
Parameters: field - the field for which to make the index definition the index definition as a String, or null if no definition is available
Retrieve a date for a specified object field.
The default method uses
ResultSet.getTimestamp(int) to obtain the date.
Parameters: result - the resultset to retrieve the value from Parameters: index - the index of the value in the resultset Parameters: field - the (MMBase) fieldtype. This value can be null the retrieved java.util.Date value, null if no text was stored throws: SQLException - when a database error occurs throws: StorageException - when data is incompatible or the function is not supported since: MMBase-1.8
Creates a fielddefinition, of the format '[fieldname] [fieldtype] NULL' or
'[fieldname] [fieldtype] NOT NULL' (depending on whether the field is nullable).
The fieldtype is taken from the type mapping in the factory.
Parameters: field - the field the typedefiniton as a String throws: StorageException - if the field type cannot be mapped
Returns a comma seperated list of fieldnames for an index.
Parameters: index - the index to create it for the field list definition as a String, or null if the index was empty, orif it consists of a composite index and composite indices are not supported.
Creates a field type definition, of the format '[fieldtype] NULL' or
'[fieldtype] NOT NULL' (depending on whether the field is nullable).
The fieldtype is taken from the type mapping in the factory.
since: MMBase-1.8 Parameters: field - the field the typedefiniton as a String throws: StorageException - if the field type cannot be mapped
protected int getJDBCtoField(int jdbcType, int mmbaseType)(Code)
Guess the (mmbase) type in storage using the JDBC type.
Because a JDBC type can represent more than one mmbase Type,
the current type is also passed - if the current type matches, that type
is returned, otherwise the method returns the closest matching MMBase type.
Retrieve a text for a specified object field.
The default method uses
ResultSet.getString(int) to obtain text.
Override this method if you want to optimize retrieving large texts,
i.e by using clobs or streams.
Parameters: result - the resultset to retrieve the text from Parameters: index - the index of the text in the resultset Parameters: field - the (MMBase) fieldtype. This value can be null the retrieved text, null if no text was stored throws: SQLException - when a database error occurs throws: StorageException - when data is incompatible or the function is not supported
Attempts to return a single field value from the resultset of a query.
Parameters: result - the resultset Parameters: index - the index of the field in the resultset Parameters: field - the expected MMBase field type. This can be null Parameters: mayShorten - Whether it would suffice to return only a 'shorted' version of the value. the value throws: StorageException - if the value cannot be retrieved from the resultset
Retrieve the XML (as a string) for a specified object field.
The default method uses
ResultSet.getString(int) to obtain text.
Unlike
Override this method if you want to optimize retrieving large texts,
i.e by using clobs or streams.
Parameters: result - the resultset to retrieve the xml from Parameters: index - the index of the xml in the resultset Parameters: field - the (MMBase) fieldtype. This value can be null the retrieved xml as text, null if nothing was stored throws: SQLException - when a database error occurs throws: StorageException - when data is incompatible or the function is not supported
Reloads the data from a node from the database.
Use this after a create or change action, so the data in memory is consistent with
any data stored in the database.
Parameters: node - the node to refresh
Store binary data of a field in a prepared statement.
This basic implementation uses a binary stream to set the data.
Null values are stored as NULL if possible, otherwise they are stored as an empty byte-array.
Override this method if you use another way to store binaries (i.e. Blobs).
Parameters: statement - the prepared statement Parameters: index - the index of the field in the prepared statement Parameters: objectValue - the data (byte array) to store Parameters: field - the MMBase field, containing meta-information Parameters: node - the node that contains the data. Used to update this node if the database layer makes changesto the data (i.e. creating a default value for a non-null field that had a null value) throws: StorageException - if the data is invalid or missing throws: SQLException - if an error occurred while filling in the fields
Store a boolean value of a field in a prepared statement.
The method uses the Casting class to convert to the appropriate value.
Null values are stored as NULL if possible, otherwise they are stored as false
Override this method if you use another way to store booleans
Parameters: statement - the prepared statement Parameters: index - the index of the field in the prepared statement Parameters: value - the data (boolean) to store Parameters: field - the MMBase field, containing meta-information Parameters: node - the node that contains the data. Used to update this node if the database layer makes changesto the data (i.e. creating a default value for a non-null field that had a null value) throws: StorageException - if the data is invalid or missing throws: SQLException - if an error occurred while filling in the fields since: MMBase-1.8
Store a Date value of a field in a prepared statement.
The method uses the Casting class to convert to the appropriate value.
Null values are stored as NULL if possible, otherwise they are stored as the date 31/12/1969 23:59:59 GMT (-1)
TODO: I think that is -1000, not -1.
Override this method if you use another way to store dates
Parameters: statement - the prepared statement Parameters: index - the index of the field in the prepared statement Parameters: value - the data (date) to store Parameters: field - the MMBase field, containing meta-information Parameters: node - the node that contains the data. Used to update this node if the database layer makes changesto the data (i.e. creating a default value for a non-null field that had a null value) throws: StorageException - if the data is invalid or missing throws: SQLException - if an error occurred while filling in the fields since: MMBase-1.8
Store a List value of a field in a prepared statement.
The method uses the Casting class to convert to the appropriate value.
Null values are stored as NULL if possible, otherwise they are stored as an empty list.
Override this method if you use another way to store lists
Parameters: statement - the prepared statement Parameters: index - the index of the field in the prepared statement Parameters: value - the data (List) to store Parameters: field - the MMBase field, containing meta-information. This value can be null Parameters: node - the node that contains the data. Used to update this node if the database layer makes changesto the data (i.e. creating a default value for a non-null field that had a null value) throws: StorageException - if the data is invalid or missing throws: SQLException - if an error occurred while filling in the fields since: MMBase-1.8
Store a node value of a field in a prepared statement
Nodes are stored in the database as numeric values.
Since a node value can be a (referential) key (depending on implementation),
Null values should be stored as NULL, not -1. If a field cannot be null when a
value is not given, an exception is thrown.
Override this method if you want to override this behavior.
Parameters: statement - the prepared statement Parameters: index - the index of the field in the prepared statement Parameters: nodeValue - the node to store Parameters: field - the MMBase field, containing meta-information Parameters: node - the node that contains the data. throws: StorageException - if the data is invalid or missing throws: SQLException - if an error occurred while filling in the fields
Stores the 'null' value in the statement if appopriate (the value is null or unset, and the
value may indeed be NULL, according to the configuration). If the value is null or unset,
but the value may not be NULL, then -1 is stored.
Parameters: statement - the prepared statement Parameters: index - the index of the field in the prepared statement Parameters: value - the numeric value to store, which will be checked for null. Parameters: field - the MMBase field, containing meta-information throws: StorageException - if the data is invalid or missing throws: SQLException - if an error occurred while filling in the fields true if a null value was set, false otherwise since: MMBase-1.7.1
Store a numeric value of a field in a prepared statement
The method uses the Casting class to convert to the appropriate value.
Null values are stored as NULL if possible, otherwise they are stored as -1.
Override this method if you want to override this behavior.
Parameters: statement - the prepared statement Parameters: index - the index of the field in the prepared statement Parameters: value - the numeric value to store. This may be a String, MMObjectNode, Numeric, or other value - themethod will convert it to the appropriate value. Parameters: field - the MMBase field, containing meta-information Parameters: node - the node that contains the data. Used to update this node if the database layer makes changesto the data (i.e. creating a default value for a non-null field that had a null value) throws: StorageException - if the data is invalid or missing throws: SQLException - if an error occurred while filling in the fields
Store the text value of a field in a prepared statement.
Null values are stored as NULL if possible, otherwise they are stored as an empty string.
If the FORCE_ENCODE_TEXT option is set, text is encoded (using the MMBase encoding) to a byte array
and stored as a binary stream.
Otherwise it uses
PreparedStatement.setString(intString) to set the data.
Override this method if you use another way to store large texts (i.e. Clobs).
Parameters: statement - the prepared statement Parameters: index - the index of the field in the prepared statement Parameters: objectValue - the text to store Parameters: field - the MMBase field, containing meta-information Parameters: node - the node that contains the data. throws: StorageException - if the data is invalid or missing throws: SQLException - if an error occurred while filling in the fields
Store the value of a field in a prepared statement
Parameters: statement - the prepared statement Parameters: index - the index of the field in the prepared statement Parameters: node - the node from which to retrieve the value Parameters: field - the MMBase field, containing meta-information throws: StorageException - if the fieldtype is invalid, or data is invalid or missing throws: SQLException - if an error occurred while filling in the fields
This default implementation calls
DatabaseStorageManager.setStringValue .
Override this method if you want to override this behavior.
since: MMBase-1.7.1
Determine whether a field (such as a large text or a blob) should be shortened or not.
A 'shortened' field contains a placeholder text ('$SHORTED') to indicate that the field is expected to be of large size
and should be retrieved by an explicit call to
DatabaseStorageManager.getStringValue(MMObjectNode,CoreField) or.
DatabaseStorageManager.getBinaryValue(MMObjectNode,CoreField) .
The default implementation returns true for binaries, and false for other
types.
Override this method if you want to be able to change the placeholder strategy.
Parameters: field - the (MMBase) fieldtype true if the field should be shortened throws: SQLException - when a database error occurs throws: StorageException - when data is incompatible or the function is not supported
Returns whether tables inherit fields form parent tables.
this determines whether fields that are inherited in mmbase builders
are redefined in the database tables.