@@ -89,7 +89,7 @@ public function createMigrationTable():void {
8989 $ this ->dbClient ->executeSql (implode ("\n" , [
9090 "create table if not exists ` {$ this ->tableName }` ( " ,
9191 "` " . self ::COLUMN_QUERY_NUMBER . "` int primary key, " ,
92- "` " . self ::COLUMN_QUERY_HASH . "` varchar(32) not null, " ,
92+ "` " . self ::COLUMN_QUERY_HASH . "` varchar(32) null, " ,
9393 "` " . self ::COLUMN_MIGRATED_AT . "` datetime not null ) " ,
9494 ]));
9595 }
@@ -144,26 +144,32 @@ public function checkFileListOrder(array $fileList):void {
144144 /** @param array<string> $migrationFileList */
145145 public function checkIntegrity (
146146 array $ migrationFileList ,
147- ?int $ migrationCount = null
147+ ?int $ migrationStartFrom = null
148148 ):int {
149149 $ fileNumber = 0 ;
150150
151151 foreach ($ migrationFileList as $ i => $ file ) {
152- $ fileNumber = $ i + 1 ;
152+ $ fileNumber = $ this -> extractNumberFromFilename ( $ file ) ;
153153 $ md5 = md5_file ($ file );
154154
155- if (is_null ($ migrationCount )
156- || $ fileNumber <= $ migrationCount ) {
155+ if ($ migrationStartFrom ) {
156+ if ($ fileNumber < $ migrationStartFrom ) {
157+ continue ;
158+ }
159+ }
160+
161+ if (is_null ($ migrationStartFrom )
162+ || $ fileNumber <= $ migrationStartFrom ) {
157163 $ result = $ this ->dbClient ->executeSql (implode ("\n" , [
158164 "select ` " . self ::COLUMN_QUERY_HASH . "` " ,
159165 "from ` {$ this ->tableName }` " ,
160166 "where ` " . self ::COLUMN_QUERY_NUMBER . "` = ? " ,
161167 "limit 1 " ,
162168 ]), [$ fileNumber ]);
163169
164- $ hashInDb = ($ result ->fetch ())->getString (self ::COLUMN_QUERY_HASH );
170+ $ hashInDb = ($ result ->fetch ())? ->getString(self ::COLUMN_QUERY_HASH );
165171
166- if ($ hashInDb !== $ md5 ) {
172+ if ($ hashInDb && $ hashInDb !== $ md5 ) {
167173 throw new MigrationIntegrityException ($ file );
168174 }
169175 }
@@ -172,7 +178,7 @@ public function checkIntegrity(
172178 return $ fileNumber ;
173179 }
174180
175- protected function extractNumberFromFilename (string $ pathName ):int {
181+ public function extractNumberFromFilename (string $ pathName ):int {
176182 $ file = new SplFileInfo ($ pathName );
177183 $ filename = $ file ->getFilename ();
178184 preg_match ("/(\d+)-?.*\.sql/ " , $ filename , $ matches );
@@ -187,15 +193,15 @@ protected function extractNumberFromFilename(string $pathName):int {
187193 /** @param array<string> $migrationFileList */
188194 public function performMigration (
189195 array $ migrationFileList ,
190- int $ existingMigrationCount = 0
196+ int $ existingFileNumber = 0
191197 ):int {
192198 $ fileNumber = 0 ;
193199 $ numCompleted = 0 ;
194200
195201 foreach ($ migrationFileList as $ i => $ file ) {
196- $ fileNumber = $ i + 1 ;
202+ $ fileNumber = $ this -> extractNumberFromFilename ( $ file ) ;
197203
198- if ($ fileNumber <= $ existingMigrationCount ) {
204+ if ($ fileNumber <= $ existingFileNumber ) {
199205 continue ;
200206 }
201207
@@ -277,7 +283,7 @@ public function selectSchema():void {
277283 }
278284 }
279285
280- protected function recordMigrationSuccess (int $ number , string $ hash ):void {
286+ protected function recordMigrationSuccess (int $ number , ? string $ hash ):void {
281287 $ now = "now() " ;
282288
283289 if ($ this ->driver === Settings::DRIVER_SQLITE ) {
@@ -295,6 +301,15 @@ protected function recordMigrationSuccess(int $number, string $hash):void {
295301 ]), [$ number , $ hash ]);
296302 }
297303
304+ /**
305+ * @param int $numberToForce A null-hashed migration will be marked as
306+ * successful with this number. This will allow the next number to be
307+ * executed out of sequence.
308+ */
309+ public function resetMigrationSequence (int $ numberToForce ):void {
310+ $ this ->recordMigrationSuccess ($ numberToForce , null );
311+ }
312+
298313 /**
299314 * @codeCoverageIgnore
300315 */
0 commit comments