From 44ffb708133b9d007d976c99cf996783b0d35cbb Mon Sep 17 00:00:00 2001 From: Nurahmadie Date: Sun, 16 Mar 2014 10:52:28 +0700 Subject: [PATCH] Use variadic parameters for DropColumns. Also add some comments. --- pkg/database/database.go | 1 + .../201402211147_github_enterprise_support.go | 2 +- ...140310104446_add_open_invitation_column.go | 2 +- pkg/database/migrate/all.go | 4 +++ pkg/database/migrate/api.go | 29 ++++++++++++++++++- pkg/database/migrate/column_type.go | 23 +++++++++++++-- pkg/database/migrate/migrate.go | 25 ++-------------- pkg/database/migrate/mysql.go | 2 +- pkg/database/migrate/postgresql.go | 2 +- pkg/database/migrate/sqlite.go | 2 +- pkg/database/migrate/sqlite_test.go | 8 ++--- 11 files changed, 64 insertions(+), 36 deletions(-) diff --git a/pkg/database/database.go b/pkg/database/database.go index 1966aee41..390c3ccf3 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -57,6 +57,7 @@ func Init(name, datasource string) error { return nil } +// Close database connection. func Close() { db.Close() } diff --git a/pkg/database/migrate/201402211147_github_enterprise_support.go b/pkg/database/migrate/201402211147_github_enterprise_support.go index 8c252d782..289c4bca7 100644 --- a/pkg/database/migrate/201402211147_github_enterprise_support.go +++ b/pkg/database/migrate/201402211147_github_enterprise_support.go @@ -21,6 +21,6 @@ func (r *Rev3) Up(mg *MigrationDriver) error { } func (r *Rev3) Down(mg *MigrationDriver) error { - _, err := mg.DropColumns("settings", []string{"github_domain", "github_apiurl"}) + _, err := mg.DropColumns("settings", "github_domain", "github_apiurl") return err } diff --git a/pkg/database/migrate/20140310104446_add_open_invitation_column.go b/pkg/database/migrate/20140310104446_add_open_invitation_column.go index a98afa5cb..c806f69af 100644 --- a/pkg/database/migrate/20140310104446_add_open_invitation_column.go +++ b/pkg/database/migrate/20140310104446_add_open_invitation_column.go @@ -16,6 +16,6 @@ func (r *rev20140310104446) Up(mg *MigrationDriver) error { } func (r *rev20140310104446) Down(mg *MigrationDriver) error { - _, err := mg.DropColumns("settings", []string{"open_invitations"}) + _, err := mg.DropColumns("settings", "open_invitations") return err } diff --git a/pkg/database/migrate/all.go b/pkg/database/migrate/all.go index 124e3ea2b..1748f18f8 100644 --- a/pkg/database/migrate/all.go +++ b/pkg/database/migrate/all.go @@ -1,5 +1,9 @@ package migrate +// All is called to collect all migration scripts +// and adds them to Revision list. New Revision +// should be added here ordered by its revision +// number. func (m *Migration) All() *Migration { // List all migrations here diff --git a/pkg/database/migrate/api.go b/pkg/database/migrate/api.go index c93d5b43f..6a2c4c699 100644 --- a/pkg/database/migrate/api.go +++ b/pkg/database/migrate/api.go @@ -8,29 +8,56 @@ import ( // Implementation details is specific for each database, // see migrate/sqlite.go for implementation reference. type Operation interface { + + // CreateTable may be used to create a table named `tableName` + // with its columns specification listed in `args` as an array of string CreateTable(tableName string, args []string) (sql.Result, error) + // RenameTable simply rename table from `tableName` to `newName` RenameTable(tableName, newName string) (sql.Result, error) + // DropTable drops table named `tableName` DropTable(tableName string) (sql.Result, error) + // AddColumn adds single new column to `tableName`, columnSpec is + // a standard column definition (column name included) which may looks like this: + // + // mg.AddColumn("example", "email VARCHAR(255) UNIQUE") + // + // it's equivalent to: + // + // mg.AddColumn("example", mg.T.String("email", UNIQUE)) + // AddColumn(tableName, columnSpec string) (sql.Result, error) + // ChangeColumn may be used to change the type of a column + // `newType` should always specify the column's new type even + // if the type is not meant to be change. Eg. + // + // mg.ChangeColumn("example", "name", "VARCHAR(255) UNIQUE") + // ChangeColumn(tableName, columnName, newType string) (sql.Result, error) - DropColumns(tableName string, columnsToDrop []string) (sql.Result, error) + // DropColumns drops a list of columns + DropColumns(tableName string, columnsToDrop ...string) (sql.Result, error) + // RenameColumns will rename columns listed in `columnChanges` RenameColumns(tableName string, columnChanges map[string]string) (sql.Result, error) + // AddIndex adds index on `tableName` indexed by `columns` AddIndex(tableName string, columns []string, flags ...string) (sql.Result, error) + // DropIndex drops index indexed by `columns` from `tableName` DropIndex(tableName string, columns []string) (sql.Result, error) } +// MigrationDriver drives migration script by injecting transaction object (*sql.Tx), +// `Operation` implementation and column type helper. type MigrationDriver struct { Operation T *columnType Tx *sql.Tx } +// DriverBuilder is a constructor for MigrationDriver type DriverBuilder func(tx *sql.Tx) *MigrationDriver diff --git a/pkg/database/migrate/column_type.go b/pkg/database/migrate/column_type.go index 6a6286283..2920f6f33 100644 --- a/pkg/database/migrate/column_type.go +++ b/pkg/database/migrate/column_type.go @@ -12,16 +12,20 @@ const ( AUTOINCREMENT NULL NOTNULL - - TSTRING - TTEXT ) +// columnType will be injected to migration script +// along with MigrationDriver. `AttrMap` is used to +// defines distinct column's attribute between database +// implementation. e.g. 'AUTOINCREMENT' in sqlite and +// 'AUTO_INCREMENT' in mysql. type columnType struct { Driver string AttrMap map[int]string } +// defaultMap defines default values for column's attribute +// lookup. var defaultMap = map[int]string{ UNIQUE: "UNIQUE", PRIMARYKEY: "PRIMARY KEY", @@ -30,34 +34,45 @@ var defaultMap = map[int]string{ NOTNULL: "NOT NULL", } +// Integer returns column definition for INTEGER typed column. +// Additional attributes may be specified as string or predefined key +// listed in defaultMap. func (c *columnType) Integer(colName string, spec ...interface{}) string { return fmt.Sprintf("%s INTEGER %s", colName, c.parseAttr(spec)) } +// String returns column definition for VARCHAR(255) typed column. func (c *columnType) String(colName string, spec ...interface{}) string { return fmt.Sprintf("%s VARCHAR(255) %s", colName, c.parseAttr(spec)) } +// Text returns column definition for TEXT typed column. func (c *columnType) Text(colName string, spec ...interface{}) string { return fmt.Sprintf("%s TEXT %s", colName, c.parseAttr(spec)) } +// Blob returns column definition for BLOB typed column func (c *columnType) Blob(colName string, spec ...interface{}) string { return fmt.Sprintf("%s BLOB %s", colName, c.parseAttr(spec)) } +// Timestamp returns column definition for TIMESTAMP typed column func (c *columnType) Timestamp(colName string, spec ...interface{}) string { return fmt.Sprintf("%s TIMESTAMP %s", colName, c.parseAttr(spec)) } +// Bool returns column definition for BOOLEAN typed column func (c *columnType) Bool(colName string, spec ...interface{}) string { return fmt.Sprintf("%s BOOLEAN %s", colName, c.parseAttr(spec)) } +// Varchar returns column definition for VARCHAR typed column. +// column's max length is specified as `length`. func (c *columnType) Varchar(colName string, length int, spec ...interface{}) string { return fmt.Sprintf("%s VARCHAR(%d) %s", colName, length, c.parseAttr(spec)) } +// attr returns string representation of column attribute specified as key for defaultMap. func (c *columnType) attr(flag int) string { if v, ok := c.AttrMap[flag]; ok { return v @@ -65,6 +80,8 @@ func (c *columnType) attr(flag int) string { return defaultMap[flag] } +// parseAttr reflects spec value for its type and returns the string +// representation returned by `attr` func (c *columnType) parseAttr(spec []interface{}) string { var attrs []string for _, v := range spec { diff --git a/pkg/database/migrate/migrate.go b/pkg/database/migrate/migrate.go index ba4e8137e..55c9d1d0f 100644 --- a/pkg/database/migrate/migrate.go +++ b/pkg/database/migrate/migrate.go @@ -1,24 +1,3 @@ -// Usage -// migrate.To(2) -// .Add(Version_1) -// .Add(Version_2) -// .Add(Version_3) -// .Exec(db) -// -// migrate.ToLatest() -// .Add(Version_1) -// .Add(Version_2) -// .Add(Version_3) -// .SetDialect(migrate.MySQL) -// .Exec(db) -// -// migrate.ToLatest() -// .Add(Version_1) -// .Add(Version_2) -// .Add(Version_3) -// .Backup(path) -// .Exec() - package migrate import ( @@ -72,7 +51,7 @@ func (m *Migration) Add(rev ...Revision) *Migration { return m } -// Execute the full list of migrations. +// Migrate executes the full list of migrations. func (m *Migration) Migrate() error { var target int64 if len(m.revs) > 0 { @@ -84,7 +63,7 @@ func (m *Migration) Migrate() error { return m.MigrateTo(target) } -// Execute all database migration until +// MigrateTo executes all database migration until // you are at the specified revision number. // If the revision number is less than the // current revision, then we will downgrade. diff --git a/pkg/database/migrate/mysql.go b/pkg/database/migrate/mysql.go index c05926a99..248b510c4 100644 --- a/pkg/database/migrate/mysql.go +++ b/pkg/database/migrate/mysql.go @@ -40,7 +40,7 @@ func (m *mysqlDriver) ChangeColumn(tableName, columnName, newSpecs string) (sql. return m.Tx.Exec(fmt.Sprintf("ALTER TABLE %s MODIFY %s %s", tableName, columnName, newSpecs)) } -func (m *mysqlDriver) DropColumns(tableName string, columnsToDrop []string) (sql.Result, error) { +func (m *mysqlDriver) DropColumns(tableName string, columnsToDrop ...string) (sql.Result, error) { for k, v := range columnsToDrop { columnsToDrop[k] = fmt.Sprintf("DROP %s", v) } diff --git a/pkg/database/migrate/postgresql.go b/pkg/database/migrate/postgresql.go index a473412a5..6225daad7 100644 --- a/pkg/database/migrate/postgresql.go +++ b/pkg/database/migrate/postgresql.go @@ -36,7 +36,7 @@ func (p *postgresqlDriver) ChangeColumn(tableName, columnName, newSpecs string) return nil, errors.New("not implemented yet") } -func (p *postgresqlDriver) DropColumns(tableName string, columnsToDrop []string) (sql.Result, error) { +func (p *postgresqlDriver) DropColumns(tableName string, columnsToDrop ...string) (sql.Result, error) { return nil, errors.New("not implemented yet") } diff --git a/pkg/database/migrate/sqlite.go b/pkg/database/migrate/sqlite.go index bed6f7f5a..3b14189dc 100644 --- a/pkg/database/migrate/sqlite.go +++ b/pkg/database/migrate/sqlite.go @@ -91,7 +91,7 @@ func (s *sqliteDriver) ChangeColumn(tableName, columnName, newType string) (sql. } -func (s *sqliteDriver) DropColumns(tableName string, columnsToDrop []string) (sql.Result, error) { +func (s *sqliteDriver) DropColumns(tableName string, columnsToDrop ...string) (sql.Result, error) { var err error var result sql.Result diff --git a/pkg/database/migrate/sqlite_test.go b/pkg/database/migrate/sqlite_test.go index be9c95b6e..7e4987f76 100644 --- a/pkg/database/migrate/sqlite_test.go +++ b/pkg/database/migrate/sqlite_test.go @@ -89,7 +89,7 @@ func (r *revision3) Up(mg *MigrationDriver) error { } func (r *revision3) Down(mg *MigrationDriver) error { - _, err := mg.DropColumns("samples", []string{"num", "url"}) + _, err := mg.DropColumns("samples", "num", "url") return err } @@ -128,7 +128,7 @@ func (r *revision4) Revision() int64 { type revision5 struct{} func (r *revision5) Up(mg *MigrationDriver) error { - _, err := mg.AddIndex("samples", []string{"url", "name"}, "") + _, err := mg.AddIndex("samples", []string{"url", "name"}) return err } @@ -170,7 +170,7 @@ func (r *revision6) Revision() int64 { type revision7 struct{} func (r *revision7) Up(mg *MigrationDriver) error { - _, err := mg.DropColumns("samples", []string{"host", "num"}) + _, err := mg.DropColumns("samples", "host", "num") return err } @@ -200,7 +200,7 @@ func (r *revision8) Up(mg *MigrationDriver) error { } func (r *revision8) Down(mg *MigrationDriver) error { - _, err := mg.DropColumns("samples", []string{"repo", "repo_id"}) + _, err := mg.DropColumns("samples", "repo", "repo_id") return err }