mirror of
https://github.com/ent/ent.git
synced 2026-05-24 09:31:56 +03:00
entc/integration/migrate: enable postgres 10,11 in migrate test
Summary: Pull Request resolved: https://github.com/facebookincubator/ent/pull/132 Reviewed By: alexsn Differential Revision: D18203398 fbshipit-source-id: a261ed3934d2e4262d7177b41546b2239e798ef5
This commit is contained in:
committed by
Facebook Github Bot
parent
440a737d73
commit
38fcf995d0
@@ -41,8 +41,8 @@ var (
|
||||
{Name: "id", Type: field.TypeInt, Increment: true},
|
||||
{Name: "age", Type: field.TypeInt},
|
||||
{Name: "name", Type: field.TypeString, Size: 2147483647},
|
||||
{Name: "phone", Type: field.TypeString},
|
||||
{Name: "buffer", Type: field.TypeBytes, Default: user.DefaultBuffer},
|
||||
{Name: "phone", Type: field.TypeString, Default: user.DefaultPhone},
|
||||
{Name: "buffer", Type: field.TypeBytes, Nullable: true},
|
||||
{Name: "title", Type: field.TypeString, Default: user.DefaultTitle},
|
||||
{Name: "renamed", Type: field.TypeString, Nullable: true},
|
||||
{Name: "blob", Type: field.TypeBytes, Nullable: true, Size: 1000},
|
||||
|
||||
@@ -22,10 +22,11 @@ func (User) Fields() []ent.Field {
|
||||
field.Int("age"),
|
||||
// extending name field to longtext.
|
||||
field.Text("name"),
|
||||
// adding new columns.
|
||||
field.String("phone"),
|
||||
// adding new columns (must be either optional, or with a default value).
|
||||
field.String("phone").
|
||||
Default("unknown"),
|
||||
field.Bytes("buffer").
|
||||
Default([]byte("{}")),
|
||||
Optional(),
|
||||
// adding new column with supported default value
|
||||
// in the database side, will append this value to
|
||||
// all existing rows.
|
||||
|
||||
@@ -54,10 +54,10 @@ var Columns = []string{
|
||||
var (
|
||||
fields = schema.User{}.Fields()
|
||||
|
||||
// descBuffer is the schema descriptor for buffer field.
|
||||
descBuffer = fields[3].Descriptor()
|
||||
// DefaultBuffer holds the default value on creation for the buffer field.
|
||||
DefaultBuffer = descBuffer.Default.([]byte)
|
||||
// descPhone is the schema descriptor for phone field.
|
||||
descPhone = fields[2].Descriptor()
|
||||
// DefaultPhone holds the default value on creation for the phone field.
|
||||
DefaultPhone = descPhone.Default.(string)
|
||||
|
||||
// descTitle is the schema descriptor for title field.
|
||||
descTitle = fields[4].Descriptor()
|
||||
|
||||
@@ -633,6 +633,24 @@ func BufferLTE(v []byte) predicate.User {
|
||||
)
|
||||
}
|
||||
|
||||
// BufferIsNil applies the IsNil predicate on the "buffer" field.
|
||||
func BufferIsNil() predicate.User {
|
||||
return predicate.User(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.IsNull(s.C(FieldBuffer)))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// BufferNotNil applies the NotNil predicate on the "buffer" field.
|
||||
func BufferNotNil() predicate.User {
|
||||
return predicate.User(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.NotNull(s.C(FieldBuffer)))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// TitleEQ applies the EQ predicate on the "title" field.
|
||||
func TitleEQ(v string) predicate.User {
|
||||
return predicate.User(
|
||||
|
||||
@@ -46,6 +46,14 @@ func (uc *UserCreate) SetPhone(s string) *UserCreate {
|
||||
return uc
|
||||
}
|
||||
|
||||
// SetNillablePhone sets the phone field if the given value is not nil.
|
||||
func (uc *UserCreate) SetNillablePhone(s *string) *UserCreate {
|
||||
if s != nil {
|
||||
uc.SetPhone(*s)
|
||||
}
|
||||
return uc
|
||||
}
|
||||
|
||||
// SetBuffer sets the buffer field.
|
||||
func (uc *UserCreate) SetBuffer(b []byte) *UserCreate {
|
||||
uc.buffer = &b
|
||||
@@ -109,11 +117,8 @@ func (uc *UserCreate) Save(ctx context.Context) (*User, error) {
|
||||
return nil, errors.New("entv2: missing required field \"name\"")
|
||||
}
|
||||
if uc.phone == nil {
|
||||
return nil, errors.New("entv2: missing required field \"phone\"")
|
||||
}
|
||||
if uc.buffer == nil {
|
||||
v := user.DefaultBuffer
|
||||
uc.buffer = &v
|
||||
v := user.DefaultPhone
|
||||
uc.phone = &v
|
||||
}
|
||||
if uc.title == nil {
|
||||
v := user.DefaultTitle
|
||||
|
||||
@@ -23,6 +23,7 @@ type UserUpdate struct {
|
||||
name *string
|
||||
phone *string
|
||||
buffer *[]byte
|
||||
clearbuffer bool
|
||||
title *string
|
||||
new_name *string
|
||||
clearnew_name bool
|
||||
@@ -68,12 +69,27 @@ func (uu *UserUpdate) SetPhone(s string) *UserUpdate {
|
||||
return uu
|
||||
}
|
||||
|
||||
// SetNillablePhone sets the phone field if the given value is not nil.
|
||||
func (uu *UserUpdate) SetNillablePhone(s *string) *UserUpdate {
|
||||
if s != nil {
|
||||
uu.SetPhone(*s)
|
||||
}
|
||||
return uu
|
||||
}
|
||||
|
||||
// SetBuffer sets the buffer field.
|
||||
func (uu *UserUpdate) SetBuffer(b []byte) *UserUpdate {
|
||||
uu.buffer = &b
|
||||
return uu
|
||||
}
|
||||
|
||||
// ClearBuffer clears the value of buffer.
|
||||
func (uu *UserUpdate) ClearBuffer() *UserUpdate {
|
||||
uu.buffer = nil
|
||||
uu.clearbuffer = true
|
||||
return uu
|
||||
}
|
||||
|
||||
// SetTitle sets the title field.
|
||||
func (uu *UserUpdate) SetTitle(s string) *UserUpdate {
|
||||
uu.title = &s
|
||||
@@ -224,6 +240,9 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
if value := uu.buffer; value != nil {
|
||||
updater.Set(user.FieldBuffer, *value)
|
||||
}
|
||||
if uu.clearbuffer {
|
||||
updater.SetNull(user.FieldBuffer)
|
||||
}
|
||||
if value := uu.title; value != nil {
|
||||
updater.Set(user.FieldTitle, *value)
|
||||
}
|
||||
@@ -266,6 +285,7 @@ type UserUpdateOne struct {
|
||||
name *string
|
||||
phone *string
|
||||
buffer *[]byte
|
||||
clearbuffer bool
|
||||
title *string
|
||||
new_name *string
|
||||
clearnew_name bool
|
||||
@@ -304,12 +324,27 @@ func (uuo *UserUpdateOne) SetPhone(s string) *UserUpdateOne {
|
||||
return uuo
|
||||
}
|
||||
|
||||
// SetNillablePhone sets the phone field if the given value is not nil.
|
||||
func (uuo *UserUpdateOne) SetNillablePhone(s *string) *UserUpdateOne {
|
||||
if s != nil {
|
||||
uuo.SetPhone(*s)
|
||||
}
|
||||
return uuo
|
||||
}
|
||||
|
||||
// SetBuffer sets the buffer field.
|
||||
func (uuo *UserUpdateOne) SetBuffer(b []byte) *UserUpdateOne {
|
||||
uuo.buffer = &b
|
||||
return uuo
|
||||
}
|
||||
|
||||
// ClearBuffer clears the value of buffer.
|
||||
func (uuo *UserUpdateOne) ClearBuffer() *UserUpdateOne {
|
||||
uuo.buffer = nil
|
||||
uuo.clearbuffer = true
|
||||
return uuo
|
||||
}
|
||||
|
||||
// SetTitle sets the title field.
|
||||
func (uuo *UserUpdateOne) SetTitle(s string) *UserUpdateOne {
|
||||
uuo.title = &s
|
||||
@@ -468,6 +503,11 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) {
|
||||
updater.Set(user.FieldBuffer, *value)
|
||||
u.Buffer = *value
|
||||
}
|
||||
if uuo.clearbuffer {
|
||||
var value []byte
|
||||
u.Buffer = value
|
||||
updater.SetNull(user.FieldBuffer)
|
||||
}
|
||||
if value := uuo.title; value != nil {
|
||||
updater.Set(user.FieldTitle, *value)
|
||||
u.Title = *value
|
||||
|
||||
@@ -7,8 +7,10 @@ package migrate
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/facebookincubator/ent/dialect"
|
||||
"github.com/facebookincubator/ent/dialect/sql"
|
||||
"github.com/facebookincubator/ent/entc/integration/migrate/entv1"
|
||||
migratev1 "github.com/facebookincubator/ent/entc/integration/migrate/entv1/migrate"
|
||||
@@ -16,7 +18,9 @@ import (
|
||||
"github.com/facebookincubator/ent/entc/integration/migrate/entv2"
|
||||
migratev2 "github.com/facebookincubator/ent/entc/integration/migrate/entv2/migrate"
|
||||
"github.com/facebookincubator/ent/entc/integration/migrate/entv2/user"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -35,29 +39,34 @@ func TestMySQL(t *testing.T) {
|
||||
drv, err := sql.Open("mysql", fmt.Sprintf("root:pass@tcp(localhost:%d)/migrate?parseTime=True", port))
|
||||
require.NoError(t, err, "connecting to migrate database")
|
||||
|
||||
// run migration and execute queries on v1.
|
||||
clientv1 := entv1.NewClient(entv1.Driver(drv))
|
||||
require.NoError(t, clientv1.Schema.Create(ctx, migratev1.WithGlobalUniqueID(true)))
|
||||
SanityV1(t, clientv1)
|
||||
|
||||
// run migration and execute queries on v2.
|
||||
clientv2 := entv2.NewClient(entv2.Driver(drv))
|
||||
require.NoError(t, clientv2.Schema.Create(ctx, migratev2.WithGlobalUniqueID(true), migratev2.WithDropIndex(true), migratev2.WithDropColumn(true)))
|
||||
SanityV2(t, clientv2)
|
||||
V1ToV2(t, clientv1, clientv2)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// since "users" created in the migration of v1, it will occupy the range of 0 ... 1<<32-1,
|
||||
// even though they are ordered differently in the migration of v2 (groups, pets, users).
|
||||
idRange(t, clientv2.User.Create().SetAge(1).SetName("foo").SetPhone("phone").SaveX(ctx).ID, 0, 1<<32)
|
||||
idRange(t, clientv2.Group.Create().SaveX(ctx).ID, 1<<32-1, 2<<32)
|
||||
idRange(t, clientv2.Pet.Create().SaveX(ctx).ID, 2<<32-1, 3<<32)
|
||||
func TestPostgres(t *testing.T) {
|
||||
// Version 12 is disabled here due to segfault on migration. It will be re-enabled on its next release.
|
||||
// More info can be found here: https://www.postgresql.org/message-id/23031.1572362774%40sss.pgh.pa.us
|
||||
for version, port := range map[string]int{"10": 5430, "11": 5431} {
|
||||
t.Run(version, func(t *testing.T) {
|
||||
dsn := fmt.Sprintf("host=localhost port=%d user=postgres password=pass sslmode=disable", port)
|
||||
root, err := sql.Open(dialect.Postgres, dsn)
|
||||
require.NoError(t, err)
|
||||
defer root.Close()
|
||||
ctx := context.Background()
|
||||
err = root.Exec(ctx, "CREATE DATABASE migrate", []interface{}{}, new(sql.Result))
|
||||
require.NoError(t, err, "creating database")
|
||||
defer root.Exec(ctx, "DROP DATABASE migrate", []interface{}{}, new(sql.Result))
|
||||
|
||||
// sql specific predicates.
|
||||
EqualFold(t, clientv2)
|
||||
ContainsFold(t, clientv2)
|
||||
drv, err := sql.Open(dialect.Postgres, dsn+" dbname=migrate")
|
||||
require.NoError(t, err, "connecting to migrate database")
|
||||
defer drv.Close()
|
||||
|
||||
// "renamed" field was renamed to "new_name".
|
||||
exist := clientv2.User.Query().Where(user.NewName("renamed")).ExistX(ctx)
|
||||
require.True(t, exist, "expect renamed column to have previous values")
|
||||
clientv1 := entv1.NewClient(entv1.Driver(drv))
|
||||
clientv2 := entv2.NewClient(entv2.Driver(drv))
|
||||
V1ToV2(t, clientv1, clientv2)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -84,6 +93,32 @@ func TestSQLite(t *testing.T) {
|
||||
ContainsFold(t, client)
|
||||
}
|
||||
|
||||
func V1ToV2(t *testing.T, clientv1 *entv1.Client, clientv2 *entv2.Client) {
|
||||
ctx := context.Background()
|
||||
|
||||
// run migration and execute queries on v1.
|
||||
require.NoError(t, clientv1.Schema.Create(ctx, migratev1.WithGlobalUniqueID(true)))
|
||||
SanityV1(t, clientv1)
|
||||
|
||||
// run migration and execute queries on v2.
|
||||
require.NoError(t, clientv2.Schema.Create(ctx, migratev2.WithGlobalUniqueID(true), migratev2.WithDropIndex(true), migratev2.WithDropColumn(true)))
|
||||
SanityV2(t, clientv2)
|
||||
|
||||
// since "users" created in the migration of v1, it will occupy the range of 0 ... 1<<32-1,
|
||||
// even though they are ordered differently in the migration of v2 (groups, pets, users).
|
||||
idRange(t, clientv2.User.Create().SetAge(1).SetName("foo").SetPhone("phone").SaveX(ctx).ID, 0, 1<<32)
|
||||
idRange(t, clientv2.Group.Create().SaveX(ctx).ID, 1<<32-1, 2<<32)
|
||||
idRange(t, clientv2.Pet.Create().SaveX(ctx).ID, 2<<32-1, 3<<32)
|
||||
|
||||
// sql specific predicates.
|
||||
EqualFold(t, clientv2)
|
||||
ContainsFold(t, clientv2)
|
||||
|
||||
// "renamed" field was renamed to "new_name".
|
||||
exist := clientv2.User.Query().Where(user.NewName("renamed")).ExistX(ctx)
|
||||
require.True(t, exist, "expect renamed column to have previous values")
|
||||
}
|
||||
|
||||
func SanityV1(t *testing.T, client *entv1.Client) {
|
||||
ctx := context.Background()
|
||||
u := client.User.Create().SetAge(1).SetName("foo").SetRenamed("renamed").SaveX(ctx)
|
||||
@@ -102,7 +137,7 @@ func SanityV1(t *testing.T, client *entv1.Client) {
|
||||
u = u.Update().SetBlob([]byte("hello")).SaveX(ctx)
|
||||
require.Equal(t, "hello", string(u.Blob))
|
||||
_, err = u.Update().SetBlob(make([]byte, 256)).Save(ctx)
|
||||
require.Error(t, err, "data too long for column 'blob' error")
|
||||
require.True(t, strings.Contains(t.Name(), "Postgres") || err != nil, "blob should be limited on SQLite and MySQL")
|
||||
|
||||
// invalid enum value.
|
||||
_, err = client.User.Create().SetAge(1).SetName("bar").SetState("unknown").Save(ctx)
|
||||
@@ -111,7 +146,7 @@ func SanityV1(t *testing.T, client *entv1.Client) {
|
||||
|
||||
func SanityV2(t *testing.T, client *entv2.Client) {
|
||||
ctx := context.Background()
|
||||
u := client.User.Create().SetAge(1).SetName("bar").SetPhone("100").SetState(user.StateLoggedOut).SaveX(ctx)
|
||||
u := client.User.Create().SetAge(1).SetName("bar").SetPhone("100").SetBuffer([]byte("{}")).SetState(user.StateLoggedOut).SaveX(ctx)
|
||||
require.Equal(t, 1, u.Age)
|
||||
require.Equal(t, "bar", u.Name)
|
||||
require.Equal(t, []byte("{}"), u.Buffer)
|
||||
|
||||
Reference in New Issue
Block a user