public function migrateUp(MigrationConfig $config, $flushDatabase = false): Awaitable
    {
        return new Coroutine(function () use ($config, $flushDatabase) {
            $migrations = $this->instantiateMigrations($config);
            
            if (empty($migrations)) {
                $skip = false;
            } else {
                $skip = yield $this->platform->hasTable('#__kk_migration');
                
                if ($skip) {
                    $mtime = clone $this->date;
                    $params = [];
                    
                    foreach (\array_values($migrations) as $i => $migration) {
                        $params[] = $migration->getVersion();
                        $date = new \DateTime('@' . \filemtime((new \ReflectionClass(\get_class($migration)))->getFileName()));
                        
                        if ($date > $mtime) {
                            $mtime = $date;
                        }
                    }
                    
                    $sql = "SELECT COUNT(*) AS cnt, MAX(`migrated`) AS mtime FROM `#__kk_migration` WHERE `version` IN (";
                    $sql .= \implode(', ', \array_fill(0, \count($params), '?')) . ")";
                    
                    $stmt = $this->conn->prepare($sql);
                    $stmt->bindAll($params);
                    
                    try {
                        $result = yield $stmt->execute();
                        
                        // Only skip migrations if all of them are alreay migrated up.
                        try {
                            $row = yield $result->fetch();
                        } finally {
                            $result->closeCursor();
                        }
                    } finally {
                        $stmt->dispose();
                    }
                    
                    $dbcnt = (int) $row['cnt'];
                    $dbmtime = \DateTime::createFromFormat('YmdHis', $row['mtime']);
                    
                    $skip = (\count($params) === $dbcnt) && ($dbmtime > $mtime);
                }
            }
            
            if (!$skip) {
                if ($flushDatabase) {
                    yield $this->platform->flushDatabase();
                }
                
                foreach ($migrations as $migration) {
                    yield from $this->executeMigrationUp($migration);
                }
            }
            
            if ($skip && $flushDatabase) {
                yield $this->platform->flushData();
            }
        });
    }