Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions contracts/database/schema/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package schema
type ColumnDefinition interface {
// AutoIncrement set the column as auto increment
AutoIncrement() ColumnDefinition
// Change the column
Change() ColumnDefinition
// Comment sets the comment value
Comment(comment string) ColumnDefinition
// Default set the default value
Expand Down Expand Up @@ -37,6 +39,8 @@ type ColumnDefinition interface {
GetUseCurrent() bool
// GetUseCurrentOnUpdate returns the useCurrentOnUpdate value
GetUseCurrentOnUpdate() bool
// IsChange returns true if the column has changed
IsChange() bool
// IsSetComment returns true if the comment value is set
IsSetComment() bool
// OnUpdate sets the column to use the value on update (Mysql only)
Expand Down
4 changes: 4 additions & 0 deletions contracts/database/schema/grammar.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ package schema
type Grammar interface {
// CompileAdd Compile an add column command.
CompileAdd(blueprint Blueprint, command *Command) string
// CompileChange Compile a change column command.
CompileChange(blueprint Blueprint, command *Command) []string
// CompileColumns Compile the query to determine the columns.
CompileColumns(schema, table string) string
// CompileComment Compile a column comment command.
CompileComment(blueprint Blueprint, command *Command) string
// CompileCreate Compile a create table command.
CompileCreate(blueprint Blueprint) string
// CompileDefault Compile a default value command.
CompileDefault(blueprint Blueprint, command *Command) string
// CompileDrop Compile a drop table command.
CompileDrop(blueprint Blueprint) string
// CompileDropAllDomains Compile the SQL needed to drop all domains.
Expand Down
18 changes: 17 additions & 1 deletion database/schema/blueprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,13 +430,23 @@ func (r *Blueprint) ToSql(grammar schema.Grammar) []string {

switch command.Name {
case constants.CommandAdd:
if command.Column.IsChange() {
if statement := grammar.CompileChange(r, command); len(statement) > 0 {
statements = append(statements, statement...)
}
continue
}
statements = append(statements, grammar.CompileAdd(r, command))
case constants.CommandComment:
if statement := grammar.CompileComment(r, command); statement != "" {
statements = append(statements, statement)
}
case constants.CommandCreate:
statements = append(statements, grammar.CompileCreate(r))
case constants.CommandDefault:
if statement := grammar.CompileDefault(r, command); statement != "" {
statements = append(statements, statement)
}
case constants.CommandDrop:
statements = append(statements, grammar.CompileDrop(r))
case constants.CommandDropColumn:
Expand Down Expand Up @@ -503,12 +513,18 @@ func (r *Blueprint) addAttributeCommands(grammar schema.Grammar) {
attributeCommands := grammar.GetAttributeCommands()
for _, column := range r.columns {
for _, command := range attributeCommands {
if command == constants.CommandComment && column.comment != nil {
if command == constants.CommandComment && (column.comment != nil || column.change) {
r.addCommand(&schema.Command{
Column: column,
Name: constants.CommandComment,
})
}
if command == constants.CommandDefault && column.def != nil {
r.addCommand(&schema.Command{
Column: column,
Name: constants.CommandDefault,
})
}
}
}
}
Expand Down
21 changes: 21 additions & 0 deletions database/schema/blueprint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,15 @@ func (s *BlueprintTestSuite) TestToSql() {
} else {
s.Empty(s.blueprint.ToSql(grammar))
}

// Change column
s.SetupTest()
s.blueprint.String("name", 100).Change()
if driver == database.DriverPostgres {
s.Len(s.blueprint.ToSql(grammar), 2)
} else {
s.Empty(s.blueprint.ToSql(grammar))
}
}
}

Expand Down Expand Up @@ -438,3 +447,15 @@ func (s *BlueprintTestSuite) TestUnsignedTinyInteger() {
unsigned: convert.Pointer(true),
})
}

func (s *BlueprintTestSuite) TestChange() {
column := "name"
customLength := 100
s.blueprint.String(column, customLength).Change()
s.Contains(s.blueprint.GetAddedColumns(), &ColumnDefinition{
length: &customLength,
name: &column,
change: true,
ttype: convert.Pointer("string"),
})
}
11 changes: 11 additions & 0 deletions database/schema/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
type ColumnDefinition struct {
allowed []any
autoIncrement *bool
change bool
comment *string
def any
length *int
Expand All @@ -29,6 +30,12 @@ func (r *ColumnDefinition) AutoIncrement() schema.ColumnDefinition {
return r
}

func (r *ColumnDefinition) Change() schema.ColumnDefinition {
r.change = true

return r
}

func (r *ColumnDefinition) Comment(comment string) schema.ColumnDefinition {
r.comment = &comment

Expand Down Expand Up @@ -149,6 +156,10 @@ func (r *ColumnDefinition) GetUseCurrentOnUpdate() bool {
return false
}

func (r *ColumnDefinition) IsChange() bool {
return r.change
}

func (r *ColumnDefinition) IsSetComment() bool {
return r != nil && r.comment != nil
}
Expand Down
7 changes: 7 additions & 0 deletions database/schema/column_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ func (s *ColumnDefinitionTestSuite) GetType() {
s.Equal("string", s.columnDefinition.GetType())
}

func (s *ColumnDefinitionTestSuite) IsChange() {
s.False(s.columnDefinition.IsChange())

s.columnDefinition.Change()
s.True(s.columnDefinition.IsChange())
}

func (s *ColumnDefinitionTestSuite) Unsigned() {
s.columnDefinition.Unsigned()
s.True(*s.columnDefinition.unsigned)
Expand Down
1 change: 1 addition & 0 deletions database/schema/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const (
CommandAdd = "add"
CommandComment = "comment"
CommandCreate = "create"
CommandDefault = "default"
CommandDrop = "drop"
CommandDropColumn = "dropColumn"
CommandDropForeign = "dropForeign"
Expand Down
10 changes: 10 additions & 0 deletions database/schema/grammars/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ func (r *Mysql) CompileAdd(blueprint schema.Blueprint, command *schema.Command)
return fmt.Sprintf("alter table %s add %s", r.wrap.Table(blueprint.GetTableName()), r.getColumn(blueprint, command.Column))
}

func (r *Mysql) CompileChange(blueprint schema.Blueprint, command *schema.Command) []string {
return []string{
fmt.Sprintf("alter table %s modify %s", r.wrap.Table(blueprint.GetTableName()), r.getColumn(blueprint, command.Column)),
Comment thread
hwbrzzl marked this conversation as resolved.
}
}

func (r *Mysql) CompileColumns(schema, table string) string {
return fmt.Sprintf(
"select column_name as `name`, data_type as `type_name`, column_type as `type`, "+
Expand Down Expand Up @@ -71,6 +77,10 @@ func (r *Mysql) CompileCreate(blueprint schema.Blueprint) string {
return fmt.Sprintf("create table %s (%s)", r.wrap.Table(blueprint.GetTableName()), strings.Join(columns, ", "))
}

func (r *Mysql) CompileDefault(_ schema.Blueprint, _ *schema.Command) string {
return ""
}

func (r *Mysql) CompileDisableForeignKeyConstraints() string {
return "SET FOREIGN_KEY_CHECKS=0;"
}
Expand Down
21 changes: 21 additions & 0 deletions database/schema/grammars/mysql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,27 @@ func (s *MysqlSuite) TestCompileAdd() {
s.Equal("alter table `goravel_users` add `name` varchar(1) not null default 'goravel' comment 'comment'", sql)
}

func (s *MysqlSuite) TestCompileChange() {
mockBlueprint := mocksschema.NewBlueprint(s.T())
mockColumn := mocksschema.NewColumnDefinition(s.T())

mockBlueprint.EXPECT().GetTableName().Return("users").Once()
mockColumn.EXPECT().GetName().Return("name").Once()
mockColumn.EXPECT().GetType().Return("string").Twice()
mockColumn.EXPECT().GetDefault().Return("goravel").Twice()
mockColumn.EXPECT().GetNullable().Return(false).Once()
mockColumn.EXPECT().GetLength().Return(1).Once()
mockColumn.EXPECT().GetOnUpdate().Return(nil).Once()
mockColumn.EXPECT().GetComment().Return("comment").Once()
mockColumn.EXPECT().GetUnsigned().Return(false).Once()

sql := s.grammar.CompileChange(mockBlueprint, &contractsschema.Command{
Column: mockColumn,
})

s.Equal([]string{"alter table `goravel_users` modify `name` varchar(1) not null default 'goravel' comment 'comment'"}, sql)
}

func (s *MysqlSuite) TestCompileCreate() {
mockColumn1 := mocksschema.NewColumnDefinition(s.T())
mockColumn2 := mocksschema.NewColumnDefinition(s.T())
Expand Down
37 changes: 34 additions & 3 deletions database/schema/grammars/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ func (r *Postgres) CompileAdd(blueprint schema.Blueprint, command *schema.Comman
return fmt.Sprintf("alter table %s add column %s", r.wrap.Table(blueprint.GetTableName()), r.getColumn(blueprint, command.Column))
}

func (r *Postgres) CompileChange(blueprint schema.Blueprint, command *schema.Command) []string {
changes := []string{fmt.Sprintf("alter column %s type %s", r.wrap.Column(command.Column.GetName()), getType(r, command.Column))}
for _, modifier := range r.modifiers {
if change := modifier(blueprint, command.Column); change != "" {
changes = append(changes, fmt.Sprintf("alter column %s%s", r.wrap.Column(command.Column.GetName()), change))
}
}

return []string{
fmt.Sprintf("alter table %s %s", r.wrap.Table(blueprint.GetTableName()), strings.Join(changes, ", ")),
}
}

func (r *Postgres) CompileColumns(schema, table string) string {
return fmt.Sprintf(
"select a.attname as name, t.typname as type_name, format_type(a.atttypid, a.atttypmod) as type, "+
Expand Down Expand Up @@ -67,6 +80,10 @@ func (r *Postgres) CompileCreate(blueprint schema.Blueprint) string {
return fmt.Sprintf("create table %s (%s)", r.wrap.Table(blueprint.GetTableName()), strings.Join(r.getColumns(blueprint), ", "))
}

func (r *Postgres) CompileDefault(_ schema.Blueprint, _ *schema.Command) string {
return ""
}

func (r *Postgres) CompileDrop(blueprint schema.Blueprint) string {
return fmt.Sprintf("drop table %s", r.wrap.Table(blueprint.GetTableName()))
}
Expand Down Expand Up @@ -291,6 +308,15 @@ func (r *Postgres) GetAttributeCommands() []string {
}

func (r *Postgres) ModifyDefault(blueprint schema.Blueprint, column schema.ColumnDefinition) string {
if column.IsChange() {
if column.GetAutoIncrement() {
return ""
}
if column.GetDefault() != nil {
return fmt.Sprintf(" set default %s", getDefaultValue(column.GetDefault()))
}
return " drop default"
}
if column.GetDefault() != nil {
return fmt.Sprintf(" default %s", getDefaultValue(column.GetDefault()))
}
Expand All @@ -299,15 +325,20 @@ func (r *Postgres) ModifyDefault(blueprint schema.Blueprint, column schema.Colum
}

func (r *Postgres) ModifyNullable(blueprint schema.Blueprint, column schema.ColumnDefinition) string {
Comment thread
almas-x marked this conversation as resolved.
if column.IsChange() {
if column.GetNullable() {
return " drop not null"
}
return " set not null"
}
if column.GetNullable() {
return " null"
} else {
return " not null"
}
return " not null"
}

func (r *Postgres) ModifyIncrement(blueprint schema.Blueprint, column schema.ColumnDefinition) string {
if !blueprint.HasCommand("primary") && slices.Contains(r.serials, column.GetType()) && column.GetAutoIncrement() {
if !column.IsChange() && !blueprint.HasCommand("primary") && slices.Contains(r.serials, column.GetType()) && column.GetAutoIncrement() {
return " primary key"
}

Expand Down
Loading