Use migrate
This commit is contained in:
parent
d0bf7b4354
commit
ba833aa770
5
README.md
Normal file
5
README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Run tests
|
||||||
|
|
||||||
|
Use lastest postgres docker from https://hub.docker.com/r/library/postgres/ and run:
|
||||||
|
|
||||||
|
env POSTGRES_DSN="postgres://test:test@192.168.99.100:32771/test?sslmode=disable" go test -v ./...
|
@ -10,53 +10,6 @@ import (
|
|||||||
"github.com/odwrtw/polochon/lib"
|
"github.com/odwrtw/polochon/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Schema = sqly.Schema{
|
|
||||||
Require: []sqly.Schema{
|
|
||||||
users.Schema,
|
|
||||||
},
|
|
||||||
Tables: []sqly.SchemaTable{
|
|
||||||
sqly.SchemaTable{
|
|
||||||
Name: "shows",
|
|
||||||
Sql: `
|
|
||||||
CREATE TABLE shows (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
imdbid text NOT NULL UNIQUE,
|
|
||||||
title text NOT NULL,
|
|
||||||
updated timestamp DEFAULT current_timestamp,
|
|
||||||
created timestamp DEFAULT current_timestamp
|
|
||||||
);
|
|
||||||
`},
|
|
||||||
sqly.SchemaTable{
|
|
||||||
Name: "episodes",
|
|
||||||
Sql: `
|
|
||||||
CREATE TABLE episodes (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
shows_id integer REFERENCES shows (id) ON DELETE CASCADE,
|
|
||||||
title text NOT NULL,
|
|
||||||
season integer NOT NULL,
|
|
||||||
episode integer NOT NULL,
|
|
||||||
updated timestamp DEFAULT current_timestamp,
|
|
||||||
created timestamp DEFAULT current_timestamp
|
|
||||||
);
|
|
||||||
`},
|
|
||||||
sqly.SchemaTable{
|
|
||||||
Name: "shows_tracked",
|
|
||||||
Sql: `
|
|
||||||
CREATE TABLE shows_tracked (
|
|
||||||
shows_id integer NOT NULL REFERENCES shows (id) ON DELETE CASCADE,
|
|
||||||
users_id integer NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
|
||||||
season integer NOT NULL,
|
|
||||||
episode integer NOT NULL
|
|
||||||
);
|
|
||||||
`},
|
|
||||||
},
|
|
||||||
Drop: `
|
|
||||||
DROP TABLE shows_tracked;
|
|
||||||
DROP TABLE episodes;
|
|
||||||
DROP TABLE shows;
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
addShowQuery = `INSERT INTO shows (imdbid, title) VALUES (:imdbid, :title) RETURNING id;`
|
addShowQuery = `INSERT INTO shows (imdbid, title) VALUES (:imdbid, :title) RETURNING id;`
|
||||||
getShowQuery = `SELECT * FROM shows WHERE imdbid=$1;`
|
getShowQuery = `SELECT * FROM shows WHERE imdbid=$1;`
|
@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
|
_ "github.com/mattes/migrate/driver/postgres"
|
||||||
"github.com/odwrtw/polochon/lib"
|
"github.com/odwrtw/polochon/lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -68,27 +69,22 @@ const showNFO1E2 = `
|
|||||||
`
|
`
|
||||||
|
|
||||||
var db *sqlx.DB
|
var db *sqlx.DB
|
||||||
|
var pgdsn string
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
pgdsn := os.Getenv("POSTGRES_DSN")
|
pgdsn = os.Getenv("POSTGRES_DSN")
|
||||||
db, err = sqlx.Connect("postgres", pgdsn)
|
db, err = sqlx.Connect("postgres", pgdsn)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Unavailable PG tests:\n %v\n", err)
|
fmt.Printf("Unavailable PG tests:\n %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = sqly.InitDB(db)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Unavailable PG tests:\n %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddRemoveShow(t *testing.T) {
|
func TestAddRemoveShow(t *testing.T) {
|
||||||
sqly.RunWithSchema(db, Schema, t, func(db *sqlx.DB, t *testing.T) {
|
sqly.RunWithLastestMigration(db, pgdsn, t, func(db *sqlx.DB, t *testing.T) {
|
||||||
nfo := strings.NewReader(showNFO1)
|
nfo := strings.NewReader(showNFO1)
|
||||||
s := &polochon.Show{}
|
s := &polochon.Show{}
|
||||||
polochon.ReadNFO(nfo, s)
|
polochon.ReadNFO(nfo, s)
|
||||||
@ -143,7 +139,7 @@ func TestAddRemoveShow(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
func TestTrackedShow(t *testing.T) {
|
func TestTrackedShow(t *testing.T) {
|
||||||
sqly.RunWithSchema(db, Schema, t, func(db *sqlx.DB, t *testing.T) {
|
sqly.RunWithLastestMigration(db, pgdsn, t, func(db *sqlx.DB, t *testing.T) {
|
||||||
nfo := strings.NewReader(showNFO1)
|
nfo := strings.NewReader(showNFO1)
|
||||||
s := &polochon.Show{}
|
s := &polochon.Show{}
|
||||||
polochon.ReadNFO(nfo, s)
|
polochon.ReadNFO(nfo, s)
|
9
sql/0001_initial.down.sql
Normal file
9
sql/0001_initial.down.sql
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
DROP TABLE shows_tracked;
|
||||||
|
DROP TABLE episodes;
|
||||||
|
DROP TABLE shows;
|
||||||
|
|
||||||
|
DROP TABLE tokens;
|
||||||
|
DROP TABLE users;
|
||||||
|
|
||||||
|
DROP FUNCTION update_modified_column();
|
||||||
|
|
54
sql/0001_initial.up.sql
Normal file
54
sql/0001_initial.up.sql
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
CREATE OR REPLACE FUNCTION update_modified_column()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
BEGIN
|
||||||
|
NEW.updated = now();
|
||||||
|
RETURN NEW;
|
||||||
|
END; $$ language 'plpgsql';
|
||||||
|
|
||||||
|
CREATE TABLE users (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
name text NOT NULL UNIQUE,
|
||||||
|
updated timestamp DEFAULT current_timestamp,
|
||||||
|
created timestamp DEFAULT current_timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TRIGGER update_users BEFORE UPDATE ON users FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||||
|
|
||||||
|
CREATE TABLE tokens (
|
||||||
|
id SERIAL,
|
||||||
|
value text NOT NULL UNIQUE,
|
||||||
|
users_id integer REFERENCES users (id) ON DELETE CASCADE,
|
||||||
|
updated timestamp DEFAULT current_timestamp,
|
||||||
|
created timestamp DEFAULT current_timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TRIGGER update_tokens BEFORE UPDATE ON tokens FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||||
|
|
||||||
|
CREATE TABLE shows (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
imdbid text NOT NULL UNIQUE,
|
||||||
|
title text NOT NULL,
|
||||||
|
updated timestamp DEFAULT current_timestamp,
|
||||||
|
created timestamp DEFAULT current_timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TRIGGER update_shows BEFORE UPDATE ON shows FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||||
|
|
||||||
|
CREATE TABLE episodes (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
shows_id integer REFERENCES shows (id) ON DELETE CASCADE,
|
||||||
|
title text NOT NULL,
|
||||||
|
season integer NOT NULL,
|
||||||
|
episode integer NOT NULL,
|
||||||
|
updated timestamp DEFAULT current_timestamp,
|
||||||
|
created timestamp DEFAULT current_timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TRIGGER update_episodes BEFORE UPDATE ON episodes FOR EACH ROW EXECUTE PROCEDURE update_modified_column();
|
||||||
|
|
||||||
|
CREATE TABLE shows_tracked (
|
||||||
|
shows_id integer NOT NULL REFERENCES shows (id) ON DELETE CASCADE,
|
||||||
|
users_id integer NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||||
|
season integer NOT NULL,
|
||||||
|
episode integer NOT NULL
|
||||||
|
);
|
@ -1,39 +0,0 @@
|
|||||||
package sqltest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
)
|
|
||||||
|
|
||||||
func MultiExec(e sqlx.Execer, query string) error {
|
|
||||||
stmts := strings.Split(query, ";\n")
|
|
||||||
if len(strings.Trim(stmts[len(stmts)-1], " \n\t\r")) == 0 {
|
|
||||||
stmts = stmts[:len(stmts)-1]
|
|
||||||
}
|
|
||||||
for _, s := range stmts {
|
|
||||||
_, err := e.Exec(s)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%s\n%s", err, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func RunWithSchema(db *sqlx.DB, create, drop string, t *testing.T, test func(db *sqlx.DB, t *testing.T)) {
|
|
||||||
defer func() {
|
|
||||||
err := MultiExec(db, drop)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s", err.Error())
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
err := MultiExec(db, create)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%s", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
test(db, t)
|
|
||||||
}
|
|
106
sqly/sqly.go
106
sqly/sqly.go
@ -2,28 +2,13 @@ package sqly
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
|
"github.com/mattes/migrate/migrate"
|
||||||
)
|
)
|
||||||
|
|
||||||
const initDBQuery = `
|
|
||||||
CREATE OR REPLACE FUNCTION update_modified_column()
|
|
||||||
RETURNS TRIGGER AS $$
|
|
||||||
BEGIN NEW.updated = now(); RETURN NEW; END; $$ language 'plpgsql';
|
|
||||||
`
|
|
||||||
|
|
||||||
// InitDB add some function to the database and template
|
|
||||||
func InitDB(db *sqlx.DB) error {
|
|
||||||
err := MultiExec(db, initDBQuery)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// BaseTable have to be embeded in all your struct which reflect a table
|
// BaseTable have to be embeded in all your struct which reflect a table
|
||||||
type BaseTable struct {
|
type BaseTable struct {
|
||||||
ID int
|
ID int
|
||||||
@ -31,84 +16,25 @@ type BaseTable struct {
|
|||||||
Created time.Time
|
Created time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type SchemaTable struct {
|
func RunWithLastestMigration(db *sqlx.DB, pgdsn string, t *testing.T, test func(db *sqlx.DB, t *testing.T)) {
|
||||||
Name string
|
|
||||||
Sql string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Schema struct {
|
|
||||||
// Create contains all tables, the key is the name and the
|
|
||||||
// value the sql
|
|
||||||
Tables []SchemaTable
|
|
||||||
|
|
||||||
// Drop contains the drop sql
|
|
||||||
Drop string
|
|
||||||
|
|
||||||
// Require add schema before create and delete after
|
|
||||||
Require []Schema
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Schema) Create(db *sqlx.DB) error {
|
|
||||||
for _, sch := range s.Require {
|
|
||||||
err := sch.Create(db)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, table := range s.Tables {
|
|
||||||
_, err := db.Exec(table.Sql)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%s\n%s", err, table.Sql)
|
|
||||||
}
|
|
||||||
trigger := fmt.Sprintf("CREATE TRIGGER update_%s BEFORE UPDATE ON %s FOR EACH ROW EXECUTE PROCEDURE update_modified_column();", table.Name, table.Name)
|
|
||||||
_, err = db.Exec(trigger)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%s\n%s", err, trigger)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Schema) Delete(db *sqlx.DB) error {
|
|
||||||
err := MultiExec(db, s.Drop)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, sch := range s.Require {
|
|
||||||
err := sch.Delete(db)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func MultiExec(e sqlx.Execer, query string) error {
|
|
||||||
stmts := strings.Split(query, ";\n")
|
|
||||||
if len(strings.Trim(stmts[len(stmts)-1], " \n\t\r")) == 0 {
|
|
||||||
stmts = stmts[:len(stmts)-1]
|
|
||||||
}
|
|
||||||
for _, s := range stmts {
|
|
||||||
_, err := e.Exec(s)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%s\n%s", err, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func RunWithSchema(db *sqlx.DB, schema Schema, t *testing.T, test func(db *sqlx.DB, t *testing.T)) {
|
|
||||||
defer func() {
|
defer func() {
|
||||||
err := schema.Delete(db)
|
allErrors, ok := migrate.DownSync(pgdsn, "../sql")
|
||||||
if err != nil {
|
if !ok {
|
||||||
t.Fatalf("%s", err.Error())
|
fmt.Println("Oh no ...")
|
||||||
|
for _, err := range allErrors {
|
||||||
|
t.Log(err)
|
||||||
|
t.Fatal("We get some errors when reset the database schema")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err := schema.Create(db)
|
allErrors, ok := migrate.UpSync(pgdsn, "../sql")
|
||||||
if err != nil {
|
if !ok {
|
||||||
t.Fatalf("%s", err.Error())
|
fmt.Println("Oh no ...")
|
||||||
|
for _, err := range allErrors {
|
||||||
|
t.Log(err)
|
||||||
|
t.Fatal("Impossible to run test we get some errors when initialize the database schema")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test(db, t)
|
test(db, t)
|
||||||
|
35
tools/run.go
35
tools/run.go
@ -1,35 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
"github.com/kr/pretty"
|
|
||||||
_ "github.com/lib/pq"
|
|
||||||
)
|
|
||||||
|
|
||||||
var pg string
|
|
||||||
var sqlFile string
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
flag.StringVar(&pg, "pg", "", "postgres database's connection string")
|
|
||||||
flag.StringVar(&sqlFile, "file", "", "path to a sql file")
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
db := sqlx.MustConnect("postgres", pg)
|
|
||||||
err := db.Ping()
|
|
||||||
if err != nil {
|
|
||||||
pretty.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if sqlFile != "" {
|
|
||||||
r, err := sqlx.LoadFile(db, sqlFile)
|
|
||||||
if err != nil {
|
|
||||||
pretty.Println(err)
|
|
||||||
}
|
|
||||||
pretty.Println(r)
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,35 +8,6 @@ import (
|
|||||||
"gitlab.quimbo.fr/odwrtw/canape-sql/sqly"
|
"gitlab.quimbo.fr/odwrtw/canape-sql/sqly"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Schema = sqly.Schema{
|
|
||||||
Tables: []sqly.SchemaTable{
|
|
||||||
sqly.SchemaTable{
|
|
||||||
Name: "users",
|
|
||||||
Sql: `
|
|
||||||
CREATE TABLE users (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
name text NOT NULL UNIQUE,
|
|
||||||
updated timestamp DEFAULT current_timestamp,
|
|
||||||
created timestamp DEFAULT current_timestamp
|
|
||||||
);`},
|
|
||||||
sqly.SchemaTable{
|
|
||||||
Name: "tokens",
|
|
||||||
Sql: `
|
|
||||||
CREATE TABLE tokens (
|
|
||||||
id SERIAL,
|
|
||||||
value text NOT NULL UNIQUE,
|
|
||||||
users_id integer REFERENCES users (id) ON DELETE CASCADE,
|
|
||||||
updated timestamp DEFAULT current_timestamp,
|
|
||||||
created timestamp DEFAULT current_timestamp
|
|
||||||
);
|
|
||||||
`},
|
|
||||||
},
|
|
||||||
Drop: `
|
|
||||||
DROP TABLE tokens;
|
|
||||||
DROP TABLE users;
|
|
||||||
`,
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
addUserQuery = `INSERT INTO users (name) VALUES ($1) RETURNING id;`
|
addUserQuery = `INSERT INTO users (name) VALUES ($1) RETURNING id;`
|
||||||
getUserQuery = `SELECT * FROM users WHERE name=$1;`
|
getUserQuery = `SELECT * FROM users WHERE name=$1;`
|
||||||
|
@ -9,30 +9,26 @@ import (
|
|||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
|
_ "github.com/mattes/migrate/driver/postgres"
|
||||||
)
|
)
|
||||||
|
|
||||||
var db *sqlx.DB
|
var db *sqlx.DB
|
||||||
|
var pgdsn string
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
pgdsn := os.Getenv("POSTGRES_DSN")
|
pgdsn = os.Getenv("POSTGRES_DSN")
|
||||||
db, err = sqlx.Connect("postgres", pgdsn)
|
db, err = sqlx.Connect("postgres", pgdsn)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Unavailable PG tests:\n %v\n", err)
|
fmt.Printf("Unavailable PG tests:\n %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = sqly.InitDB(db)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Unavailable PG tests:\n %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUser(t *testing.T) {
|
func TestUser(t *testing.T) {
|
||||||
sqly.RunWithSchema(db, Schema, t, func(db *sqlx.DB, t *testing.T) {
|
sqly.RunWithLastestMigration(db, pgdsn, t, func(db *sqlx.DB, t *testing.T) {
|
||||||
|
|
||||||
// Add a new user
|
// Add a new user
|
||||||
u := &User{Name: "plop"}
|
u := &User{Name: "plop"}
|
||||||
@ -100,7 +96,7 @@ func TestUser(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTokenAddDelete(t *testing.T) {
|
func TestTokenAddDelete(t *testing.T) {
|
||||||
sqly.RunWithSchema(db, Schema, t, func(db *sqlx.DB, t *testing.T) {
|
sqly.RunWithLastestMigration(db, pgdsn, t, func(db *sqlx.DB, t *testing.T) {
|
||||||
// Add a new user
|
// Add a new user
|
||||||
u := &User{Name: "plop"}
|
u := &User{Name: "plop"}
|
||||||
err := u.Add(db)
|
err := u.Add(db)
|
||||||
@ -160,7 +156,7 @@ func TestTokenAddDelete(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTokenCheck(t *testing.T) {
|
func TestTokenCheck(t *testing.T) {
|
||||||
sqly.RunWithSchema(db, Schema, t, func(db *sqlx.DB, t *testing.T) {
|
sqly.RunWithLastestMigration(db, pgdsn, t, func(db *sqlx.DB, t *testing.T) {
|
||||||
u := &User{Name: "plop"}
|
u := &User{Name: "plop"}
|
||||||
u.Add(db)
|
u.Add(db)
|
||||||
token, err := u.NewToken(db)
|
token, err := u.NewToken(db)
|
||||||
@ -186,7 +182,7 @@ func TestTokenCheck(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAutoUpdateCols(t *testing.T) {
|
func TestAutoUpdateCols(t *testing.T) {
|
||||||
sqly.RunWithSchema(db, Schema, t, func(db *sqlx.DB, t *testing.T) {
|
sqly.RunWithLastestMigration(db, pgdsn, t, func(db *sqlx.DB, t *testing.T) {
|
||||||
u := &User{Name: "plop"}
|
u := &User{Name: "plop"}
|
||||||
u.Add(db)
|
u.Add(db)
|
||||||
u.Name = "toto"
|
u.Name = "toto"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user