Streaming data

Streamable data sets enable you to create a Java object (DataSetData) that contains all the data of a DataSet. Similarly, the DataSetData object can be used to provide a DataSet with column information and data.

The DataSetData object implements the java.io.Serializable interface and may subsequently be serialized using writeObject in java.io.ObjectOutputStream and read using readObject in java.io.ObjectInputStream. This method turns the data into a byte array and passes it through sockets or some other transport medium. Alternatively, the object can be passed via Java RMI, which will do the serialization directly.

In addition to saving a complete set of data in the DataSet, you may save only the changes to the data set. This functionality can implement a middle-tier server that communicates with a DBMS and a thin client which is capable of editing a DataSet.

Example: Using streamable data sets

One example of when you would use a streamable DataSet is in a 3-tier system with a Java server application that responds to client requests for data from certain data sources. The server may use JBuilder QueryDataSets or ProcedureDataSets to provide the data to the server machine. The data can be extracted using DataSetData.extractDataSet and sent over a wire to the client. On the client side, the data can be loaded into a TableDataSet and edited with JBuilder DataSet controls or with calls to the DataSet Java API. The server application may remove all the data in its DataSet such that it will be ready to serve other client applications.

When the user on the client application wants to save the changes, the data may be extracted with DataSetData.extractDataSetChanges and sent to the server. Before the server loads these changes, it should get the physical column types from the DBMS using the metadata of the DataSet. Next, the DataSet is loaded with the changes and the usual resolvers in JBuilder are applied to resolve the data back to the DBMS.

If resolution errors occur, they might not be detected by UI actions when the resolution is happening on a remote server machine. The resolver could handle the errors by creating an errors DataSet. Each error message should be tagged with the INTERNALROW value of the row for which the error occurred. DataSetData can transport these errors to the client application. If the DataSet is still around, the client application can easily link the errors to the DataSet and display the error text for each row.

Using streamable DataSet methods

The static methods extractDataSet and extractDataSetChanges will populate the DataSetData with nontransient private data members, that specify

  1. Metadata information consisting of

    The properties are currently stored as the 3 high bits of each data type. Each data type is a byte. The columnCount is stored implicitly as the length of the columnNames array.

  2. Status bits for each row. A short is stored for each row.

  3. Null bits for each data element. 2 bits are stored for each data element. The possible values used are:

    The last value is used only for extractDataSetChanges. Values that are unchanged in the UPDATED version are stored as null, saving space for large binaries, etc.

  4. The data itself, organized in an array of column data. If a data column is of type Variant.INTEGER, an int array will be used for the values of that column.

  5. For extractDataSetChanges, a special column, INTERNALROW, is added to the data section. This data column contains long values that designate the internalRow of the DataSet the data was extracted from. This data column should be used for error reporting in case the changes could not be applied to the target DBMS.

The loadDataSet method will load the data into a DataSet. Any columns that do not already exist in the DataSet will be added. Note that physical types and properties such as sqlType, precision, and scale are not contained in the DataSetData object. These properties must be found on the DBMS directly. However these properties are not necessary for editing purposes. The special column INTERNALROW shows up as any other column in the data set.