support gaussdb
This commit is contained in:
parent
49b01a3e93
commit
306da0069b
@ -206,9 +206,9 @@ func TestDeleteSliceWithAssociations(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// only sqlite, postgres, sqlserver support returning
|
// only sqlite, postgres, gaussdb, sqlserver support returning
|
||||||
func TestSoftDeleteReturning(t *testing.T) {
|
func TestSoftDeleteReturning(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "sqlite" && DB.Dialector.Name() != "postgres" && DB.Dialector.Name() != "sqlserver" {
|
if DB.Dialector.Name() != "sqlite" && DB.Dialector.Name() != "postgres" && DB.Dialector.Name() != "gaussdb" && DB.Dialector.Name() != "sqlserver" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,7 +233,7 @@ func TestSoftDeleteReturning(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteReturning(t *testing.T) {
|
func TestDeleteReturning(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "sqlite" && DB.Dialector.Name() != "postgres" && DB.Dialector.Name() != "sqlserver" {
|
if DB.Dialector.Name() != "sqlite" && DB.Dialector.Name() != "postgres" && DB.Dialector.Name() != "gaussdb" && DB.Dialector.Name() != "sqlserver" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ func TestSupportedDialectorWithErrDuplicatedKey(t *testing.T) {
|
|||||||
t.Fatalf("failed to connect database, got error %v", err)
|
t.Fatalf("failed to connect database, got error %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
dialectors := map[string]bool{"sqlite": true, "postgres": true, "mysql": true, "sqlserver": true}
|
dialectors := map[string]bool{"sqlite": true, "postgres": true, "gaussdb": true, "mysql": true, "sqlserver": true}
|
||||||
if supported, found := dialectors[db.Dialector.Name()]; !(found && supported) {
|
if supported, found := dialectors[db.Dialector.Name()]; !(found && supported) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -81,7 +81,7 @@ func TestSupportedDialectorWithErrForeignKeyViolated(t *testing.T) {
|
|||||||
t.Fatalf("failed to connect database, got error %v", err)
|
t.Fatalf("failed to connect database, got error %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
dialectors := map[string]bool{"sqlite": true, "postgres": true, "mysql": true, "sqlserver": true}
|
dialectors := map[string]bool{"sqlite": true, "postgres": true, "gaussdb": true, "mysql": true, "sqlserver": true}
|
||||||
if supported, found := dialectors[db.Dialector.Name()]; !(found && supported) {
|
if supported, found := dialectors[db.Dialector.Name()]; !(found && supported) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/moseszane168/gaussdb"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gorm.io/driver/postgres"
|
"gorm.io/driver/postgres"
|
||||||
|
|
||||||
@ -83,7 +84,45 @@ func TestMigrate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAutoMigrateInt8PG(t *testing.T) {
|
func TestAutoMigrateInt8PG(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "postgres" {
|
if DB.Dialector.Name() != "postgres" || DB.Dialector.Name() != "gaussdb" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type Smallint int8
|
||||||
|
|
||||||
|
type MigrateInt struct {
|
||||||
|
Int8 Smallint
|
||||||
|
}
|
||||||
|
|
||||||
|
tracer := Tracer{
|
||||||
|
Logger: DB.Config.Logger,
|
||||||
|
Test: func(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
|
||||||
|
sql, _ := fc()
|
||||||
|
if strings.HasPrefix(sql, "ALTER TABLE \"migrate_ints\" ALTER COLUMN \"int8\" TYPE smallint") {
|
||||||
|
t.Fatalf("shouldn't execute ALTER COLUMN TYPE if such type is already existed in DB schema: sql: %s",
|
||||||
|
sql)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
DB.Migrator().DropTable(&MigrateInt{})
|
||||||
|
|
||||||
|
// The first AutoMigrate to make table with field with correct type
|
||||||
|
if err := DB.AutoMigrate(&MigrateInt{}); err != nil {
|
||||||
|
t.Fatalf("Failed to auto migrate: error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// make new session to set custom logger tracer
|
||||||
|
session := DB.Session(&gorm.Session{Logger: tracer})
|
||||||
|
|
||||||
|
// The second AutoMigrate to catch an error
|
||||||
|
if err := session.AutoMigrate(&MigrateInt{}); err != nil {
|
||||||
|
t.Fatalf("Failed to auto migrate: error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAutoMigrateGaussDB(t *testing.T) {
|
||||||
|
if DB.Dialector.Name() != "gaussdb" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +221,94 @@ func TestAutoMigrateNullable(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSmartMigrateColumn(t *testing.T) {
|
func TestSmartMigrateColumn(t *testing.T) {
|
||||||
fullSupported := map[string]bool{"mysql": true, "postgres": true}[DB.Dialector.Name()]
|
fullSupported := map[string]bool{"mysql": true, "postgres": true, "gaussdb": true}[DB.Dialector.Name()]
|
||||||
|
|
||||||
|
type UserMigrateColumn struct {
|
||||||
|
ID uint
|
||||||
|
Name string
|
||||||
|
Salary float64
|
||||||
|
Birthday time.Time `gorm:"precision:4"`
|
||||||
|
}
|
||||||
|
|
||||||
|
DB.Migrator().DropTable(&UserMigrateColumn{})
|
||||||
|
|
||||||
|
DB.AutoMigrate(&UserMigrateColumn{})
|
||||||
|
|
||||||
|
type UserMigrateColumn2 struct {
|
||||||
|
ID uint
|
||||||
|
Name string `gorm:"size:128"`
|
||||||
|
Salary float64 `gorm:"precision:2"`
|
||||||
|
Birthday time.Time `gorm:"precision:2"`
|
||||||
|
NameIgnoreMigration string `gorm:"size:100"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := DB.Table("user_migrate_columns").AutoMigrate(&UserMigrateColumn2{}); err != nil {
|
||||||
|
t.Fatalf("failed to auto migrate, got error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
columnTypes, err := DB.Table("user_migrate_columns").Migrator().ColumnTypes(&UserMigrateColumn{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to get column types, got error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, columnType := range columnTypes {
|
||||||
|
switch columnType.Name() {
|
||||||
|
case "name":
|
||||||
|
if length, _ := columnType.Length(); (fullSupported || length != 0) && length != 128 {
|
||||||
|
t.Fatalf("name's length should be 128, but got %v", length)
|
||||||
|
}
|
||||||
|
case "salary":
|
||||||
|
if precision, o, _ := columnType.DecimalSize(); (fullSupported || precision != 0) && precision != 2 {
|
||||||
|
t.Fatalf("salary's precision should be 2, but got %v %v", precision, o)
|
||||||
|
}
|
||||||
|
case "birthday":
|
||||||
|
if precision, _, _ := columnType.DecimalSize(); (fullSupported || precision != 0) && precision != 2 {
|
||||||
|
t.Fatalf("birthday's precision should be 2, but got %v", precision)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserMigrateColumn3 struct {
|
||||||
|
ID uint
|
||||||
|
Name string `gorm:"size:256"`
|
||||||
|
Salary float64 `gorm:"precision:3"`
|
||||||
|
Birthday time.Time `gorm:"precision:3"`
|
||||||
|
NameIgnoreMigration string `gorm:"size:128;-:migration"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := DB.Table("user_migrate_columns").AutoMigrate(&UserMigrateColumn3{}); err != nil {
|
||||||
|
t.Fatalf("failed to auto migrate, got error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
columnTypes, err = DB.Table("user_migrate_columns").Migrator().ColumnTypes(&UserMigrateColumn{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to get column types, got error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, columnType := range columnTypes {
|
||||||
|
switch columnType.Name() {
|
||||||
|
case "name":
|
||||||
|
if length, _ := columnType.Length(); (fullSupported || length != 0) && length != 256 {
|
||||||
|
t.Fatalf("name's length should be 128, but got %v", length)
|
||||||
|
}
|
||||||
|
case "salary":
|
||||||
|
if precision, _, _ := columnType.DecimalSize(); (fullSupported || precision != 0) && precision != 3 {
|
||||||
|
t.Fatalf("salary's precision should be 2, but got %v", precision)
|
||||||
|
}
|
||||||
|
case "birthday":
|
||||||
|
if precision, _, _ := columnType.DecimalSize(); (fullSupported || precision != 0) && precision != 3 {
|
||||||
|
t.Fatalf("birthday's precision should be 2, but got %v", precision)
|
||||||
|
}
|
||||||
|
case "name_ignore_migration":
|
||||||
|
if length, _ := columnType.Length(); (fullSupported || length != 0) && length != 100 {
|
||||||
|
t.Fatalf("name_ignore_migration's length should still be 100 but got %v", length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSmartMigrateColumnGaussDB(t *testing.T) {
|
||||||
|
fullSupported := map[string]bool{"mysql": true, "gaussdb": true}[DB.Dialector.Name()]
|
||||||
|
|
||||||
type UserMigrateColumn struct {
|
type UserMigrateColumn struct {
|
||||||
ID uint
|
ID uint
|
||||||
@ -850,7 +976,68 @@ func TestMigrateColumnOrder(t *testing.T) {
|
|||||||
|
|
||||||
// https://github.com/go-gorm/gorm/issues/5047
|
// https://github.com/go-gorm/gorm/issues/5047
|
||||||
func TestMigrateSerialColumn(t *testing.T) {
|
func TestMigrateSerialColumn(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "postgres" {
|
if DB.Dialector.Name() != "postgres" || DB.Dialector.Name() != "gaussdb" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type Event struct {
|
||||||
|
ID uint `gorm:"primarykey"`
|
||||||
|
UID uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type Event1 struct {
|
||||||
|
ID uint `gorm:"primarykey"`
|
||||||
|
UID uint32 `gorm:"not null;autoIncrement"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Event2 struct {
|
||||||
|
ID uint `gorm:"primarykey"`
|
||||||
|
UID uint16 `gorm:"not null;autoIncrement"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
err = DB.Migrator().DropTable(&Event{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("DropTable err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create sequence
|
||||||
|
err = DB.Table("events").AutoMigrate(&Event1{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("AutoMigrate err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete sequence
|
||||||
|
err = DB.Table("events").AutoMigrate(&Event{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("AutoMigrate err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// update sequence
|
||||||
|
err = DB.Table("events").AutoMigrate(&Event1{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("AutoMigrate err:%v", err)
|
||||||
|
}
|
||||||
|
err = DB.Table("events").AutoMigrate(&Event2{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("AutoMigrate err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
DB.Table("events").Save(&Event2{})
|
||||||
|
DB.Table("events").Save(&Event2{})
|
||||||
|
DB.Table("events").Save(&Event2{})
|
||||||
|
|
||||||
|
events := make([]*Event, 0)
|
||||||
|
DB.Table("events").Find(&events)
|
||||||
|
|
||||||
|
AssertEqual(t, 3, len(events))
|
||||||
|
for _, v := range events {
|
||||||
|
AssertEqual(t, v.ID, v.UID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMigrateSerialColumnGaussDB(t *testing.T) {
|
||||||
|
if DB.Dialector.Name() != "gaussdb" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -975,7 +1162,7 @@ func TestMigrateAutoIncrement(t *testing.T) {
|
|||||||
|
|
||||||
// https://github.com/go-gorm/gorm/issues/5320
|
// https://github.com/go-gorm/gorm/issues/5320
|
||||||
func TestPrimarykeyID(t *testing.T) {
|
func TestPrimarykeyID(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "postgres" {
|
if DB.Dialector.Name() != "postgres" || DB.Dialector.Name() != "gaussdb" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1009,6 +1196,41 @@ func TestPrimarykeyID(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPrimarykeyIDGaussDB(t *testing.T) {
|
||||||
|
if DB.Dialector.Name() != "gaussdb" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type MissPKLanguage struct {
|
||||||
|
ID string `gorm:"type:uuid;default:uuid_generate_v4()"`
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type MissPKUser struct {
|
||||||
|
ID string `gorm:"type:uuid;default:uuid_generate_v4()"`
|
||||||
|
MissPKLanguages []MissPKLanguage `gorm:"many2many:miss_pk_user_languages;"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
err = DB.Migrator().DropTable(&MissPKUser{}, &MissPKLanguage{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("DropTable err:%v", err)
|
||||||
|
}
|
||||||
|
// TODO: ERROR: could not open extension control file: No such file or directory (SQLSTATE 58P01)
|
||||||
|
DB.Exec(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp";`)
|
||||||
|
|
||||||
|
err = DB.AutoMigrate(&MissPKUser{}, &MissPKLanguage{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("AutoMigrate err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// patch
|
||||||
|
err = DB.AutoMigrate(&MissPKUser{}, &MissPKLanguage{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("AutoMigrate err:%v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCurrentTimestamp(t *testing.T) {
|
func TestCurrentTimestamp(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "mysql" {
|
if DB.Dialector.Name() != "mysql" {
|
||||||
return
|
return
|
||||||
@ -1175,7 +1397,7 @@ func findColumnType(dest interface{}, columnName string) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestInvalidCachedPlanSimpleProtocol(t *testing.T) {
|
func TestInvalidCachedPlanSimpleProtocol(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "postgres" {
|
if DB.Dialector.Name() != "postgres" || DB.Dialector.Name() != "gaussdb" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1209,6 +1431,42 @@ func TestInvalidCachedPlanSimpleProtocol(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: ERROR: must have at least one column (SQLSTATE 0A000)
|
||||||
|
func TestInvalidCachedPlanSimpleProtocolGaussDB(t *testing.T) {
|
||||||
|
if DB.Dialector.Name() != "gaussdb" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
db, err := gorm.Open(gaussdb.Open(gaussdbDSN), &gorm.Config{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Open err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Object1 struct{}
|
||||||
|
type Object2 struct {
|
||||||
|
Field1 string
|
||||||
|
}
|
||||||
|
type Object3 struct {
|
||||||
|
Field2 string
|
||||||
|
}
|
||||||
|
db.Migrator().DropTable("objects")
|
||||||
|
|
||||||
|
err = db.Table("objects").AutoMigrate(&Object1{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("AutoMigrate err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Table("objects").AutoMigrate(&Object2{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("AutoMigrate err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Table("objects").AutoMigrate(&Object3{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("AutoMigrate err:%v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDifferentTypeWithoutDeclaredLength(t *testing.T) {
|
func TestDifferentTypeWithoutDeclaredLength(t *testing.T) {
|
||||||
type DiffType struct {
|
type DiffType struct {
|
||||||
ID uint
|
ID uint
|
||||||
@ -1249,7 +1507,43 @@ func TestDifferentTypeWithoutDeclaredLength(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMigrateArrayTypeModel(t *testing.T) {
|
func TestMigrateArrayTypeModel(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "postgres" {
|
if DB.Dialector.Name() != "postgres" || DB.Dialector.Name() != "gaussdb" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type ArrayTypeModel struct {
|
||||||
|
ID uint
|
||||||
|
Number string `gorm:"type:varchar(51);NOT NULL"`
|
||||||
|
TextArray []string `gorm:"type:text[];NOT NULL"`
|
||||||
|
NestedTextArray [][]string `gorm:"type:text[][]"`
|
||||||
|
NestedIntArray [][]int64 `gorm:"type:integer[3][3]"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
DB.Migrator().DropTable(&ArrayTypeModel{})
|
||||||
|
|
||||||
|
err = DB.AutoMigrate(&ArrayTypeModel{})
|
||||||
|
AssertEqual(t, nil, err)
|
||||||
|
|
||||||
|
ct, err := findColumnType(&ArrayTypeModel{}, "number")
|
||||||
|
AssertEqual(t, nil, err)
|
||||||
|
AssertEqual(t, "varchar", ct.DatabaseTypeName())
|
||||||
|
|
||||||
|
ct, err = findColumnType(&ArrayTypeModel{}, "text_array")
|
||||||
|
AssertEqual(t, nil, err)
|
||||||
|
AssertEqual(t, "text[]", ct.DatabaseTypeName())
|
||||||
|
|
||||||
|
ct, err = findColumnType(&ArrayTypeModel{}, "nested_text_array")
|
||||||
|
AssertEqual(t, nil, err)
|
||||||
|
AssertEqual(t, "text[]", ct.DatabaseTypeName())
|
||||||
|
|
||||||
|
ct, err = findColumnType(&ArrayTypeModel{}, "nested_int_array")
|
||||||
|
AssertEqual(t, nil, err)
|
||||||
|
AssertEqual(t, "integer[]", ct.DatabaseTypeName())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMigrateArrayTypeModelGaussDB(t *testing.T) {
|
||||||
|
if DB.Dialector.Name() != "gaussdb" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1572,7 +1866,66 @@ func TestMigrateView(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMigrateExistingBoolColumnPG(t *testing.T) {
|
func TestMigrateExistingBoolColumnPG(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "postgres" {
|
if DB.Dialector.Name() != "postgres" || DB.Dialector.Name() != "gaussdb" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type ColumnStruct struct {
|
||||||
|
gorm.Model
|
||||||
|
Name string
|
||||||
|
StringBool string
|
||||||
|
SmallintBool int `gorm:"type:smallint"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ColumnStruct2 struct {
|
||||||
|
gorm.Model
|
||||||
|
Name string
|
||||||
|
StringBool bool // change existing boolean column from string to boolean
|
||||||
|
SmallintBool bool // change existing boolean column from smallint or other to boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
DB.Migrator().DropTable(&ColumnStruct{})
|
||||||
|
|
||||||
|
if err := DB.AutoMigrate(&ColumnStruct{}); err != nil {
|
||||||
|
t.Errorf("Failed to migrate, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := DB.Table("column_structs").AutoMigrate(&ColumnStruct2{}); err != nil {
|
||||||
|
t.Fatalf("no error should happened when auto migrate column, but got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if columnTypes, err := DB.Migrator().ColumnTypes(&ColumnStruct{}); err != nil {
|
||||||
|
t.Fatalf("no error should returns for ColumnTypes")
|
||||||
|
} else {
|
||||||
|
stmt := &gorm.Statement{DB: DB}
|
||||||
|
stmt.Parse(&ColumnStruct2{})
|
||||||
|
|
||||||
|
for _, columnType := range columnTypes {
|
||||||
|
switch columnType.Name() {
|
||||||
|
case "id":
|
||||||
|
if v, ok := columnType.PrimaryKey(); !ok || !v {
|
||||||
|
t.Fatalf("column id primary key should be correct, name: %v, column: %#v", columnType.Name(),
|
||||||
|
columnType)
|
||||||
|
}
|
||||||
|
case "string_bool":
|
||||||
|
dataType := DB.Dialector.DataTypeOf(stmt.Schema.LookUpField(columnType.Name()))
|
||||||
|
if !strings.Contains(strings.ToUpper(dataType), strings.ToUpper(columnType.DatabaseTypeName())) {
|
||||||
|
t.Fatalf("column name type should be correct, name: %v, length: %v, expects: %v, column: %#v",
|
||||||
|
columnType.Name(), columnType.DatabaseTypeName(), dataType, columnType)
|
||||||
|
}
|
||||||
|
case "smallint_bool":
|
||||||
|
dataType := DB.Dialector.DataTypeOf(stmt.Schema.LookUpField(columnType.Name()))
|
||||||
|
if !strings.Contains(strings.ToUpper(dataType), strings.ToUpper(columnType.DatabaseTypeName())) {
|
||||||
|
t.Fatalf("column name type should be correct, name: %v, length: %v, expects: %v, column: %#v",
|
||||||
|
columnType.Name(), columnType.DatabaseTypeName(), dataType, columnType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMigrateExistingBoolColumnGaussDB(t *testing.T) {
|
||||||
|
if DB.Dialector.Name() != "gaussdb" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ func TestManyToManyWithMultiPrimaryKeys(t *testing.T) {
|
|||||||
t.Skip("skip sqlite, sqlserver due to it doesn't support multiple primary keys with auto increment")
|
t.Skip("skip sqlite, sqlserver due to it doesn't support multiple primary keys with auto increment")
|
||||||
}
|
}
|
||||||
|
|
||||||
if name := DB.Dialector.Name(); name == "postgres" {
|
if name := DB.Dialector.Name(); name == "postgres" || name == "mysql" || name == "gaussdb" {
|
||||||
stmt := gorm.Statement{DB: DB}
|
stmt := gorm.Statement{DB: DB}
|
||||||
stmt.Parse(&Blog{})
|
stmt.Parse(&Blog{})
|
||||||
stmt.Schema.LookUpField("ID").Unique = true
|
stmt.Schema.LookUpField("ID").Unique = true
|
||||||
@ -142,6 +142,9 @@ func TestManyToManyWithCustomizedForeignKeys(t *testing.T) {
|
|||||||
if name := DB.Dialector.Name(); name == "postgres" {
|
if name := DB.Dialector.Name(); name == "postgres" {
|
||||||
t.Skip("skip postgres due to it only allow unique constraint matching given keys")
|
t.Skip("skip postgres due to it only allow unique constraint matching given keys")
|
||||||
}
|
}
|
||||||
|
if name := DB.Dialector.Name(); name == "gaussdb" {
|
||||||
|
t.Skip("skip gaussdb due to it only allow unique constraint matching given keys")
|
||||||
|
}
|
||||||
|
|
||||||
DB.Migrator().DropTable(&Blog{}, &Tag{}, "blog_tags", "locale_blog_tags", "shared_blog_tags")
|
DB.Migrator().DropTable(&Blog{}, &Tag{}, "blog_tags", "locale_blog_tags", "shared_blog_tags")
|
||||||
if err := DB.AutoMigrate(&Blog{}, &Tag{}); err != nil {
|
if err := DB.AutoMigrate(&Blog{}, &Tag{}); err != nil {
|
||||||
@ -268,6 +271,10 @@ func TestManyToManyWithCustomizedForeignKeys2(t *testing.T) {
|
|||||||
t.Skip("skip postgres due to it only allow unique constraint matching given keys")
|
t.Skip("skip postgres due to it only allow unique constraint matching given keys")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if name := DB.Dialector.Name(); name == "gaussdb" {
|
||||||
|
t.Skip("skip gaussdb due to it only allow unique constraint matching given keys")
|
||||||
|
}
|
||||||
|
|
||||||
DB.Migrator().DropTable(&Blog{}, &Tag{}, "blog_tags", "locale_blog_tags", "shared_blog_tags")
|
DB.Migrator().DropTable(&Blog{}, &Tag{}, "blog_tags", "locale_blog_tags", "shared_blog_tags")
|
||||||
if err := DB.AutoMigrate(&Blog{}, &Tag{}); err != nil {
|
if err := DB.AutoMigrate(&Blog{}, &Tag{}); err != nil {
|
||||||
t.Fatalf("Failed to auto migrate, got error: %v", err)
|
t.Fatalf("Failed to auto migrate, got error: %v", err)
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestPostgresReturningIDWhichHasStringType(t *testing.T) {
|
func TestPostgresReturningIDWhichHasStringType(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "postgres" {
|
if DB.Dialector.Name() != "postgres" || DB.Dialector.Name() != "gaussdb" {
|
||||||
t.Skip()
|
t.Skip()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ func TestPostgresReturningIDWhichHasStringType(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPostgres(t *testing.T) {
|
func TestPostgres(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "postgres" {
|
if DB.Dialector.Name() != "postgres" || DB.Dialector.Name() != "gaussdb" {
|
||||||
t.Skip()
|
t.Skip()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ type Category struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMany2ManyWithDefaultValueUUID(t *testing.T) {
|
func TestMany2ManyWithDefaultValueUUID(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "postgres" {
|
if DB.Dialector.Name() != "postgres" || DB.Dialector.Name() != "gaussdb" {
|
||||||
t.Skip()
|
t.Skip()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +191,7 @@ func TestMany2ManyWithDefaultValueUUID(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPostgresOnConstraint(t *testing.T) {
|
func TestPostgresOnConstraint(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "postgres" {
|
if DB.Dialector.Name() != "postgres" || DB.Dialector.Name() != "gaussdb" {
|
||||||
t.Skip()
|
t.Skip()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ type SerializerPostgresStruct struct {
|
|||||||
func (*SerializerPostgresStruct) TableName() string { return "serializer_structs" }
|
func (*SerializerPostgresStruct) TableName() string { return "serializer_structs" }
|
||||||
|
|
||||||
func adaptorSerializerModel(s *SerializerStruct) interface{} {
|
func adaptorSerializerModel(s *SerializerStruct) interface{} {
|
||||||
if DB.Dialector.Name() == "postgres" {
|
if DB.Dialector.Name() == "postgres" || DB.Dialector.Name() == "gaussdb" {
|
||||||
sps := SerializerPostgresStruct(*s)
|
sps := SerializerPostgresStruct(*s)
|
||||||
return &sps
|
return &sps
|
||||||
}
|
}
|
||||||
|
@ -487,7 +487,7 @@ func replaceQuoteInSQL(sql string) string {
|
|||||||
|
|
||||||
// convert dialect special quote into double quote
|
// convert dialect special quote into double quote
|
||||||
switch DB.Dialector.Name() {
|
switch DB.Dialector.Name() {
|
||||||
case "postgres":
|
case "postgres", "gaussdb":
|
||||||
sql = strings.ReplaceAll(sql, `"`, `"`)
|
sql = strings.ReplaceAll(sql, `"`, `"`)
|
||||||
case "mysql", "sqlite":
|
case "mysql", "sqlite":
|
||||||
sql = strings.ReplaceAll(sql, "`", `"`)
|
sql = strings.ReplaceAll(sql, "`", `"`)
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/moseszane168/gaussdb"
|
||||||
"gorm.io/driver/postgres"
|
"gorm.io/driver/postgres"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/schema"
|
"gorm.io/gorm/schema"
|
||||||
@ -251,6 +252,82 @@ func TestPostgresTableWithIdentifierLength(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPostgresTableWithIdentifierLengthGaussDB(t *testing.T) {
|
||||||
|
if DB.Dialector.Name() != "gaussdb" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type LongString struct {
|
||||||
|
ThisIsAVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString string `gorm:"unique"`
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("default", func(t *testing.T) {
|
||||||
|
db, _ := gorm.Open(gaussdb.Open(gaussdbDSN), &gorm.Config{})
|
||||||
|
user, err := schema.Parse(&LongString{}, &sync.Map{}, db.Config.NamingStrategy)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to parse user unique, got error %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
constraints := user.ParseUniqueConstraints()
|
||||||
|
if len(constraints) != 1 {
|
||||||
|
t.Fatalf("failed to find unique constraint, got %v", constraints)
|
||||||
|
}
|
||||||
|
|
||||||
|
for key := range constraints {
|
||||||
|
if len(key) != 63 {
|
||||||
|
t.Errorf("failed to find unique constraint, got %v", constraints)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("naming strategy", func(t *testing.T) {
|
||||||
|
db, _ := gorm.Open(gaussdb.Open(gaussdbDSN), &gorm.Config{
|
||||||
|
NamingStrategy: schema.NamingStrategy{},
|
||||||
|
})
|
||||||
|
|
||||||
|
user, err := schema.Parse(&LongString{}, &sync.Map{}, db.Config.NamingStrategy)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to parse user unique, got error %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
constraints := user.ParseUniqueConstraints()
|
||||||
|
if len(constraints) != 1 {
|
||||||
|
t.Fatalf("failed to find unique constraint, got %v", constraints)
|
||||||
|
}
|
||||||
|
|
||||||
|
for key := range constraints {
|
||||||
|
if len(key) != 63 {
|
||||||
|
t.Errorf("failed to find unique constraint, got %v", constraints)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("namer", func(t *testing.T) {
|
||||||
|
uname := "custom_unique_name"
|
||||||
|
db, _ := gorm.Open(gaussdb.Open(gaussdbDSN), &gorm.Config{
|
||||||
|
NamingStrategy: mockUniqueNamingStrategy{
|
||||||
|
UName: uname,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
user, err := schema.Parse(&LongString{}, &sync.Map{}, db.Config.NamingStrategy)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to parse user unique, got error %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
constraints := user.ParseUniqueConstraints()
|
||||||
|
if len(constraints) != 1 {
|
||||||
|
t.Fatalf("failed to find unique constraint, got %v", constraints)
|
||||||
|
}
|
||||||
|
|
||||||
|
for key := range constraints {
|
||||||
|
if key != uname {
|
||||||
|
t.Errorf("failed to find unique constraint, got %v", constraints)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type mockUniqueNamingStrategy struct {
|
type mockUniqueNamingStrategy struct {
|
||||||
UName string
|
UName string
|
||||||
schema.NamingStrategy
|
schema.NamingStrategy
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/moseszane168/gaussdb"
|
||||||
"gorm.io/driver/mysql"
|
"gorm.io/driver/mysql"
|
||||||
"gorm.io/driver/postgres"
|
"gorm.io/driver/postgres"
|
||||||
"gorm.io/driver/sqlite"
|
"gorm.io/driver/sqlite"
|
||||||
@ -21,6 +22,7 @@ var DB *gorm.DB
|
|||||||
var (
|
var (
|
||||||
mysqlDSN = "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local"
|
mysqlDSN = "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local"
|
||||||
postgresDSN = "user=gorm password=gorm dbname=gorm host=localhost port=9920 sslmode=disable TimeZone=Asia/Shanghai"
|
postgresDSN = "user=gorm password=gorm dbname=gorm host=localhost port=9920 sslmode=disable TimeZone=Asia/Shanghai"
|
||||||
|
gaussdbDSN = "user=gaussdb password=Gaussdb@123 dbname=gorm host=localhost port=9920 sslmode=disable TimeZone=Asia/Shanghai"
|
||||||
sqlserverDSN = "sqlserver://sa:LoremIpsum86@localhost:9930?database=master"
|
sqlserverDSN = "sqlserver://sa:LoremIpsum86@localhost:9930?database=master"
|
||||||
tidbDSN = "root:@tcp(localhost:9940)/test?charset=utf8&parseTime=True&loc=Local"
|
tidbDSN = "root:@tcp(localhost:9940)/test?charset=utf8&parseTime=True&loc=Local"
|
||||||
)
|
)
|
||||||
@ -65,6 +67,15 @@ func OpenTestConnection(cfg *gorm.Config) (db *gorm.DB, err error) {
|
|||||||
DSN: dbDSN,
|
DSN: dbDSN,
|
||||||
PreferSimpleProtocol: true,
|
PreferSimpleProtocol: true,
|
||||||
}), cfg)
|
}), cfg)
|
||||||
|
case "gaussdb":
|
||||||
|
log.Println("testing gaussdb...")
|
||||||
|
if dbDSN == "" {
|
||||||
|
dbDSN = gaussdbDSN
|
||||||
|
}
|
||||||
|
db, err = gorm.Open(gaussdb.New(gaussdb.Config{
|
||||||
|
DSN: dbDSN,
|
||||||
|
PreferSimpleProtocol: true,
|
||||||
|
}), cfg)
|
||||||
case "sqlserver":
|
case "sqlserver":
|
||||||
// go install github.com/microsoft/go-sqlcmd/cmd/sqlcmd@latest
|
// go install github.com/microsoft/go-sqlcmd/cmd/sqlcmd@latest
|
||||||
// SQLCMDPASSWORD=LoremIpsum86 sqlcmd -U sa -S localhost:9930
|
// SQLCMDPASSWORD=LoremIpsum86 sqlcmd -U sa -S localhost:9930
|
||||||
|
@ -765,9 +765,9 @@ func TestSaveWithPrimaryValue(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// only sqlite, postgres, sqlserver support returning
|
// only sqlite, postgres, gaussdb, sqlserver support returning
|
||||||
func TestUpdateReturning(t *testing.T) {
|
func TestUpdateReturning(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "sqlite" && DB.Dialector.Name() != "postgres" && DB.Dialector.Name() != "sqlserver" {
|
if DB.Dialector.Name() != "sqlite" && DB.Dialector.Name() != "postgres" && DB.Dialector.Name() != "gaussdb" && DB.Dialector.Name() != "sqlserver" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -883,9 +883,9 @@ func TestSaveWithHooks(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// only postgres, sqlserver, sqlite support update from
|
// only postgres, gaussdb, sqlserver, sqlite support update from
|
||||||
func TestUpdateFrom(t *testing.T) {
|
func TestUpdateFrom(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "postgres" && DB.Dialector.Name() != "sqlite" && DB.Dialector.Name() != "sqlserver" {
|
if DB.Dialector.Name() != "postgres" && DB.Dialector.Name() != "gaussdb" && DB.Dialector.Name() != "sqlite" && DB.Dialector.Name() != "sqlserver" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user