Skip to content

Commit

Permalink
Merge pull request #15 from stellarwp/feat/has-foreign-key
Browse files Browse the repository at this point in the history
Add Table::has_foreign_key method
  • Loading branch information
lucatume authored Apr 4, 2023
2 parents 35d4054 + 79fb5c0 commit 018ad9d
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 19 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ All notable changes to this project will be documented in this file. This projec

## [unreleased] Unreleased

## [1.1.2] 2022-11-22
* Feature - Added `Table::has_foreign_key()` method.

## [1.1.2] 2022-11-2

* Tweak - Set the composer's `config.platform.php` to `7.0`.

Expand Down
34 changes: 26 additions & 8 deletions docs/schemas-field.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,17 +147,35 @@ public function after_update() {
$table_name = static::table_name( true );
$updated = false;

if ( $this->exists() && $this->has_index( 'boom' ) ) {
$udpated = $wpdb->query( "ALTER TABLE `{$table_name}` ADD UNIQUE( `name` )" );
}
// Add a UNIQUE constraint on the name column.
if ( $this->exists() && ! $this->has_index( 'boom' ) ) {
$updated = $wpdb->query( "ALTER TABLE `{$table_name}` ADD UNIQUE( `name` )" );

if ( $updated ) {
$message = "Added UNIQUE constraint to the {$table_name} table on name.";
} else {
$message = "Failed to add a unique constraint on the {$table_name} table.";
}

if ( $updated ) {
$message = "Added UNIQUE constraint to the {$table_name} table on name.";
} else {
$message = "Failed to add a unique constraint on the {$table_name} table.";
$results[ $table_name . '.name' ] = $message;
}

$results[ $table_name . '.name' ] = $message;
// Add a FOREIGN KEY constraint on the reseller_id column.
if ( $this->exists() && ! $this->has_foreign_key( 'reseller_id' ) ) {
$referenced_table = $wpdb->prefix . 'resellers';
$updated = $wpdb->query( "ALTER TABLE `{$table_name}`
ADD FOREIGN KEY ( `reseller_id` )
REFERENCES `$referenced_table` ( `id` )"
);

if ( $updated ) {
$message = "Added FOREIGN KEY constraint to the {$table_name} table on reseller_id.";
} else {
$message = "Failed to add a FOREIGN KEY constraint on the {$table_name} table.";
}

$results[ $table_name . '.reseller_id' ] = $message;
}

return $results;
}
Expand Down
34 changes: 26 additions & 8 deletions docs/schemas-table.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,17 +162,35 @@ public function after_update() {
$table_name = static::table_name( true );
$updated = false;

if ( $this->exists() && $this->has_index( 'boom' ) ) {
$udpated = $wpdb->query( "ALTER TABLE `{$table_name}` ADD UNIQUE( `name` )" );
}
// Add a UNIQUE constraint on the name column.
if ( $this->exists() && ! $this->has_index( 'boom' ) ) {
$updated = $wpdb->query( "ALTER TABLE `{$table_name}` ADD UNIQUE( `name` )" );

if ( $updated ) {
$message = "Added UNIQUE constraint to the {$table_name} table on name.";
} else {
$message = "Failed to add a unique constraint on the {$table_name} table.";
}

if ( $updated ) {
$message = "Added UNIQUE constraint to the {$table_name} table on name.";
} else {
$message = "Failed to add a unique constraint on the {$table_name} table.";
$results[ $table_name . '.name' ] = $message;
}

$results[ $table_name . '.name' ] = $message;
// Add a FOREIGN KEY constraint on the reseller_id column.
if ( $this->exists() && ! $this->has_foreign_key( 'reseller_id' ) ) {
$referenced_table = $wpdb->prefix . 'resellers';
$updated = $wpdb->query( "ALTER TABLE `{$table_name}`
ADD FOREIGN KEY ( `reseller_id` )
REFERENCES `$referenced_table` ( `id` )"
);

if ( $updated ) {
$message = "Added FOREIGN KEY constraint to the {$table_name} table on reseller_id.";
} else {
$message = "Failed to add a FOREIGN KEY constraint on the {$table_name} table.";
}

$results[ $table_name . '.reseller_id' ] = $message;
}

return $results;
}
Expand Down
22 changes: 22 additions & 0 deletions src/Schema/Tables/Contracts/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -531,4 +531,26 @@ public function update() {

return $results;
}

/**
* Checks if a foreign key exists on a table.
*
* @since TBD
*
* @param string $foreign_key The foreign key to check for.
* @param string|null $table_name The table name to check. Defaults to the current table.
*
* @return bool Whether the foreign key exists on the table.
*/
public function has_foreign_key( string $foreign_key, string $table_name = null ): bool {
$table_name = $table_name ?: static::table_name();

$count = $this->db::table( $this->db::raw( 'information_schema.statistics' ) )
->whereRaw( 'WHERE TABLE_SCHEMA = DATABASE()' )
->where( 'TABLE_NAME', $table_name )
->where( 'INDEX_NAME', $foreign_key )
->count();

return $count >= 1;
}
}
46 changes: 46 additions & 0 deletions tests/_support/Traits/Table_Fixtures.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,50 @@ protected function get_definition() {

return $field;
}

public function get_foreign_key_table() {
$table = new class extends Table {
const SCHEMA_VERSION = '1.0.0';

protected static $base_table_name = 'foreignkey';
protected static $group = 'bork';
protected static $schema_slug = 'bork-with-foreignkey';
protected static $uid_column = 'id';

protected function get_definition() {
global $wpdb;
$table_name = self::table_name( true );
$charset_collate = $wpdb->get_charset_collate();

return "
CREATE TABLE `{$table_name}` (
`id` int(11) UNSIGNED NOT NULL,
`name` varchar(25) NOT NULL,
`simple_id` int(11) UNSIGNED NOT NULL
) {$charset_collate};
";
}

protected function after_update( array $results ) {
if ( $this->has_foreign_key( 'simple_id' ) ) {
return $results;
}

global $wpdb;
$table_name = $this->table_name();
$simple_table = $wpdb->prefix . 'simple';
$updated = $wpdb->query( "ALTER TABLE $table_name ADD FOREIGN KEY (simple_id) REFERENCES $simple_table(id)" );

$result = $updated ?
'FOREIGN KEY added to ' . $table_name . ' on column simple_id to table ' . $simple_table . ' on column id' :
'Failed to add FOREIGN KEY NOT to ' . $table_name . ' on column simple_id to table ' . $simple_table . ' on column id';

$results[] = $result;

return $results;
}
};

return $table;
}
}
46 changes: 44 additions & 2 deletions tests/wpunit/Tables/TableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@
class TableTest extends SchemaTestCase {
use Table_Fixtures;

/**
* @before
*/
public function drop_tables() {
$this->get_simple_table()->drop();
$this->get_foreign_key_table()->drop();
}

/**
* Should have index.
*
* @test
*/
public function should_have_index() {
$table = $this->get_simple_table();
$table = $this->get_simple_table();

Register::table( $table );

Expand All @@ -28,11 +36,45 @@ public function should_have_index() {
* @test
*/
public function should_have_fake_index() {
$table = $this->get_simple_table();
$table = $this->get_simple_table();

Register::table( $table );

$this->assertFalse( $table->has_index( 'bork' ) );
}

/**
* It should not have foreign key
*
* @test
*/
public function should_not_have_foreign_key() {
$simple_table = $this->get_simple_table();
$foreign_key_table = $this->get_foreign_key_table();

Register::table( $simple_table );
Register::table( $foreign_key_table );

$this->assertFalse( $simple_table->has_foreign_key( 'simple_id' ) );
$this->assertFalse( $foreign_key_table->has_foreign_key( 'not_really' ) );
}

/**
* It should have foreign key
*
* @test
*/
public function should_have_foreign_key() {
$simple_table = $this->get_simple_table();
$foreign_key_table = $this->get_foreign_key_table();

Register::table( $simple_table );
Register::table( $foreign_key_table );

$this->assertFalse( $simple_table->has_foreign_key( 'simple_id' ) );
$this->assertFalse( $foreign_key_table->has_foreign_key( 'not_really' ) );

$this->assertTrue( $foreign_key_table->has_foreign_key( 'simple_id' ) );
}
}

0 comments on commit 018ad9d

Please sign in to comment.