diff --git a/src/Model/Column.php b/src/Model/Column.php index 62fb987..afbbdef 100644 --- a/src/Model/Column.php +++ b/src/Model/Column.php @@ -64,6 +64,11 @@ class Column */ private $primaryKey; + /** + * @var int + */ + private $primaryKeyLength; + /** * @var string */ @@ -286,6 +291,22 @@ public function setPrimaryKey($primaryKey) $this->primaryKey = $primaryKey; } + /** + * @return int + */ + public function getPrimaryKeyLength() + { + return $this->primaryKeyLength; + } + + /** + * @param int $primaryKeyLength + */ + public function setPrimaryKeyLength($primaryKeyLength) + { + $this->primaryKeyLength = $primaryKeyLength; + } + /** * @return string */ diff --git a/src/Model/Table.php b/src/Model/Table.php index 28dcd4d..67a4597 100644 --- a/src/Model/Table.php +++ b/src/Model/Table.php @@ -9,6 +9,11 @@ class Table */ private $name; + /** + * @var bool + */ + private $ifNotExists; + /** * @var string */ @@ -70,6 +75,22 @@ public function getName() return $this->name; } + /** + * @return bool + */ + public function isIfNotExists() + { + return $this->ifNotExists; + } + + /** + * @param bool $ifNotExists + */ + public function setIfNotExists($ifNotExists) + { + $this->ifNotExists = $ifNotExists; + } + /** * @return string */ @@ -324,7 +345,13 @@ public function generatePrimaryKeyCreationScript() $primaryKeys = []; foreach ($this->primaryKeys as $primaryKeyColumn) { - $primaryKeys[] = sprintf('`%s`', $primaryKeyColumn->getName()); + if ($primaryKeyColumn->getPrimaryKeyLength()) { + $primaryKey = sprintf('`%s`(%s)', $primaryKeyColumn->getName(), $primaryKeyColumn->getPrimaryKeyLength()); + } else { + $primaryKey = sprintf('`%s`', $primaryKeyColumn->getName()); + } + + $primaryKeys[] = $primaryKey; } return sprintf('PRIMARY KEY (%s)', implode(',', $primaryKeys)); @@ -369,6 +396,12 @@ public function generateCreationScript($ignoreAutoIncrement = false, $sortKeys = $tableOptions = []; + if ($this->ifNotExists) { + $ifNotExists = ' IF NOT EXISTS'; + } else { + $ifNotExists = ''; + } + if ($this->engine) { $tableOptions[] = sprintf('ENGINE=%s', $this->engine); } @@ -387,6 +420,6 @@ public function generateCreationScript($ignoreAutoIncrement = false, $sortKeys = $implodedTableOptions = ' ' . $implodedTableOptions; } - return trim(sprintf('CREATE TABLE `%s` (%s %s%s)%s;', $this->name, PHP_EOL, implode(',' . PHP_EOL . ' ', $tableDefinitions), PHP_EOL, $implodedTableOptions)); + return trim(sprintf('CREATE TABLE%s `%s` (%s %s%s)%s;', $ifNotExists, $this->name, PHP_EOL, implode(',' . PHP_EOL . ' ', $tableDefinitions), PHP_EOL, $implodedTableOptions)); } } diff --git a/src/Parser.php b/src/Parser.php index c19dbf2..310d7f3 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -43,6 +43,7 @@ public function parseTables($sqlScript) $tables = []; for ($i = 0; $i < count($matches[0]); $i++) { $name = $matches['tableName'][$i]; + $ifNotExists = $matches['ifNotExists'][$i]; $definition = $matches['tableDefinition'][$i]; $creationScript = $matches['creationScript'][$i]; $engine = $matches['engine'][$i]; @@ -53,6 +54,10 @@ public function parseTables($sqlScript) $table->setDefinition(trim($definition)); $table->setCreationScript(trim($creationScript) . ';'); + if ($ifNotExists) { + $table->setIfNotExists(true); + } + if ($engine) { $table->setEngine($engine); } @@ -171,8 +176,20 @@ public function parsePrimaryKey(Table $table) $primaryKeyNames = explode(',', str_replace('`', '', $matches['primaryKey'])); foreach ($primaryKeyNames as $primaryKeyName) { - $primaryKeyColumn = $table->getColumnByName(trim($primaryKeyName)); + if (preg_match('/^(?[^\(]+)\((?\d+)\)/', $primaryKeyName, $keyMatches)) { + $columnName = $keyMatches['columnName']; + $keyLength = $keyMatches['keyLength']; + } else { + $columnName = $primaryKeyName; + $keyLength = null; + } + $primaryKeyColumn = $table->getColumnByName(trim($columnName)); $primaryKeyColumn->setPrimaryKey(true); + + if ($keyLength) { + $primaryKeyColumn->setPrimaryKeyLength($keyLength); + } + $table->addPrimaryKey($primaryKeyColumn); } } diff --git a/src/RegExpPattern.php b/src/RegExpPattern.php index 2d3296d..a07ffc8 100644 --- a/src/RegExpPattern.php +++ b/src/RegExpPattern.php @@ -31,7 +31,7 @@ class RegExpPattern */ public static function tables() { - $pattern = '/(?CREATE\s+TABLE\s+`(?\S+)`\s+'; + $pattern = '/(?CREATE\s+TABLE\s+(?IF NOT EXISTS)?\s*`(?\S+)`\s+'; $pattern .= '\((?[^;\/]+)\)'; $pattern .= '(?:\s+ENGINE=(?[^;\s]+))?\s*'; $pattern .= '(?:AUTO_INCREMENT=(?\d+))?\s*'; @@ -77,7 +77,7 @@ public static function dataType() */ public static function primaryKey() { - return '/PRIMARY KEY \((?.+?)\)/'; + return '/PRIMARY KEY \((?(?:`[^`]+`\s*(?:\(\d+\))?,?)+)\)/'; } /** diff --git a/tests/ParserTest.php b/tests/ParserTest.php index 0eafbdb..269b127 100644 --- a/tests/ParserTest.php +++ b/tests/ParserTest.php @@ -286,4 +286,20 @@ public function testIsParsingDoubleUnsignedType() $this->assertEquals('double unsigned', $database->getTableByName('jos_finder_links')->getColumnByName('list_price')->getColumnType()); $this->assertEquals('double', $database->getTableByName('jos_finder_links')->getColumnByName('list_price')->getDataType()); } + + public function testIsParsingPrimaryKeyLength() + { + $creationScript = $this->getDatabaseFixture('jos_extwebdav_properties.sql'); + + $parser = new Parser(); + + $database = $parser->parseDatabase($creationScript); + + $this->assertInstanceOf(Database::class, $database); + $this->assertCount(1, $database->getTables()); + $this->assertCount(4, $database->getTableByName('jos_extwebdav_properties')->getColumns()); + $this->assertCount(3, $database->getTableByName('jos_extwebdav_properties')->getPrimaryKeys()); + + $this->assertEquals($creationScript, $database->getTableByName('jos_extwebdav_properties')->generateCreationScript()); + } } diff --git a/tests/fixtures/jos_extwebdav_properties.sql b/tests/fixtures/jos_extwebdav_properties.sql new file mode 100644 index 0000000..2144bd8 --- /dev/null +++ b/tests/fixtures/jos_extwebdav_properties.sql @@ -0,0 +1,8 @@ +CREATE TABLE IF NOT EXISTS `jos_extwebdav_properties` ( + `path` varchar(255) NOT NULL DEFAULT '', + `name` varchar(120) NOT NULL DEFAULT '', + `ns` varchar(120) NOT NULL DEFAULT 'DAV:', + `value` text, + PRIMARY KEY (`ns`(100),`path`(100),`name`(50)), + KEY `path` (`path`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; \ No newline at end of file