feat(merge): 🎉 Add support for constraints and indexes in merge results
All checks were successful
CI / Test (1.24) (push) Successful in -26m24s
CI / Test (1.25) (push) Successful in -26m10s
CI / Lint (push) Successful in -26m33s
CI / Build (push) Successful in -26m40s
Release / Build and Release (push) Successful in -26m23s
Integration Tests / Integration Tests (push) Successful in -25m53s
All checks were successful
CI / Test (1.24) (push) Successful in -26m24s
CI / Test (1.25) (push) Successful in -26m10s
CI / Lint (push) Successful in -26m33s
CI / Build (push) Successful in -26m40s
Release / Build and Release (push) Successful in -26m23s
Integration Tests / Integration Tests (push) Successful in -25m53s
* Enhance MergeResult to track added constraints and indexes. * Update merge logic to increment counters for added constraints and indexes. * Modify GetMergeSummary to include constraints and indexes in the output. * Add comprehensive tests for merging constraints and indexes.
This commit is contained in:
@@ -15,6 +15,8 @@ type MergeResult struct {
|
||||
SchemasAdded int
|
||||
TablesAdded int
|
||||
ColumnsAdded int
|
||||
ConstraintsAdded int
|
||||
IndexesAdded int
|
||||
RelationsAdded int
|
||||
DomainsAdded int
|
||||
EnumsAdded int
|
||||
@@ -171,6 +173,7 @@ func (r *MergeResult) mergeConstraints(table *models.Table, srcTable *models.Tab
|
||||
// Constraint doesn't exist, add it
|
||||
newConst := cloneConstraint(srcConst)
|
||||
table.Constraints[constName] = newConst
|
||||
r.ConstraintsAdded++
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -193,6 +196,7 @@ func (r *MergeResult) mergeIndexes(table *models.Table, srcTable *models.Table)
|
||||
// Index doesn't exist, add it
|
||||
newIdx := cloneIndex(srcIdx)
|
||||
table.Indexes[idxName] = newIdx
|
||||
r.IndexesAdded++
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -598,6 +602,8 @@ func GetMergeSummary(result *MergeResult) string {
|
||||
fmt.Sprintf("Schemas added: %d", result.SchemasAdded),
|
||||
fmt.Sprintf("Tables added: %d", result.TablesAdded),
|
||||
fmt.Sprintf("Columns added: %d", result.ColumnsAdded),
|
||||
fmt.Sprintf("Constraints added: %d", result.ConstraintsAdded),
|
||||
fmt.Sprintf("Indexes added: %d", result.IndexesAdded),
|
||||
fmt.Sprintf("Views added: %d", result.ViewsAdded),
|
||||
fmt.Sprintf("Sequences added: %d", result.SequencesAdded),
|
||||
fmt.Sprintf("Enums added: %d", result.EnumsAdded),
|
||||
@@ -606,6 +612,7 @@ func GetMergeSummary(result *MergeResult) string {
|
||||
}
|
||||
|
||||
totalAdded := result.SchemasAdded + result.TablesAdded + result.ColumnsAdded +
|
||||
result.ConstraintsAdded + result.IndexesAdded +
|
||||
result.ViewsAdded + result.SequencesAdded + result.EnumsAdded +
|
||||
result.RelationsAdded + result.DomainsAdded
|
||||
|
||||
|
||||
617
pkg/merge/merge_test.go
Normal file
617
pkg/merge/merge_test.go
Normal file
@@ -0,0 +1,617 @@
|
||||
package merge
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
||||
)
|
||||
|
||||
func TestMergeDatabases_NilInputs(t *testing.T) {
|
||||
result := MergeDatabases(nil, nil, nil)
|
||||
if result == nil {
|
||||
t.Fatal("Expected non-nil result")
|
||||
}
|
||||
if result.SchemasAdded != 0 {
|
||||
t.Errorf("Expected 0 schemas added, got %d", result.SchemasAdded)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeDatabases_NewSchema(t *testing.T) {
|
||||
target := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{Name: "public"},
|
||||
},
|
||||
}
|
||||
source := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{Name: "auth"},
|
||||
},
|
||||
}
|
||||
|
||||
result := MergeDatabases(target, source, nil)
|
||||
if result.SchemasAdded != 1 {
|
||||
t.Errorf("Expected 1 schema added, got %d", result.SchemasAdded)
|
||||
}
|
||||
if len(target.Schemas) != 2 {
|
||||
t.Errorf("Expected 2 schemas in target, got %d", len(target.Schemas))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeDatabases_ExistingSchema(t *testing.T) {
|
||||
target := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{Name: "public"},
|
||||
},
|
||||
}
|
||||
source := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{Name: "public"},
|
||||
},
|
||||
}
|
||||
|
||||
result := MergeDatabases(target, source, nil)
|
||||
if result.SchemasAdded != 0 {
|
||||
t.Errorf("Expected 0 schemas added, got %d", result.SchemasAdded)
|
||||
}
|
||||
if len(target.Schemas) != 1 {
|
||||
t.Errorf("Expected 1 schema in target, got %d", len(target.Schemas))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeTables_NewTable(t *testing.T) {
|
||||
target := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "users",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
source := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "posts",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result := MergeDatabases(target, source, nil)
|
||||
if result.TablesAdded != 1 {
|
||||
t.Errorf("Expected 1 table added, got %d", result.TablesAdded)
|
||||
}
|
||||
if len(target.Schemas[0].Tables) != 2 {
|
||||
t.Errorf("Expected 2 tables in target schema, got %d", len(target.Schemas[0].Tables))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeColumns_NewColumn(t *testing.T) {
|
||||
target := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "users",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{
|
||||
"id": {Name: "id", Type: "int"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
source := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "users",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{
|
||||
"email": {Name: "email", Type: "varchar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result := MergeDatabases(target, source, nil)
|
||||
if result.ColumnsAdded != 1 {
|
||||
t.Errorf("Expected 1 column added, got %d", result.ColumnsAdded)
|
||||
}
|
||||
if len(target.Schemas[0].Tables[0].Columns) != 2 {
|
||||
t.Errorf("Expected 2 columns in target table, got %d", len(target.Schemas[0].Tables[0].Columns))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeConstraints_NewConstraint(t *testing.T) {
|
||||
target := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "users",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{},
|
||||
Constraints: map[string]*models.Constraint{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
source := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "users",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{},
|
||||
Constraints: map[string]*models.Constraint{
|
||||
"ukey_users_email": {
|
||||
Type: models.UniqueConstraint,
|
||||
Columns: []string{"email"},
|
||||
Name: "ukey_users_email",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result := MergeDatabases(target, source, nil)
|
||||
if result.ConstraintsAdded != 1 {
|
||||
t.Errorf("Expected 1 constraint added, got %d", result.ConstraintsAdded)
|
||||
}
|
||||
if len(target.Schemas[0].Tables[0].Constraints) != 1 {
|
||||
t.Errorf("Expected 1 constraint in target table, got %d", len(target.Schemas[0].Tables[0].Constraints))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeConstraints_NilConstraintsMap(t *testing.T) {
|
||||
target := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "users",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{},
|
||||
Constraints: nil, // Nil map
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
source := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "users",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{},
|
||||
Constraints: map[string]*models.Constraint{
|
||||
"ukey_users_email": {
|
||||
Type: models.UniqueConstraint,
|
||||
Columns: []string{"email"},
|
||||
Name: "ukey_users_email",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result := MergeDatabases(target, source, nil)
|
||||
if result.ConstraintsAdded != 1 {
|
||||
t.Errorf("Expected 1 constraint added, got %d", result.ConstraintsAdded)
|
||||
}
|
||||
if target.Schemas[0].Tables[0].Constraints == nil {
|
||||
t.Error("Expected constraints map to be initialized")
|
||||
}
|
||||
if len(target.Schemas[0].Tables[0].Constraints) != 1 {
|
||||
t.Errorf("Expected 1 constraint in target table, got %d", len(target.Schemas[0].Tables[0].Constraints))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeIndexes_NewIndex(t *testing.T) {
|
||||
target := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "users",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{},
|
||||
Indexes: map[string]*models.Index{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
source := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "users",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{},
|
||||
Indexes: map[string]*models.Index{
|
||||
"idx_users_email": {
|
||||
Name: "idx_users_email",
|
||||
Columns: []string{"email"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result := MergeDatabases(target, source, nil)
|
||||
if result.IndexesAdded != 1 {
|
||||
t.Errorf("Expected 1 index added, got %d", result.IndexesAdded)
|
||||
}
|
||||
if len(target.Schemas[0].Tables[0].Indexes) != 1 {
|
||||
t.Errorf("Expected 1 index in target table, got %d", len(target.Schemas[0].Tables[0].Indexes))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeIndexes_NilIndexesMap(t *testing.T) {
|
||||
target := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "users",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{},
|
||||
Indexes: nil, // Nil map
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
source := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "users",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{},
|
||||
Indexes: map[string]*models.Index{
|
||||
"idx_users_email": {
|
||||
Name: "idx_users_email",
|
||||
Columns: []string{"email"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result := MergeDatabases(target, source, nil)
|
||||
if result.IndexesAdded != 1 {
|
||||
t.Errorf("Expected 1 index added, got %d", result.IndexesAdded)
|
||||
}
|
||||
if target.Schemas[0].Tables[0].Indexes == nil {
|
||||
t.Error("Expected indexes map to be initialized")
|
||||
}
|
||||
if len(target.Schemas[0].Tables[0].Indexes) != 1 {
|
||||
t.Errorf("Expected 1 index in target table, got %d", len(target.Schemas[0].Tables[0].Indexes))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeOptions_SkipTableNames(t *testing.T) {
|
||||
target := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "users",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
source := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "migrations",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
opts := &MergeOptions{
|
||||
SkipTableNames: map[string]bool{
|
||||
"migrations": true,
|
||||
},
|
||||
}
|
||||
|
||||
result := MergeDatabases(target, source, opts)
|
||||
if result.TablesAdded != 0 {
|
||||
t.Errorf("Expected 0 tables added (skipped), got %d", result.TablesAdded)
|
||||
}
|
||||
if len(target.Schemas[0].Tables) != 1 {
|
||||
t.Errorf("Expected 1 table in target schema, got %d", len(target.Schemas[0].Tables))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeViews_NewView(t *testing.T) {
|
||||
target := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Views: []*models.View{},
|
||||
},
|
||||
},
|
||||
}
|
||||
source := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Views: []*models.View{
|
||||
{
|
||||
Name: "user_summary",
|
||||
Schema: "public",
|
||||
Definition: "SELECT * FROM users",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result := MergeDatabases(target, source, nil)
|
||||
if result.ViewsAdded != 1 {
|
||||
t.Errorf("Expected 1 view added, got %d", result.ViewsAdded)
|
||||
}
|
||||
if len(target.Schemas[0].Views) != 1 {
|
||||
t.Errorf("Expected 1 view in target schema, got %d", len(target.Schemas[0].Views))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeEnums_NewEnum(t *testing.T) {
|
||||
target := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Enums: []*models.Enum{},
|
||||
},
|
||||
},
|
||||
}
|
||||
source := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Enums: []*models.Enum{
|
||||
{
|
||||
Name: "user_role",
|
||||
Schema: "public",
|
||||
Values: []string{"admin", "user"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result := MergeDatabases(target, source, nil)
|
||||
if result.EnumsAdded != 1 {
|
||||
t.Errorf("Expected 1 enum added, got %d", result.EnumsAdded)
|
||||
}
|
||||
if len(target.Schemas[0].Enums) != 1 {
|
||||
t.Errorf("Expected 1 enum in target schema, got %d", len(target.Schemas[0].Enums))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeDomains_NewDomain(t *testing.T) {
|
||||
target := &models.Database{
|
||||
Domains: []*models.Domain{},
|
||||
}
|
||||
source := &models.Database{
|
||||
Domains: []*models.Domain{
|
||||
{
|
||||
Name: "auth",
|
||||
Description: "Authentication domain",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result := MergeDatabases(target, source, nil)
|
||||
if result.DomainsAdded != 1 {
|
||||
t.Errorf("Expected 1 domain added, got %d", result.DomainsAdded)
|
||||
}
|
||||
if len(target.Domains) != 1 {
|
||||
t.Errorf("Expected 1 domain in target, got %d", len(target.Domains))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeRelations_NewRelation(t *testing.T) {
|
||||
target := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Relations: []*models.Relationship{},
|
||||
},
|
||||
},
|
||||
}
|
||||
source := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Relations: []*models.Relationship{
|
||||
{
|
||||
Name: "fk_posts_user",
|
||||
Type: models.OneToMany,
|
||||
FromTable: "posts",
|
||||
FromColumns: []string{"user_id"},
|
||||
ToTable: "users",
|
||||
ToColumns: []string{"id"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result := MergeDatabases(target, source, nil)
|
||||
if result.RelationsAdded != 1 {
|
||||
t.Errorf("Expected 1 relation added, got %d", result.RelationsAdded)
|
||||
}
|
||||
if len(target.Schemas[0].Relations) != 1 {
|
||||
t.Errorf("Expected 1 relation in target schema, got %d", len(target.Schemas[0].Relations))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetMergeSummary(t *testing.T) {
|
||||
result := &MergeResult{
|
||||
SchemasAdded: 1,
|
||||
TablesAdded: 2,
|
||||
ColumnsAdded: 5,
|
||||
ConstraintsAdded: 3,
|
||||
IndexesAdded: 2,
|
||||
ViewsAdded: 1,
|
||||
}
|
||||
|
||||
summary := GetMergeSummary(result)
|
||||
if summary == "" {
|
||||
t.Error("Expected non-empty summary")
|
||||
}
|
||||
if len(summary) < 50 {
|
||||
t.Errorf("Summary seems too short: %s", summary)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetMergeSummary_Nil(t *testing.T) {
|
||||
summary := GetMergeSummary(nil)
|
||||
if summary == "" {
|
||||
t.Error("Expected non-empty summary for nil result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestComplexMerge(t *testing.T) {
|
||||
// Target with existing structure
|
||||
target := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "users",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{
|
||||
"id": {Name: "id", Type: "int"},
|
||||
},
|
||||
Constraints: map[string]*models.Constraint{},
|
||||
Indexes: map[string]*models.Index{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Source with new columns, constraints, and indexes
|
||||
source := &models.Database{
|
||||
Schemas: []*models.Schema{
|
||||
{
|
||||
Name: "public",
|
||||
Tables: []*models.Table{
|
||||
{
|
||||
Name: "users",
|
||||
Schema: "public",
|
||||
Columns: map[string]*models.Column{
|
||||
"email": {Name: "email", Type: "varchar"},
|
||||
"guid": {Name: "guid", Type: "uuid"},
|
||||
},
|
||||
Constraints: map[string]*models.Constraint{
|
||||
"ukey_users_email": {
|
||||
Type: models.UniqueConstraint,
|
||||
Columns: []string{"email"},
|
||||
Name: "ukey_users_email",
|
||||
},
|
||||
"ukey_users_guid": {
|
||||
Type: models.UniqueConstraint,
|
||||
Columns: []string{"guid"},
|
||||
Name: "ukey_users_guid",
|
||||
},
|
||||
},
|
||||
Indexes: map[string]*models.Index{
|
||||
"idx_users_email": {
|
||||
Name: "idx_users_email",
|
||||
Columns: []string{"email"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result := MergeDatabases(target, source, nil)
|
||||
|
||||
// Verify counts
|
||||
if result.ColumnsAdded != 2 {
|
||||
t.Errorf("Expected 2 columns added, got %d", result.ColumnsAdded)
|
||||
}
|
||||
if result.ConstraintsAdded != 2 {
|
||||
t.Errorf("Expected 2 constraints added, got %d", result.ConstraintsAdded)
|
||||
}
|
||||
if result.IndexesAdded != 1 {
|
||||
t.Errorf("Expected 1 index added, got %d", result.IndexesAdded)
|
||||
}
|
||||
|
||||
// Verify target has merged data
|
||||
table := target.Schemas[0].Tables[0]
|
||||
if len(table.Columns) != 3 {
|
||||
t.Errorf("Expected 3 columns in merged table, got %d", len(table.Columns))
|
||||
}
|
||||
if len(table.Constraints) != 2 {
|
||||
t.Errorf("Expected 2 constraints in merged table, got %d", len(table.Constraints))
|
||||
}
|
||||
if len(table.Indexes) != 1 {
|
||||
t.Errorf("Expected 1 index in merged table, got %d", len(table.Indexes))
|
||||
}
|
||||
|
||||
// Verify specific constraint
|
||||
if _, exists := table.Constraints["ukey_users_guid"]; !exists {
|
||||
t.Error("Expected ukey_users_guid constraint to exist")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user