-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Implement Create * Add DropIfExist * chore: update mocks * Add unit tests * add test cases * add test cases * ifx * optimize code * optimize test cases * optimize test cases --------- Co-authored-by: hwbrzzl <[email protected]>
- Loading branch information
Showing
28 changed files
with
3,015 additions
and
376 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,30 @@ | ||
package migration | ||
|
||
import ( | ||
"github.com/goravel/framework/contracts/database/orm" | ||
) | ||
|
||
type Blueprint interface { | ||
// Build Execute the blueprint to build / modify the table. | ||
Build(query orm.Query, grammar Grammar) error | ||
// Create Indicate that the table needs to be created. | ||
Create() | ||
// DropIfExists Indicate that the table should be dropped if it exists. | ||
DropIfExists() | ||
// GetAddedColumns Get the added columns. | ||
GetAddedColumns() []ColumnDefinition | ||
// GetTableName Get the table name with prefix. | ||
GetTableName() string | ||
// HasCommand Determine if the blueprint has a specific command. | ||
HasCommand(command string) bool | ||
// ID Create a new auto-incrementing big integer (8-byte) column on the table. | ||
ID(column ...string) ColumnDefinition | ||
// Integer Create a new integer (4-byte) column on the table. | ||
Integer(column string) ColumnDefinition | ||
// SetTable Set the table that the blueprint operates on. | ||
SetTable(name string) | ||
// String Create a new string column on the table. | ||
String(column string, length ...int) ColumnDefinition | ||
// ToSql Get the raw SQL statements for the blueprint. | ||
ToSql(query orm.Query, grammar Grammar) []string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package migration | ||
|
||
type ColumnDefinition interface { | ||
// AutoIncrement set the column as auto increment | ||
AutoIncrement() ColumnDefinition | ||
// GetAutoIncrement returns the autoIncrement value | ||
GetAutoIncrement() bool | ||
// GetChange returns the change value | ||
GetChange() bool | ||
// GetDefault returns the default value | ||
GetDefault() any | ||
// GetLength returns the length value | ||
GetLength() int | ||
// GetName returns the name value | ||
GetName() string | ||
// GetNullable returns the nullable value | ||
GetNullable() bool | ||
// GetType returns the type value | ||
GetType() string | ||
// Unsigned set the column as unsigned | ||
Unsigned() ColumnDefinition | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package migration | ||
|
||
import ( | ||
"github.com/goravel/framework/contracts/database/orm" | ||
) | ||
|
||
type Grammar interface { | ||
// CompileCreate Compile a create table command. | ||
CompileCreate(blueprint Blueprint, query orm.Query) string | ||
// CompileDropIfExists Compile a drop table (if exists) command. | ||
CompileDropIfExists(blueprint Blueprint) string | ||
// GetAttributeCommands Get the commands for the schema build. | ||
GetAttributeCommands() []string | ||
// GetModifiers Get the column modifiers. | ||
GetModifiers() []func(Blueprint, ColumnDefinition) string | ||
// TypeBigInteger Create the column definition for a big integer type. | ||
TypeBigInteger(column ColumnDefinition) string | ||
// TypeInteger Create the column definition for an integer type. | ||
TypeInteger(column ColumnDefinition) string | ||
// TypeString Create the column definition for a string type. | ||
TypeString(column ColumnDefinition) string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package migration | ||
|
||
type Migrator interface { | ||
//Run() | ||
//RunUp() | ||
//RunDown() | ||
//Rollback() | ||
//Reset() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package migration | ||
|
||
type Repository interface { | ||
//// CreateRepository Create the migration repository data store. | ||
//CreateRepository() | ||
//// Delete Remove a migration from the log. | ||
//Delete(migration string) | ||
//// DeleteRepository Delete the migration repository data store. | ||
//DeleteRepository() | ||
//// GetLast Get the last migration batch. | ||
//GetLast() | ||
//// GetMigrationBatches Get the completed migrations with their batch numbers. | ||
//GetMigrationBatches() | ||
//// GetMigrations Get the list of migrations. | ||
//GetMigrations(steps int) | ||
//// GetMigrationsByBatch Get the list of the migrations by batch. | ||
//GetMigrationsByBatch(batch int) | ||
//// GetNextBatchNumber Get the next migration batch number. | ||
//GetNextBatchNumber() | ||
//// GetRan Get the completed migrations. | ||
//GetRan() | ||
//// Log that a migration was run. | ||
//Log(file, batch string) | ||
//// RepositoryExists Determine if the migration repository exists. | ||
//RepositoryExists() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
package migration | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/goravel/framework/contracts/database/migration" | ||
ormcontract "github.com/goravel/framework/contracts/database/orm" | ||
"github.com/goravel/framework/support/convert" | ||
) | ||
|
||
const ( | ||
commandAdd = "add" | ||
commandChange = "change" | ||
commandComment = "comment" | ||
commandCreate = "create" | ||
commandDropIfExists = "dropIfExists" | ||
defaultStringLength = 255 | ||
) | ||
|
||
type Blueprint struct { | ||
columns []*ColumnDefinition | ||
commands []*migration.Command | ||
prefix string | ||
schema string | ||
table string | ||
} | ||
|
||
func NewBlueprint(prefix, schema string) *Blueprint { | ||
return &Blueprint{ | ||
prefix: prefix, | ||
schema: schema, | ||
} | ||
} | ||
|
||
func (r *Blueprint) BigIncrements(column string) migration.ColumnDefinition { | ||
return r.UnsignedBigInteger(column).AutoIncrement() | ||
} | ||
|
||
func (r *Blueprint) BigInteger(column string) migration.ColumnDefinition { | ||
columnImpl := &ColumnDefinition{ | ||
name: &column, | ||
ttype: convert.Pointer("bigInteger"), | ||
} | ||
|
||
r.addColumn(columnImpl) | ||
|
||
return columnImpl | ||
} | ||
|
||
func (r *Blueprint) Build(query ormcontract.Query, grammar migration.Grammar) error { | ||
for _, sql := range r.ToSql(query, grammar) { | ||
// TODO remove | ||
fmt.Println("sql:", sql) | ||
if _, err := query.Exec(sql); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (r *Blueprint) Create() { | ||
r.addCommand(&migration.Command{ | ||
Name: commandCreate, | ||
}) | ||
} | ||
|
||
func (r *Blueprint) DropIfExists() { | ||
r.addCommand(&migration.Command{ | ||
Name: commandDropIfExists, | ||
}) | ||
} | ||
|
||
func (r *Blueprint) GetAddedColumns() []migration.ColumnDefinition { | ||
var columns []migration.ColumnDefinition | ||
for _, column := range r.columns { | ||
if column.change == nil || !*column.change { | ||
columns = append(columns, column) | ||
} | ||
} | ||
|
||
return columns | ||
} | ||
|
||
func (r *Blueprint) GetChangedColumns() []migration.ColumnDefinition { | ||
var columns []migration.ColumnDefinition | ||
for _, column := range r.columns { | ||
if column.change != nil && *column.change { | ||
columns = append(columns, column) | ||
} | ||
} | ||
|
||
return columns | ||
} | ||
|
||
func (r *Blueprint) GetTableName() string { | ||
// TODO Add schema for Postgres | ||
return r.prefix + r.table | ||
} | ||
|
||
func (r *Blueprint) HasCommand(command string) bool { | ||
for _, c := range r.commands { | ||
if c.Name == command { | ||
return true | ||
} | ||
} | ||
|
||
return false | ||
} | ||
|
||
func (r *Blueprint) ID(column ...string) migration.ColumnDefinition { | ||
if len(column) > 0 { | ||
return r.BigIncrements(column[0]) | ||
} | ||
|
||
return r.BigIncrements("id") | ||
} | ||
|
||
func (r *Blueprint) Integer(column string) migration.ColumnDefinition { | ||
columnImpl := &ColumnDefinition{ | ||
name: &column, | ||
ttype: convert.Pointer("integer"), | ||
} | ||
|
||
r.addColumn(columnImpl) | ||
|
||
return columnImpl | ||
} | ||
|
||
func (r *Blueprint) SetTable(name string) { | ||
r.table = name | ||
} | ||
|
||
func (r *Blueprint) String(column string, length ...int) migration.ColumnDefinition { | ||
defaultLength := defaultStringLength | ||
if len(length) > 0 { | ||
defaultLength = length[0] | ||
} | ||
|
||
columnImpl := &ColumnDefinition{ | ||
length: &defaultLength, | ||
name: &column, | ||
ttype: convert.Pointer("string"), | ||
} | ||
r.addColumn(columnImpl) | ||
|
||
return columnImpl | ||
} | ||
|
||
func (r *Blueprint) ToSql(query ormcontract.Query, grammar migration.Grammar) []string { | ||
r.addImpliedCommands(grammar) | ||
|
||
var statements []string | ||
for _, command := range r.commands { | ||
switch command.Name { | ||
case commandCreate: | ||
statements = append(statements, grammar.CompileCreate(r, query)) | ||
case commandDropIfExists: | ||
statements = append(statements, grammar.CompileDropIfExists(r)) | ||
} | ||
} | ||
|
||
return statements | ||
} | ||
|
||
func (r *Blueprint) UnsignedBigInteger(column string) migration.ColumnDefinition { | ||
return r.BigInteger(column).Unsigned() | ||
} | ||
|
||
func (r *Blueprint) addAttributeCommands(grammar migration.Grammar) { | ||
attributeCommands := grammar.GetAttributeCommands() | ||
for _, column := range r.columns { | ||
for _, command := range attributeCommands { | ||
if command == "comment" && column.comment != nil { | ||
r.addCommand(&migration.Command{ | ||
Column: column, | ||
Name: commandComment, | ||
}) | ||
} | ||
} | ||
} | ||
} | ||
|
||
func (r *Blueprint) addColumn(column *ColumnDefinition) { | ||
r.columns = append(r.columns, column) | ||
} | ||
|
||
func (r *Blueprint) addCommand(command *migration.Command) { | ||
r.commands = append(r.commands, command) | ||
} | ||
|
||
func (r *Blueprint) addImpliedCommands(grammar migration.Grammar) { | ||
var commands []*migration.Command | ||
if len(r.GetAddedColumns()) > 0 && !r.isCreate() { | ||
commands = append(commands, &migration.Command{ | ||
Name: commandAdd, | ||
}) | ||
} | ||
if len(r.GetChangedColumns()) > 0 && !r.isCreate() { | ||
commands = append(commands, &migration.Command{ | ||
Name: commandChange, | ||
}) | ||
} | ||
if len(commands) > 0 { | ||
r.commands = append(commands, r.commands...) | ||
} | ||
r.addAttributeCommands(grammar) | ||
} | ||
|
||
func (r *Blueprint) isCreate() bool { | ||
for _, command := range r.commands { | ||
if command.Name == commandCreate { | ||
return true | ||
} | ||
} | ||
|
||
return false | ||
} |
Oops, something went wrong.