Repository: pocketbase/pocketbase
File: tools/migrate/runner.go (Go)

Code before:

	err := r.db.Transactional(func(tx *dbx.Tx) error {
		totalReverted := 0

		for i := len(r.migrationsList.Items()) - 1; i >= 0; i-- {
			m := r.migrationsList.Item(i)

			// skip unapplied
			if !r.isMigrationApplied(tx, m.file) {
				continue
			}

			// revert limit reached
			if toRevertCount-totalReverted <= 0 {
				break
			}

			if err := m.down(tx); err != nil {
				return fmt.Errorf("Failed to revert migration %s: %w", m.file, err)
			}

			if err := r.saveRevertedMigration(tx, m.file); err != nil {
				return fmt.Errorf("Failed to save reverted migration info for %s: %w", m.file, err)
			}

			totalReverted++
			applied = append(applied, m.file)
		}

		return nil
	})

	if err != nil {
		return nil, err
	}
	return applied, nil
}

func (r *Runner) createMigrationsTable() error {
	rawQuery := fmt.Sprintf(
		"CREATE TABLE IF NOT EXISTS %v (file VARCHAR(255) PRIMARY KEY NOT NULL, applied INTEGER NOT NULL)",
		r.db.QuoteTableName(r.tableName),
	)

	_, err := r.db.NewQuery(rawQuery).Execute()

	return err
}

func (r *Runner) isMigrationApplied(tx dbx.Builder, file string) bool {
	var exists bool

Review comment (bug):
Let's remove this counter. It'll be better to rename the `applied` variable and change it declaration to `reverted := make([]string, 0, toRevertCount)` and use the `len(reverted)` instead. Or in other words, the function should look simething like this:
```go
func (r *Runner) Down(toRevertCount int) ([]string, error) {
	reverted := make([]string, 0, toRevertCount)

	err := r.db.Transactional(func(tx *dbx.Tx) error {
		for i := len(r.migrationsList.Items()) - 1; i >= 0; i-- {
			m := r.migrationsList.Item(i)

			// skip unapplied
			if !r.isMigrationApplied(tx, m.file) {
				continue
			}

			// revert limit reached
			if toRevertCount-len(reverted) <= 0 {
				break
			}

			if err := m.down(tx); err != nil {
				return fmt.Errorf("Failed to revert migration %s: %w", m.file, err)
			}

			if err := r.saveRevertedMigration(tx, m.file); err != nil {
				return fmt.Errorf("Failed to save reverted migration info for %s: %w", m.file, err)
			}

			reverted = append(reverted, m.file)
		}

		return nil
	})

	if err != nil {
		return nil, err
	}
	return reverted, nil
}
```



Code after:

	err := r.db.Transactional(func(tx *dbx.Tx) error {
		for i := len(r.migrationsList.Items()) - 1; i >= 0; i-- {
			m := r.migrationsList.Item(i)

			// skip unapplied
			if !r.isMigrationApplied(tx, m.file) {
				continue
			}

			// revert limit reached
			if toRevertCount-len(reverted) <= 0 {
				break
			}

			if err := m.down(tx); err != nil {
				return fmt.Errorf("Failed to revert migration %s: %w", m.file, err)
			}

			if err := r.saveRevertedMigration(tx, m.file); err != nil {
				return fmt.Errorf("Failed to save reverted migration info for %s: %w", m.file, err)
			}

			reverted = append(reverted, m.file)
		}

		return nil
	})

	if err != nil {
		return nil, err
	}
	return reverted, nil
}

func (r *Runner) createMigrationsTable() error {
	rawQuery := fmt.Sprintf(
		"CREATE TABLE IF NOT EXISTS %v (file VARCHAR(255) PRIMARY KEY NOT NULL, applied INTEGER NOT NULL)",
		r.db.QuoteTableName(r.tableName),
	)

	_, err := r.db.NewQuery(rawQuery).Execute()

	return err
}

func (r *Runner) isMigrationApplied(tx dbx.Builder, file string) bool {
	var exists bool

	err := tx.Select("count(*)").
		From(r.tableName).