3 !!! info "Available since WoltLab Suite 5.2."
5 While the [sql](package_pip_sql.md) package installation plugin supports adding and removing tables, columns, and indices, it is not able to handle cases where the added table, column, or index already exist.
6 We have added a new PHP-based API to manipulate the database scheme which can be used in combination with the [script](package_pip_script.md) package installation plugin that skips parts that already exist:
13 (new DatabaseTableChangeProcessor(
14 /** @var ScriptPackageInstallationPlugin $this */
15 $this->installation->getPackage(),
17 WCF::getDB()->getEditor())
21 All of the relevant components can be found in the `wcf\system\database\table` namespace.
26 There are two classes representing database tables: `DatabaseTable` and `PartialDatabaseTable`.
27 If a new table should be created, use `DatabaseTable`.
28 In all other cases, `PartialDatabaseTable` should be used as it provides an additional save-guard against accidentally creating a new table by having a typo in the table name:
29 If the tables does not already exist, a table represented by `PartialDatabaseTable` will cause an exception (while a `DatabaseTable` table will simply be created).
31 To create a table, a `DatabaseTable` object with the table's name as to be created and table's columns, foreign keys and indices have to be specified:
34 DatabaseTable::create('foo1_bar')
46 To update a table, the same code as above can be used, except for `PartialDatabaseTable` being used instead of `DatabaseTable`.
48 To drop a table, only the `drop()` method has to be called:
51 PartialDatabaseTable::create('foo1_bar')
58 To represent a column of a database table, you have to create an instance of the relevant column class found in the `wcf\system\database\table\column` namespace.
59 Such instances are created similarly to database table objects using the `create()` factory method and passing the column name as the parameter.
61 Every column type supports the following methods:
63 - `defaultValue($defaultValue)` sets the default value of the column (default: none).
64 - `drop()` to drop the column.
65 - `notNull($notNull = true)` sets if the value of the column can be `NULL` (default: `false`).
67 Depending on the specific column class implementing additional interfaces, the following methods are also available:
69 - `IAutoIncrementDatabaseTableColumn::autoIncrement($autoIncrement = true)` sets if the value of the colum is auto-incremented.
70 - `IDecimalsDatabaseTableColumn::decimals($decimals)` sets the number of decimals the column supports.
71 - `IEnumDatabaseTableColumn::enumValues(array $values)` sets the predetermined set of valid values of the column.
72 - `ILengthDatabaseTableColumn::length($length)` sets the (maximum) length of the column.
74 Additionally, there are some additionally classes of commonly used columns with specific properties:
76 - `DefaultFalseBooleanDatabaseTableColumn` (a `tinyint` column with length `1`, default value `0` and whose values cannot be `null`)
77 - `DefaultTrueBooleanDatabaseTableColumn` (a `tinyint` column with length `0`, default value `0` and whose values cannot be `null`)
78 - `NotNullInt10DatabaseTableColumn` (a `int` column with length `10` and whose values cannot be `null`)
79 - `NotNullVarchar191DatabaseTableColumn` (a `varchar` column with length `191` and whose values cannot be `null`)
80 - `NotNullVarchar255DatabaseTableColumn` (a `varchar` column with length `255` and whose values cannot be `null`)
81 - `ObjectIdDatabaseTableColumn` (a `int` column with length `10`, whose values cannot be `null`, and whose values are auto-incremented)
86 DefaultFalseBooleanDatabaseTableColumn::create('isDisabled')
88 NotNullInt10DatabaseTableColumn::create('fooTypeID')
90 SmallintDatabaseTableColumn::create('bar')
98 Foreign keys are represented by `DatabaseTableForeignKey` objects:
101 DatabaseTableForeignKey::create()
103 ->referencedTable('wcf1_foo')
104 ->referencedColumns(['fooID'])
105 ->onDelete('CASCADE')
108 The supported actions for `onDelete()` and `onUpdate()` are `CASCADE`, `NO ACTION`, and `SET NULL`.
109 To drop a foreign key, all of the relevant data to create the foreign key has to be present and the `drop()` method has to be called.
111 `DatabaseTableForeignKey::create()` also supports the foreign key name as a parameter.
112 If it is not present, `DatabaseTable::foreignKeys()` will automatically set one based on the foreign key's data.
117 Indices are represented by `DatabaseTableIndex` objects:
120 DatabaseTableIndex::create()
121 ->type(DatabaseTableIndex::UNIQUE_TYPE)
125 There are four different types: `DatabaseTableIndex::DEFAULT_TYPE` (default), `DatabaseTableIndex::PRIMARY_TYPE`, `DatabaseTableIndex::UNIQUE_TYPE`, and `DatabaseTableIndex::FULLTEXT_TYPE`.
126 For primary keys, there is also the `DatabaseTablePrimaryIndex` class which automatically sets the type to `DatabaseTableIndex::PRIMARY_TYPE`.
127 To drop a index, all of the relevant data to create the index has to be present and the `drop()` method has to be called.
129 `DatabaseTableIndex::create()` also supports the index name as a parameter.
130 If it is not present, `DatabaseTable::indices()` will automatically set one based on the index data.