Skip to content

Commit

Permalink
Merge #350 - Fix #296 - Support KEY order (ASC/DESC)
Browse files Browse the repository at this point in the history
Fixes: #296
Pull-request: #350

Signed-off-by: William Desportes <williamdes@wdes.fr>
  • Loading branch information
williamdes committed Aug 25, 2021
2 parents 1eb7d53 + 70894e4 commit 97e90e7
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 3 deletions.
22 changes: 19 additions & 3 deletions src/Components/Key.php
Expand Up @@ -55,9 +55,10 @@ class Key extends Component
public $name;

/**
* Columns.
* The key columns
*
* @var array
* @var array[]
* @phpstan-var array{name?: string, length?: int, order?: string}[]
*/
public $columns;

Expand Down Expand Up @@ -116,7 +117,7 @@ public static function parse(Parser $parser, TokensList $list, array $options =
/**
* Last parsed column.
*
* @var array
* @var array<string,mixed>
*/
$lastColumn = array();

Expand Down Expand Up @@ -186,6 +187,16 @@ public static function parse(Parser $parser, TokensList $list, array $options =
$lastColumn = array();
}
}
} elseif (
(
$token->type === Token::TYPE_KEYWORD
)
&&
(
($token->keyword === 'ASC') || ($token->keyword === 'DESC')
)
) {
$lastColumn['order'] = $token->keyword;
} else {
$lastColumn['name'] = $token->value;
}
Expand Down Expand Up @@ -244,6 +255,11 @@ public static function build($component, array $options = array())
if (isset($column['length'])) {
$tmp .= '(' . $column['length'] . ')';
}

if (isset($column['order'])) {
$tmp .= ' ' . $column['order'];
}

$columns[] = $tmp;
}

Expand Down
45 changes: 45 additions & 0 deletions tests/Builder/CreateStatementTest.php
Expand Up @@ -617,6 +617,51 @@ public function testBuildSelect()
);
}

public function testBuildCreateTableSortedIndex()
{
$parser = new Parser(
<<<'SQL'
CREATE TABLE `entries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`fk_ug_id` int(11) DEFAULT NULL,
`amount` decimal(10,2) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `entries__ug` (`fk_ug_id` DESC),
KEY `entries__ug2` (`fk_ug_id` ASC),
KEY `33` (`id` ASC, `fk_ug_id` DESC)
) /*!50100 TABLESPACE `innodb_system` */ ENGINE=InnoDB AUTO_INCREMENT=4465 DEFAULT CHARSET=utf8
SQL
);

/** @var CreateStatement $stmt */
$stmt = $parser->statements[0];

$tableBody = <<<'SQL'
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`fk_ug_id` int(11) DEFAULT NULL,
`amount` decimal(10,2) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `entries__ug` (`fk_ug_id` DESC),
KEY `entries__ug2` (`fk_ug_id` ASC),
KEY `33` (`id` ASC,`fk_ug_id` DESC)
)
SQL;

$this->assertEquals(
$tableBody,
CreateDefinition::build($stmt->fields)
);

$this->assertEquals(
'CREATE TABLE `entries` '
. $tableBody
. ' ENGINE=InnoDB AUTO_INCREMENT=4465 DEFAULT CHARSET=utf8 TABLESPACE `innodb_system`',
$stmt->build()
);

}

public function testBuildCreateTableComplexIndexes()
{
$parser = new Parser(
Expand Down
55 changes: 55 additions & 0 deletions tests/Components/KeyTest.php
Expand Up @@ -58,6 +58,61 @@ public function testParseKeyWithLengthWithoutOptions()
), $component->columns);
}

public function testParseKeyWithLengthWithoutOptionsWithOrder()
{
$component = Key::parse(
new Parser(),
$this->getTokensList('KEY `alias_type_idx` (`alias_type`(10) ASC),')
);
$this->assertEquals('KEY', $component->type);
$this->assertEquals('alias_type_idx', $component->name);
$this->assertEquals(new OptionsArray(), $component->options);
$this->assertNull($component->expr);
$this->assertSame(array(
array(
'name' => 'alias_type',
'length' => 10,
'order' => 'ASC',
)
), $component->columns);
}

public function testParseKeyWithoutOptionsWithOrderLowercase()
{
$component = Key::parse(
new Parser(),
$this->getTokensList('KEY `alias_type_idx` (`alias_type` desc),')
);
$this->assertEquals('KEY', $component->type);
$this->assertEquals('alias_type_idx', $component->name);
$this->assertEquals(new OptionsArray(), $component->options);
$this->assertNull($component->expr);
$this->assertSame(array(
array(
'name' => 'alias_type',
'order' => 'DESC',
)
), $component->columns);
}

public function testParseKeyWithoutOptionsWithOrder()
{
$component = Key::parse(
new Parser(),
$this->getTokensList('KEY `alias_type_idx` (`alias_type` DESC),')
);
$this->assertEquals('KEY', $component->type);
$this->assertEquals('alias_type_idx', $component->name);
$this->assertEquals(new OptionsArray(), $component->options);
$this->assertNull($component->expr);
$this->assertSame(array(
array(
'name' => 'alias_type',
'order' => 'DESC',
)
), $component->columns);
}

public function testParseKeyWithLengthWithOptions()
{
$component = Key::parse(
Expand Down

0 comments on commit 97e90e7

Please sign in to comment.