Working with Columns
A Column is the collection of one
type of information (for example, a collection of phone numbers or job titles).
A collection of Column components are managed by a
StorageDataSet.
A Column object can be created explicitly
in your code, or generated automatically when you instantiate the StorageDataSet subclass, for example,
by a QueryDataSet
when a query is executed. Each Column contains properties
that describe or manage that column of data. Some of the properties in Column hold metadata (defined below)
that is typically obtained from the data source. Other Column properties
are used to control its appearance and editing in
data-aware controls.
Note: Abstract or superclass class names are often used to refer generally to all their subclasses.
For example, a reference to a StorageDataSet object implies
any one (or all, depending on its usage) of its subclasses QueryDataSet,
TableDataSet,
ProcedureDataSet (Client/Server version), and
DataSetView.
The following topics are discussed:
For updates to this topic, see the online help or download a documentation update from http://www.borland.com/techpubs/jbuilder/
Column properties and metadata
The following topics are discussed:
Metadata and how it is obtained
Metadata is information about the data. Examples of metadata
are column name, table name, whether the column is part of the unique
row id or not, whether it is searchable, its precision, scale, and so on.
This information is typically obtained from the data source.
The metadata is then stored in properties
of Column components for each column in the StorageDataSet.
When you obtain data from a data source (a process referred to as providing), and store
it in one of the subclasses of StorageDataSet , you typically obtain not only rows of data
from the data source, but also metadata.
For example, the first time that you ask a QueryDataSet to
perform a query, it typically runs two queries: one for metadata discovery and the second for fetching rows of data that your application displays and manipulates.
Subsequent queries performed by that instance of QueryDataSet only do row data fetching. A query may be re-executed if <EM>rowId</EM>s need to be added later.
The QueryDataSet component then creates Column objects
automatically as needed at run time. One Column is created for each column in the provided data. Each Column then gets some
of its properties from the metadata, such as columnName,
tableName, rowId, searchable,
precision, scale, and so on.
You can suppress the initial metadata query to increase performance if your program already knows what the necessary metadata is. This is described in
Suppressing the initial metadata query.
Non-metadata Column properties
Columns have additional properties that are not obtained from metadata that you may want to set, for example, caption, editMask,
displayMask, background and foreground colors, and
alignment. These types of properties are typically intended
to control the default appearance of this data item in
data-aware controls, or to control how it can be edited by the user.
The properties you set in an application are usually of the non-metadata type.
Setting column properties
You can set Column properties through the JBuilder visual design tools or in code
manually. Any column that you define or modify through the visual design tools will be persistent.
Setting Column properties using JBuilder's visual design tools
The Inspector allows you to work with Column properties. To set Column properties:
- Open (or create) a project that contains a StorageDataSet that you want to work with. If you are creating a new project, you could follow the Tutorial: Querying a database for an example.
Tip: You can click the Test Query button on the query property editor to test your query and its connection to the Database.
- Open the UI Designer by selecting the Frame container object in the Navigation pane, and then clicking the Design tab in the AppBrowser.
- In the Component tree, select the StorageDataSet component.
- Double-click the StorageDataSet to display its columns.
- Select the Column you want to work with. The Inspector displays the column's properties and events. Set the properties you want.
Setting properties in code
To set properties manually in your source code on one or more columns in a
StorageDataSet:
- Provide data to the StorageDataSet. For example, run a query
using a QueryDataSet component. See the Tutorial: Querying a database for an example.
- Obtain an array of references to the existing Column
objects in the StorageDataSet by calling the getColumn(java.lang.String)
method of the ReadRow.
- Identify which column(s) in the array you want to work with by reading their properties, for example using the
getColumnName() property of the Column component.
- Set the properties on the appropriate columns as needed.
Note:
If you want the property settings to remain in force past the next time that data is provided, you must set the column's persist
property to true. This is described in the following section.
Persistent columns
A persistent column is a Column object which was already
part of a StorageDataSet, and whose persist
property was set to true before data was provided.
A persistent Column allows you to keep
Column property settings across a data-provide
operation. A persistent column does not cause the data in that
column of the data rows to freeze across data provide operations.
Normally, a StorageDataSet automatically creates new Column objects
for every column found in the data provided by the data source. It discards any Column objects that were explicitly added previously, or automatically created
for a previous batch of data. This discarding of previous Column
objects could cause you to lose property settings on the old Column which you
might want to retain.
To avoid this, mark a Column as persistent by setting
its persist property to true. When a column is persistent, the Column is not discarded when new data is provided to the
StorageDataSet. Instead, the existing Column object is used again to control the same column in the newly-provided data. The column matching is done by column name.
Any column that you define or modify through the visual design tools will be persistent. Persistent columns are discussed more thoroughly in Specifying required data in your application.
Creating persistent Columns explicitly in code
You can create Column objects explicitly and attach them to a StorageDataSet, using either addColumn()
to add a single Column, or setColumns()
to add several new columns at one time.
When using addColumn, you must set the Column to persistent prior to obtaining data from the data source or you will lose all of the column's property settings during the provide. The
persist property is set automatically with the setColumns method.
Note: The UI Designer calls the StorageDataSet.setColumns() method
when working with columns. If you want to load and modify your application in the UI Designer, use the setColumns
method so the columns are recognized at design time.
At run time, there is no difference between either method.
Combining live metadata with persistent columns
During the providing phase, a StorageDataSet first obtains metadata from the data source, if possible. This metadata is used to update any
existing matching persistent columns, and to create other columns that might be needed. The metaDataUpdate property of the StorageDataSet
class controls the extent of the updating of metadata on persistent columns.
Suppressing the initial metadata query
In some situations, you may want to suppress the lookup of metadata from a data source,
and instead use metadata that you provide in persistent Column
objects. This can offer performance benefits and allow for customizing of the metadata.
For example, when executing a query via a QueryDataSet,
the metadata is obtained in an initial query that fetches no
data rows, and the Column objects are given their metadata
from the results. Then a second query is run to fetch the actual row data.
The initial metadata query can take some time. To speed up the performance of your program's query operation, capture the metadata in persistent columns and change the DataSet component's metaDataUpdate
property to None.
Note: This is safe to do only if you are certain that the schema (structure) of your database will not change in ways that affect the critical
metadata needed by your DataSet, such as rowId and
tableName. If the schema does change later, your program
will most likely fail to run properly.
To suppress the metadata discovery using the JBuilder's visual design tools:
- Finalize your database schemas and query statements for your
application.
- Follow the first 3 steps in
Setting Column properties using JBuilder's visual design tools
to obtain the metadata into the columns listed in the Component tree.
- For each Column, set any property. If you don't want to change any property settings, set any property, then set it back to its default value. This forces the generation of a
persistent column and captures the current state of the metadata.
- Select the StorageDataSet object in the Component tree.
- Select its metaDataUpdate property, and unselect all Column properties by selecting the None button.
Removing persistent columns
This section describes how to undo column persistence so that a modified query no longer returns the (unwanted) columns in a StorageDataSet.
When you have a QueryDataSet or TableDataSet with persistent columns, you declare that these columns will exist in the resulting DataSet whether or not they still exist in the corresponding data source. But what happens if you no longer want these persistent columns?
When you alter the query string of a QueryDataSet, your old persistent columns are not lost. Instead, the new columns obtained from running the query are appended to your list of columns. You may make any of these new columns persistent by setting any of their properties.
Note: When you expand a StorageDataSet by clicking its plus (+) sign in the Component tree, the list of columns does not change automatically when you change the query string. To refresh the columns list based on the results of the modified query, double click the QueryDataSet in the Component tree. This executes the query again and appends any new columns found in the modified query.
To delete a persistent column you no longer need, select it in the Component tree and press the Delete key, or select the column in the Column Designer and click the Delete button on the toolbar. This causes the following actions:
- The column is marked as non-persistent
- Any code that sets properties of this column is removed
- Any event handler logic you may have placed on this column is removed.
To verify that a deleted persistent column is no longer part of the QueryDataSet, double-click the data set in the Component tree. This re-executes the query and displays all the columns in the resulting QueryDataSet
Using persistent columns to add empty columns to a DataSet
On occasion you may want to add one or more extra columns to a
StorageDataSet, columns that are not provided from the
data source and that are not intended to be resolved back
to the data source. For example, you might
- Need an extra column for internal utility purposes. If you want to hide the column from displaying in data-aware controls, set the visible property of the
Column to false.
- Construct a new DataSet manually by adding the columns you want before computing the data stored in its rows.
- Construct a new DataSet to store data from a custom data
source that isn't supported by JBuilder's providers and therefore doesn't provide metadata automatically.
In such cases, you can explicitly add a Column
to the DataSet, before or after providing data. The columnName must be unique and cannot duplicate a name that
already exists in the provided data. Additionally, if you will be providing
data after adding the Column, be sure to mark the Column
persistent so that the Column is not discarded when new data is provided.
To add a column manually in source code, follow the instructions in
Creating Columns explicitly in code
To add a column manually using the JBuilder visual design tools:
- Follow the first 3 steps in
Setting Column properties using JBuilder's visual design tools
to obtain the metadata into the columns listed in the Component tree.
(You can skip the steps for providing data if you want to add columns
to an empty DataSet.)
- Select <new column>. This option appears at the bottom of the list of columns.
- In the Inspector, set the columnName, making sure that it is different from existing column names.
- Set any other properties as needed for this new column.
JBuilder creates code for a new persistent Column object and
attaches it to your DataSet. The new Column exists even before the data is provided. Because its name is dissimilar from any provided column
names, this Column is not populated with data during the providing phase; all rows in this Column have null values.
Controlling column order in a DataSet
When a StorageDataSet is provided data, it
- Deletes any non-persistent columns, moving the persistent columns to the left.
- Merges columns from the provided data with persistent columns. If a persistent column has the same name and data type as a provided column, it is considered to be the same column.
- Places the provided columns into the data set in the order specified in the query or procedure.
- Adds the remaining columns - those defined only in the application - in the order they are defined in the data set's setColumns() method.
- Tries to move every column whose preferredOrdinal property is set to its desired place. (If two columns have the same preferredOrdinal, this won't be possible.)
This means that:
- Columns that are defined in your application and that are not provided by the query or procedure will appear after columns that are provided.
- Setting properties on some columns (whether provided or defined in the application), but not others, will not change their order.
- You can change the position of any column by setting its preferredOrdinal property. Columns whose preferredOrdinal is not set retain their position relative to each other.