diff --git a/migrator/executor.go b/migrator/executor.go new file mode 100644 index 0000000..de567e0 --- /dev/null +++ b/migrator/executor.go @@ -0,0 +1,49 @@ +package main + +import ( + "context" + "fmt" + "os" + "path" + + "github.com/jmoiron/sqlx" + "github.com/pkg/errors" +) + +func migrate(ctx context.Context, pathToMigrations string) error { + files, err := os.ReadDir(pathToMigrations) + if err != nil { + return errors.Wrapf(err, "read directory failed: %v", err) + } + + if err = checkVersion(ctx, ""); err != nil { + return err + } + + for _, file := range files { + if err = execute(ctx, path.Join(pathToMigrations, file.Name())); err != nil { + return errors.Wrapf(err, "migration for file %s failed: %v", file.Name(), err) + } + } + + return nil +} + +func execute(ctx context.Context, pathToFile string) error { + if pathToFile == "" { + return fmt.Errorf("empty path to sql file") + } + + conn, err := sqlx.Connect("postgres", "") + if err != nil { + return errors.Wrapf(err, "connect to database was failed: %v", err) + } + + defer conn.Close() + + if _, err = conn.ExecContext(ctx, ""); err != nil { + return errors.Wrapf(err, "exec migration script was failed: %v", err) + } + + return nil +} diff --git a/migrator/migrator.go b/migrator/migrator.go new file mode 100644 index 0000000..3c65457 --- /dev/null +++ b/migrator/migrator.go @@ -0,0 +1,16 @@ +package main + +import ( + "log" + + "golang.org/x/net/context" +) + +func main() { + ctx, cancel := context.WithTimeout(context.Background(), 3000) + defer cancel() + + if err := migrate(ctx, ""); err != nil { + log.Fatal(err) + } +} diff --git a/migrator/version.go b/migrator/version.go new file mode 100644 index 0000000..00f61a6 --- /dev/null +++ b/migrator/version.go @@ -0,0 +1,67 @@ +package main + +import ( + "context" + "fmt" + + "github.com/jmoiron/sqlx" + "github.com/pkg/errors" +) + +const ( + selectTableVersionIsExist = "SELECT 1 FROM information_schema.tables WHERE scheme = 'public' AND name = 'db_version'" + createTableVersion = "CREATE TABLE public.db_version (id SERIAL, name TEXT, created_at TIMESTAMP, processing_at TIMESTAMP, status TEXT)" +) + +func checkVersion(ctx context.Context, connectionString string) error { + conn, err := sqlx.Connect("postgres", connectionString) + if err != nil { + return errors.Wrapf(err, "connect to database failed: %v", err) + } + defer conn.Close() + + rows, err := conn.QueryContext(ctx, selectTableVersionIsExist) + if err != nil { + return errors.Wrapf(err, "check table version is exist failed: %v", err) + } + + if rows.Next() { + return nil + } + + if _, err = conn.ExecContext(ctx, createTableVersion); err != nil { + return errors.Wrapf(err, "create table version failed: %v", err) + } + + return nil +} + +const createStatusQuery = "" + +func createStatus(ctx context.Context, conn *sqlx.DB, name, status string) error { + if conn == nil { + return fmt.Errorf("") + } + + _, err := conn.ExecContext(ctx, createStatusQuery) + if err != nil { + return errors.Wrapf(err, "create status failed: %v", err) + } + + return nil +} + +const updateStatusQuery = "" + +func updateStatus(ctx context.Context, conn *sqlx.DB, status string) error { + if conn == nil { + return fmt.Errorf("") + } + + _, err := conn.ExecContext(ctx, updateStatusQuery, status) + if err != nil { + return errors.Wrapf(err, "update status failed: %v", err) + } + + return nil +}