diff --git a/.gitea/workflows/release-tag.yml b/.gitea/workflows/release-tag.yml index 835825f8..e65b9521 100644 --- a/.gitea/workflows/release-tag.yml +++ b/.gitea/workflows/release-tag.yml @@ -9,13 +9,13 @@ jobs: release: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: setup go uses: actions/setup-go@v5 with: - go-version: '>=1.20.1' + go-version-file: 'go.mod' - name: Use Go Action id: use-go-action uses: https://gitea.com/actions/release-action@main diff --git a/.gitea/workflows/test-cockroach.yml b/.gitea/workflows/test-cockroach.yml index 25527e86..4e547267 100644 --- a/.gitea/workflows/test-cockroach.yml +++ b/.gitea/workflows/test-cockroach.yml @@ -5,38 +5,15 @@ on: - master pull_request: -env: - GOPROXY: https://goproxy.io,direct - GOPATH: /go_path - GOCACHE: /go_cache - jobs: test-cockroach: name: test cockroach runs-on: ubuntu-latest steps: - # - name: cache go path - # id: cache-go-path - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_path - # key: go_path-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_path-${{ github.repository }}- - # go_path- - # - name: cache go cache - # id: cache-go-cache - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_cache - # key: go_cache-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_cache-${{ github.repository }}- - # go_cache- + - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: 1.20 - - uses: actions/checkout@v3 + go-version-file: 'go.mod' - name: test cockroach env: TEST_COCKROACH_HOST: "cockroach:26257" diff --git a/.gitea/workflows/test-mariadb.yml b/.gitea/workflows/test-mariadb.yml index 19a3640c..0ddfcf58 100644 --- a/.gitea/workflows/test-mariadb.yml +++ b/.gitea/workflows/test-mariadb.yml @@ -5,38 +5,15 @@ on: - master pull_request: -env: - GOPROXY: https://goproxy.io,direct - GOPATH: /go_path - GOCACHE: /go_cache - jobs: lint: name: test mariadb runs-on: ubuntu-latest steps: - # - name: cache go path - # id: cache-go-path - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_path - # key: go_path-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_path-${{ github.repository }}- - # go_path- - # - name: cache go cache - # id: cache-go-cache - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_cache - # key: go_cache-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_cache-${{ github.repository }}- - # go_cache- + - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: 1.20 - - uses: actions/checkout@v3 + go-version-file: 'go.mod' - name: test mariadb env: TEST_MYSQL_HOST: mariadb diff --git a/.gitea/workflows/test-mssql-collation.yml b/.gitea/workflows/test-mssql-collation.yml index 552f43a1..3d6d7ad1 100644 --- a/.gitea/workflows/test-mssql-collation.yml +++ b/.gitea/workflows/test-mssql-collation.yml @@ -5,39 +5,15 @@ on: - master pull_request: -env: - GOPROXY: https://goproxy.io,direct - GOPATH: /go_path - GOCACHE: /go_cache - RUNNER_TOOL_CACHE: /toolcache # specify with your cache path - jobs: test-mssql-collation: name: test mssql with collation runs-on: ubuntu-latest steps: - # - name: cache go path - # id: cache-go-path - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_path - # key: go_path-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_path-${{ github.repository }}- - # go_path- - # - name: cache go cache - # id: cache-go-cache - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_cache - # key: go_cache-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_cache-${{ github.repository }}- - # go_cache- - - uses: actions/setup-go@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 with: - go-version: 1.20 - - uses: actions/checkout@v3 + go-version-file: 'go.mod' - name: test mssql with collation env: TEST_MSSQL_HOST: mssql2 diff --git a/.gitea/workflows/test-mssql.yml b/.gitea/workflows/test-mssql.yml index 676df6a1..027ba5e3 100644 --- a/.gitea/workflows/test-mssql.yml +++ b/.gitea/workflows/test-mssql.yml @@ -5,38 +5,15 @@ on: - master pull_request: -env: - GOPROXY: https://goproxy.io,direct - GOPATH: /go_path - GOCACHE: /go_cache - jobs: test-mssql: name: test mssql runs-on: ubuntu-latest steps: - # - name: cache go path - # id: cache-go-path - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_path - # key: go_path-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_path-${{ github.repository }}- - # go_path- - # - name: cache go cache - # id: cache-go-cache - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_cache - # key: go_cache-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_cache-${{ github.repository }}- - # go_cache- + - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: 1.20 - - uses: actions/checkout@v3 + go-version-file: 'go.mod' - name: test mssql env: TEST_MSSQL_HOST: mssql diff --git a/.gitea/workflows/test-mysql.yml b/.gitea/workflows/test-mysql.yml index 6603f522..d3eabf14 100644 --- a/.gitea/workflows/test-mysql.yml +++ b/.gitea/workflows/test-mysql.yml @@ -5,38 +5,15 @@ on: - master pull_request: -env: - GOPROXY: https://goproxy.io,direct - GOPATH: /go_path - GOCACHE: /go_cache - jobs: test-mysql: name: test mysql runs-on: ubuntu-latest steps: - # - name: cache go path - # id: cache-go-path - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_path - # key: go_path-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_path-${{ github.repository }}- - # go_path- - # - name: cache go cache - # id: cache-go-cache - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_cache - # key: go_cache-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_cache-${{ github.repository }}- - # go_cache- + - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: 1.20 - - uses: actions/checkout@v3 + go-version-file: 'go.mod' - name: test mysql utf8mb4 env: TEST_MYSQL_HOST: mysql diff --git a/.gitea/workflows/test-mysql8.yml b/.gitea/workflows/test-mysql8.yml index 131b91a3..8318c345 100644 --- a/.gitea/workflows/test-mysql8.yml +++ b/.gitea/workflows/test-mysql8.yml @@ -5,38 +5,15 @@ on: - master pull_request: -env: - GOPROXY: https://goproxy.io,direct - GOPATH: /go_path - GOCACHE: /go_cache - jobs: lint: name: test mysql8 runs-on: ubuntu-latest steps: - # - name: cache go path - # id: cache-go-path - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_path - # key: go_path-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_path-${{ github.repository }}- - # go_path- - # - name: cache go cache - # id: cache-go-cache - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_cache - # key: go_cache-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_cache-${{ github.repository }}- - # go_cache- + - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: 1.20 - - uses: actions/checkout@v3 + go-version-file: 'go.mod' - name: test mysql8 env: TEST_MYSQL_HOST: mysql8 diff --git a/.gitea/workflows/test-postgres.yml b/.gitea/workflows/test-postgres.yml index a5fcbef6..18e2cb4a 100644 --- a/.gitea/workflows/test-postgres.yml +++ b/.gitea/workflows/test-postgres.yml @@ -5,38 +5,15 @@ on: - master pull_request: -env: - GOPROXY: https://goproxy.io,direct - GOPATH: /go_path - GOCACHE: /go_cache - jobs: lint: name: test postgres runs-on: ubuntu-latest steps: - # - name: cache go path - # id: cache-go-path - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_path - # key: go_path-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_path-${{ github.repository }}- - # go_path- - # - name: cache go cache - # id: cache-go-cache - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_cache - # key: go_cache-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_cache-${{ github.repository }}- - # go_cache- + - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: 1.20 - - uses: actions/checkout@v3 + go-version-file: 'go.mod' - name: test postgres env: TEST_PGSQL_HOST: pgsql diff --git a/.gitea/workflows/test-sqlite.yml b/.gitea/workflows/test-sqlite.yml index 99820b42..2fdf7410 100644 --- a/.gitea/workflows/test-sqlite.yml +++ b/.gitea/workflows/test-sqlite.yml @@ -5,38 +5,15 @@ on: - master pull_request: -env: - GOPROXY: https://goproxy.io,direct - GOPATH: /go_path - GOCACHE: /go_cache - jobs: test-sqlite: name: unit test & test sqlite runs-on: ubuntu-latest steps: - # - name: cache go path - # id: cache-go-path - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_path - # key: go_path-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_path-${{ github.repository }}- - # go_path- - # - name: cache go cache - # id: cache-go-cache - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_cache - # key: go_cache-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_cache-${{ github.repository }}- - # go_cache- + - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: 1.20 - - uses: actions/checkout@v3 + go-version-file: 'go.mod' - name: vet run: make vet - name: format check diff --git a/.gitea/workflows/test-tidb.yml b/.gitea/workflows/test-tidb.yml index 67d907e5..0d87e404 100644 --- a/.gitea/workflows/test-tidb.yml +++ b/.gitea/workflows/test-tidb.yml @@ -5,38 +5,15 @@ on: - master pull_request: -env: - GOPROXY: https://goproxy.io,direct - GOPATH: /go_path - GOCACHE: /go_cache - jobs: test-tidb: name: test tidb runs-on: ubuntu-latest steps: - # - name: cache go path - # id: cache-go-path - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_path - # key: go_path-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_path-${{ github.repository }}- - # go_path- - # - name: cache go cache - # id: cache-go-cache - # uses: https://github.com/actions/cache@v3 - # with: - # path: /go_cache - # key: go_cache-${{ github.repository }}-${{ github.ref_name }} - # restore-keys: | - # go_cache-${{ github.repository }}- - # go_cache- + - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: 1.20 - - uses: actions/checkout@v3 + go-version-file: 'go.mod' - name: test tidb env: TEST_TIDB_HOST: "tidb:4000" diff --git a/internal/statements/update.go b/internal/statements/update.go index 61342e33..dd490aef 100644 --- a/internal/statements/update.go +++ b/internal/statements/update.go @@ -126,6 +126,9 @@ func (statement *Statement) BuildUpdates(tableValue reflect.Value, if fieldValue.CanAddr() { if structConvert, ok := fieldValue.Addr().Interface().(convert.Conversion); ok { + if !includeNil && !requiredField && utils.IsZero(fieldValue.Interface()) { + continue + } data, err := structConvert.ToDB() if err != nil { return nil, nil, err diff --git a/migrate/migrate.go b/migrate/migrate.go index cd553ecb..2e5a6e3a 100644 --- a/migrate/migrate.go +++ b/migrate/migrate.go @@ -199,7 +199,7 @@ func (m *Migrate) createMigrationTableIfNotExists() error { idCol := schemas.NewColumn(m.options.IDColumnName, "", schemas.SQLType{ Name: "VARCHAR", - }, 255, 0, true) + }, 255, 0, false) idCol.IsPrimaryKey = true table := schemas.NewTable(m.options.TableName, reflect.TypeOf(new(schemas.Table))) diff --git a/sync.go b/sync.go index 4c02257b..44167652 100644 --- a/sync.go +++ b/sync.go @@ -17,6 +17,8 @@ type SyncOptions struct { IgnoreConstrains bool // IgnoreIndices will not add or delete indices IgnoreIndices bool + // IgnoreDropIndices will not delete indices + IgnoreDropIndices bool } type SyncResult struct{} @@ -55,6 +57,7 @@ func (session *Session) Sync(beans ...interface{}) error { WarnIfDatabaseColumnMissed: false, IgnoreConstrains: false, IgnoreIndices: false, + IgnoreDropIndices: false, }, beans...) return err } @@ -246,7 +249,7 @@ func (session *Session) SyncWithOptions(opts SyncOptions, beans ...interface{}) for name2, index2 := range oriTable.Indexes { if _, ok := foundIndexNames[name2]; !ok { // ignore based on there type - if (index2.Type == schemas.IndexType && opts.IgnoreIndices) || + if (index2.Type == schemas.IndexType && (opts.IgnoreIndices || opts.IgnoreDropIndices)) || (index2.Type == schemas.UniqueType && opts.IgnoreConstrains) { // make sure we do not add a index with same name later delete(addedNames, name2) diff --git a/tests/schema_test.go b/tests/schema_test.go index db9f9e8f..3657950e 100644 --- a/tests/schema_test.go +++ b/tests/schema_test.go @@ -698,7 +698,7 @@ func TestSyncWithOptions(t *testing.T) { assert.NotNil(t, result) assert.Len(t, getIndicesOfBeanFromDB(t, &SyncWithOpts1{}), 0) - // only ignore indices + // only ignore constrains result, err = testEngine.SyncWithOptions(xorm.SyncOptions{IgnoreConstrains: true}, &SyncWithOpts2{}) assert.NoError(t, err) assert.NotNil(t, result) @@ -706,7 +706,7 @@ func TestSyncWithOptions(t *testing.T) { assert.Len(t, indices, 2) assert.ElementsMatch(t, []string{"ttt", "index"}, getKeysFromMap(indices)) - // only ignore constrains + // only ignore indices result, err = testEngine.SyncWithOptions(xorm.SyncOptions{IgnoreIndices: true}, &SyncWithOpts3{}) assert.NoError(t, err) assert.NotNil(t, result) @@ -714,9 +714,16 @@ func TestSyncWithOptions(t *testing.T) { assert.Len(t, indices, 4) assert.ElementsMatch(t, []string{"ttt", "index", "unique", "lll"}, getKeysFromMap(indices)) + // only ignore drop indices + result, err = testEngine.SyncWithOptions(xorm.SyncOptions{IgnoreDropIndices: true}, &SyncWithOpts3{}) + assert.NoError(t, err) + assert.NotNil(t, result) + indices = getIndicesOfBeanFromDB(t, &SyncWithOpts1{}) + assert.Len(t, indices, 4) + assert.ElementsMatch(t, []string{"ttt", "index", "unique", "lll"}, getKeysFromMap(indices)) + tableInfoFromStruct, _ := testEngine.TableInfo(&SyncWithOpts1{}) assert.ElementsMatch(t, getKeysFromMap(tableInfoFromStruct.Indexes), getKeysFromMap(getIndicesOfBeanFromDB(t, &SyncWithOpts1{}))) - } func getIndicesOfBeanFromDB(t *testing.T, bean interface{}) map[string]*schemas.Index { diff --git a/tests/types_test.go b/tests/types_test.go index dfdb4766..9079d34b 100644 --- a/tests/types_test.go +++ b/tests/types_test.go @@ -619,3 +619,95 @@ func TestMyArray(t *testing.T) { assert.True(t, has) assert.EqualValues(t, v, m.Content) } + +type ZDecimal struct { + value *big.Int +} + +func (d *ZDecimal) FromDB(data []byte) error { + i, _ := strconv.ParseInt(string(data), 10, 64) + *d = ZDecimal{ + value: big.NewInt(i), + } + return nil +} + +func (d ZDecimal) ToDB() ([]byte, error) { + if d.value == nil { + return []byte("0"), nil + } + return []byte(fmt.Sprintf("%d", (d.value).Int64())), nil +} + +func (d ZDecimal) IsZero() bool { + if d.value == nil { + return true + } + return d.value.Sign() == 0 +} + +func (d ZDecimal) String() string { + if d.value == nil { + return "0" + } + return d.value.String() +} + +func TestZDecimal(t *testing.T) { + type ZMyMoney struct { + Id int64 + Account string + Amount ZDecimal + } + + assert.NoError(t, PrepareEngine()) + assertSync(t, new(ZMyMoney)) + + _, err := testEngine.Insert(&ZMyMoney{ + Account: "test", + Amount: ZDecimal{ + value: big.NewInt(10000000000000000), + }, + }) + assert.NoError(t, err) + + m := ZMyMoney{ + Id: 1, + } + has, err := testEngine.Get(&m) + assert.NoError(t, err) + assert.True(t, has) + + _, err = testEngine.Update(&ZMyMoney{ + Id: 1, + Account: "test2", + }) + assert.NoError(t, err) + m2 := ZMyMoney{ + Id: 1, + } + has, err = testEngine.Get(&m2) + + assert.NoError(t, err) + assert.True(t, has) + assert.Equal(t, "test2", "test2") + assert.False(t, m2.Amount.IsZero()) + assert.Equal(t, "10000000000000000", m2.Amount.String()) + + _, err = testEngine.AllCols().Update(&ZMyMoney{ + Id: 1, + Account: "test3", + }) + assert.NoError(t, err) + + var m3 = ZMyMoney{ + Id: 1, + } + has, err = testEngine.Get(&m3) + + assert.NoError(t, err) + assert.True(t, has) + assert.Equal(t, "test3", "test3") + assert.True(t, m3.Amount.IsZero()) + assert.Equal(t, "0", m3.Amount.String()) +}