README

Gondolier

GoDoc CircleCI Go Report Card

Description

Gondolier is a library to auto migrate database schemas in Go (golang) using structs. Quick demo:

type Customer struct {
    Id   uint64 `gondolier:"type:bigint;id"`
    Name string `gondolier:"type:varchar(255);notnull"`
    Age  int    `gondolier:"type:integer;notnull"`
}

type Order struct {
    Id    uint64 `gondolier:"type:bigint;id"`
    Buyer uint64 `gondolier:"type:bigint;fk:customer.id;notnull"`
}

type OrderPosition struct {
    Id       uint64 `gondolier:"type:bigint;id"`
    Order    uint64 `gondolier:"type:bigint;fk:order.id;notnull"`
    Quantity int    `gondolier:"type:integer;notnull"`
    Cost     int    `gondolier:"type:integer;notnull"`
}

type Obsolete struct{}

func main() {
    // connect to database
    db, _ := sql.Open("postgres", dbString())
    defer db.Close()

    // migrate your schema
    gondolier.Use(db, &gondolier.Postgres{Schema: "public",
        DropColumns: true,
        Log:         true})
    gondolier.Model(Customer{}, Order{}, OrderPosition{})
    gondolier.Drop(Obsolete{})
    gondolier.Migrate()
}

View the full demo

Features
  • create and update your database schema just from your data model defined in Go
  • drop columns when they're no longer needed (removed in struct)
  • drop tables by passing a struct (which can be empty)
Supported databases
  • Postgres
Limits
  • no multi primary key support yet
  • there is no way Gondolier can check if the data model is valid, so it might fail to execute the migration (with a panic)

Installation

To install Gondolier, go get all dependencies and Gondolier:

go get github.com/lib/pq # for Postgres
go get github.com/emvi/gondolier

Usage

Gondolier consists only out of a few methods. First, you set up Gondolier by passing the database connection and the migrator to Use:

gondolier.Use(dbconn, migrator)

The migrator is an interface which is used by Gondolier to migrate the data model. Example:

gondolier.Postgres{Schema: "public", DropColums: true, Log: true}

This will configure the Postgres migrator to use the schema "public", drop columns when the field is missing in the data model and output executed SQL statements to log (using the standard log library).

Now you can define a naming schema used to name tables and columns:

gondolier.Naming(&gondolier.SnakeCase{})

You can define your own naming schema by implementing the NameSchema interface. Currently SnakeCase is the default. You don't need to call Naming to set it.

Now call Model and pass the models which define your database schema:

gondolier.Model(MyModel{}, &AnotherModel{})

Model accepts objects and pointers. The models must define a decorator with meta information. For more details take a look at the Postgres Migrator or the example implementation. Here is a short example:

type MyModel struct {
    Id       uint64 `gondolier:"type:bigint;id"` // id is a shortcut
    SomeAttr string `gondolier:"type:text;notnull"`
}

type AnotherModel struct {
    Id         uint64   `gondolier:"type:bigint;pk;seq:1,1,-,-,1;default:nextval(seq);notnull"` // long version for "id"
    UniqueAttr int      `gondolier:"type:integer;notnull;unique;default:42"`
    AnArray    []string `gondolier:"type:varchar(100)[]"`
    ForeignKey uint64   `gondolier:"type:bigint;fk:MyModel.Id;notnull"`
}

Afterwards, call Migrate to start the migration:

gondolier.Migrate()

To drop a table that is no longer needed, call Drop. You can remove all attributes from the struct, only the name must match the old struct:

type DropMe struct {}
gondolier.Drop(DropMe{})

Contribute

See CONTRIBUTING.md

License

MIT

Documentation

Overview

    Package gondolier is a library to auto migrate database schemas for Go using structs.

    Quick example:

    TODO
    

    Index

    Constants

    This section is empty.

    Variables

    This section is empty.

    Functions

    func Drop

    func Drop(models ...interface{})

      Drop drops tables for given objects if they exist. The database connection and migrator must be set before by calling Use(). The objects can be passed as references, values or mixed. This function might panic if an invalid model is used or the tables cannot be dropped.

      Example:

      Drop(&MyModel{}, AnotherModel{})
      

      func Migrate

      func Migrate()

        Migrate migrates models added previously using Model(). The database connection and migrator must be set before by calling Use().

        Example:

        Use(Postgres)
        Model(MyModel{}, AnotherModel{})
        Migrate()
        

        func Model

        func Model(models ...interface{})

          Model adds one or more objects for migration. The objects can be passed as references, values or mixed. This function might panic if an invalid model is used.

          Example:

          Model(&MyModel{}, AnotherModel{})
          

          func Naming

          func Naming(schema NameSchema)

            Naming sets the naming pattern used for migration. Default is snake case.

            Example:

            Naming(SnakeCase)
            

            func Use

            func Use(conn *sql.DB, m Migrator)

              Use sets the database connection and migrator.

              Types

              type MetaField

              type MetaField struct {
              	Name string
              	Tags []MetaTag
              }

                MetaField is the description of one field of a model for migration.

                type MetaModel

                type MetaModel struct {
                	ModelName string
                	Fields    []MetaField
                }

                  MetaModel is the description of a model for migration.

                  type MetaTag

                  type MetaTag struct {
                  	Name  string
                  	Value string
                  }

                    MetaTag is the description of a tag for a model field.

                    type Migrator

                    type Migrator interface {
                    	Migrate([]MetaModel)
                    	DropTable(string)
                    }

                      Migrator interface used to migrate a database schema for a specific database.

                      type NameSchema

                      type NameSchema interface {
                      	Get(string) string
                      }

                        NameSchema interface used to translate model names to schema names.

                        type Postgres

                        type Postgres struct {
                        	Schema      string
                        	DropColumns bool
                        	Log         bool
                        	// contains filtered or unexported fields
                        }

                          Postgres migrator for Postgres databases. You can use the following options to configure your data model:

                          // The type must be the database type.
                          type:database type
                          // Sets the column as primary key.
                          pk/primary key
                          // Creates and sets a sequence with given parameters for the column.
                          seq:start,increment,minvalue,maxvalue,cache
                          // Sets the default value for column, strings must be escaped.
                          // next(seq) refers to the sequences assign for this column (using seq:...).
                          default:default value/next(seq)
                          // Sets not null constraint for column.
                          not null/notnull
                          // Optional. Drops not null constraint if set for column. Not null is also dropped if not null is not set.
                          null
                          // Sets unique constraint for column.
                          unique
                          // Shortcut for primary key, not null, seq:1,1,-,-,1 and default:next(seq).
                          id
                          // Sets foreign key constraint for column.
                          // It refers to the given model and column.
                          // Example: fk:MyModel.Id
                          fk/foreign key:Model.Column
                          

                          func (*Postgres) DropTable

                          func (m *Postgres) DropTable(name string)

                            DropTable drops the given table.

                            func (*Postgres) Migrate

                            func (m *Postgres) Migrate(metaModels []MetaModel)

                              Migrate migrates the given data model.

                              type SnakeCase

                              type SnakeCase struct{}

                                SnakeCase translates model names to schema names in snake case.

                                Example:

                                Model -> model
                                MyModel -> my_model
                                SOMEModel -> some_model
                                

                                func (*SnakeCase) Get

                                func (n *SnakeCase) Get(name string) string

                                  Get returns the given name in snake case.