<commit_before>package migration

import (
	"fmt"
	"log"
	"path"
	"regexp"
	"strings"

	"github.com/nicday/turtle/config"
	"github.com/nicday/turtle/db"
)

var (
	upMigrationRegex   = regexp.MustCompile(`(\d+)_([\w-]+)_up\.sql`)
	downMigrationRegex = regexp.MustCompile(`(\d+)_([\w-]+)_down\.sql`)
	migrationIDRegex   = regexp.MustCompile(`(\d+)_([\w-]+)`)
)

// Migration is a SQL migration
type Migration struct {
	ID       string
	UpPath   string
	DownPath string

	active bool
}

// AddPath adds or updates a path for a migration direction.
func (m *Migration) AddPath(path string) {
	if direction(path) == "up" {
		m.UpPath = path
	} else {
		m.DownPath = path
	}
}

// Apply runs the up migration on the database.
func (m Migration) Apply() error {
	// Return early if the migration is already active
	active, err := db.MigrationActive(m.ID)
	if err != nil {
		return err
	}
	if active {
		return nil
	}

	sql, err := FS.ReadFile(m.UpPath)
	if err != nil {
		return err
	}

	tx, err := db.Conn.Begin()
	if err != nil {
		return err
	}

	_, err = tx.Exec(string(sql))
	if err != nil {
		log.Printf("[Error] Unable to apply migration (%s): %v", m.ID, err)
		if err := tx.Rollback(); err != nil {
			log.Printf("[Error] Unable to roll back transaction: %v", err)
			return err
		}
		return err
	}

	err = tx.Commit()
	if err != nil {
		log.Printf("[Error] Unable to commit transaction: %v", err)
		return err
	}

	// Update the migration log
	err = db.InsertMigration(m.ID)
	if err != nil {
		return err
	}

	fmt.Printf("Migration(%s) applied\n", m.ID)

	return nil
}

// Revert runs the down migration on the database.
func (m Migration) Revert() error {
	// Return early if the migration isn't active
	active, err := db.MigrationActive(m.ID)
	if err != nil {
		return err
	}
	if active == false {
		return nil
	}

	sql, err := FS.ReadFile(m.DownPath)
	if err != nil {
		return err
	}

	tx, err := db.Conn.Begin()
	if err != nil {
		return err
	}

	_, err = tx.Exec(string(sql))
	if err != nil {
		log.Printf("[Error] Unable to revert migration (%s): %v", m.ID, err)
		if err := tx.Rollback(); err != nil {
			log.Printf("[Error] Unable to roll back transaction: %v", err)
			return err
		}
		return err
	}

	err = tx.Commit()
	if err != nil {
		log.Printf("[Error] Unable to commit transaction: %v", err)
		return err
	}

	// Update the migration log
	err = db.DeleteMigration(m.ID)
	if err != nil {
		return err
	}

	fmt.Printf("Migration (%s) reverted\n", m.ID)

	return nil
}

// ApplyAll applies all migrations in chronological order.
func ApplyAll() error {
	err := assertMigrationTable()
	if err != nil {
		return err
	}

	migrations, err := all()
	if err != nil {
		return err
	}

	ordered := SortMigrations(migrations, "asc")

	for _, m := range ordered {
		err = m.Apply()
		if err != nil {
			return err
		}
	}

	return nil
}

// RevertAll reverts all migrations in reverse chronological order.
func RevertAll() error {
	err := assertMigrationTable()
	if err != nil {
		return err
	}

	migrations, err := all()
	if err != nil {
		return err
	}

	ordered := SortMigrations(migrations, "desc")

	for _, m := range ordered {
		err = m.Revert()
		if err != nil {
			return err
		}
	}

	return nil
}<commit_msg>Revert return true on completion<commit_after>package migration

import (
	"fmt"
	"log"
	"path"
	"regexp"
	"strings"

	"github.com/nicday/turtle/config"
	"github.com/nicday/turtle/db"
)

var (
	upMigrationRegex   = regexp.MustCompile(`(\d+)_([\w-]+)_up\.sql`)
	downMigrationRegex = regexp.MustCompile(`(\d+)_([\w-]+)_down\.sql`)
	migrationIDRegex   = regexp.MustCompile(`(\d+)_([\w-]+)`)
)

// Migration is a SQL migration
type Migration struct {
	ID       string
	UpPath   string
	DownPath string

	active bool
}

// AddPath adds or updates a path for a migration direction.
func (m *Migration) AddPath(path string) {
	if direction(path) == "up" {
		m.UpPath = path
	} else {
		m.DownPath = path
	}
}

// Apply runs the up migration on the database.
func (m Migration) Apply() error {
	// Return early if the migration is already active
	active, err := db.MigrationActive(m.ID)
	if err != nil {
		return err
	}
	if active {
		return nil
	}

	sql, err := FS.ReadFile(m.UpPath)
	if err != nil {
		return err
	}

	tx, err := db.Conn.Begin()
	if err != nil {
		return err
	}

	_, err = tx.Exec(string(sql))
	if err != nil {
		log.Printf("[Error] Unable to apply migration (%s): %v", m.ID, err)
		if err := tx.Rollback(); err != nil {
			log.Printf("[Error] Unable to roll back transaction: %v", err)
			return err
		}
		return err
	}

	err = tx.Commit()
	if err != nil {
		log.Printf("[Error] Unable to commit transaction: %v", err)
		return err
	}

	// Update the migration log
	err = db.InsertMigration(m.ID)
	if err != nil {
		return err
	}

	fmt.Printf("Migration(%s) applied\n", m.ID)

	return nil
}

// Revert runs the down migration on the database. True will be returned if the migration was completed.
func (m Migration) Revert() (bool, error) {
	// Return early if the migration isn't active
	active, err := db.MigrationActive(m.ID)
	if err != nil {
		return false, err
	}
	if active == false {
		return false, nil
	}

	sql, err := FS.ReadFile(m.DownPath)
	if err != nil {
		return false, err
	}

	tx, err := db.Conn.Begin()
	if err != nil {
		return false, err
	}

	_, err = tx.Exec(string(sql))
	if err != nil {
		log.Printf("[Error] Unable to revert migration (%s): %v", m.ID, err)
		if err := tx.Rollback(); err != nil {
			log.Printf("[Error] Unable to roll back transaction: %v", err)
			return false, err
		}
		return false, err
	}

	err = tx.Commit()
	if err != nil {
		log.Printf("[Error] Unable to commit transaction: %v", err)
		return false, err
	}

	// Update the migration log
	err = db.DeleteMigration(m.ID)
	if err != nil {
		return false, err
	}

	fmt.Printf("Migration (%s) reverted\n", m.ID)

	return true, nil
}

// ApplyAll applies all migrations in chronological order.
func ApplyAll() error {
	err := assertMigrationTable()
	if err != nil {
		return err
	}

	migrations, err := all()
	if err != nil {
		return err
	}

	ordered := SortMigrations(migrations, "asc")

	for _, m := range ordered {
		err = m.Apply()
		if err != nil {
			return err
		}
	}

	return nil
}

// RevertAll reverts all migrations in reverse chronological order.
func RevertAll() error {
	err := assertMigrationTable()
	if err != nil {
		return err
	}

	migrations, err := all()
	if err != nil {
		return err
	}

	ordered := SortMigrations(migrations, "desc")

	for _, m := range ordered {
		_, err := m.Revert()
		if err != nil {
			return err
		}
	}

	return nil
}
{'fraction_non_alphanumeric': 0.14402792533009562, 'fraction_numerical': 0.0, 'mean_word_length': 3.072929542645241, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1643160', 'n_tokens_mistral': 2516, 'n_tokens_neox': 2406, 'n_words': 743}