diff --git a/common/framework/parsers/dbtable/constraint.php b/common/framework/parsers/dbtable/constraint.php index c2ceddaa4..8de87ef66 100644 --- a/common/framework/parsers/dbtable/constraint.php +++ b/common/framework/parsers/dbtable/constraint.php @@ -10,6 +10,7 @@ class Constraint public $type; public $column; public $references; - public $on_update; - public $on_delete; + public $condition; + public $on_delete = 'RESTRICT'; + public $on_update = 'RESTRICT'; } diff --git a/common/framework/parsers/dbtable/table.php b/common/framework/parsers/dbtable/table.php index 6dc6d6420..54553d540 100644 --- a/common/framework/parsers/dbtable/table.php +++ b/common/framework/parsers/dbtable/table.php @@ -12,4 +12,106 @@ class Table public $indexes = array(); public $primary_key = array(); public $constraints = array(); + + /** + * Generate the CREATE TABLE query for this table. + * + * @param string $prefix + * @param string $charset + * @param string $engine + * @return string + */ + public function getCreateQuery(string $prefix = '', string $charset = 'utf8mb4', string $engine = 'innodb') + { + // Initialize the query. + $result = 'CREATE TABLE `' . $prefix . $this->name . '` ('; + + // Add columns. + $columns = array(); + foreach ($this->columns as $column) + { + $columndef = ' `' . $column->name . '`' . ' ' . strtoupper($column->type); + if ($column->size) + { + $columndef .= '(' . $column->size . ')'; + } + if ($column->utf8mb4 === false && $charset === 'utf8mb4') + { + $columndef .= ' CHARACTER SET utf8 COLLATE utf8_unicode_ci'; + } + if ($column->not_null) + { + $columndef .= ' NOT NULL'; + } + if ($column->default_value !== null) + { + if (preg_match('/(?:int|float|double|decimal|number)/i', $column->type) && is_numeric($column->default_value)) + { + $columndef .= ' DEFAULT ' . $column->default_value; + } + else + { + $columndef .= ' DEFAULT \'' . $column->default_value . '\''; + } + } + if ($column->auto_increment) + { + $columndef .= ' AUTO_INCREMENT'; + } + $columns[] = $columndef; + } + + // Add indexes. + if (count($this->primary_key)) + { + $pkcolumns = array_map(function($str) { + return '`' . $str . '`'; + }, $this->primary_key); + $pkdef = ' ' . 'PRIMARY KEY (' . implode(', ', $pkcolumns) . ')'; + $columns[] = $pkdef; + } + foreach ($this->indexes as $index) + { + $idxcolumns = array_map(function($str) { + return '`' . $str . '`'; + }, $index->columns); + $idxtype = ($index->is_unique ? 'UNIQUE' : 'INDEX'); + $idxdef = ' ' . $idxtype . ' `' . $index->name . '` (' . implode(', ', $idxcolumns) . ')'; + $columns[] = $idxdef; + } + + // Add constraints. + foreach ($this->constraints as $constraint) + { + $contype = strtoupper($constraint->type); + if ($contype === 'FOREIGN KEY') + { + $condef = ' ' . $contype . ' (`' . $constraint->column . '`)'; + list($reftable, $refcolumn) = explode('.', $constraint->references); + $condef .= ' REFERENCES `' . $prefix . $reftable . '` (`' . $refcolumn . '`)'; + $condef .= ' ON DELETE ' . strtoupper($constraint->on_delete); + $condef .= ' ON UPDATE ' . strtoupper($constraint->on_update); + } + if ($contype === 'CHECK') + { + $condef = ' ' . $contype . ' (' . $constraint->condition . ')'; + } + $columns[] = $condef; + } + + // Finish the query. + $footer = ''; + if ($engine) + { + $footer .= ' ENGINE = ' . (strtolower($engine) === 'innodb' ? 'InnoDB' : 'MyISAM'); + } + if ($charset) + { + $footer .= ' CHARACTER SET ' . $charset . ' COLLATE ' . $charset . '_unicode_ci'; + } + $result .= "\n" . implode(",\n", $columns); + $result .= "\n" . ') ' . $footer . ';'; + + return $result; + } } diff --git a/common/framework/parsers/dbtableparser.php b/common/framework/parsers/dbtableparser.php index 3fda78870..deb51e590 100644 --- a/common/framework/parsers/dbtableparser.php +++ b/common/framework/parsers/dbtableparser.php @@ -159,13 +159,14 @@ class DBTableParser // Load other constraints (foreign keys). foreach ($xml->constraint as $const_info) { - $const = new DBTable\Constraint; - $const->type = strtolower($const_info['type']); - $const->column = strval($const_info['column']); - $const->references = strval($const_info['references']); - $const->on_update = strtolower($const_info['on_update'] ?: $const_info['on-update']); - $const->on_delete = strtolower($const_info['on_delete'] ?: $const_info['on-delete']); - $table->constraints[] = $const; + $constraint = new DBTable\Constraint; + $constraint->type = strtolower($const_info['type']); + $constraint->column = strval($const_info['column']) ?: null; + $constraint->references = strval($const_info['references']) ?: null; + $constraint->condition = strval($const_info['condition']) ?: null; + $constraint->on_delete = (strtolower($const_info['on_delete'] ?: $const_info['on-delete'])) ?: $constraint->on_delete; + $constraint->on_update = (strtolower($const_info['on_update'] ?: $const_info['on-update'])) ?: $constraint->on_update; + $table->constraints[] = $constraint; } // Return the complete table definition.