# Converting from DBKit 1 to DBKit 2

## Introduction

DBKit 2 removes the TableConnection class. In its place, three new classes `DBKit.Window</api/databases/dbkit/window>`, `DBKit.Page</api/databases/dbkit/page>` and `DBKit.Container</api/databases/dbkit/container>` take over everything the TableConnection used to do: connecting to the database, loading rows, tracking the current row and managing the controls on the layout. Converting a project mostly means deleting the TableConnection instances and the code that went with them, setting the Super of your layouts to one of the new classes, and learning a few new property names.

One thing that has not changed is binding. In DBKit 1 you bound a control by setting its Column property or, more commonly, by simply naming the control the same as the database column. That is still how it works in DBKit 2, except the property is now called `ColumnName`.

## Replace the TableConnection

In DBKit 1, every layout had a TableConnection instance that connected the layout's controls to a database table. In DBKit 2 there is no TableConnection. Instead, set the Super of the layout itself:

- Desktop: set the window's Super to `DBKit.Window`.
- Web: set the webpage's Super to `DBKit.Page`.
- `DBKit.Container` allows you to embed DBKit controls on a DesktopWindow or WebPage that doesn't have `DBKit.Window` or `DBKit.Page` as its super.

Then delete the TableConnection instance from the layout. Its settings move to the layout, and a few property names have changed:

| DBKit 1 TableConnection property | DBKit 2 layout property                                                                                                                                 |
|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
| Table                            | `TableName`                                                                                                                                             |
| Connection                       | `Database`                                                                                                                                              |
| ConnectionName                   | No equivalent. Set the Database property directly on each layout; layouts using different databases just use different connections.                     |
| AutoConnect                      | No equivalent. DBKit 2 layouts connect automatically.                                                                                                   |
| CreateNewRow                     | No equivalent as a property. To open a layout ready to create a new row, use a DBKit.NewButton or call `NewRow` on the DBKit.Table.                     |
| QueryRows                        | No equivalent. The DBKit.Table loads its own rows. Use the layout's `Where` and `OrderBy` properties instead of assigning a RowSet from your own query. |

The easiest way to set the layout's `Database` property is to add a `DatabaseConnection</topics/databases/connecting_to_a_database>` to your project (Insert \> DatabaseConnection), then select it from the Database popup menu in the Inspector. You can also assign it in code.

If you assigned the QueryRows property a RowSet from your own query in order to filter or sort the rows, set the layout's `Where` and `OrderBy` properties instead. For example, where you previously wrote `SELECT * FROM customers WHERE country = 'USA' ORDER BY lastname`, set `TableName` to `customers`, `Where` to `country = 'USA'` and `OrderBy` to `lastname`.

Loading related rows no longer requires code. In DBKit 1 you wrote code in the TableConnection's LoadingRow event that queried with SelectSQL and assigned the resulting RowSet to another TableConnection's QueryRows. In DBKit 2, do two things and DBKit loads the related rows for you:

1.  Set the layout's `TableRelationships` property. Each relationship must name the table on both sides, in the form `foreignTable.column=primaryTable.column`:

``` text
invoices.customerid=customers.id
```

The table names on both sides are required. `customerid=id` will not work. 2. Set a `DBKit.Table</api/databases/dbkit/table>`'s `TableName` to the related table (`invoices` in this example).

## Replace the QueryRowsListBox with a Table

DBKit 1's QueryRowsListBox (and DBKit.ListBox) are replaced by `DBKit.Table</api/databases/dbkit/table>` in DBKit 2. Since you're converting, there's no need to drag a new control: select the QueryRowsListBox on the layout and change its Super to `DBKit.Table`.

A few property names have changed:

| DBKit 1 QueryRowsListBox property | DBKit 2 DBKit.Table property                 |
|-----------------------------------|----------------------------------------------|
| Columns                           | `ColumnNames<dbkit.table.columnnames>`       |
| Table                             | `TableName`                                  |
| Connector                         | No equivalent. It isn't needed.              |
| Concatenater                      | Removed.                                     |
| QueryRows                         | No equivalent. The table loads its own rows. |

The `BindDatabaseColumns` method is also gone; set the `ColumnNames<dbkit.table.columnnames>` property in the Inspector instead.

## Update your controls

All DBKit data entry controls (TextField, TextArea, NumberField, CheckBox, PopupMenu, RadioGroup, Slider, DatePicker and the rest) work the same way in DBKit 2, with these property name changes:

| DBKit 1 property | DBKit 2 property                |
|------------------|---------------------------------|
| Column           | `ColumnName`                    |
| Table            | `TableName`                     |
| Connector        | No equivalent. It isn't needed. |

`DisplayName` and `Mandatory` are unchanged. As in DBKit 1, if you named your controls to match the database column names, you don't need to set `ColumnName` at all.

The `Bind` method on controls (which took the TableConnection) is gone, as are the TableConnection's `BindAllControls` and `BindEntryControl` methods. Binding is automatic, so delete any `Bind` calls. If your TableConnection's Opening event only called `BindAllControls`, you can delete the event entirely.

## Code you no longer need

In DBKit 1, the TableConnection had methods for everything the layout did with rows, and methods to wire up buttons in code. In DBKit 2 the layout manages rows itself and buttons wire themselves up when you set their Super, so this code goes away:

| DBKit 1 code                                                                                                                                         | DBKit 2                                                                                        |
|------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| BindDeleteButton, BindEditButton, BindNewButton, BindUndoButton, BindEditingButton, BindToolbar, BindNavigationButton, BindMoveToFirstRowButton, ... | Delete these calls. Setting the button's Super to the DBKit button class is all that's needed. |
| BindSearchField                                                                                                                                      | Delete. The DBKit.SearchField finds the DBKit.Table on the layout automatically.               |
| BindListBoxControl, BindListBoxColumn                                                                                                                | Delete. No longer needed.                                                                      |
| LoadSelectedRow                                                                                                                                      | Delete. The selected row loads automatically.                                                  |
| EditRow                                                                                                                                              | Delete. Use a DBKit.EditButton.                                                                |
| UndoRowChanges                                                                                                                                       | Delete. Use a DBKit.UndoButton.                                                                |
| NewRow                                                                                                                                               | Delete. Use a DBKit.NewButton.                                                                 |
| ConfirmDeleteRow                                                                                                                                     | Delete. Use a DBKit.DeleteButton.                                                              |
| MoveToFirstRow, MoveToNextRow, MoveToPreviousRow, MoveToLastRow                                                                                      | Delete. Use the DBKit navigation buttons.                                                      |
| CurrentRow, PrimaryKeyColumn, HasBoundListBox, BoundQueryRowsListBox                                                                                 | Delete. The layout tracks the current row itself (see `DBKit.Window.CurrentRow`).              |
| Connect, Connected, Close, CheckForRowChange, RemoveSelectedRow, TableColumnType                                                                     | Delete. No longer needed.                                                                      |

The localizable strings moved as well. The TableConnection's `Confirm*` and `DeleteConfirm*` strings are now properties of the layout (for example `UnsavedChangesMessage` and `DeleteConfirmMessage`), and the edit button captions are now `EditCaption` and `DoneCaption` on DBKit.EditButton.

Update your events -----------------

| DBKit 1 TableConnection event | DBKit 2                                                                                                                                                       |
|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| LoadingRow                    | `RowLoaded` on the layout or table. Note: RowLoaded is notification-only; it cannot prevent the row from loading the way returning False from LoadingRow did. |
| SavingRow                     | `RowSaving` on the layout or table.                                                                                                                           |
| ControlsStateChanged          | Removed. DBKit 2 manages control state itself.                                                                                                                |
| Error                         | `Error` on the layout.                                                                                                                                        |
| Opening                       | Unchanged. Still the Opening event.                                                                                                                           |
| Closing                       | Unchanged. Still the Closing event on desktop and the Closed event on web.                                                                                    |

## Update SearchField

The DBKit.SearchField still exists in DBKit 2 and works the same way, with these changes:

| DBKit 1 SearchField    | DBKit 2 DBKit.SearchField                                                         |
|------------------------|-----------------------------------------------------------------------------------|
| Connector              | No equivalent. It isn't needed.                                                   |
| Table                  | No equivalent. The SearchField finds the DBKit.Table on the layout automatically. |
| Columns                | `Columns<dbkit.searchfield.columns>` (unchanged)                                  |
| HintPrefix             | `HintPrefix<dbkit.searchfield.hintprefix>` (unchanged)                            |
| ToolTipMessage         | ToolTipMessage (unchanged)                                                        |
| ShowAllRowsByDefault   | Removed. The table shows all rows by default.                                     |
| Search(), UpdateHint() | Removed. Searching is automatic as the user types.                                |

New in DBKit 2: the SearchField has an `AutoHint<dbkit.searchfield.autohint>` property that automatically sets its hint from the column names, a `SearchInSelection<dbkit.searchfield.searchinselection>` property and a `SearchComplete<dbkit.searchfield.searchcomplete>` event.

Explore what's new in DBKit 2 ----------------------------

Once your project is converted, these DBKit 2 features are worth a look. You may find they replace code you wrote yourself in DBKit 1:

- `DBKit.Table</api/databases/dbkit/table>` loads rows lazily, so large tables stay responsive. It also has aggregate methods (`Average<dbkit.table.average>`, `Sum<dbkit.table.sum>`, `Minimum<dbkit.table.minimum>`, `Maximum<dbkit.table.maximum>`), a `Refresh<dbkit.table.refresh>` method and `AllowDirectCellEditing<dbkit.table.allowdirectcellediting>` for editing values right in the table.
- `RowDisplayed<dbkit.table.rowdisplayed>` is a new table event for displaying calculated values in a column.
- `DBKit.Row</api/databases/dbkit/row>` is a new class representing the current database row, passed to the row events.
- `Where` and `OrderBy` on the layout replace hand-written queries for filtering and sorting.
- `TableRelationships` on the layout replaces hand-written code for loading related rows.
- `AutomaticHints` on the layout (and `AutoHint<dbkit.searchfield.autohint>` on SearchField) automatically set control hints from display names.
- `DBKit.Container` allows you to embed DBKit controls on a DesktopWindow or WebPage that doesn't have `DBKit.Window` or `DBKit.Page` as its super.
- **DBKit.EditingButton** combines Edit, Delete, New and Undo into a single control.
