From f78eb0fe4b9bfab90d0bd9ee3265b1abf0de415e Mon Sep 17 00:00:00 2001 From: Saeid Kanishka Date: Thu, 9 Mar 2023 03:07:02 +0100 Subject: [PATCH 01/15] feat: error translator support added (#136) * feat: error translator support added * refactor: removed redundent error deserialization --------- Co-authored-by: Saeid Saeidee --- error_translator.go | 21 +++++++++++++++++++++ go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 error_translator.go diff --git a/error_translator.go b/error_translator.go new file mode 100644 index 0000000..d0b936c --- /dev/null +++ b/error_translator.go @@ -0,0 +1,21 @@ +package sqlite + +import ( + "github.com/mattn/go-sqlite3" + + "gorm.io/gorm" +) + +var errCodes = map[string]sqlite3.ErrNoExtended{ + "uniqueConstraint": 2067, +} + +func (dialector Dialector) Translate(err error) error { + if sqliteErr, ok := err.(*sqlite3.Error); ok { + if sqliteErr.ExtendedCode == errCodes["uniqueConstraint"] { + return gorm.ErrDuplicatedKey + } + } + + return err +} diff --git a/go.mod b/go.mod index 039ce28..02898c7 100644 --- a/go.mod +++ b/go.mod @@ -5,5 +5,5 @@ go 1.14 require ( github.com/jinzhu/now v1.1.5 // indirect github.com/mattn/go-sqlite3 v1.14.15 - gorm.io/gorm v1.24.0 + gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11 ) diff --git a/go.sum b/go.sum index dc55f42..685067d 100644 --- a/go.sum +++ b/go.sum @@ -5,5 +5,5 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -gorm.io/gorm v1.24.0 h1:j/CoiSm6xpRpmzbFJsQHYj+I8bGYWLXVHeYEyyKlF74= -gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA= +gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11 h1:9qNbmu21nNThCNnF5i2R3kw2aL27U8ZwbzccNjOmW0g= +gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= From 502ed638813648aa22ac8c66c3f969c4b18a8ad4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Mar 2023 10:47:34 +0800 Subject: [PATCH 02/15] Bump actions/setup-go from 3 to 4 (#137) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 3 to 4. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7cc82c..903eb65 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: go-version: ${{ matrix.go }} - uses: actions/checkout@v3 From 07da3b307c6c4f1c75fecf116cb04cb006f107b7 Mon Sep 17 00:00:00 2001 From: black-06 Date: Tue, 11 Apr 2023 11:22:16 +0800 Subject: [PATCH 03/15] fix parse unique index (#138) --- ddlmod.go | 32 ++++++++++++++++++++------------ ddlmod_test.go | 22 ++++++++++++++++++++-- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/ddlmod.go b/ddlmod.go index 87886d2..e6dcbc3 100644 --- a/ddlmod.go +++ b/ddlmod.go @@ -16,12 +16,23 @@ var ( indexRegexp = regexp.MustCompile(fmt.Sprintf("(?is)CREATE(?: UNIQUE)? INDEX [%v]?[\\w\\d-]+[%v]? ON (.*)$", sqliteSeparator, sqliteSeparator)) tableRegexp = regexp.MustCompile(fmt.Sprintf("(?is)(CREATE TABLE [%v]?[\\w\\d-]+[%v]?)(?: \\((.*)\\))?", sqliteSeparator, sqliteSeparator)) separatorRegexp = regexp.MustCompile(fmt.Sprintf("[%v]", sqliteSeparator)) - columnsRegexp = regexp.MustCompile(fmt.Sprintf("\\([%v]?([\\w\\d]+)[%v]?(?:,[%v]?([\\w\\d]+)[%v]){0,}\\)", sqliteSeparator, sqliteSeparator, sqliteSeparator, sqliteSeparator)) + columnsRegexp = regexp.MustCompile(fmt.Sprintf("[(,][%v]?(\\w+)[%v]?", sqliteSeparator, sqliteSeparator)) columnRegexp = regexp.MustCompile(fmt.Sprintf("^[%v]?([\\w\\d]+)[%v]?\\s+([\\w\\(\\)\\d]+)(.*)$", sqliteSeparator, sqliteSeparator)) defaultValueRegexp = regexp.MustCompile("(?i) DEFAULT \\(?(.+)?\\)?( |COLLATE|GENERATED|$)") regRealDataType = regexp.MustCompile(`[^\d](\d+)[^\d]?`) ) +func getAllColumns(s string) []string { + allMatches := columnsRegexp.FindAllStringSubmatch(s, -1) + columns := make([]string, 0, len(allMatches)) + for _, matches := range allMatches { + if len(matches) > 1 { + columns = append(columns, matches[1]) + } + } + return columns +} + type ddl struct { head string fields []string @@ -98,15 +109,12 @@ func parseDDL(strs ...string) (*ddl, error) { } if strings.HasPrefix(fUpper, "PRIMARY KEY") { - matches := columnsRegexp.FindStringSubmatch(f) - if len(matches) > 1 { - for _, name := range matches[1:] { - for idx, column := range result.columns { - if column.NameValue.String == name { - column.PrimaryKeyValue = sql.NullBool{Bool: true, Valid: true} - result.columns[idx] = column - break - } + for _, name := range getAllColumns(f) { + for idx, column := range result.columns { + if column.NameValue.String == name { + column.PrimaryKeyValue = sql.NullBool{Bool: true, Valid: true} + result.columns[idx] = column + break } } } @@ -151,9 +159,9 @@ func parseDDL(strs ...string) (*ddl, error) { } } } else if matches := indexRegexp.FindStringSubmatch(str); len(matches) > 0 { - if columns := columnsRegexp.FindStringSubmatch(matches[1]); len(columns) == 1 { + for _, column := range getAllColumns(matches[1]) { for idx, c := range result.columns { - if c.NameValue.String == columns[0] { + if c.NameValue.String == column { c.UniqueValue = sql.NullBool{Bool: true, Valid: true} result.columns[idx] = c } diff --git a/ddlmod_test.go b/ddlmod_test.go index edc1c47..6ec7db7 100644 --- a/ddlmod_test.go +++ b/ddlmod_test.go @@ -20,7 +20,7 @@ func TestParseDDL(t *testing.T) { "CREATE UNIQUE INDEX `idx_profiles_refer` ON `profiles`(`text`)", }, 6, []migrator.ColumnType{ {NameValue: sql.NullString{String: "id", Valid: true}, DataTypeValue: sql.NullString{String: "integer", Valid: true}, ColumnTypeValue: sql.NullString{String: "integer", Valid: true}, PrimaryKeyValue: sql.NullBool{Bool: true, Valid: true}, NullableValue: sql.NullBool{Valid: true}, UniqueValue: sql.NullBool{Valid: true}, DefaultValueValue: sql.NullString{Valid: false}}, - {NameValue: sql.NullString{String: "text", Valid: true}, DataTypeValue: sql.NullString{String: "varchar", Valid: true}, LengthValue: sql.NullInt64{Int64: 500, Valid: true}, ColumnTypeValue: sql.NullString{String: "varchar(500)", Valid: true}, DefaultValueValue: sql.NullString{String: "hello", Valid: true}, NullableValue: sql.NullBool{Valid: true}, UniqueValue: sql.NullBool{Valid: true}, PrimaryKeyValue: sql.NullBool{Valid: true}}, + {NameValue: sql.NullString{String: "text", Valid: true}, DataTypeValue: sql.NullString{String: "varchar", Valid: true}, LengthValue: sql.NullInt64{Int64: 500, Valid: true}, ColumnTypeValue: sql.NullString{String: "varchar(500)", Valid: true}, DefaultValueValue: sql.NullString{String: "hello", Valid: true}, NullableValue: sql.NullBool{Valid: true}, UniqueValue: sql.NullBool{Bool: true, Valid: true}, PrimaryKeyValue: sql.NullBool{Valid: true}}, {NameValue: sql.NullString{String: "age", Valid: true}, DataTypeValue: sql.NullString{String: "integer", Valid: true}, ColumnTypeValue: sql.NullString{String: "integer", Valid: true}, DefaultValueValue: sql.NullString{String: "18", Valid: true}, NullableValue: sql.NullBool{Valid: true}, UniqueValue: sql.NullBool{Valid: true}, PrimaryKeyValue: sql.NullBool{Valid: true}}, {NameValue: sql.NullString{String: "user_id", Valid: true}, DataTypeValue: sql.NullString{String: "integer", Valid: true}, ColumnTypeValue: sql.NullString{String: "integer", Valid: true}, DefaultValueValue: sql.NullString{Valid: false}, NullableValue: sql.NullBool{Valid: true}, UniqueValue: sql.NullBool{Valid: true}, PrimaryKeyValue: sql.NullBool{Valid: true}}, }, @@ -56,11 +56,29 @@ func TestParseDDL(t *testing.T) { ColumnTypeValue: sql.NullString{String: "int", Valid: true}, NullableValue: sql.NullBool{Bool: false, Valid: true}, DefaultValueValue: sql.NullString{Valid: false}, - UniqueValue: sql.NullBool{Valid: true}, + UniqueValue: sql.NullBool{Bool: true, Valid: true}, PrimaryKeyValue: sql.NullBool{Valid: true}, }, }, }, + { + "unique index", + []string{ + "CREATE TABLE `test-b` (`field` integer NOT NULL)", + "CREATE UNIQUE INDEX `idx_uq` ON `test-b`(`field`) WHERE field = 0", + }, + 1, + []migrator.ColumnType{ + { + NameValue: sql.NullString{String: "field", Valid: true}, + DataTypeValue: sql.NullString{String: "integer", Valid: true}, + ColumnTypeValue: sql.NullString{String: "integer", Valid: true}, + PrimaryKeyValue: sql.NullBool{Bool: false, Valid: true}, + UniqueValue: sql.NullBool{Bool: true, Valid: true}, + NullableValue: sql.NullBool{Bool: false, Valid: true}, + }, + }, + }, } for _, p := range params { From cb2c532328e787b1f50cc5b6eca8ee0de07a72ed Mon Sep 17 00:00:00 2001 From: black-06 Date: Tue, 11 Apr 2023 11:24:11 +0800 Subject: [PATCH 04/15] distinguish between schema.Time and tag time (#133) fix https://github.com/go-gorm/gorm/issues/6033 --- sqlite.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sqlite.go b/sqlite.go index cb1afff..8617f00 100644 --- a/sqlite.go +++ b/sqlite.go @@ -178,7 +178,12 @@ func (dialector Dialector) DataTypeOf(field *schema.Field) string { case schema.String: return "text" case schema.Time: - return "datetime" + // Distinguish between schema.Time and tag time + if val, ok := field.TagSettings["TYPE"]; ok { + return val + } else { + return "datetime" + } case schema.Bytes: return "blob" } From 3aa841daf2521715ee3474e970388497b0ae92ad Mon Sep 17 00:00:00 2001 From: Saeid Kanishka Date: Fri, 21 Apr 2023 16:24:44 +0200 Subject: [PATCH 05/15] fix: dependency issue with go-sqlite3 package (#143) * fix: dependency issue with go-sqlite3 package * doc: documentation has been added --------- Co-authored-by: Saeid Saeidee --- error_translator.go | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/error_translator.go b/error_translator.go index d0b936c..23df522 100644 --- a/error_translator.go +++ b/error_translator.go @@ -1,21 +1,37 @@ package sqlite import ( - "github.com/mattn/go-sqlite3" + "encoding/json" "gorm.io/gorm" ) -var errCodes = map[string]sqlite3.ErrNoExtended{ +var errCodes = map[string]int{ "uniqueConstraint": 2067, } +type ErrMessage struct { + Code int `json:"Code"` + ExtendedCode int `json:"ExtendedCode"` + SystemErrno int `json:"SystemErrno"` +} + +// Translate it will translate the error to native gorm errors. +// We are not using go-sqlite3 error type intentionally here because it will need the CGO_ENABLED=1 and cross-C-compiler. func (dialector Dialector) Translate(err error) error { - if sqliteErr, ok := err.(*sqlite3.Error); ok { - if sqliteErr.ExtendedCode == errCodes["uniqueConstraint"] { - return gorm.ErrDuplicatedKey - } + parsedErr, marshalErr := json.Marshal(err) + if marshalErr != nil { + return err } + var errMsg ErrMessage + unmarshalErr := json.Unmarshal(parsedErr, &errMsg) + if unmarshalErr != nil { + return err + } + + if errMsg.ExtendedCode == errCodes["uniqueConstraint"] { + return gorm.ErrDuplicatedKey + } return err } From 5acf810258993531d1509fe9305b8b69f64b7add Mon Sep 17 00:00:00 2001 From: Rico Date: Fri, 21 Apr 2023 16:26:43 +0200 Subject: [PATCH 06/15] Fix two regexes related to SQL create statement parsing (#140) * fix: use \s in tableRegexp to match multiline create statements * fix: improve tableReg regex to correctly match table name * tests: add test cases for different spacing cases --- ddlmod.go | 2 +- ddlmod_test.go | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ migrator.go | 2 +- 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/ddlmod.go b/ddlmod.go index e6dcbc3..8061ded 100644 --- a/ddlmod.go +++ b/ddlmod.go @@ -14,7 +14,7 @@ import ( var ( sqliteSeparator = "`|\"|'|\t" indexRegexp = regexp.MustCompile(fmt.Sprintf("(?is)CREATE(?: UNIQUE)? INDEX [%v]?[\\w\\d-]+[%v]? ON (.*)$", sqliteSeparator, sqliteSeparator)) - tableRegexp = regexp.MustCompile(fmt.Sprintf("(?is)(CREATE TABLE [%v]?[\\w\\d-]+[%v]?)(?: \\((.*)\\))?", sqliteSeparator, sqliteSeparator)) + tableRegexp = regexp.MustCompile(fmt.Sprintf("(?is)(CREATE TABLE [%v]?[\\w\\d-]+[%v]?)(?:\\s*\\((.*)\\))?", sqliteSeparator, sqliteSeparator)) separatorRegexp = regexp.MustCompile(fmt.Sprintf("[%v]", sqliteSeparator)) columnsRegexp = regexp.MustCompile(fmt.Sprintf("[(,][%v]?(\\w+)[%v]?", sqliteSeparator, sqliteSeparator)) columnRegexp = regexp.MustCompile(fmt.Sprintf("^[%v]?([\\w\\d]+)[%v]?\\s+([\\w\\(\\)\\d]+)(.*)$", sqliteSeparator, sqliteSeparator)) diff --git a/ddlmod_test.go b/ddlmod_test.go index 6ec7db7..f6fc6e7 100644 --- a/ddlmod_test.go +++ b/ddlmod_test.go @@ -98,6 +98,75 @@ func TestParseDDL(t *testing.T) { } } +func TestParseDDL_Whitespaces(t *testing.T) { + testColumns := []migrator.ColumnType{ + { + NameValue: sql.NullString{String: "id", Valid: true}, + DataTypeValue: sql.NullString{String: "integer", Valid: true}, + ColumnTypeValue: sql.NullString{String: "integer", Valid: true}, + NullableValue: sql.NullBool{Bool: false, Valid: true}, + DefaultValueValue: sql.NullString{Valid: false}, + UniqueValue: sql.NullBool{Bool: true, Valid: true}, + PrimaryKeyValue: sql.NullBool{Bool: true, Valid: true}, + }, + { + NameValue: sql.NullString{String: "dark_mode", Valid: true}, + DataTypeValue: sql.NullString{String: "numeric", Valid: true}, + ColumnTypeValue: sql.NullString{String: "numeric", Valid: true}, + NullableValue: sql.NullBool{Valid: true}, + DefaultValueValue: sql.NullString{String: "true", Valid: true}, + UniqueValue: sql.NullBool{Bool: false, Valid: true}, + PrimaryKeyValue: sql.NullBool{Bool: false, Valid: true}, + }, + } + + params := []struct { + name string + sql []string + nFields int + columns []migrator.ColumnType + }{ + { + "with_newline", + []string{"CREATE TABLE `users`\n(\nid integer primary key unique,\ndark_mode numeric DEFAULT true)"}, + 2, + testColumns, + }, + { + "with_newline_2", + []string{"CREATE TABLE `users` (\n\nid integer primary key unique,\ndark_mode numeric DEFAULT true)"}, + 2, + testColumns, + }, + { + "with_missing_space", + []string{"CREATE TABLE `users`(id integer primary key unique, dark_mode numeric DEFAULT true)"}, + 2, + testColumns, + }, + { + "with_many_spaces", + []string{"CREATE TABLE `users` (id integer primary key unique, dark_mode numeric DEFAULT true)"}, + 2, + testColumns, + }, + } + for _, p := range params { + t.Run(p.name, func(t *testing.T) { + ddl, err := parseDDL(p.sql...) + + if err != nil { + panic(err.Error()) + } + + if len(ddl.fields) != p.nFields { + t.Fatalf("fields length doesn't match: expect: %v, got %v", p.nFields, len(ddl.fields)) + } + tests.AssertEqual(t, ddl.columns, p.columns) + }) + } +} + func TestParseDDL_error(t *testing.T) { params := []struct { name string diff --git a/migrator.go b/migrator.go index 9d11cfc..3edce2d 100644 --- a/migrator.go +++ b/migrator.go @@ -390,7 +390,7 @@ func (m Migrator) recreateTable(value interface{}, tablePtr *string, return nil } - tableReg, err := regexp.Compile(" ('|`|\"| )" + table + "('|`|\"| ) ") + tableReg, err := regexp.Compile("\\s*('|`|\")?\\b" + table + "\\b('|`|\")?\\s*") if err != nil { return err } From 96a6beea7a699d9870f0a0bdb4b290174cea4836 Mon Sep 17 00:00:00 2001 From: black-06 Date: Fri, 19 May 2023 18:48:11 +0800 Subject: [PATCH 07/15] fix: migrator run with nil schema (#147) --- migrator.go | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/migrator.go b/migrator.go index 3edce2d..7458326 100644 --- a/migrator.go +++ b/migrator.go @@ -271,28 +271,29 @@ func (m Migrator) BuildIndexOptions(opts []schema.IndexOption, stmt *gorm.Statem func (m Migrator) CreateIndex(value interface{}, name string) error { return m.RunWithValue(value, func(stmt *gorm.Statement) error { - if idx := stmt.Schema.LookIndex(name); idx != nil { - opts := m.BuildIndexOptions(idx.Fields, stmt) - values := []interface{}{clause.Column{Name: idx.Name}, clause.Table{Name: stmt.Table}, opts} + if stmt.Schema != nil { + if idx := stmt.Schema.LookIndex(name); idx != nil { + opts := m.BuildIndexOptions(idx.Fields, stmt) + values := []interface{}{clause.Column{Name: idx.Name}, clause.Table{Name: stmt.Table}, opts} - createIndexSQL := "CREATE " - if idx.Class != "" { - createIndexSQL += idx.Class + " " - } - createIndexSQL += "INDEX ?" + createIndexSQL := "CREATE " + if idx.Class != "" { + createIndexSQL += idx.Class + " " + } + createIndexSQL += "INDEX ?" - if idx.Type != "" { - createIndexSQL += " USING " + idx.Type - } - createIndexSQL += " ON ??" + if idx.Type != "" { + createIndexSQL += " USING " + idx.Type + } + createIndexSQL += " ON ??" - if idx.Where != "" { - createIndexSQL += " WHERE " + idx.Where - } + if idx.Where != "" { + createIndexSQL += " WHERE " + idx.Where + } - return m.DB.Exec(createIndexSQL, values...).Error + return m.DB.Exec(createIndexSQL, values...).Error + } } - return fmt.Errorf("failed to create index with name %v", name) }) } @@ -300,8 +301,10 @@ func (m Migrator) CreateIndex(value interface{}, name string) error { func (m Migrator) HasIndex(value interface{}, name string) bool { var count int m.RunWithValue(value, func(stmt *gorm.Statement) error { - if idx := stmt.Schema.LookIndex(name); idx != nil { - name = idx.Name + if stmt.Schema != nil { + if idx := stmt.Schema.LookIndex(name); idx != nil { + name = idx.Name + } } if name != "" { @@ -327,8 +330,10 @@ func (m Migrator) RenameIndex(value interface{}, oldName, newName string) error func (m Migrator) DropIndex(value interface{}, name string) error { return m.RunWithValue(value, func(stmt *gorm.Statement) error { - if idx := stmt.Schema.LookIndex(name); idx != nil { - name = idx.Name + if stmt.Schema != nil { + if idx := stmt.Schema.LookIndex(name); idx != nil { + name = idx.Name + } } return m.DB.Exec("DROP INDEX ?", clause.Column{Name: name}).Error From 0d652e16cdf4ab215f20d973cb89c70729e18a84 Mon Sep 17 00:00:00 2001 From: Kenny Leung Date: Fri, 19 May 2023 03:48:58 -0700 Subject: [PATCH 08/15] update gorm to 1.25 (#145) Signed-off-by: Kenny Leung --- .github/workflows/ci.yml | 2 +- go.mod | 10 +++++++--- go.sum | 9 ++++----- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 903eb65..d7222d5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ jobs: name: Test strategy: matrix: - go: ['1.19', '1.18', '1.17'] + go: ['1.20', '1.19', '1.18', '1.17'] platform: [ubuntu-latest] # can not run in windows OS runs-on: ubuntu-latest steps: diff --git a/go.mod b/go.mod index 02898c7..5e47b63 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,13 @@ module gorm.io/driver/sqlite -go 1.14 +go 1.20 require ( + github.com/mattn/go-sqlite3 v1.14.16 + gorm.io/gorm v1.25.0 +) + +require ( + github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - github.com/mattn/go-sqlite3 v1.14.15 - gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11 ) diff --git a/go.sum b/go.sum index 685067d..3290593 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,8 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= -github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11 h1:9qNbmu21nNThCNnF5i2R3kw2aL27U8ZwbzccNjOmW0g= -gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +gorm.io/gorm v1.25.0 h1:+KtYtb2roDz14EQe4bla8CbQlmb9dN3VejSai3lprfU= +gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= From 32a05460a885a62e0a848b3fe3950470de261307 Mon Sep 17 00:00:00 2001 From: guangwu Date: Sun, 28 May 2023 15:20:29 +0800 Subject: [PATCH 09/15] code optimization and add ignore file (#149) --- .gitignore | 1 + ddlmod.go | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f11b75 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ diff --git a/ddlmod.go b/ddlmod.go index 8061ded..246f616 100644 --- a/ddlmod.go +++ b/ddlmod.go @@ -13,12 +13,12 @@ import ( var ( sqliteSeparator = "`|\"|'|\t" - indexRegexp = regexp.MustCompile(fmt.Sprintf("(?is)CREATE(?: UNIQUE)? INDEX [%v]?[\\w\\d-]+[%v]? ON (.*)$", sqliteSeparator, sqliteSeparator)) - tableRegexp = regexp.MustCompile(fmt.Sprintf("(?is)(CREATE TABLE [%v]?[\\w\\d-]+[%v]?)(?:\\s*\\((.*)\\))?", sqliteSeparator, sqliteSeparator)) + indexRegexp = regexp.MustCompile(fmt.Sprintf(`(?is)CREATE(?: UNIQUE)? INDEX [%v]?[\w\d-]+[%v]? ON (.*)$`, sqliteSeparator, sqliteSeparator)) + tableRegexp = regexp.MustCompile(fmt.Sprintf(`(?is)(CREATE TABLE [%v]?[\w\d-]+[%v]?)(?:\s*\((.*)\))?`, sqliteSeparator, sqliteSeparator)) separatorRegexp = regexp.MustCompile(fmt.Sprintf("[%v]", sqliteSeparator)) - columnsRegexp = regexp.MustCompile(fmt.Sprintf("[(,][%v]?(\\w+)[%v]?", sqliteSeparator, sqliteSeparator)) - columnRegexp = regexp.MustCompile(fmt.Sprintf("^[%v]?([\\w\\d]+)[%v]?\\s+([\\w\\(\\)\\d]+)(.*)$", sqliteSeparator, sqliteSeparator)) - defaultValueRegexp = regexp.MustCompile("(?i) DEFAULT \\(?(.+)?\\)?( |COLLATE|GENERATED|$)") + columnsRegexp = regexp.MustCompile(fmt.Sprintf(`[(,][%v]?(\w+)[%v]?`, sqliteSeparator, sqliteSeparator)) + columnRegexp = regexp.MustCompile(fmt.Sprintf(`^[%v]?([\w\d]+)[%v]?\s+([\w\(\)\d]+)(.*)$`, sqliteSeparator, sqliteSeparator)) + defaultValueRegexp = regexp.MustCompile(`(?i) DEFAULT \(?(.+)?\)?( |COLLATE|GENERATED|$)`) regRealDataType = regexp.MustCompile(`[^\d](\d+)[^\d]?`) ) From 86ba6431a312b3ede757cba66fb223d17301e17a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jun 2023 15:05:48 +0800 Subject: [PATCH 10/15] Bump github.com/mattn/go-sqlite3 from 1.14.16 to 1.14.17 (#153) Bumps [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) from 1.14.16 to 1.14.17. - [Release notes](https://github.com/mattn/go-sqlite3/releases) - [Commits](https://github.com/mattn/go-sqlite3/compare/v1.14.16...v1.14.17) --- updated-dependencies: - dependency-name: github.com/mattn/go-sqlite3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5e47b63..3201bfd 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module gorm.io/driver/sqlite go 1.20 require ( - github.com/mattn/go-sqlite3 v1.14.16 + github.com/mattn/go-sqlite3 v1.14.17 gorm.io/gorm v1.25.0 ) diff --git a/go.sum b/go.sum index 3290593..a231927 100644 --- a/go.sum +++ b/go.sum @@ -2,7 +2,7 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= -github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= +github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= gorm.io/gorm v1.25.0 h1:+KtYtb2roDz14EQe4bla8CbQlmb9dN3VejSai3lprfU= gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= From cb7f946bd69e13cf35558a9a9cab22951a644a38 Mon Sep 17 00:00:00 2001 From: Saeid Date: Wed, 7 Jun 2023 09:06:51 +0200 Subject: [PATCH 11/15] feat: foreign key violatation error (#150) Co-authored-by: Saeid Saeidee Co-authored-by: Jinzhu --- error_translator.go | 9 +++++---- go.mod | 2 +- go.sum | 2 ++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/error_translator.go b/error_translator.go index 23df522..e33d3cf 100644 --- a/error_translator.go +++ b/error_translator.go @@ -6,8 +6,9 @@ import ( "gorm.io/gorm" ) -var errCodes = map[string]int{ - "uniqueConstraint": 2067, +var errCodes = map[int]error{ + 2067: gorm.ErrDuplicatedKey, + 768: gorm.ErrForeignKeyViolated, } type ErrMessage struct { @@ -30,8 +31,8 @@ func (dialector Dialector) Translate(err error) error { return err } - if errMsg.ExtendedCode == errCodes["uniqueConstraint"] { - return gorm.ErrDuplicatedKey + if translatedErr, found := errCodes[errMsg.ExtendedCode]; found { + return translatedErr } return err } diff --git a/go.mod b/go.mod index 3201bfd..0c031e7 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( github.com/mattn/go-sqlite3 v1.14.17 - gorm.io/gorm v1.25.0 + gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55 ) require ( diff --git a/go.sum b/go.sum index a231927..45bb183 100644 --- a/go.sum +++ b/go.sum @@ -6,3 +6,5 @@ github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6 github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= gorm.io/gorm v1.25.0 h1:+KtYtb2roDz14EQe4bla8CbQlmb9dN3VejSai3lprfU= gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55 h1:sC1Xj4TYrLqg1n3AN10w871An7wJM0gzgcm8jkIkECQ= +gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= From 9ac07d29747c72b2523af3f01229e3cfbad3343d Mon Sep 17 00:00:00 2001 From: black-06 Date: Wed, 7 Jun 2023 15:07:57 +0800 Subject: [PATCH 12/15] fix: RenameIndex should drop old index (#151) --- migrator.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/migrator.go b/migrator.go index 7458326..fd2eeb4 100644 --- a/migrator.go +++ b/migrator.go @@ -322,6 +322,9 @@ func (m Migrator) RenameIndex(value interface{}, oldName, newName string) error var sql string m.DB.Raw("SELECT sql FROM sqlite_master WHERE type = ? AND tbl_name = ? AND name = ?", "index", stmt.Table, oldName).Row().Scan(&sql) if sql != "" { + if err := m.DropIndex(value, oldName); err != nil { + return err + } return m.DB.Exec(strings.Replace(sql, oldName, newName, 1)).Error } return fmt.Errorf("failed to find index with name %v", oldName) From 2a60d4fe201a68ce7bcf9e7865e8cbda6877eb01 Mon Sep 17 00:00:00 2001 From: Fabio Bonelli Date: Fri, 9 Jun 2023 04:18:50 +0200 Subject: [PATCH 13/15] fix: translate SQLITE_CONSTRAINT_PRIMARYKEY to ErrDuplicatedKey (#152) Translate the SQLITE_CONSTRAINT_PRIMARYKEY error code to ErrDuplicatedKey as well for consistency. --- error_translator.go | 1 + 1 file changed, 1 insertion(+) diff --git a/error_translator.go b/error_translator.go index e33d3cf..c5736cb 100644 --- a/error_translator.go +++ b/error_translator.go @@ -7,6 +7,7 @@ import ( ) var errCodes = map[int]error{ + 1555: gorm.ErrDuplicatedKey, 2067: gorm.ErrDuplicatedKey, 768: gorm.ErrForeignKeyViolated, } From cf6cd11e949ab8e7e97682d03bf1a608ddf2ec4d Mon Sep 17 00:00:00 2001 From: Saeid Date: Fri, 9 Jun 2023 04:19:25 +0200 Subject: [PATCH 14/15] fix: ErrForeignKeyViolated error constant (#155) * fix: ErrForeignKeyViolated error constant * refactor: added error codes reference --------- Co-authored-by: Saeid Saeidee --- error_translator.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/error_translator.go b/error_translator.go index c5736cb..f674cb1 100644 --- a/error_translator.go +++ b/error_translator.go @@ -6,10 +6,11 @@ import ( "gorm.io/gorm" ) +// The error codes to map sqlite errors to gorm errors, here is a reference about error codes for sqlite https://www.sqlite.org/rescode.html. var errCodes = map[int]error{ 1555: gorm.ErrDuplicatedKey, 2067: gorm.ErrDuplicatedKey, - 768: gorm.ErrForeignKeyViolated, + 787: gorm.ErrForeignKeyViolated, } type ErrMessage struct { From 397ec6fa8c64060db1dd392675cf51ab919c4c3c Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Thu, 8 Jun 2023 21:20:12 -0500 Subject: [PATCH 15/15] Fix columnType.Unique() returns true for non-unique index DDL. (#154) Signed-off-by: Jeff Ortel --- ddlmod.go | 2 +- ddlmod_test.go | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ddlmod.go b/ddlmod.go index 246f616..39cc13a 100644 --- a/ddlmod.go +++ b/ddlmod.go @@ -162,7 +162,7 @@ func parseDDL(strs ...string) (*ddl, error) { for _, column := range getAllColumns(matches[1]) { for idx, c := range result.columns { if c.NameValue.String == column { - c.UniqueValue = sql.NullBool{Bool: true, Valid: true} + c.UniqueValue = sql.NullBool{Bool: strings.ToUpper(strings.Fields(str)[1]) == "UNIQUE", Valid: true} result.columns[idx] = c } } diff --git a/ddlmod_test.go b/ddlmod_test.go index f6fc6e7..763c3ce 100644 --- a/ddlmod_test.go +++ b/ddlmod_test.go @@ -79,6 +79,24 @@ func TestParseDDL(t *testing.T) { }, }, }, + { + "non-unique index", + []string{ + "CREATE TABLE `test-c` (`field` integer NOT NULL)", + "CREATE INDEX `idx_uq` ON `test-b`(`field`) WHERE field = 0", + }, + 1, + []migrator.ColumnType{ + { + NameValue: sql.NullString{String: "field", Valid: true}, + DataTypeValue: sql.NullString{String: "integer", Valid: true}, + ColumnTypeValue: sql.NullString{String: "integer", Valid: true}, + PrimaryKeyValue: sql.NullBool{Bool: false, Valid: true}, + UniqueValue: sql.NullBool{Bool: false, Valid: true}, + NullableValue: sql.NullBool{Bool: false, Valid: true}, + }, + }, + }, } for _, p := range params {