Skip to content

Commit 40c7acd

Browse files
Fix index tokenizer to accept multiple columns / fks (#68)
1 parent b99bd4b commit 40c7acd

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

src/Tokenizers/MySQL/IndexTokenizer.php

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,35 @@ private function consumeForeignKey()
5656
if (strtoupper($piece) === 'FOREIGN') {
5757
$this->consume(); //KEY
5858

59-
$columns = $this->columnsToArray($this->consume());
59+
$columns = [];
60+
$token = $this->consume();
61+
62+
while(!is_null($token)) {
63+
$columns = array_merge($columns, $this->columnsToArray($token));
64+
$token = $this->consume();
65+
if(strtoupper($token) === 'REFERENCES') {
66+
$this->putBack($token);
67+
break;
68+
}
69+
}
6070
$this->definition->setIndexColumns($columns);
6171

6272
$this->consume(); //REFERENCES
6373

6474
$referencedTable = $this->parseColumn($this->consume());
6575
$this->definition->setForeignReferencedTable($referencedTable);
6676

67-
$referencedColumns = $this->columnsToArray($this->consume());
77+
$referencedColumns = [];
78+
$token = $this->consume();
79+
while(!is_null($token)){
80+
$referencedColumns = array_merge($referencedColumns, $this->columnsToArray($token));
81+
$token = $this->consume();
82+
if(strtoupper($token) === 'ON'){
83+
$this->putBack($token);
84+
break;
85+
}
86+
}
87+
6888
$this->definition->setForeignReferencedColumns($referencedColumns);
6989

7090
$this->consumeConstraintActions();

tests/Unit/Tokenizers/MySQL/IndexTokenizerTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,19 @@ public function test_it_tokenizes_foreign_key_with_update_and_delete()
194194
$this->assertEquals('$table->foreign(\'user_id\', \'fk_bank_accounts_user_id\')->references(\'id\')->on(\'users\')->onUpdate(\'cascade\')->onDelete(\'cascade\')', $indexDefinition->render());
195195
}
196196

197+
public function test_it_tokenizes_foreign_key_with_multiple_columns(){
198+
$indexTokenizer = IndexTokenizer::parse('CONSTRAINT `table2_ibfk_1` FOREIGN KEY (`table2-foreign1`, `table2-foreign2`) REFERENCES `table1` (`table1-field1`, `table1-field2`) ON DELETE CASCADE ON UPDATE CASCADE');
199+
$definition = $indexTokenizer->definition();
200+
201+
$this->assertEquals('foreign', $definition->getIndexType());
202+
$this->assertTrue($definition->isMultiColumnIndex());
203+
$this->assertCount(2, $definition->getIndexColumns());
204+
$this->assertEquals('table1', $definition->getForeignReferencedTable());
205+
$this->assertSame(['table1-field1', 'table1-field2'], $definition->getForeignReferencedColumns());
206+
$this->assertSame(['table2-foreign1', 'table2-foreign2'], $definition->getIndexColumns());
207+
$this->assertEquals('$table->foreign([\'table2-foreign1\', \'table2-foreign2\'], \'table2_ibfk_1\')->references([\'table1-field1\', \'table1-field2\'])->on(\'table1\')->onDelete(\'cascade\')->onUpdate(\'cascade\')', $definition->render());
208+
}
209+
197210
public function test_it_tokenizes_foreign_key_with_update_restrict()
198211
{
199212
$indexTokenizer = IndexTokenizer::parse('CONSTRAINT `fk_bank_accounts_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON UPDATE NO ACTION');

0 commit comments

Comments
 (0)