https://github.com/gsamokovarov/gloat
Next-gen database migrations framework for Go.
https://github.com/gsamokovarov/gloat
golang migrations sql
Last synced: about 1 year ago
JSON representation
Next-gen database migrations framework for Go.
- Host: GitHub
- URL: https://github.com/gsamokovarov/gloat
- Owner: gsamokovarov
- License: mit
- Created: 2017-04-10T19:04:56.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2018-09-21T08:54:39.000Z (over 7 years ago)
- Last Synced: 2025-03-31T04:11:12.498Z (about 1 year ago)
- Topics: golang, migrations, sql
- Language: Go
- Homepage:
- Size: 70.3 KB
- Stars: 14
- Watchers: 2
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Gloat /ɡlōt/
> Contemplate or dwell on one's own success or another's misfortune with
> smugness or malignant pleasure.
Gloat is a modular SQL migration library for the Go programming language. Being
a library, gloat can be easily integrated into your application or ORM.
## Library
If you are using gloat as a library, the main components you'll be dealing with
are migration, source, store and SQL executor. You'll be using those through the
methods on the `Gloat` struct.
```go
db, err := sql.Open("postgres", "connection string")
if err != nil {
// Handle the *sql.DB creation error.
}
gl := gloat.Gloat{
Store: gloat.NewPostgreSQLStore(db),
Source: gloat.NewFileSystemSource("migrations"),
Executor: gloat.NewSQLExecutor(db),
}
```
### Migration
Migration holds all the relevant information for a migration. The content of
the forward (up) side of a migration, the backward (down) side, a path and
version. The version is used to determine the order of which the migrations
would be executed. The path is the name in a store.
```go
type Migration struct {
UpSQL []byte
DownSQL []byte
Path string
Version int64
}
```
### Source
The `Source` interface represents a source of migration. The most common source
is the file system.
```go
type Source interface {
Collect() (Migrations, error)
}
```
`gloat.NewFileSystemSource` is a constructor function that creates a source
that collects migrations from a folder with the following structure:
```
migrations/
└── 20170329154959_introduce_domain_model
├── down.sql
└── up.sql
```
In the example above `migrations` is a folder that stores all of the
migrations. A migrations itself is a folder with a name in the form of
`:timestamp_:name` containing `up.sql` and `down.sql` files.
The `up.sql` file contains the SQL that's executed when a migration is applied:
```sql
CREATE TABLE users (
id bigserial PRIMARY KEY NOT NULL,
name character varying NOT NULL,
email character varying NOT NULL,
created_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL
);
```
While `down.sql` is executed when a migration is reverted:
```sql
DROP TABLE users;
```
If the `down.sql` file is not present, we say that a migration is irreversible.
## Store
The Store is an interface representing a place where the applied migrations are
recorded. The common thing is to store the migrations in a database table. The
`gloat.DatabaseStore` does just that. The `gloat.NewPostgreSQLStore` constructor
function creates such store that records the migration in a table called
`schema_migrations`. The table is automatically created if it does not exist.
```go
type Store interface {
Source
Insert(*Migration, StoreExecer) error
Remove(*Migration, StoreExecer) error
}
```
The `Store.Insert` records the migration version in to the `schema_migrations`
table, while `Store.Remove` deletes the column with the version from
the table. There are the following builtin store constructors:
```go
// NewPostgreSQLStore creates a Store for PostgreSQL.
func NewPostgreSQLStore(db *sql.DB) Store {}
// NewMySQLStore creates a Store for MySQL.
func NewMySQLStore(db *sql.DB) Store {}
// NewSQLite3Store creates a Store for SQLite3.
func NewSQLite3Store(db *sql.DB) Store {}
```
### Executor
The `Executor` interface, well, it executes the migrations. For SQL migrations,
there is the `gloat.SQLExecutor` implementation. It's an interface,
nevertheless, so you can fake it out during testing.
```go
type Executor interface {
Up(*Migration, Store) error
Down(*Migration, Store) error
}
```
The executor executes the migration `UpSQL` or `DownSQL` sections.
### Gloat
A `Gloat` binds a migration `Source`, `Store` and `Executor` into one thing, so
it's easier to `Apply`, and `Revert` migrations.
```go
gl := gloat.Gloat{
Store: gloat.NewPostgreSQLStore(db),
Source: gloat.NewFileSystemSource("migrations"),
Executor: gloat.NewSQLExecutor(db),
}
// Applies all of the unapplied migrations.
if migrations, err := gl.Unapplied(); err == nil {
for _, migration := range migrations {
gl.Apply(migration)
}
}
// Revert the last applied migration.
if migration, err := gl.Current(); err == nil {
gl.Revert(migration)
}
```
Here is a description for the main Gloat methods.
```go
// Unapplied returns the unapplied migrations in the current gloat.
func (c *Gloat) Unapplied() (Migrations, error) {}
// Current returns the latest applied migration. Even if no error is returned,
// the current migration can be nil.
//
// This is the case when the last applied migration is no longer available from
// the source or there are no migrations to begin with.
func (c *Gloat) Current() (*Migration, error) {}
// Apply applies a migration.
func (c *Gloat) Apply(migration *Migration) error {}
// Revert rollbacks a migration.
func (c *Gloat) Revert(migration *Migration) error {}
```