Skip to content

Commit

Permalink
Add HasIndex method for dialect interface
Browse files Browse the repository at this point in the history
  • Loading branch information
jinzhu committed Mar 2, 2015
1 parent 61a878d commit 3499738
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 15 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ type Address struct {
ID int
Address1 string `sql:"not null;unique"` // Set field as not nullable and unique
Address2 string `sql:"type:varchar(100);unique"`
Post sql.NullString `sql:not null`
Post sql.NullString `sql:"not null"`
}

type Language struct {
Expand Down
10 changes: 8 additions & 2 deletions common_dialect.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,19 @@ func (s *commonDialect) databaseName(scope *Scope) string {

func (s *commonDialect) HasTable(scope *Scope, tableName string) bool {
var count int
scope.NewDB().Raw("SELECT count(*) FROM INFORMATION_SCHEMA.tables WHERE table_name = ? AND table_schema = ?", tableName, s.databaseName(scope)).Row().Scan(&count)
scope.NewDB().Raw("SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_name = ? AND table_schema = ?", tableName, s.databaseName(scope)).Row().Scan(&count)
return count > 0
}

func (s *commonDialect) HasColumn(scope *Scope, tableName string, columnName string) bool {
var count int
scope.NewDB().Raw("SELECT count(*) FROM information_schema.columns WHERE table_schema = ? AND table_name = ? AND column_name = ?", s.databaseName(scope), tableName, columnName).Row().Scan(&count)
scope.NewDB().Raw("SELECT count(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = ? AND table_name = ? AND column_name = ?", s.databaseName(scope), tableName, columnName).Row().Scan(&count)
return count > 0
}

func (s *commonDialect) HasIndex(scope *Scope, tableName string, indexName string) bool {
var count int
scope.NewDB().Raw("SELECT count(*) FROM INFORMATION_SCHEMA.STATISTICS where table_name = ? AND index_name = ?", tableName, indexName).Row().Scan(&count)
return count > 0
}

Expand Down
2 changes: 1 addition & 1 deletion customize_column_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestCustomizeColumn(t *testing.T) {
DB.DropTable(&CustomizeColumn{})
DB.AutoMigrate(&CustomizeColumn{})

scope := DB.Model("").NewScope(&CustomizeColumn{})
scope := DB.NewScope(&CustomizeColumn{})
if !scope.Dialect().HasColumn(scope, scope.TableName(), col) {
t.Errorf("CustomizeColumn should have column %s", col)
}
Expand Down
1 change: 1 addition & 0 deletions dialect.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type Dialect interface {
Quote(key string) string
HasTable(scope *Scope, tableName string) bool
HasColumn(scope *Scope, tableName string, columnName string) bool
HasIndex(scope *Scope, tableName string, indexName string) bool
RemoveIndex(scope *Scope, indexName string)
}

Expand Down
20 changes: 10 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,16 @@ func (s *DB) AddIndex(indexName string, column ...string) *DB {
return s
}

func (s *DB) AddUniqueIndex(indexName string, column ...string) *DB {
s.clone().NewScope(s.Value).addIndex(true, indexName, column...)
return s
}

func (s *DB) RemoveIndex(indexName string) *DB {
s.clone().NewScope(s.Value).removeIndex(indexName)
return s
}

/*
Add foreign key to the given scope
Expand All @@ -410,16 +420,6 @@ func (s *DB) AddForeignKey(field string, dest string, onDelete string, onUpdate
return s
}

func (s *DB) AddUniqueIndex(indexName string, column ...string) *DB {
s.clone().NewScope(s.Value).addIndex(true, indexName, column...)
return s
}

func (s *DB) RemoveIndex(indexName string) *DB {
s.clone().NewScope(s.Value).removeIndex(indexName)
return s
}

func (s *DB) Association(column string) *Association {
var err error
scope := s.clone().NewScope(s.Value)
Expand Down
25 changes: 25 additions & 0 deletions migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,43 @@ func TestIndexes(t *testing.T) {
t.Errorf("Got error when tried to create index: %+v", err)
}

scope := DB.NewScope(&Email{})
if !scope.Dialect().HasIndex(scope, scope.TableName(), "idx_email_email") {
t.Errorf("Email should have index idx_email_email")
}

if err := DB.Model(&Email{}).RemoveIndex("idx_email_email").Error; err != nil {
t.Errorf("Got error when tried to remove index: %+v", err)
}

if scope.Dialect().HasIndex(scope, scope.TableName(), "idx_email_email") {
t.Errorf("Email's index idx_email_email should be deleted")
}

if err := DB.Model(&Email{}).AddIndex("idx_email_email_and_user_id", "user_id", "email").Error; err != nil {
t.Errorf("Got error when tried to create index: %+v", err)
}

if !scope.Dialect().HasIndex(scope, scope.TableName(), "idx_email_email_and_user_id") {
t.Errorf("Email should have index idx_email_email_and_user_id")
}

if err := DB.Model(&Email{}).RemoveIndex("idx_email_email_and_user_id").Error; err != nil {
t.Errorf("Got error when tried to remove index: %+v", err)
}

if scope.Dialect().HasIndex(scope, scope.TableName(), "idx_email_email_and_user_id") {
t.Errorf("Email's index idx_email_email_and_user_id should be deleted")
}

if err := DB.Model(&Email{}).AddUniqueIndex("idx_email_email_and_user_id", "user_id", "email").Error; err != nil {
t.Errorf("Got error when tried to create index: %+v", err)
}

if !scope.Dialect().HasIndex(scope, scope.TableName(), "idx_email_email_and_user_id") {
t.Errorf("Email should have index idx_email_email_and_user_id")
}

if DB.Save(&User{Name: "unique_indexes", Emails: []Email{{Email: "[email protected]"}, {Email: "[email protected]"}, {Email: "[email protected]"}}}).Error == nil {
t.Errorf("Should get to create duplicate record when having unique index")
}
Expand All @@ -54,6 +75,10 @@ func TestIndexes(t *testing.T) {
t.Errorf("Got error when tried to remove index: %+v", err)
}

if scope.Dialect().HasIndex(scope, scope.TableName(), "idx_email_email_and_user_id") {
t.Errorf("Email's index idx_email_email_and_user_id should be deleted")
}

if DB.Save(&User{Name: "unique_indexes", Emails: []Email{{Email: "[email protected]"}, {Email: "[email protected]"}}}).Error != nil {
t.Errorf("Should be able to create duplicated emails after remove unique index")
}
Expand Down
6 changes: 6 additions & 0 deletions mssql.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ func (s *mssql) HasColumn(scope *Scope, tableName string, columnName string) boo
return count > 0
}

func (s *mssql) HasIndex(scope *Scope, tableName string, indexName string) bool {
var count int
scope.NewDB().Raw("SELECT count(*) FROM sys.indexes WHERE name=? AND object_id=OBJECT_ID(?)", indexName, tableName).Row().Scan(&count)
return count > 0
}

func (s *mssql) RemoveIndex(scope *Scope, indexName string) {
scope.NewDB().Exec(fmt.Sprintf("DROP INDEX %v ON %v", indexName, scope.QuotedTableName()))
}
6 changes: 6 additions & 0 deletions mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ func (s *mysql) HasColumn(scope *Scope, tableName string, columnName string) boo
return count > 0
}

func (s *mysql) HasIndex(scope *Scope, tableName string, indexName string) bool {
var count int
scope.NewDB().Raw("SELECT count(*) FROM INFORMATION_SCHEMA.STATISTICS where table_name = ? AND index_name = ?", tableName, indexName).Row().Scan(&count)
return count > 0
}

func (s *mysql) RemoveIndex(scope *Scope, indexName string) {
scope.NewDB().Exec(fmt.Sprintf("DROP INDEX %v ON %v", indexName, scope.QuotedTableName()))
}
8 changes: 7 additions & 1 deletion postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,20 @@ func (s *postgres) HasTable(scope *Scope, tableName string) bool {

func (s *postgres) HasColumn(scope *Scope, tableName string, columnName string) bool {
var count int
scope.NewDB().Raw("SELECT count(*) FROM information_schema.columns WHERE table_name = ? AND column_name = ?", tableName, columnName).Row().Scan(&count)
scope.NewDB().Raw("SELECT count(*) FROM INFORMATION_SCHEMA.columns WHERE table_name = ? AND column_name = ?", tableName, columnName).Row().Scan(&count)
return count > 0
}

func (s *postgres) RemoveIndex(scope *Scope, indexName string) {
scope.NewDB().Exec(fmt.Sprintf("DROP INDEX %v", indexName))
}

func (s *postgres) HasIndex(scope *Scope, tableName string, indexName string) bool {
var count int
scope.NewDB().Raw("SELECT count(*) FROM pg_indexes WHERE tablename = ? AND indexname = ?", tableName, indexName).Row().Scan(&count)
return count > 0
}

var hstoreType = reflect.TypeOf(Hstore{})

type Hstore map[string]*string
Expand Down
6 changes: 6 additions & 0 deletions sqlite3.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ func (s *sqlite3) HasColumn(scope *Scope, tableName string, columnName string) b
return count > 0
}

func (s *sqlite3) HasIndex(scope *Scope, tableName string, indexName string) bool {
var count int
scope.NewDB().Raw(fmt.Sprintf("SELECT count(*) FROM sqlite_master WHERE tbl_name = ? AND sql LIKE '%%INDEX %v ON%%'", indexName), tableName).Row().Scan(&count)
return count > 0
}

func (s *sqlite3) RemoveIndex(scope *Scope, indexName string) {
scope.NewDB().Exec(fmt.Sprintf("DROP INDEX %v", indexName))
}

0 comments on commit 3499738

Please sign in to comment.