@@ -1034,57 +1034,52 @@ protected function recreateIndicesAndTriggers(AlterInstructions $instructions):
10341034 * the given table, and of those tables whose constraints are
10351035 * targeting it.
10361036 *
1037- * @param \Phinx\Db\Util\AlterInstructions $instructions The instructions to process
1038- * @param string $tableName The name of the table for which to check constraints.
1037+ * @param string|array<string> $tableName The name of the table for which to check constraints.
10391038 * @return \Phinx\Db\Util\AlterInstructions
10401039 */
1041- protected function validateForeignKeys (AlterInstructions $ instructions , string $ tableName ): AlterInstructions
1040+ protected function validateForeignKeys (string | array $ tableNames ): void
10421041 {
1043- $ instructions ->addPostStep (function ($ state ) use ($ tableName ) {
1044- $ tablesToCheck = [
1045- $ tableName ,
1046- ];
1047-
1048- $ otherTables = $ this
1049- ->query (
1050- "SELECT name FROM sqlite_master WHERE type = 'table' AND name != ? " ,
1051- [$ tableName ],
1052- )
1053- ->fetchAll ();
1054-
1055- foreach ($ otherTables as $ otherTable ) {
1056- $ foreignKeyList = $ this ->getTableInfo ($ otherTable ['name ' ], 'foreign_key_list ' );
1057- foreach ($ foreignKeyList as $ foreignKey ) {
1058- if (strcasecmp ($ foreignKey ['table ' ], $ tableName ) === 0 ) {
1059- $ tablesToCheck [] = $ otherTable ['name ' ];
1060- break ;
1061- }
1062- }
1063- }
1064-
1065- $ tablesToCheck = array_unique (array_map ('strtolower ' , $ tablesToCheck ));
1042+ if (!is_array ($ tableNames )) {
1043+ $ tableNames = [$ tableNames ];
1044+ }
10661045
1067- foreach ($ tablesToCheck as $ tableToCheck ) {
1068- $ schema = $ this ->getSchemaName ($ tableToCheck , true )['schema ' ];
1046+ $ tablesToCheck = $ tableNames ;
10691047
1070- $ stmt = $ this ->query (
1071- sprintf ('PRAGMA %sforeign_key_check(%s) ' , $ schema , $ this ->quoteTableName ($ tableToCheck )),
1072- );
1073- $ row = $ stmt ->fetch ();
1074- $ stmt ->closeCursor ();
1048+ $ otherTables = $ this
1049+ ->query (
1050+ "SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT IN ( " . implode (', ' ,array_fill (0 , count ($ tableNames ), '? ' )) . ') ' ,
1051+ $ tableNames
1052+ )
1053+ ->fetchAll ();
10751054
1076- if (is_array ($ row )) {
1077- throw new RuntimeException (sprintf (
1078- 'Integrity constraint violation: FOREIGN KEY constraint on `%s` failed. ' ,
1079- $ tableToCheck ,
1080- ));
1055+ foreach ($ otherTables as $ otherTable ) {
1056+ $ foreignKeyList = $ this ->getTableInfo ($ otherTable ['name ' ], 'foreign_key_list ' );
1057+ foreach ($ foreignKeyList as $ foreignKey ) {
1058+ if (in_array (strtolower ($ foreignKey ['table ' ]), $ tableNames )) {
1059+ $ tablesToCheck [] = $ otherTable ['name ' ];
1060+ break ;
10811061 }
10821062 }
1063+ }
10831064
1084- return $ state ;
1085- });
1065+ $ tablesToCheck = array_unique (array_map ('strtolower ' , $ tablesToCheck ));
10861066
1087- return $ instructions ;
1067+ foreach ($ tablesToCheck as $ tableToCheck ) {
1068+ $ schema = $ this ->getSchemaName ($ tableToCheck , true )['schema ' ];
1069+
1070+ $ stmt = $ this ->query (
1071+ sprintf ('PRAGMA %sforeign_key_check(%s) ' , $ schema , $ this ->quoteTableName ($ tableToCheck )),
1072+ );
1073+ $ row = $ stmt ->fetch ();
1074+ $ stmt ->closeCursor ();
1075+
1076+ if (is_array ($ row )) {
1077+ throw new RuntimeException (sprintf (
1078+ 'Integrity constraint violation: FOREIGN KEY constraint on `%s` failed. ' ,
1079+ $ tableToCheck ,
1080+ ));
1081+ }
1082+ }
10881083 }
10891084
10901085 /**
@@ -1239,7 +1234,6 @@ protected function endAlterByCopyTable(
12391234 string $ tableName ,
12401235 ?string $ renamedOrRemovedColumnName = null ,
12411236 ?string $ newColumnName = null ,
1242- bool $ validateForeignKeys = true ,
12431237 ): AlterInstructions {
12441238 $ instructions = $ this ->bufferIndicesAndTriggers ($ instructions , $ tableName );
12451239
@@ -1251,26 +1245,9 @@ protected function endAlterByCopyTable(
12511245 }
12521246 }
12531247
1254- $ foreignKeysEnabled = (bool )$ this ->fetchRow ('PRAGMA foreign_keys ' )['foreign_keys ' ];
1255-
1256- if ($ foreignKeysEnabled ) {
1257- $ instructions ->addPostStep ('PRAGMA foreign_keys = OFF ' );
1258- }
1259-
12601248 $ instructions = $ this ->copyAndDropTmpTable ($ instructions , $ tableName );
12611249 $ instructions = $ this ->recreateIndicesAndTriggers ($ instructions );
12621250
1263- if ($ foreignKeysEnabled ) {
1264- $ instructions ->addPostStep ('PRAGMA foreign_keys = ON ' );
1265- }
1266-
1267- if (
1268- $ foreignKeysEnabled &&
1269- $ validateForeignKeys
1270- ) {
1271- $ instructions = $ this ->validateForeignKeys ($ instructions , $ tableName );
1272- }
1273-
12741251 return $ instructions ;
12751252 }
12761253
@@ -1661,7 +1638,7 @@ protected function getDropPrimaryKeyInstructions(Table $table, string $column):
16611638 return $ newState + $ state ;
16621639 });
16631640
1664- return $ this ->endAlterByCopyTable ($ instructions , $ tableName , null , null , false );
1641+ return $ this ->endAlterByCopyTable ($ instructions , $ tableName , null , null );
16651642 }
16661643
16671644 /**
@@ -2013,4 +1990,31 @@ public function getDecoratedConnection(): Connection
20131990
20141991 return $ this ->decoratedConnection = $ this ->buildConnection (SqliteDriver::class, $ options );
20151992 }
1993+
1994+ /**
1995+ * {@inheritDoc}
1996+ */
1997+ public function preExecuteActions (): array
1998+ {
1999+ $ foreignKeysEnabled = (bool )$ this ->fetchRow ('PRAGMA foreign_keys ' )['foreign_keys ' ];
2000+
2001+ if ($ foreignKeysEnabled ) {
2002+ $ this ->execute ('PRAGMA foreign_keys = OFF ' );
2003+ }
2004+
2005+ return [
2006+ 'foreignKeysEnabled ' => $ foreignKeysEnabled ,
2007+ ];
2008+ }
2009+
2010+ /**
2011+ * {@inheritDoc}
2012+ */
2013+ public function postExecuteActions (array $ tableNames , array $ preOptions ): void
2014+ {
2015+ if ($ preOptions ['foreignKeysEnabled ' ]) {
2016+ $ this ->execute ('PRAGMA foreign_keys = ON ' );
2017+ $ this ->validateForeignKeys ($ tableNames );
2018+ }
2019+ }
20162020}
0 commit comments