Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
a64a38d7
Commit
a64a38d7
authored
Jan 18, 2015
by
Torkel Ödegaard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added migration log and migration id, do not execute already executed migrations
parent
8bfed750
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
194 additions
and
65 deletions
+194
-65
pkg/services/sqlstore/migrations/builder.go
+18
-12
pkg/services/sqlstore/migrations/migrations.go
+15
-20
pkg/services/sqlstore/migrations/migrations_test.go
+8
-2
pkg/services/sqlstore/migrations/migrator.go
+75
-31
pkg/services/sqlstore/migrations/migrator_test.go
+78
-0
No files found.
pkg/services/sqlstore/migrations/builder.go
View file @
a64a38d7
...
...
@@ -13,6 +13,8 @@ const (
type
Migration
interface
{
Sql
(
dialect
Dialect
)
string
Id
()
string
SetId
(
string
)
}
type
ColumnType
string
...
...
@@ -22,7 +24,15 @@ const (
)
type
MigrationBase
struct
{
desc
string
id
string
}
func
(
m
*
MigrationBase
)
Id
()
string
{
return
m
.
id
}
func
(
m
*
MigrationBase
)
SetId
(
id
string
)
{
m
.
id
=
id
}
type
RawSqlMigration
struct
{
...
...
@@ -53,11 +63,6 @@ func (m *RawSqlMigration) Mysql(sql string) *RawSqlMigration {
return
m
}
func
(
m
*
RawSqlMigration
)
Desc
(
desc
string
)
*
RawSqlMigration
{
m
.
desc
=
desc
return
m
}
type
AddColumnMigration
struct
{
MigrationBase
tableName
string
...
...
@@ -90,16 +95,12 @@ func (m *AddColumnMigration) Sql(dialect Dialect) string {
return
fmt
.
Sprintf
(
"ALTER TABLE %s ADD COLUMN %s %s"
,
m
.
tableName
,
m
.
columnName
,
dialect
.
ToDBTypeSql
(
m
.
columnType
,
m
.
length
))
}
func
(
m
*
AddColumnMigration
)
Desc
(
desc
string
)
*
AddColumnMigration
{
m
.
desc
=
desc
return
m
}
type
AddIndexMigration
struct
{
MigrationBase
tableName
string
columns
string
indexName
string
unique
string
}
func
(
m
*
AddIndexMigration
)
Name
(
name
string
)
*
AddIndexMigration
{
...
...
@@ -112,11 +113,16 @@ func (m *AddIndexMigration) Table(tableName string) *AddIndexMigration {
return
m
}
func
(
m
*
AddIndexMigration
)
Unique
()
*
AddIndexMigration
{
m
.
unique
=
"UNIQUE"
return
m
}
func
(
m
*
AddIndexMigration
)
Columns
(
columns
...
string
)
*
AddIndexMigration
{
m
.
columns
=
strings
.
Join
(
columns
,
","
)
return
m
}
func
(
m
*
AddIndexMigration
)
Sql
(
dialect
Dialect
)
string
{
return
fmt
.
Sprintf
(
"CREATE
UNIQUE INDEX %s ON %s(%s)"
,
m
.
indexName
,
m
.
tableName
,
m
.
columns
)
return
fmt
.
Sprintf
(
"CREATE
%s INDEX %s ON %s(%s)"
,
m
.
unique
,
m
.
indexName
,
m
.
tableName
,
m
.
columns
)
}
pkg/services/sqlstore/migrations/migrations.go
View file @
a64a38d7
package
migrations
var
migrationList
[]
Migration
import
"time"
// Id int64
// Login string `xorm:"UNIQUE NOT NULL"`
...
...
@@ -16,9 +16,11 @@ var migrationList []Migration
// Created time.Time
// Updated time.Time
func
init
()
{
// ------------------------------
addMigration
(
new
(
RawSqlMigration
)
.
Desc
(
"Create account table"
)
.
func
AddMigrations
(
mg
*
Migrator
)
{
// TABLE Account
// -------------------------------
mg
.
AddMigration
(
"create account table"
,
new
(
RawSqlMigration
)
.
Sqlite
(
`
CREATE TABLE account (
id INTEGER PRIMARY KEY AUTOINCREMENT,
...
...
@@ -34,25 +36,18 @@ func init() {
)
`
))
// ------------------------------
addMigration
(
new
(
AddIndexMigration
)
.
mg
.
AddMigration
(
"add index UIX_account.login"
,
new
(
AddIndexMigration
)
.
Name
(
"UIX_account_login"
)
.
Table
(
"account"
)
.
Columns
(
"login"
))
// ------------------------------
addMigration
(
new
(
AddColumnMigration
)
.
Desc
(
"Add name column"
)
.
mg
.
AddMigration
(
"add column"
,
new
(
AddColumnMigration
)
.
Table
(
"account"
)
.
Column
(
"name"
)
.
Type
(
DB_TYPE_STRING
)
.
Length
(
255
))
}
func
addMigration
(
m
Migration
)
{
migrationList
=
append
(
migrationList
,
m
)
}
type
SchemaVersion
struct
{
Version
int
}
type
SchemaLog
struct
{
Id
int64
Version
int64
Desc
string
Info
string
Error
bool
type
MigrationLog
struct
{
Id
int64
MigrationId
string
Sql
string
Success
bool
Error
string
Timestamp
time
.
Time
}
pkg/services/sqlstore/migrations/migrations_test.go
View file @
a64a38d7
...
...
@@ -6,6 +6,7 @@ import (
"testing"
"github.com/go-xorm/xorm"
"github.com/torkelo/grafana-pro/pkg/log"
.
"github.com/smartystreets/goconvey/convey"
)
...
...
@@ -31,8 +32,10 @@ func cleanDB(x *xorm.Engine) {
var
indexTypes
=
[]
string
{
"Unknown"
,
""
,
"UNIQUE"
}
func
TestMigrations
(
t
*
testing
.
T
)
{
log
.
NewLogger
(
0
,
"console"
,
`{"level": 0}`
)
testDBs
:=
[][]
string
{
//
[]string{"mysql", "grafana:password@tcp(localhost:3306)/grafana_tests?charset=utf8"},
[]
string
{
"mysql"
,
"grafana:password@tcp(localhost:3306)/grafana_tests?charset=utf8"
},
[]
string
{
"sqlite3"
,
":memory:"
},
}
...
...
@@ -46,7 +49,10 @@ func TestMigrations(t *testing.T) {
cleanDB
(
x
)
}
err
=
StartMigration
(
x
)
mg
:=
NewMigrator
(
x
)
AddMigrations
(
mg
)
err
=
mg
.
Start
()
So
(
err
,
ShouldBeNil
)
tables
,
err
:=
x
.
DBMetas
()
...
...
pkg/services/sqlstore/migrations/
engine
.go
→
pkg/services/sqlstore/migrations/
migrator
.go
View file @
a64a38d7
package
migrations
import
(
"time"
_
"github.com/go-sql-driver/mysql"
"github.com/go-xorm/xorm"
_
"github.com/lib/pq"
...
...
@@ -8,60 +10,102 @@ import (
"github.com/torkelo/grafana-pro/pkg/log"
)
var
x
*
xorm
.
Engine
var
dialect
Dialect
type
Migrator
struct
{
x
*
xorm
.
Engine
dialect
Dialect
migrations
[]
Migration
}
func
NewMigrator
(
engine
*
xorm
.
Engine
)
*
Migrator
{
mg
:=
&
Migrator
{}
mg
.
x
=
engine
mg
.
migrations
=
make
([]
Migration
,
0
)
switch
mg
.
x
.
DriverName
()
{
case
MYSQL
:
mg
.
dialect
=
new
(
Mysql
)
case
SQLITE
:
mg
.
dialect
=
new
(
Sqlite3
)
}
return
mg
}
func
(
mg
*
Migrator
)
AddMigration
(
id
string
,
m
Migration
)
{
m
.
SetId
(
id
)
mg
.
migrations
=
append
(
mg
.
migrations
,
m
)
}
func
getSchemaVersion
()
(
int
,
error
)
{
exists
,
err
:=
x
.
IsTableExist
(
new
(
SchemaVersion
))
func
(
mg
*
Migrator
)
GetMigrationLog
()
(
map
[
string
]
MigrationLog
,
error
)
{
exists
,
err
:=
mg
.
x
.
IsTableExist
(
new
(
MigrationLog
))
if
err
!=
nil
{
return
0
,
err
return
nil
,
err
}
if
!
exists
{
if
err
:=
x
.
CreateTables
(
new
(
SchemaVersion
));
err
!=
nil
{
return
0
,
err
if
err
:=
mg
.
x
.
CreateTables
(
new
(
MigrationLog
));
err
!=
nil
{
return
nil
,
err
}
return
0
,
nil
return
nil
,
nil
}
v
:=
SchemaVersion
{}
_
,
err
=
x
.
Table
(
"schema_version"
)
.
Limit
(
1
,
0
)
.
Desc
(
"version"
)
.
Get
(
&
v
)
return
v
.
Version
,
err
}
logMap
:=
make
(
map
[
string
]
MigrationLog
)
logItems
:=
make
([]
MigrationLog
,
0
)
if
err
=
mg
.
x
.
Find
(
&
logItems
);
err
!=
nil
{
return
nil
,
err
}
func
setEngineAndDialect
(
engine
*
xorm
.
Engine
)
{
x
=
engine
switch
x
.
DriverName
()
{
case
MYSQL
:
dialect
=
new
(
Mysql
)
case
SQLITE
:
dialect
=
new
(
Sqlite3
)
for
_
,
logItem
:=
range
logItems
{
if
!
logItem
.
Success
{
continue
}
logMap
[
logItem
.
MigrationId
]
=
logItem
}
}
func
StartMigration
(
engine
*
xorm
.
Engine
)
error
{
log
.
Info
(
"Starting database schema migration: DB: %v"
,
engine
.
DriverName
())
return
logMap
,
nil
}
setEngineAndDialect
(
engine
)
func
(
mg
*
Migrator
)
Start
()
error
{
log
.
Info
(
"Migrator::Start DB migration"
)
_
,
err
:=
getSchemaVersion
()
logMap
,
err
:=
mg
.
GetMigrationLog
()
if
err
!=
nil
{
return
err
}
for
_
,
m
:=
range
migrationList
{
if
err
:=
execMigration
(
m
);
err
!=
nil
{
for
_
,
m
:=
range
mg
.
migrations
{
_
,
exists
:=
logMap
[
m
.
Id
()]
if
exists
{
log
.
Info
(
"Migrator:: Skipping migration: %v, Already executed"
,
m
.
Id
())
continue
}
record
:=
MigrationLog
{
MigrationId
:
m
.
Id
(),
Sql
:
m
.
Sql
(
mg
.
dialect
),
Timestamp
:
time
.
Now
(),
}
if
err
:=
mg
.
exec
(
m
);
err
!=
nil
{
record
.
Error
=
err
.
Error
()
mg
.
x
.
Insert
(
&
record
)
return
err
}
else
{
record
.
Success
=
true
mg
.
x
.
Insert
(
&
record
)
}
}
return
nil
}
func
execMigration
(
m
Migration
)
error
{
err
:=
inTransaction
(
func
(
sess
*
xorm
.
Session
)
error
{
_
,
err
:=
sess
.
Exec
(
m
.
Sql
(
dialect
))
func
(
mg
*
Migrator
)
exec
(
m
Migration
)
error
{
log
.
Info
(
"Migrator::exec migration id: %v"
,
m
.
Id
())
err
:=
mg
.
inTransaction
(
func
(
sess
*
xorm
.
Session
)
error
{
_
,
err
:=
sess
.
Exec
(
m
.
Sql
(
mg
.
dialect
))
if
err
!=
nil
{
log
.
Error
(
3
,
"Migrator::exec FAILED migration id: %v, err: %v"
,
m
.
Id
(),
err
)
return
err
}
return
nil
...
...
@@ -76,10 +120,10 @@ func execMigration(m Migration) error {
type
dbTransactionFunc
func
(
sess
*
xorm
.
Session
)
error
func
inTransaction
(
callback
dbTransactionFunc
)
error
{
func
(
mg
*
Migrator
)
inTransaction
(
callback
dbTransactionFunc
)
error
{
var
err
error
sess
:=
x
.
NewSession
()
sess
:=
mg
.
x
.
NewSession
()
defer
sess
.
Close
()
if
err
=
sess
.
Begin
();
err
!=
nil
{
...
...
pkg/services/sqlstore/migrations/migrator_test.go
0 → 100644
View file @
a64a38d7
package
migrations
import
(
"testing"
"github.com/go-xorm/xorm"
.
"github.com/smartystreets/goconvey/convey"
)
// func cleanDB(x *xorm.Engine) {
// tables, _ := x.DBMetas()
// sess := x.NewSession()
// defer sess.Close()
//
// for _, table := range tables {
// if _, err := sess.Exec("SET FOREIGN_KEY_CHECKS = 0"); err != nil {
// panic("Failed to disable foreign key checks")
// }
// if _, err := sess.Exec("DROP TABLE " + table.Name); err != nil {
// panic(fmt.Sprintf("Failed to delete table: %v, err: %v", table.Name, err))
// }
// if _, err := sess.Exec("SET FOREIGN_KEY_CHECKS = 1"); err != nil {
// panic("Failed to disable foreign key checks")
// }
// }
// }
//
// var indexTypes = []string{"Unknown", "", "UNIQUE"}
//
func
TestMigrator
(
t
*
testing
.
T
)
{
Convey
(
"Migrator"
,
t
,
func
()
{
x
,
err
:=
xorm
.
NewEngine
(
SQLITE
,
":memory:"
)
So
(
err
,
ShouldBeNil
)
mg
:=
NewMigrator
(
x
)
Convey
(
"Given one migration"
,
func
()
{
mg
.
AddMigration
(
"test migration"
,
new
(
RawSqlMigration
)
.
Sqlite
(
`
CREATE TABLE account (
id INTEGER PRIMARY KEY AUTOINCREMENT
)`
)
.
Mysql
(
`
CREATE TABLE account (
id BIGINT NOT NULL AUTO_INCREMENT, PRIMARY KEY (id)
)`
))
err
:=
mg
.
Start
()
So
(
err
,
ShouldBeNil
)
log
,
err
:=
mg
.
GetMigrationLog
()
So
(
err
,
ShouldBeNil
)
So
(
len
(
log
),
ShouldEqual
,
1
)
})
// So(err, ShouldBeNil)
//
// So(len(tables), ShouldEqual, 2)
// fmt.Printf("\nDB Schema after migration: table count: %v\n", len(tables))
//
// for _, table := range tables {
// fmt.Printf("\nTable: %v \n", table.Name)
// for _, column := range table.Columns() {
// fmt.Printf("\t %v \n", column.String(x.Dialect()))
// }
//
// if len(table.Indexes) > 0 {
// fmt.Printf("\n\tIndexes:\n")
// for _, index := range table.Indexes {
// fmt.Printf("\t %v (%v) %v \n", index.Name, strings.Join(index.Cols, ","), indexTypes[index.Type])
// }
// }
// }
})
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment