org.mmbase.storage.implementation.database
Class DatabaseStorageManager

java.lang.Object
  extended by org.mmbase.storage.implementation.database.DatabaseStorageManager
All Implemented Interfaces:
StorageManager<DatabaseStorageManagerFactory>
Direct Known Subclasses:
InformixStorageManager, RelationalDatabaseStorageManager, ViewDatabaseStorageManager

public class DatabaseStorageManager
extends Object
implements StorageManager<DatabaseStorageManagerFactory>

A JDBC implementation of an object related storage manager.

Since:
MMBase-1.7
Version:
$Id: DatabaseStorageManager.java 42689 2010-06-24 14:54:17Z michiel $
Author:
Pierre van Rooden
Javadoc:

Nested Class Summary
protected static class DatabaseStorageManager.InputStreamBlob
           
 
Field Summary
protected  Connection activeConnection
          The currently active Connection.
protected  Map<MMObjectNode,String> changes
          Pool of changed nodes in a transaction
protected  DatabaseStorageManagerFactory factory
          The factory that created this manager
protected  boolean inTransaction
          true if a transaction has been started.
static int OBJ2TYPE_MAX_SIZE
          Max size of the object type cache
protected static List<Integer> sequenceKeys
           
protected  int transactionIsolation
          The transaction issolation level to use when starting a transaction.
protected static Cache<Integer,Integer> typeCache
          The cache that contains the last X types of all requested objects
 
Constructor Summary
DatabaseStorageManager()
          Constructor
 
Method Summary
protected  void addToTableNameCache(String name)
           
static StringBuilder appendDirectory(StringBuilder pathBuffer, int number, String separator)
          Appends subdirectories to the beginning of the given StringBuilder.
protected  void appendField(StringBuilder fieldNames, StringBuilder fieldValues, CoreField field)
           
 void beginTransaction()
          Starts a transaction on this StorageManager instance.
 void change(CoreField field)
          Changes a field to the storage of this builder.
 void change(MMObjectBuilder builder)
          Changes the storage of a builder to match its new configuration.
 void change(MMObjectNode node)
          Commit this node to the specified builder.
protected  void change(MMObjectNode node, MMObjectBuilder builder)
          Change this node in the specified builder.
protected  void change(MMObjectNode node, MMObjectBuilder builder, String tableName, Collection<CoreField> changeFields)
          Commits changes in node to table.
protected  File checkFile(File binaryFile, MMObjectNode node, CoreField field)
          Checks whether file is readable and existing.
 void commit()
          Closes any transaction that was started and commits all changes.
protected  void commitChange(MMObjectNode node, String change)
          Commits the change to a node.
 int convertLegacyBinaryFiles()
          Convert legacy file
 void create()
          Create the basic elements for this storage
 void create(CoreField field)
          Creates a field and adds it to the storage of this builder.
protected  void create(Index index)
          Create an index or a unique constraint.
 void create(MMObjectBuilder builder)
          Create a storage element to store the specified builder's objects.
 int create(MMObjectNode node)
          This method creates a new object in the storage, and registers the change.
protected  void create(MMObjectNode node, List<CoreField> createFields, String tablename)
           
protected  void create(MMObjectNode node, MMObjectBuilder builder)
          This method inserts a new object in a specific builder, and registers the change.
protected  void createIndex(Index index, String tablename)
          Create an index or a unique constraint.
protected  void createIndices(CoreField field)
          (Re)create all constraints and indices that contain a specific field.
 int createKey()
          Gives an unique number for a new node, to be inserted in the storage.
protected  void createSequence()
          Creates a means for the database to pre-create keys with increasing numbers.
protected  void createTable(MMObjectBuilder builder, List<CoreField> tableFields, String tableName)
           
 void delete(CoreField field)
          Deletes a field from the storage of this builder.
protected  void delete(Index index)
          Drop a constraint or index.
 void delete(MMObjectBuilder builder)
          Drops the storage of this builder.
 void delete(MMObjectNode node)
          Delete a node
protected  void delete(MMObjectNode node, MMObjectBuilder builder)
          Delete a node from a specific builder This method makes it easier to implement relational databases, where you may need to remove the node in more than one builder.
protected  void delete(MMObjectNode node, MMObjectBuilder builder, List<CoreField> blobFileField, String tablename)
           
protected  void deleteIndices(CoreField field)
          Drop all constraints and indices that contain a specific field.
 void executeQuery(String sql, ResultSetReader reader)
           
protected  int executeUpdate(String query, MMObjectNode node, List<CoreField> fields)
          Executes an update query for given node and fields.
protected  int executeUpdateCheckConnection(String query, MMObjectNode node, List<CoreField> fields)
          Executes an update query for given node and fields.
 boolean exists()
          Determine if the basic storage elements exist Basic storage elements include the 'object' storage (where all objects and their types are registered).
protected  boolean exists(Index index)
          Determines if an index exists.
protected  boolean exists(Index index, String tablename)
          Determines if an index exists.
 boolean exists(MMObjectBuilder builder)
          Determine if a storage element exists for storing the given builder's objects
protected  boolean exists(String tableName)
          Queries the database metadata to test whether a given table exists.
protected  void fillNode(MMObjectNode node, ResultSet result, MMObjectBuilder builder)
          Fills a single Node from the resultset of a query.
protected  Connection getActiveConnection()
          Obtains an active connection, opening a new one if needed.
protected  File getBinaryFile(MMObjectNode node, String fieldName)
          Defines how binary (blob) data files must look like.
 byte[] getBinaryValue(MMObjectNode node, CoreField field)
          Retrieve a large binary object (byte array) for a specified object field.
protected  Blob getBlobFromDatabase(MMObjectNode node, CoreField field, boolean mayShorten)
          Read a binary (blob) from a field in the database
 Blob getBlobValue(MMObjectNode node, CoreField field)
           
 Blob getBlobValue(MMObjectNode node, CoreField field, boolean mayShorten)
           
protected  Blob getBlobValue(ResultSet result, int index, CoreField field, boolean mayShorten)
          Retrieve a large binary object (byte array) for a specified object field.
protected  Boolean getBooleanValue(ResultSet result, int index, CoreField field)
          Retrieve a boolean value for a specified object field.
protected  String getConstraintDefinition(CoreField field)
          Creates an index definition string for a field to be passed when creating a table.
protected  Date getDateTimeValue(ResultSet result, int index, CoreField field)
          Retrieve a date for a specified object field.
 DatabaseStorageManagerFactory getFactory()
           
protected  String getFieldDefinition(CoreField field)
          Creates a fielddefinition, of the format '[fieldname] [fieldtype] NULL' or '[fieldname] [fieldtype] NOT NULL' (depending on whether the field is nullable).
protected  String getFieldList(Index index)
          Returns a comma seperated list of fieldnames for an index.
 String getFieldTypeDefinition(CoreField field)
          Creates a field type definition, of the format '[fieldtype] NULL' or '[fieldtype] NOT NULL' (depending on whether the field is nullable).
 InputStream getInputStreamValue(MMObjectNode node, CoreField field)
           
protected  int getJDBCtoField(int jdbcType, int mmbaseType)
          Guess the (mmbase) type in storage using the JDBC type.
protected  long getLogStartTime()
           
 MMObjectNode getNode(MMObjectBuilder builder, int number)
          Select a node from a specified builder
 int getNodeType(int number)
          Returns the nodetype for a specified nodereference
 String getStringValue(MMObjectNode node, CoreField field)
          Retrieve a large text for a specified object field.
protected  Object getStringValue(ResultSet result, int index, CoreField field, boolean mayShorten)
          Retrieve a text for a specified object field.
 Object getValue(ResultSet result, int index, CoreField field, boolean mayShorten)
          Attempts to return a single field value from the resultset of a query.
 double getVersion()
          Returns the version of this factory implementation.
protected  Document getXMLValue(ResultSet result, int index, CoreField field, boolean mayShorten)
          Retrieve the XML (as a string) for a specified object field.
 void init(DatabaseStorageManagerFactory factory)
          Initializes the manager.
protected  boolean isBinaryColumnType(int st)
          Sometimes (legacy) string were stored in binary fields.
 boolean isNull(MMObjectNode node, CoreField field)
          Checks for null values for a field from the storage of this builder.
protected  boolean isPartOfBuilderDefinition(CoreField field)
          Determines whether the storage should make a field definition in a builder table for a specified field.
 boolean isVerified(MMObjectBuilder builder)
          Check if builders are already verified with the database.
protected  boolean logQuery(String query, long startTime)
           
protected  void refresh(MMObjectNode node)
          Reloads the data from a node from the database.
protected  void releaseActiveConnection()
          Safely closes the active connection.
 boolean rollback()
          Cancels any transaction that was started and rollback changes if possible.
protected  void setBinaryValue(PreparedStatement statement, int index, Object objectValue, CoreField field, MMObjectNode node)
          Store binary data of a field in a prepared statement.
protected  void setBooleanValue(PreparedStatement statement, int index, Object value, CoreField field, MMObjectNode node)
          Store a boolean value of a field in a prepared statement.
protected  void setDateTimeValue(PreparedStatement statement, int index, Object value, CoreField field, MMObjectNode node)
          Store a Date value of a field in a prepared statement.
protected  void setDecimalValue(PreparedStatement statement, int index, Object value, CoreField field, MMObjectNode node)
           
protected  void setListValue(PreparedStatement statement, int index, Object value, CoreField field, MMObjectNode node)
          Store a List value of a field in a prepared statement.
 int setNodeType(MMObjectNode node, MMObjectBuilder bul)
           
protected  void setNodeTypeLeaveRelations(MMObjectNode node, MMObjectBuilder buil)
           
protected  void setNodeTypeRememberRelations(MMObjectNode node, MMObjectBuilder buil)
           
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.
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.
protected  Object setStringValue(PreparedStatement statement, int index, Object objectValue, CoreField field, MMObjectNode node)
          Store the text value of a field in a prepared statement.
protected  void setValue(PreparedStatement statement, int index, MMObjectNode node, CoreField field)
          Store the value of a field in a prepared statement
protected  void setXMLValue(PreparedStatement statement, int index, Object objectValue, CoreField field, MMObjectNode node)
          This default implementation calls setStringValue(java.sql.PreparedStatement, int, java.lang.Object, org.mmbase.core.CoreField, org.mmbase.module.core.MMObjectNode).
protected  boolean shorten(CoreField field)
          Determine whether a field (such as a large text or a blob) should be shortened or not.
 int size()
          Return the total number of objects in the storage
 int size(MMObjectBuilder builder)
          Return the number of objects of a builder in the storage
protected  void storeBinaryAsFile(MMObjectNode node, CoreField field)
          Store a binary (blob) data file
protected  boolean tablesInheritFields()
          Returns whether tables inherit fields form parent tables.
protected  void unloadShortedFields(MMObjectNode node, MMObjectBuilder builder)
           
 void verify(MMObjectBuilder builder)
          Tests whether a builder and the table present in the database match.
protected  boolean verifyTables()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

OBJ2TYPE_MAX_SIZE

public static final int OBJ2TYPE_MAX_SIZE
Max size of the object type cache

See Also:
Constant Field Values

sequenceKeys

protected static final List<Integer> sequenceKeys

typeCache

protected static Cache<Integer,Integer> typeCache
The cache that contains the last X types of all requested objects

Since:
1.7

factory

protected DatabaseStorageManagerFactory factory
The factory that created this manager


activeConnection

protected Connection activeConnection
The currently active Connection. This member is set by {!link #getActiveConnection()} and unset by releaseActiveConnection()


inTransaction

protected boolean inTransaction
true if a transaction has been started. This member is for state maitenance and may be true even if the storage does not support transactions


transactionIsolation

protected int transactionIsolation
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.


changes

protected final Map<MMObjectNode,String> changes
Pool of changed nodes in a transaction

Constructor Detail

DatabaseStorageManager

public DatabaseStorageManager()
Constructor

Method Detail

getLogStartTime

protected final long getLogStartTime()

logQuery

protected final boolean logQuery(String query,
                                 long startTime)

getVersion

public double getVersion()
Description copied from interface: StorageManager
Returns the version of this factory implementation. The factory uses this number to verify whether it can handle storage configuration files that list version requirements.

Specified by:
getVersion in interface StorageManager<DatabaseStorageManagerFactory>
Returns:
the version as an integer

init

public void init(DatabaseStorageManagerFactory factory)
          throws StorageException
Description copied from interface: StorageManager
Initializes the manager. Called by a StorageManagerFactory when instantiating the manager with the getStorageManager() method.

Specified by:
init in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
factory - the StorageManagerFactory instance that created this storage manager.
Throws:
StorageConfigurationException - if the initialization failed
StorageException

getFactory

public DatabaseStorageManagerFactory getFactory()
Since:
MMBase-1.9.1

verifyTables

protected boolean verifyTables()
Since:
MMBase-1.8.7

getActiveConnection

protected Connection getActiveConnection()
                                  throws SQLException
Obtains an active connection, opening a new one if needed. This method sets and then returns the 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

releaseActiveConnection

protected void releaseActiveConnection()
Safely closes the active connection. If a transaction has been started, the connection is not closed.


beginTransaction

public void beginTransaction()
                      throws StorageException
Description copied from interface: StorageManager
Starts a transaction on this StorageManager instance. All commands passed to the instance will be treated as being in this transaction. If transactions are not supported by the storage, no actual storage transaction is started, but the code continues as if it has.

Specified by:
beginTransaction in interface StorageManager<DatabaseStorageManagerFactory>
Throws:
StorageException - if the transaction could not be created

commit

public void commit()
            throws StorageException
Description copied from interface: StorageManager
Closes any transaction that was started and commits all changes. If transactions are not supported by the storage, nothing really happens (as changes are allready committed), but the code continues as if it has.

Specified by:
commit in interface StorageManager<DatabaseStorageManagerFactory>
Throws:
StorageException - if a transaction is not currently active, or an error occurred while committing

rollback

public boolean rollback()
                 throws StorageException
Description copied from interface: StorageManager
Cancels any transaction that was started and rollback changes if possible. If transactions are not supported by the storage, nothing really happens (as changes are allready committed), but the code continues as if it has (through in that case it will return false).

Specified by:
rollback in interface StorageManager<DatabaseStorageManagerFactory>
Returns:
true if changes were rolled back, false if the transaction was canceled but the storage does not support rollback
Throws:
StorageException - if a transaction is not currently active, or an error occurred during rollback

commitChange

protected void commitChange(MMObjectNode node,
                            String change)
Commits the change to a node. If the manager is in a transaction (and supports it), the change is stored in a changes object (to be committed after the transaction ends). Otherwise it directly commits and broadcasts the changes

Parameters:
node - the node to register
change - the type of change: "n": new, "c": commit, "d": delete, "r" : relation changed

createKey

public int createKey()
              throws StorageException
Description copied from interface: StorageManager
Gives an unique number for a new node, to be inserted in the storage. This method should work with multiple mmbases

Specified by:
createKey in interface StorageManager<DatabaseStorageManagerFactory>
Returns:
unique number
Throws:
StorageException

getStringValue

public String getStringValue(MMObjectNode node,
                             CoreField field)
                      throws StorageException
Description copied from interface: StorageManager
Retrieve a large text for a specified object field. Implement this method to allow for optimization of storing and retrieving large texts.

Specified by:
getStringValue in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
node - the node to retrieve the text from
field - the Type of the field to retrieve
Returns:
the retrieved text
Throws:
StorageException - if an error occurred while retrieving the text value

isBinaryColumnType

protected boolean isBinaryColumnType(int st)
Sometimes (legacy) string were stored in binary fields. They must be dealt with seperately.

Since:
MMBase-1.9

getStringValue

protected Object getStringValue(ResultSet result,
                                int index,
                                CoreField field,
                                boolean mayShorten)
                         throws StorageException,
                                SQLException
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
index - the index of the text in the resultset
field - the (MMBase) fieldtype. This value can be null
Returns:
the retrieved text, null if no text was stored
Throws:
SQLException - when a database error occurs
StorageException - when data is incompatible or the function is not supported

getXMLValue

protected Document getXMLValue(ResultSet result,
                               int index,
                               CoreField field,
                               boolean mayShorten)
                        throws StorageException,
                               SQLException
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
index - the index of the xml in the resultset
field - the (MMBase) fieldtype. This value can be null
Returns:
the retrieved xml as text, null if nothing was stored
Throws:
SQLException - when a database error occurs
StorageException - when data is incompatible or the function is not supported

getDateTimeValue

protected Date getDateTimeValue(ResultSet result,
                                int index,
                                CoreField field)
                         throws StorageException,
                                SQLException
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
index - the index of the value in the resultset
field - the (MMBase) fieldtype. This value can be null
Returns:
the retrieved java.util.Date value, null if no text was stored
Throws:
SQLException - when a database error occurs
StorageException - when data is incompatible or the function is not supported
Since:
MMBase-1.8

getBooleanValue

protected Boolean getBooleanValue(ResultSet result,
                                  int index,
                                  CoreField field)
                           throws StorageException,
                                  SQLException
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
index - the index of the value in the resultset
field - the (MMBase) fieldtype. This value can be null
Returns:
the retrieved Boolean value, null if no text was stored
Throws:
SQLException - when a database error occurs
StorageException - when data is incompatible or the function is not supported
Since:
MMBase-1.8

shorten

protected boolean shorten(CoreField field)
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 getStringValue(MMObjectNode, CoreField) or. 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
Returns:
true if the field should be shortened
Throws:
StorageException - when data is incompatible or the function is not supported

getBlobFromDatabase

protected Blob getBlobFromDatabase(MMObjectNode node,
                                   CoreField field,
                                   boolean mayShorten)
Read a binary (blob) from a field in the database

Parameters:
node - the node the binary data belongs to
field - the binary field
Returns:
An InputStream representing the binary data, null if no binary data was stored, or VALUE_SHORTED, if mayShorten

getBinaryValue

public byte[] getBinaryValue(MMObjectNode node,
                             CoreField field)
                      throws StorageException
Description copied from interface: StorageManager
Retrieve a large binary object (byte array) for a specified object field. Implement this method to allow for optimization of storing and retrieving binary objects.

Specified by:
getBinaryValue in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
node - the node to retrieve the byte array from
field - the CoreField of the field to retrieve
Returns:
the retrieved byte array
Throws:
StorageException - if an error occurred while retrieving the binary value
See Also:
StorageManager.getBinaryValue(org.mmbase.module.core.MMObjectNode, org.mmbase.core.CoreField)

getInputStreamValue

public InputStream getInputStreamValue(MMObjectNode node,
                                       CoreField field)
                                throws StorageException
Specified by:
getInputStreamValue in interface StorageManager<DatabaseStorageManagerFactory>
Throws:
StorageException
See Also:
StorageManager.getInputStreamValue(org.mmbase.module.core.MMObjectNode, org.mmbase.core.CoreField)

getBlobValue

public Blob getBlobValue(MMObjectNode node,
                         CoreField field)
                  throws StorageException
Throws:
StorageException

getBlobValue

public Blob getBlobValue(MMObjectNode node,
                         CoreField field,
                         boolean mayShorten)
                  throws StorageException
Throws:
StorageException

getBlobValue

protected Blob getBlobValue(ResultSet result,
                            int index,
                            CoreField field,
                            boolean mayShorten)
                     throws StorageException,
                            SQLException
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
index - the index of the text in the resultset, or -1 to retireiv from file (blobs).
field - the (MMBase) fieldtype. This value can be null
Returns:
the retrieved data, null if no binary data was stored
Throws:
SQLException - when a database error occurs
StorageException - when data is incompatible or the function is not supported

appendDirectory

public static StringBuilder appendDirectory(StringBuilder pathBuffer,
                                            int number,
                                            String separator)
Appends subdirectories to the beginning of the given StringBuilder. This is based on the given (node) number. This ensures that there are never too many files in one directory.

Since:
MMBase-1.9.1

getBinaryFile

protected File getBinaryFile(MMObjectNode node,
                             String fieldName)
Defines how binary (blob) data files must look like.

Parameters:
node - the node the binary data belongs to
fieldName - the name of the binary field
Returns:
The File where to store or read the binary data

storeBinaryAsFile

protected void storeBinaryAsFile(MMObjectNode node,
                                 CoreField field)
                          throws StorageException
Store a binary (blob) data file

Parameters:
node - the node the binary data belongs to
field - the binary field
Throws:
StorageException - when an error occured while a binary is written to file
To Do:
how to do this in a transaction???

checkFile

protected File checkFile(File binaryFile,
                         MMObjectNode node,
                         CoreField field)
Checks whether file is readable and existing. Warns if not. If non-existing it checks older locations.

Parameters:
binaryFile - file location of binary
node - the binary is a field value of this node
field - field of the node
Returns:
the file to be used, or null if no existing readable file could be found, also no 'legacy' one.

create

public int create(MMObjectNode node)
           throws StorageException
Description copied from interface: StorageManager
This method creates a new object in the storage, and registers the change. Only fields with states of DBSTATE_PERSISTENT or DBSTATE_SYSTEM are stored.

Specified by:
create in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
node - The node to insert
Returns:
The (new) number for this node, or -1 if an error occurs.
Throws:
StorageException - if an error occurred during insert
See Also:
StorageManager.create(org.mmbase.module.core.MMObjectNode)

create

protected void create(MMObjectNode node,
                      MMObjectBuilder builder)
               throws StorageException
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
builder - the builder to store the node
Throws:
StorageException - if an error occurred during creation

appendField

protected void appendField(StringBuilder fieldNames,
                           StringBuilder fieldValues,
                           CoreField field)
Since:
MMBase-1.9.1

create

protected void create(MMObjectNode node,
                      List<CoreField> createFields,
                      String tablename)

unloadShortedFields

protected void unloadShortedFields(MMObjectNode node,
                                   MMObjectBuilder builder)

executeUpdateCheckConnection

protected int executeUpdateCheckConnection(String query,
                                           MMObjectNode node,
                                           List<CoreField> fields)
                                    throws SQLException
Executes an update query for given node and fields. It will close the connections which are no good, which it determines by trying "SELECT 1 FROM " after failure. If that happens, the connection is explicitly closed (in case the driver has not done that), which will render is unusable and at least GenericDataSource will automaticly try to get new ones.

Throws:
SQLException - If something wrong with the query, or the database is down or could not be contacted.
Since:
MMBase-1.7.1

executeUpdate

protected int executeUpdate(String query,
                            MMObjectNode node,
                            List<CoreField> fields)
                     throws SQLException
Executes an update query for given node and fields. This is wrapped in a function because it is repeatedly called in executeUpdateCheckConnection(java.lang.String, org.mmbase.module.core.MMObjectNode, java.util.List) which in turn is called from several spots in this class.

Parameters:
query - update query
node - updated node
fields - updated fields
Throws:
SQLException - if database connections failures occurs
Since:
MMBase-1.7.1

change

public void change(MMObjectNode node)
            throws StorageException
Description copied from interface: StorageManager
Commit this node to the specified builder.

Specified by:
change in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
node - The node to commit
Throws:
StorageException - if an error occurred during commit

change

protected void change(MMObjectNode node,
                      MMObjectBuilder builder)
               throws StorageException
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
builder - the builder to store the node
Throws:
StorageException - if an error occurred during change

change

protected void change(MMObjectNode node,
                      MMObjectBuilder builder,
                      String tableName,
                      Collection<CoreField> changeFields)
Commits changes in node to table.


setValue

protected void setValue(PreparedStatement statement,
                        int index,
                        MMObjectNode node,
                        CoreField field)
                 throws StorageException,
                        SQLException
Store the value of a field in a prepared statement

Parameters:
statement - the prepared statement
index - the index of the field in the prepared statement
node - the node from which to retrieve the value
field - the MMBase field, containing meta-information
Throws:
StorageException - if the fieldtype is invalid, or data is invalid or missing
SQLException - if an error occurred while filling in the fields
To Do:
Note that this code contains some code that should really be implemented in CoreField. In particular, casting should be done in CoreField, IMO.

setNullValue

protected boolean setNullValue(PreparedStatement statement,
                               int index,
                               Object value,
                               CoreField field,
                               int type)
                        throws StorageException,
                               SQLException
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
index - the index of the field in the prepared statement
value - the numeric value to store, which will be checked for null.
field - the MMBase field, containing meta-information
Returns:
true if a null value was set, false otherwise
Throws:
StorageException - if the data is invalid or missing
SQLException - if an error occurred while filling in the fields
Since:
MMBase-1.7.1

setNumericValue

protected void setNumericValue(PreparedStatement statement,
                               int index,
                               Object value,
                               CoreField field,
                               MMObjectNode node)
                        throws StorageException,
                               SQLException
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
index - the index of the field in the prepared statement
value - the numeric value to store. This may be a String, MMObjectNode, Numeric, or other value - the method will convert it to the appropriate value.
field - the MMBase field, containing meta-information
node - the node that contains the data. Used to update this node if the database layer makes changes to 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
SQLException - if an error occurred while filling in the fields

setNodeValue

protected void setNodeValue(PreparedStatement statement,
                            int index,
                            Object nodeValue,
                            CoreField field,
                            MMObjectNode node)
                     throws StorageException,
                            SQLException
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
index - the index of the field in the prepared statement
nodeValue - the node to store
field - the MMBase field, containing meta-information
node - the node that contains the data.
Throws:
StorageException - if the data is invalid or missing
SQLException - if an error occurred while filling in the fields

setBooleanValue

protected void setBooleanValue(PreparedStatement statement,
                               int index,
                               Object value,
                               CoreField field,
                               MMObjectNode node)
                        throws StorageException,
                               SQLException
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
index - the index of the field in the prepared statement
value - the data (boolean) to store
field - the MMBase field, containing meta-information
node - the node that contains the data. Used to update this node if the database layer makes changes to 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
SQLException - if an error occurred while filling in the fields
Since:
MMBase-1.8

setDateTimeValue

protected void setDateTimeValue(PreparedStatement statement,
                                int index,
                                Object value,
                                CoreField field,
                                MMObjectNode node)
                         throws StorageException,
                                SQLException
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
index - the index of the field in the prepared statement
value - the data (date) to store
field - the MMBase field, containing meta-information
node - the node that contains the data. Used to update this node if the database layer makes changes to 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
SQLException - if an error occurred while filling in the fields
Since:
MMBase-1.8

setDecimalValue

protected void setDecimalValue(PreparedStatement statement,
                               int index,
                               Object value,
                               CoreField field,
                               MMObjectNode node)
                        throws StorageException,
                               SQLException
Throws:
StorageException
SQLException
Since:
MMBase-1.9.1

setListValue

protected void setListValue(PreparedStatement statement,
                            int index,
                            Object value,
                            CoreField field,
                            MMObjectNode node)
                     throws StorageException,
                            SQLException
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
index - the index of the field in the prepared statement
value - the data (List) to store
field - the MMBase field, containing meta-information. This value can be null
node - the node that contains the data. Used to update this node if the database layer makes changes to 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
SQLException - if an error occurred while filling in the fields
Since:
MMBase-1.8

setBinaryValue

protected void setBinaryValue(PreparedStatement statement,
                              int index,
                              Object objectValue,
                              CoreField field,
                              MMObjectNode node)
                       throws StorageException,
                              SQLException
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
index - the index of the field in the prepared statement
objectValue - the data (byte array) to store
field - the MMBase field, containing meta-information
node - the node that contains the data. Used to update this node if the database layer makes changes to 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
SQLException - if an error occurred while filling in the fields

setStringValue

protected Object setStringValue(PreparedStatement statement,
                                int index,
                                Object objectValue,
                                CoreField field,
                                MMObjectNode node)
                         throws StorageException,
                                SQLException
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(int, String) to set the data. Override this method if you use another way to store large texts (i.e. Clobs).

Parameters:
statement - the prepared statement
index - the index of the field in the prepared statement
objectValue - the text to store
field - the MMBase field, containing meta-information
node - the node that contains the data.
Throws:
StorageException - if the data is invalid or missing
SQLException - if an error occurred while filling in the fields

setXMLValue

protected void setXMLValue(PreparedStatement statement,
                           int index,
                           Object objectValue,
                           CoreField field,
                           MMObjectNode node)
                    throws StorageException,
                           SQLException
This default implementation calls setStringValue(java.sql.PreparedStatement, int, java.lang.Object, org.mmbase.core.CoreField, org.mmbase.module.core.MMObjectNode). Override this method if you want to override this behavior.

Parameters:
statement - prepared update statement
index - index in statement to set the value in
objectValue - value to set
field - update of this node field
node - updated node
Throws:
StorageException - error occured in storage layer
SQLException - if database connections failures occurs
Since:
MMBase-1.7.1

delete

public void delete(MMObjectNode node)
            throws StorageException
Description copied from interface: StorageManager
Delete a node

Specified by:
delete in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
node - The node to delete
Throws:
StorageException - if an error occurred during delete
See Also:
StorageManager.delete(org.mmbase.module.core.MMObjectNode)

setNodeTypeRememberRelations

protected void setNodeTypeRememberRelations(MMObjectNode node,
                                            MMObjectBuilder buil)
                                     throws StorageException
Throws:
StorageException

setNodeTypeLeaveRelations

protected void setNodeTypeLeaveRelations(MMObjectNode node,
                                         MMObjectBuilder buil)
                                  throws StorageException
Throws:
StorageException

setNodeType

public int setNodeType(MMObjectNode node,
                       MMObjectBuilder bul)
                throws StorageException
Specified by:
setNodeType in interface StorageManager<DatabaseStorageManagerFactory>
Throws:
StorageException

delete

protected void delete(MMObjectNode node,
                      MMObjectBuilder builder)
               throws StorageException
Delete a node from a specific builder This method makes it easier to implement relational databases, 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

delete

protected void delete(MMObjectNode node,
                      MMObjectBuilder builder,
                      List<CoreField> blobFileField,
                      String tablename)

getNode

public MMObjectNode getNode(MMObjectBuilder builder,
                            int number)
                     throws StorageException
Description copied from interface: StorageManager
Select a node from a specified builder

Specified by:
getNode in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
builder - The builder to select from
number - the number of the node
Returns:
the MMObjectNode that was found, or null f it doesn't exist
Throws:
StorageException - if an error occurred during the get
See Also:
StorageManager.getNode(org.mmbase.module.core.MMObjectBuilder, int)

refresh

protected void refresh(MMObjectNode node)
                throws StorageException
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
Throws:
StorageException - error occured in storage layer

fillNode

protected void fillNode(MMObjectNode node,
                        ResultSet result,
                        MMObjectBuilder builder)
                 throws StorageException
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
result - the resultset
builder - the builder to use for creating the node
Throws:
StorageException - if the resultset is exhausted or a database error occurred

getValue

public Object getValue(ResultSet result,
                       int index,
                       CoreField field,
                       boolean mayShorten)
                throws StorageException
Attempts to return a single field value from the resultset of a query.

Parameters:
result - the resultset
index - the index of the field in the resultset
field - the expected MMBase field type. This can be null
mayShorten - Whether it would suffice to return only a 'shorted' version of the value.
Returns:
the value
Throws:
StorageException - if the value cannot be retrieved from the resultset
To Do:
This method is called from the search query code and therefor needs to be public. Perhaps code from searchquery should be moved to storage.

getNodeType

public int getNodeType(int number)
                throws StorageException
Description copied from interface: StorageManager
Returns the nodetype for a specified nodereference

Specified by:
getNodeType in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
number - the number of the node
Returns:
int the object type or -1 if not found
Throws:
StorageException - if an error occurred during selection
See Also:
StorageManager.getNodeType(int)

tablesInheritFields

protected boolean tablesInheritFields()
Returns whether tables inherit fields form parent tables. this determines whether fields that are inherited in mmbase builders are redefined in the database tables.

Returns:
tables inherit fields form parent tables

isPartOfBuilderDefinition

protected boolean isPartOfBuilderDefinition(CoreField field)
Determines whether the storage should make a field definition in a builder table for a specified field.

Parameters:
field -
Returns:
storage should make a field definition

create

public void create(MMObjectBuilder builder)
            throws StorageException
Description copied from interface: StorageManager
Create a storage element to store the specified builder's objects.

Specified by:
create in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
builder - the builder to create the storage element for
Throws:
StorageException - if an error occurred during the creation of the storage element
See Also:
StorageManager.create(org.mmbase.module.core.MMObjectBuilder)

createTable

protected void createTable(MMObjectBuilder builder,
                           List<CoreField> tableFields,
                           String tableName)

addToTableNameCache

protected void addToTableNameCache(String name)

getFieldTypeDefinition

public String getFieldTypeDefinition(CoreField field)
                              throws StorageException
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.

Parameters:
field - the field
Returns:
the typedefiniton as a String
Throws:
StorageException - if the field type cannot be mapped
Since:
MMBase-1.8

getFieldDefinition

protected String getFieldDefinition(CoreField field)
                             throws StorageException
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
Returns:
the typedefiniton as a String
Throws:
StorageException - if the field type cannot be mapped

getConstraintDefinition

protected String getConstraintDefinition(CoreField field)
                                  throws StorageException
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
Returns:
the index definition as a String, or null if no definition is available
Throws:
StorageException

change

public void change(MMObjectBuilder builder)
            throws StorageException
Description copied from interface: StorageManager
Changes the storage of a builder to match its new configuration.

Specified by:
change in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
builder - the builder whose storage to change
Throws:
StorageException

delete

public void delete(MMObjectBuilder builder)
            throws StorageException
Description copied from interface: StorageManager
Drops the storage of this builder.

Specified by:
delete in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
builder - the builder whose storage to drop
Throws:
StorageException

create

public void create()
            throws StorageException
Description copied from interface: StorageManager
Create the basic elements for this storage

Specified by:
create in interface StorageManager<DatabaseStorageManagerFactory>
Throws:
StorageException - if an error occurred during the creation of the object storage

createSequence

protected void createSequence()
                       throws StorageException
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 createKey().

Throws:
StorageException - when the sequence can not be created

exists

public boolean exists(MMObjectBuilder builder)
               throws StorageException
Description copied from interface: StorageManager
Determine if a storage element exists for storing the given builder's objects

Specified by:
exists in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
builder - the builder to check
Returns:
true if the storage element exists, false if it doesn't
Throws:
StorageException - if an error occurred while querying the storage

exists

protected boolean exists(String tableName)
                  throws StorageException
Queries the database metadata to test whether a given table exists.

Parameters:
tableName - name of the table to look for
Returns:
true if the table exists
Throws:
StorageException - when the metadata could not be retrieved

exists

public boolean exists()
               throws StorageException
Description copied from interface: StorageManager
Determine if the basic storage elements exist Basic storage elements include the 'object' storage (where all objects and their types are registered).

Specified by:
exists in interface StorageManager<DatabaseStorageManagerFactory>
Returns:
true if basic storage elements exist
Throws:
StorageException - if an error occurred while querying the storage

size

public int size(MMObjectBuilder builder)
         throws StorageException
Description copied from interface: StorageManager
Return the number of objects of a builder in the storage

Specified by:
size in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
builder - the builder whose objects to count
Returns:
the number of objects the builder has
Throws:
StorageException - if the storage element for the builder does not exists

size

public int size()
         throws StorageException
Description copied from interface: StorageManager
Return the total number of objects in the storage

Specified by:
size in interface StorageManager<DatabaseStorageManagerFactory>
Returns:
the number of objects
Throws:
StorageException - if the basic storage elements do not exist

getJDBCtoField

protected int getJDBCtoField(int jdbcType,
                             int mmbaseType)
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.


isVerified

public boolean isVerified(MMObjectBuilder builder)
Check if builders are already verified with the database.

Parameters:
builder - Builder which might be verified
Returns:
true when already verified

verify

public void verify(MMObjectBuilder builder)
            throws StorageException
Tests whether a builder and the table present in the database match.

Throws:
StorageException

exists

protected boolean exists(Index index,
                         String tablename)
Determines if an index exists. You should have an active connection before calling this method.

Parameters:
index - the index to test
tablename - the tablename to test the index against
Throws:
StorageException - when a database error occurs

exists

protected boolean exists(Index index)
                  throws StorageException
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

deleteIndices

protected void deleteIndices(CoreField field)
                      throws StorageException
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

delete

protected void delete(Index index)
               throws StorageException
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

getFieldList

protected String getFieldList(Index index)
Returns a comma seperated list of fieldnames for an index.

Parameters:
index - the index to create it for
Returns:
the field list definition as a String, or null if the index was empty, or if it consists of a composite index and composite indices are not supported.

createIndices

protected void createIndices(CoreField field)
                      throws StorageException
(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

create

protected void create(Index index)
               throws StorageException
Create an index or a unique constraint.

Parameters:
index - the index to create
Throws:
StorageException

createIndex

protected void createIndex(Index index,
                           String tablename)
Create an index or a unique constraint.

Parameters:
index - the index to create
tablename - name of the table

create

public void create(CoreField field)
            throws StorageException
Description copied from interface: StorageManager
Creates a field and adds it to the storage of this builder.

Specified by:
create in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
field - the CoreField of the field to add
Throws:
StorageException
See Also:
StorageManager.create(org.mmbase.core.CoreField)

change

public void change(CoreField field)
            throws StorageException
Description copied from interface: StorageManager
Changes a field to the storage of this builder.

Specified by:
change in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
field - the CoreField of the field to change
Throws:
StorageException
See Also:
StorageManager.change(org.mmbase.core.CoreField)

delete

public void delete(CoreField field)
            throws StorageException
Description copied from interface: StorageManager
Deletes a field from the storage of this builder.

Specified by:
delete in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
field - the CoreField of the field to delete
Throws:
StorageException
See Also:
StorageManager.delete(org.mmbase.core.CoreField)

convertLegacyBinaryFiles

public int convertLegacyBinaryFiles()
                             throws SearchQueryException,
                                    SQLException
Convert legacy file

Returns:
Number of converted fields. Or -1 if not storing binaries as files
Throws:
SearchQueryException
SQLException - if opening the connection failed

isNull

public boolean isNull(MMObjectNode node,
                      CoreField field)
               throws StorageException
Description copied from interface: StorageManager
Checks for null values for a field from the storage of this builder.

Specified by:
isNull in interface StorageManager<DatabaseStorageManagerFactory>
Parameters:
node - the node to check the value for
field - the CoreField
Returns:
true when value is null in storage
Throws:
StorageException - if an error occurred during the get
See Also:
StorageManager.isNull(org.mmbase.module.core.MMObjectNode, org.mmbase.core.CoreField)

executeQuery

public void executeQuery(String sql,
                         ResultSetReader reader)
                  throws SQLException
Throws:
SQLException
Since:
MMBase-1.9.1


MMBase 2.0-SNAPSHOT - null