borland Packages Class Hierarchy datastore Package
java.lang.Object +----com.borland.datastore.DataStoreConnection +----com.borland.datastore.DataStore
Variables Constructors Properties Methods Event Listeners
Implements Designable, Store
The DataStore
component represents a physical DataStore file.
See the package
documentation for a brief overview of DataStore features, and the
JDataStore Developer's Guide for detailed usage information.
The functionality of previous versions of the DataStore
has
been divided into this class and its superclass, the
DataStoreConnection
class, which represents connections to a
DataStore file. Multiple connections from the same process are now
supported. Multi-user access to table streams in the DataStore is
supported through the remote JDBC driver; users of the remote driver
communicate with a single DataStore JDBC server process. A simple server
is provided by running the com.borland.jbuilder.dsserver.Server
class (in the datastore3.1.jar
library file).
DataStore
instead of MemoryStore
By default, once data is loaded into a DataExpress component the storage
mechanism is in-memory storage through the use of a MemoryStore
.
Alternate storage systems such as the DataStore
are allowed by
setting the StorageDataSet
object's
store
property. (Currently MemoryStore
and DataStore
are the
only implementations of the
Store
interface required by the store
property.)
The main advantage of DataStore
over MemoryStore
is
persistence, which enables off-line computing. In addition, you can
increase the performance of any application with large
StorageDataSets
. StorageDataSets
using
MemoryStore
have a small performance edge over
DataStore
for small number of rows, however, DataStore
stores data and indexes in an extremely compact format. As the number of
rows in a StorageDataSet
increases, using a DataStore
is much more performant and requires much less memory than using a
MemoryStore
.
Whether the data's storage is MemoryStore
or
DataStore
does not effect how you work with a DataSet
or other data-aware controls connected to the DataSet
.
Persistence, however, does require use of Java serialization
(java.io.Serializable).
If this is not possible, you cannot use DataStore
components
and should use the default in-memory storage mechanism.
There are two ways to create a DataStore file, depending on how you are using the DataStore with a StorageDataSet
- either as
persistent off-line storage or as an embedded database through the DataExpress API. Either way, the name of the DataStore file is
controlled by the DataStore
object's fileName
property, and starts out with the same general steps:
DataStore
.
fileName
for the DataStore file.
blockSize
, if desired.
TxManager
DataStore
's txManager
property
DataStore
's
userName
property
When using the DataStore with a StorageDataSet
, you
continue with these two steps:
DataStore
to the StorageDataSet
's
store
property.
StorageDataSet
's
storeName
property. This name will identify the
StorageDataSet
's data inside the DataStore.
This will create the DataStore when necessary. The alternative is to create the DataStore manually, which is more likely when using the JDBC driver to access the DataStore. There is only one additional step:
DataStore
's create
method.
Because the DataStore
is a subclass of
DataStoreConnection
, the create
method (if successful)
results in an open connection to the newly-created DataStore through the
DataStore
object. You can then use methods in the
datastore
package (the DataStore API) and a local JDBC driver
simultaneously to access the contents of the DataStore.
The steps for opening an existing DataStore are very similar to the
steps for creating one. For either type of use, it is not necessary to
instantiate a TxManager
to assign to the txManager
property; this will be done automatically when you open a transactional
DataStore. It doesn't hurt if you do assign one, and assigning one with
different properties before you open the DataStore is how you change
transactional properties.
Otherwise, the steps for using an existing DataStore with a
StorageDataSet
are identical to the steps when creating one.
Also, you may use the same DataStore with multiple
StorageDataSets
; each one must have a different (uniquely
identifying) storeName
property. This name is
case-sensitive.
Opening a DataStore manually has two differences:
open
method instead of the create
method.
DataStoreConnection
class to open a connection to an
existing DataStore. This is the superclass of DataStore
which actually contains the fileName
property and
open
method.
If you're using the JDBC driver to access the DataStore, you don't need to open the DataStore manually.
The directory structure of the DataStore
associates a name
and various directory status with a particular data stream. (The "/"
character is the directory separator in the DataStore's internal file
system.) DataStore
currently has these public data stream
categories:
DataSet
that extends from
StorageDataSet
(for example, QueryDataSet
,
ProcedureDataSet
, and TableDataSet
). All
StorageDataSet
features are supported including master
detail, picklists, constraints, calc fields, sorting, filtering, and
aggregation.
DataStore
component provides
methods to create and open arbitrary file streams
(createFileStream
and openFileStream
). These
methods return a FileStream
that extends the Java
InputStream
class with additional seek()
and
write()
methods.
Data of type Object can be stored in the DataStore
as a
file stream. The DataStore
component provides convenience
methods to serialize and deserialize them through the
writeObject()
and readObject()
methods. If these
Objects do not support Java serialization, an Exception
is
raised when the DataStore
attempts to save the Object.
Also, the class must exist on the classpath when the
DataStore
attempts to read an Object. (You can also persist
Java Objects in a DataStore
by using a DataSet
with a Column
that has an Object data type.)
You can access a DataStore's
directory structure by calling
its openDirectory()
method. This returns a
TableDataSet
with several columns for the name, data stream
category, modification time, size, delete status, and so on. The
directory structure for the DataStore's
file system typically
contains multiple levels that you can traverse using this
TableDataSet
.
Call deleteStream()
to delete a stream. The contents of
these streams are reallocated as new storage is needed for existing
streams. Although streams can be undeleted, the entire contents may not
be present if space was already used for new allocations.
Time values stored in the DataStore's
directory
DataSet
and in Time, Date, and TimeStamp columns are recorded
in UTC time.
See the openDirectory()
method for more information on the directory DataSet
.
Check the DataStore
's consistent
property to see if
the contents of the DataStore file may have been corrupted. One possible
cause of corruption is calling System.exit()
without properly
closing the connections to the DataStore. Certain exceptions may also
indicate possible or definite damage to the contents of a DataStore.
If the DataStore was transactional, and the log files have been lost
or damaged, set the readOnly
property to true
before attempting to open the DataStore.
You may check the integrity of the DataStore with a
StreamVerifier
object. If it indicates there are errors, use
the DataStoreConnection.copyStreams
method to attempt to copy
all the streams to a new DataStore. copyStreams
tries to repair
damaged streams and copy them correctly.
copyStreams
is also the way to upgrade an older version of
DataStore to the current version. Simply copy all the streams to a new
DataStore file.
The following code fragment shows the basic steps for copying all the streams to a new DataStore:
// dataStore is the source, which has already been opened DataStore newStore; // First create a copy with the same basic structure newStore = new DataStore(); newStore.setFileName( "COPY_" + dataStore.getFileName() ); newStore.setBlockSize( dataStore.getBlockSize() ); newStore.create(); // Copy all streams, ignoring errors dataStore.copyStreams( "", // From root directory "*", // All streams newStore, // To new store "", // To root directory DataStore.COPY_IGNORE_ERRORS, // Ignore individual errors System.out ); // Status messages to console // Be sure to close new DataStore newStore.shutdown();
When the data type of a
Column
component in a StorageDataSet
that is bound to a
DataStore
is changed, type coercions occur when going from one
type to another. Note that this form of coercion is different than the
ones peformed when providing and resolving data (see
CoerceToListener
and
CoerceFromListener
).
The following table describes what happens when a data
type is coerced to another data type. The data types on the left
indicate the original data type of the Column
with the data
types listed along the top of the table indicating the new data type of
the Column
.
From\To | Big Decimal | Double | Float | Long | int | Short | boolean | Time | Date | Time stamp | String | Input Stream | Object |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
BigDecimal | None | Prec | Prec | Prec | Prec | Prec | Prec | Prec | Prec | Prec | Ok | Loss | Loss |
Double | Prec | None | Prec | Prec | Prec | Prec | Prec | Prec | Prec | Prec | Ok | Loss | Loss |
Float | Prec | Ok | None | Prec | Prec | Prec | Prec | Prec | Prec | Prec | Ok | Loss | Loss |
Long | Ok | Prec | Prec | None | Prec | Prec | Prec | Prec | Prec | Prec | Ok | Loss | Loss |
int | Ok | Ok | Prec | Ok | None | Prec | Prec | Prec | Prec | Prec | Ok | Loss | Loss |
Short | Ok | Ok | Ok | Ok | Ok | None | Prec | Prec | Prec | Prec | Ok | Loss | Loss |
boolean | Ok | Ok | Ok | Ok | Ok | Ok | None | Prec | Prec | Prec | Ok | Loss | Loss |
Time | Prec | Prec | Prec | Prec | Prec | Prec | Prec | None | Prec | Prec | Ok | Loss | Loss |
Date | Prec | Prec | Prec | Prec | Prec | Prec | Prec | Prec | None | Prec | Ok | Loss | Loss |
Timestamp | Prec | Prec | Prec | Prec | Prec | Prec | Prec | Prec | Prec | None | Ok | Loss | Loss |
Where the table values represent the following:
The specifications of a DataStore
are as follows:
Capacity | Max DataStore file size: Blocksize * 2 gigabytes (approx 4,400 gigabytes) |
Default block size | 4k |
Maximum rows | 4 billion rows per table |
Maximum row length | 1/3 block size
Note: long values are stored as Strings and Binary Large Objects (BLOBs). BLOBs are limited to 2 gigabytes each. |
See the BasicJDataStore sample project located in the /samples/JDataStore/basics directory of your JBuilder installation. This tutorial demonstrates the basic usage of a JDataStore database using the JDataStore JDBC driver and the DataExpress Java bean components.
The OfflineEditing project in /samples/JDataStore/OffLineEditing steps you through an application that allows off-line editing using a DataStore
.
public static final short ACTIVE_STATE = 0x1Constant that designates a permanent, active stream. One of the possible values stored in the State column of the directory
DataSet
(as
returned by the openDirectory()
method).
public static final short AGG_STREAM = (short)5|TABLE_STREAM|HIDDEN_STREAMConstant that designates a hidden, internal stream used to maintain aggregates in a
TABLE_STREAM
. One of the possible values stored
in the Type column of the directory DataSet
(as returned by the
openDirectory()
method).
public static final short DELETED_STATE = 0x4Constant that designates a deleted stream. One of the possible values stored in the State column of the
DataStore's
directory DataSet
(as returned by the openDirectory()
method).
public static final short DELETED_STREAM = (short)2|TABLE_STREAM|HIDDEN_STREAMConstant that designates a hidden, internal stream used to store
DataSet
(TABLE_STREAM
) deleted rows. One of the possible values
stored in the Type column of the directory DataSet
(as returned
by the openDirectory()
method).
public static final String DIR_ACCESS = "Access"Reserved for future use.
public static final String DIR_BLOB_LENGTH = "BlobLength"Constant that refers to the BlobLength Column of the directory
DataSet
(returned by the openDirectory()
method) that stores the length (in bytes) of the table stream's
blobs.
public static final String DIR_DEL_TIME = "DelTime"Constant that refers to the DeleteTime Column of the directory
DataSet
(returned by the openDirectory()
method) that stores the UTC time a stream was deleted.
public static final String DIR_ID = "Id"Constant that refers to the Id Column of the directory
DataSet
(returned by the openDirectory()
method) that is a unique identifier for a stream.
public static final String DIR_LENGTH = "Length"Constant that refers to the Length Column of the directory
DataSet
(returned by the openDirectory()
method) that stores the length in bytes of a stream.
public static final String DIR_MOD_TIME = "ModTime"Constant that refers to the ModTime Column of the directory
DataSet
(returned by the openDirectory()
method) that stores the last UTC time a stream was modified.
public static final String DIR_PROPERTIES = "Properties"Constant that refers to the Properties Column of the directory
DataSet
(returned by the openDirectory()
method) that lists persisted properties and events for a
DataSet
stream.
public static final String DIR_STATE = "State"Constant that refers to the State Column of the directory
DataSet
(returned by the openDirectory()
method) that stores one of the DataStore.*_STATE values.
public static final String DIR_STORE_NAME = "StoreName"Constant that refers to the StoreName Column of the directory
DataSet
(returned by the openDirectory()
method) that stores the name for a stream. The name may be up
to 192 bytes long.
public static final String DIR_TYPE = "Type"Constant that refers to the Type Column of the directory
DataSet
(returned by the openDirectory()
method) that stores one of the DataStore.*_STREAM values.
public static final short FETCH_STREAM = (short)6|TABLE_STREAM|HIDDEN_STREAMConstant used to designate a hidden, internal stream that tracks detail groups (keys) fetched for a detail
DataSet
(TABLE_STREAM
).
One of the possible values stored
in the Type column of the directory DataSet
(as returned by the
openDirectory()
method).
public static final short FILE_STREAM = 0x2000Attribute for a file stream or serialized object stream. One of the possible values stored in the Type column of the directory
DataSet
(as returned by the
openDirectory()
method).
createFileStream()
, openFileStream()
, writeObject()
,
readObject()
methods
public static final short HIDDEN_STREAM = 0x4000Attribute that designates a stream for internal use. One of the possible values stored in the Type column of the directory
DataSet
(as returned by the
openDirectory()
method).
public static final short INSERTED_STREAM = (short)3|TABLE_STREAM|HIDDEN_STREAMConstant that refers to a hidden stream used to index
TABLE_STREAM
inserted rows. One of the possible values stored
in the Type column of the directory DataSet
(as returned by the
openDirectory()
method).
public static final int MAX_BIGDECIMAL_SCALE = 127Maximum scale that can be used for
BigDecimal
columns. Use of larger scales will be reduced to this scale.
public static final short ORIGINALS_STREAM = (short)4|TABLE_STREAM|HIDDEN_STREAMConstant that designates a hidden stream used to store
TABLE_STREAM
original rows and index updated rows.
One of the possible values stored
in the Type column of the directory DataSet
(as returned by the
openDirectory()
method).
public static final short SECOND_INDEX_STREAM = (short)7|TABLE_STREAM|HIDDEN_STREAMConstant that designates a hidden stream which maintains a secondary index of a
TABLE_STREAM
, including sorted and/or filtered views
of its associated TABLE_STREAM
. There can be one or more
SECOND_INDEX_STREAM
s. One of the possible values stored
in the Type column of the directory DataSet
(as returned by the
openDirectory()
method).
public static final int STORE_VERSION = VERSION_7_0Indicates what the version of a newly created DataStore file will be.
public static final short TABLE_FILE_STREAM = (short)1|TABLE_STREAM|HIDDEN_STREAMConstant used as an attribute for a file stream or serialized object stream stored inside a
TABLE_STREAM
. One of the possible values stored
in the Type column of the directory DataSet
(as returned by the
openDirectory()
method).
createFileStream()
, openFileStream()
, writeObject()
,
readObject()
methods
public static final short TABLE_STREAM = (short)0x8000Constant used as an attribute for a table stream.
DataSets
are
persisted with this attribute. One of the possible values stored
in the Type column of the directory DataSet
(as returned by the
openDirectory()
method).
public static final int VERSION_3_0 = 0x3000FConstant used for the 3.0 version number.
public static final int VERSION_3_14 = 0x00000E3.14 version number.
public static final int VERSION_4_0 = 0x040000Constant used for the 4.0 version number.
public static final int VERSION_5_0 = 0x0500005.0 version number. Time/Date/Timestamp data types stored in UTC instead of local time.
public static final int VERSION_6_0 = 0x0600006.0 version number. Time/Date/Timestamp data types stored in UTC instead of local time.
public static final int VERSION_7_0 = 0x0700007.0 version number.
NullTermStringKeyElement
will pad with NullTermOverHead
.
public DataStore()Constructs a
DataStore
component configured for a default block
size of 4KB and a maximum sort buffer size of 12MB. Change the
blockSize
and maxSortBuffer
properties if desired
before creating a new DataStore file with create()
.
public final int getBlockSize() public final synchronized void setBlockSize(int blockSize)Specifies the block size of the
DataStore
file, expressed in
kilobytes. Unless specifically set, this property defaults to 4k. This
property has no effect on an existing DataStore
and is used
only when creating a new DataStore
. On failure, the
setBlockSize
method throws a DataSetException
.
public final boolean isConsistent()
Returns false if the DataStore
was ever
shutdown improperly. Improper shutdown (such as calling
System.exit()
without closing a DataStore
) can cause a
DataStore
to become corrupted. If the DataStore
is
using a TxManager
, the TxManager
will bring the
DataStore
back to an action- and transaction-consistent state
when the DataStore
is reopened. isConsistent
can also
be set back to true if a StreamVerifier
can
successfully verify the entire DataStore
. This leaves the
DataStore
action-consistent, but not transaction-consistent.
public boolean isEncrypted()Returns a boolean value indicating whether or not the
DataStore
is encrypted.
public Locale getLocale() public synchronized void setLocale(Locale locale)Specifies the locale associated with this
DataStore
. StorageDataSet
components use this property when the locale
property is not set at the StorageDataSet
level.
public final int getMaxRowLength()Read-only property that returns the maximum length in bytes for a row stored in this
DataStore
. Note that Columns with large storage requirements like
long Strings, Objects or BLOBs are stored separately and are not limited by this length.
public final int getMaxRowLocks() public final void setMaxRowLocks(int maxRowLocks)Maximum number of row locks (used for repeatable read transactions) allowed for this
DataStore
.
public final int getMaxSortBuffer() public final void setMaxSortBuffer(int maxSortBuffer)Determines the maximum memory in bytes that is used for the buffer when performing sorting operations such as building indexes. Increasing this number may improve the performance of very large sorts. The minimum value for this property is 32*1024.
public final String getOpenMode() public final synchronized void setOpenMode(String mode)Controls whether streams are opened in read/write ("rw") or read-only ("r") mode. If the
readOnly
property is true,
no changes will be allowed, superseding this property.
public final long getSaveInterval() public final void setSaveInterval(long interval)Determines the time interval for asynchronous cache block saving for this
DataStore
component.
The interval value is expressed in milliseconds and must be greater than or equal to 100 and less than or equal to
2500. Both the setter and getter may throw a DataSetException
when applicable.
public final int getSaveMode() public final void setSaveMode(int mode)Determines when cached changes to the
DataStore
are saved to
disk. This property is ignored for transactional DataStores (their
TxManager
provides crash recovery). Set this property to one of
the following:
save()
or shutdown()
methods are called on the DataStore
.
DataStore
block is allocated or deleted.
This is the default setting, which provides more safety by saving cached blocks more frequently.
DataStore
.
This setting provides the most safety by saving cache blocks whenever they are modified.
Use this when debugging to ensure all modified cache blocks are constantly saved.
FileStream
classes when the
FileStream
is first created. FileStream.write()
operations are currently only saved by the daemon thread or an explicit
call to DataStore.save()
. Note that this property can be set
dynamically without closing the DataStore
.
public final TxManager getTxManager() public final void setTxManager(TxManager tm)The transaction manager for the
DataStore
. If this property is
null when the DataStore
is created, it will
not be transactional. It can be made transactional anytime in the future
by setting this property before opening the DataStore
.
public final void create()Creates a new
DataStore
file using the fileName
property. If a TxManager
has been assigned to the
txManager
property (which then requires that the userName
property also be set), the DataStore
will be
transactional, and the corresponding log files will be created as well.
A DataSetException
is thrown if the file specified in the
fileName
property already exists.
DataStoreConnection.open
method
public final void finalize()Closes the
DataStore
if it is still open.
public final void save()Saves the contents of the cache to the
DataStore
file. On
error, this method throws a DataSetException
.
public final void shutdown()Flushes the data cache, closes all connections to the
DataStore
, and closes the DataStore
. On failure, this
method throws a DataSetException
. If an IOException
is
generated, it is thrown via a chained DataSetException
.
public void sync()Forces DataStore data to be written to disk. For a non-transactional DataStore, this guarantees that all changes have been written safely.
public final void addResponseListener(ResponseListener listener) public final void removeResponseListener(ResponseListener listener)