From 5e171af1c7d95f93ce4f47271a7c41fd9598272c Mon Sep 17 00:00:00 2001 From: Breeze0806 <53822089+Breeze0806@users.noreply.github.com> Date: Fri, 16 Aug 2024 23:42:45 +0800 Subject: [PATCH] =?UTF-8?q?=20replace=20interface{}=20to=20any,=20add=20fu?= =?UTF-8?q?zz=20test=20and=20fi=E2=80=A6=20=E2=80=A6x=20bug=20-0=20(#48)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix & style: fix the issue that datax output too much log, replace the package "io/ioutil". * style: replace the package "io/ioutil" * style & test & fix : replace interface{} to any, add fuzz test and fix bug -0 * style: add license --- .gitignore | 2 +- datax/README.md | 6 +- datax/README_zh-CN.md | 6 +- datax/common/plugin/task.go | 4 +- datax/common/plugin/task_test.go | 2 +- datax/core/job/help_test.go | 2 +- datax/core/statistics/container/metrics.go | 2 +- .../core/statistics/container/metrics_test.go | 2 +- datax/plugin/reader/dbms/parameter.go | 12 +- datax/plugin/reader/dbms/parameter_test.go | 12 +- datax/plugin/reader/dbms/querier.go | 2 +- datax/plugin/reader/dbms/querier_help_test.go | 4 +- datax/plugin/writer/dbms/execer.go | 4 +- datax/plugin/writer/dbms/execer_help_test.go | 6 +- element/column.go | 2 +- element/column_test.go | 2 +- element/error.go | 2 +- element/help_test.go | 2 +- element/number.go | 7 + element/number_fuzz_test.go | 44 ++++++ element/number_test.go | 134 +++++++----------- element/time.go | 8 +- element/time_column_value.go | 4 +- element/time_test.go | 2 +- storage/database/README.md | 2 +- storage/database/README_zh-CN.md | 2 +- storage/database/db.go | 20 +-- .../database/db2/decode_chinese_linux_test.go | 2 +- .../db2/decode_chinese_windows_test.go | 2 +- storage/database/db2/field.go | 2 +- storage/database/db2/field_test.go | 2 +- storage/database/db_help_test.go | 2 +- storage/database/db_test.go | 2 +- storage/database/help_test.go | 2 +- storage/database/mysql/field.go | 2 +- storage/database/mysql/field_test.go | 2 +- storage/database/mysql/table.go | 4 +- storage/database/mysql/table_test.go | 4 +- storage/database/oracle/field.go | 2 +- storage/database/oracle/field_test.go | 2 +- storage/database/oracle/table.go | 4 +- storage/database/oracle/table_test.go | 4 +- storage/database/postgres/field.go | 2 +- storage/database/postgres/field_test.go | 2 +- storage/database/postgres/table.go | 4 +- storage/database/postgres/table_test.go | 4 +- storage/database/sqlserver/field.go | 2 +- storage/database/sqlserver/field_test.go | 2 +- storage/database/sqlserver/table.go | 4 +- storage/database/sqlserver/table_test.go | 4 +- storage/database/table.go | 16 +-- storage/database/table_test.go | 6 +- storage/stream/file/xlsx/stream.go | 4 +- 53 files changed, 200 insertions(+), 185 deletions(-) create mode 100644 element/number_fuzz_test.go diff --git a/.gitignore b/.gitignore index fcf7d44..797f4b4 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,6 @@ release/* *.tar.gz *.chn *.en - +testdata *.swp tags diff --git a/datax/README.md b/datax/README.md index 352d5ee..6bec448 100644 --- a/datax/README.md +++ b/datax/README.md @@ -152,7 +152,7 @@ type Querier interface { // Checks connectivity PingContext(ctx context.Context) error // Queries using a query statement - QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) + QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) // Obtains a specific table based on parameters FetchTableWithParam(ctx context.Context, param database.Parameter) (database.Table, error) // Retrieves records using parameters and a handler @@ -278,9 +278,9 @@ type Execer interface { // Checks connectivity PingContext(ctx context.Context) error // Queries using a query statement - QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) + QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) // Executes a query statement - ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) + ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) // Obtains a specific table based on parameters FetchTableWithParam(ctx context.Context, param database.Parameter) (database.Table, error) // Performs batch execution diff --git a/datax/README_zh-CN.md b/datax/README_zh-CN.md index 9f430bb..c1f0cb2 100644 --- a/datax/README_zh-CN.md +++ b/datax/README_zh-CN.md @@ -158,7 +158,7 @@ type Querier interface { //检测连通性 PingContext(ctx context.Context) error //通过query查询语句进行查询 - QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) + QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) //通过参数param获取具体表 FetchTableWithParam(ctx context.Context, param database.Parameter) (database.Table, error) //通过参数param,处理句柄handler获取记录 @@ -284,9 +284,9 @@ type Execer interface { //检测连通性 PingContext(ctx context.Context) error //通过query查询语句进行查询 - QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) + QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) //通过query查询语句进行查询 - ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) + ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) //通过参数param获取具体表 FetchTableWithParam(ctx context.Context, param database.Parameter) (database.Table, error) //批量执行 diff --git a/datax/common/plugin/task.go b/datax/common/plugin/task.go index b2df6b6..505ee65 100644 --- a/datax/common/plugin/task.go +++ b/datax/common/plugin/task.go @@ -42,7 +42,7 @@ type Task interface { // Set Task ID SetTaskID(taskID int64) // Wrap Error - Wrapf(err error, format string, args ...interface{}) error + Wrapf(err error, format string, args ...any) error // Format - Log format Format(format string) string } @@ -105,7 +105,7 @@ func (b *BaseTask) SetJobID(jobID int64) { } // Wrapf - Wraps an error with additional context -func (b *BaseTask) Wrapf(err error, format string, args ...interface{}) error { +func (b *BaseTask) Wrapf(err error, format string, args ...any) error { return errors.Wrapf(err, b.Format(format), args...) } diff --git a/datax/common/plugin/task_test.go b/datax/common/plugin/task_test.go index 3078882..e6414bc 100644 --- a/datax/common/plugin/task_test.go +++ b/datax/common/plugin/task_test.go @@ -170,7 +170,7 @@ func TestBaseTask_Wrapf(t *testing.T) { type args struct { err error format string - args []interface{} + args []any } tests := []struct { name string diff --git a/datax/core/job/help_test.go b/datax/core/job/help_test.go index 0f38ef7..86fb9c3 100644 --- a/datax/core/job/help_test.go +++ b/datax/core/job/help_test.go @@ -225,7 +225,7 @@ func (m *mockWriter) Task() writer.Task { } func equalConfigJSON(gotConfig, wantConfig *config.JSON) bool { - var got, want interface{} + var got, want any err := json.Unmarshal([]byte(gotConfig.String()), &got) if err != nil { panic(err) diff --git a/datax/core/statistics/container/metrics.go b/datax/core/statistics/container/metrics.go index 6a65d5c..494fa35 100644 --- a/datax/core/statistics/container/metrics.go +++ b/datax/core/statistics/container/metrics.go @@ -43,7 +43,7 @@ func (m *Metrics) JSON() *encoding.JSON { } // Set - Sets the value at the specified path -func (m *Metrics) Set(path string, value interface{}) error { +func (m *Metrics) Set(path string, value any) error { m.Lock() defer m.Unlock() return m.metricJSON.Set(path, value) diff --git a/datax/core/statistics/container/metrics_test.go b/datax/core/statistics/container/metrics_test.go index 0a7cc9d..1aecec8 100644 --- a/datax/core/statistics/container/metrics_test.go +++ b/datax/core/statistics/container/metrics_test.go @@ -73,7 +73,7 @@ func TestNewMetrics(t *testing.T) { func TestMetrics_Set(t *testing.T) { type args struct { path string - value interface{} + value any } tests := []struct { name string diff --git a/datax/plugin/reader/dbms/parameter.go b/datax/plugin/reader/dbms/parameter.go index 73ed8b6..2011824 100644 --- a/datax/plugin/reader/dbms/parameter.go +++ b/datax/plugin/reader/dbms/parameter.go @@ -69,7 +69,7 @@ func (t *TableParam) Query(_ []element.Record) (string, error) { } // Agrs Get query parameters -func (t *TableParam) Agrs(_ []element.Record) ([]interface{}, error) { +func (t *TableParam) Agrs(_ []element.Record) ([]any, error) { return nil, nil } @@ -119,7 +119,7 @@ func (q *QueryParam) Query(_ []element.Record) (string, error) { } // Agrs Get query parameters -func (q *QueryParam) Agrs(_ []element.Record) (a []interface{}, err error) { +func (q *QueryParam) Agrs(_ []element.Record) (a []any, err error) { if len(q.Config.GetQuerySQL()) > 0 { return nil, nil } @@ -134,7 +134,7 @@ func (q *QueryParam) Agrs(_ []element.Record) (a []interface{}, err error) { if right, err = q.Config.GetSplitConfig().Range.rightColumn(v.Name()); err != nil { return } - var li, ri interface{} + var li, ri any if li, err = v.Valuer(left).Value(); err != nil { return } @@ -178,7 +178,7 @@ func (s *SplitParam) Query(_ []element.Record) (string, error) { } // Agrs Get query parameters -func (s *SplitParam) Agrs(_ []element.Record) ([]interface{}, error) { +func (s *SplitParam) Agrs(_ []element.Record) ([]any, error) { return nil, nil } @@ -213,7 +213,7 @@ func (m *MinParam) Query(_ []element.Record) (string, error) { } // Agrs Get query parameters -func (m *MinParam) Agrs(_ []element.Record) ([]interface{}, error) { +func (m *MinParam) Agrs(_ []element.Record) ([]any, error) { return nil, nil } @@ -248,6 +248,6 @@ func (m *MaxParam) Query(_ []element.Record) (string, error) { } // Agrs Get query parameters -func (m *MaxParam) Agrs(_ []element.Record) ([]interface{}, error) { +func (m *MaxParam) Agrs(_ []element.Record) ([]any, error) { return nil, nil } diff --git a/datax/plugin/reader/dbms/parameter_test.go b/datax/plugin/reader/dbms/parameter_test.go index 62b00bb..e9a49a5 100644 --- a/datax/plugin/reader/dbms/parameter_test.go +++ b/datax/plugin/reader/dbms/parameter_test.go @@ -121,7 +121,7 @@ func Test_tableParam_Agrs(t *testing.T) { name string t *TableParam args args - want []interface{} + want []any wantErr bool }{ { @@ -263,7 +263,7 @@ func Test_queryParam_Agrs(t *testing.T) { q *QueryParam args args config *BaseConfig - want []interface{} + want []any wantErr bool }{ { @@ -295,7 +295,7 @@ func Test_queryParam_Agrs(t *testing.T) { args: args{ in0: nil, }, - want: []interface{}{ + want: []any{ int64(11), int64(22), }, }, @@ -472,7 +472,7 @@ func TestSplitParam_Agrs(t *testing.T) { name string s *SplitParam args args - want []interface{} + want []any wantErr bool }{ { @@ -567,7 +567,7 @@ func TestMinParam_Agrs(t *testing.T) { name string m *MinParam args args - want []interface{} + want []any wantErr bool }{ { @@ -652,7 +652,7 @@ func TestMaxParam_Agrs(t *testing.T) { name string m *MaxParam args args - want []interface{} + want []any wantErr bool }{ { diff --git a/datax/plugin/reader/dbms/querier.go b/datax/plugin/reader/dbms/querier.go index aad820a..de5b235 100644 --- a/datax/plugin/reader/dbms/querier.go +++ b/datax/plugin/reader/dbms/querier.go @@ -28,7 +28,7 @@ type Querier interface { // Check connectivity. PingContext(ctx context.Context) error // Perform a query using the specified query statement. - QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) + QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) // Obtain a specific table based on the provided parameters. FetchTableWithParam(ctx context.Context, param database.Parameter) (database.Table, error) // Retrieve records using the provided parameters and the handler. diff --git a/datax/plugin/reader/dbms/querier_help_test.go b/datax/plugin/reader/dbms/querier_help_test.go index f9aa13d..b23a2cf 100644 --- a/datax/plugin/reader/dbms/querier_help_test.go +++ b/datax/plugin/reader/dbms/querier_help_test.go @@ -121,7 +121,7 @@ func (m *MockQuerier) PingContext(ctx context.Context) error { return m.PingErr } -func (m *MockQuerier) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) { +func (m *MockQuerier) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) { return nil, m.QueryErr } @@ -216,7 +216,7 @@ func (m *MockSender) Shutdown() error { } func equalConfigJSON(gotConfig, wantConfig *config.JSON) bool { - var got, want interface{} + var got, want any err := json.Unmarshal([]byte(gotConfig.String()), &got) if err != nil { panic(err) diff --git a/datax/plugin/writer/dbms/execer.go b/datax/plugin/writer/dbms/execer.go index 2a1d6f4..ea5d899 100644 --- a/datax/plugin/writer/dbms/execer.go +++ b/datax/plugin/writer/dbms/execer.go @@ -26,9 +26,9 @@ type Execer interface { // Obtain relational database configuration through configuration PingContext(ctx context.Context) error - QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) + QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) // BaseDbHandler Basic Database Execution Handler Encapsulation - ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) + ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) FetchTableWithParam(ctx context.Context, param database.Parameter) (database.Table, error) diff --git a/datax/plugin/writer/dbms/execer_help_test.go b/datax/plugin/writer/dbms/execer_help_test.go index b9c367a..1f18e81 100644 --- a/datax/plugin/writer/dbms/execer_help_test.go +++ b/datax/plugin/writer/dbms/execer_help_test.go @@ -150,11 +150,11 @@ func (m *MockExecer) PingContext(ctx context.Context) error { return m.PingErr } -func (m *MockExecer) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) { +func (m *MockExecer) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) { return nil, m.QueryErr } -func (m *MockExecer) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) { +func (m *MockExecer) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) { if query == "wait" { time.Sleep(100 * time.Millisecond) } @@ -245,7 +245,7 @@ func (m *MockReceiver) Shutdown() error { } func equalConfigJSON(gotConfig, wantConfig *config.JSON) bool { - var got, want interface{} + var got, want any err := json.Unmarshal([]byte(gotConfig.String()), &got) if err != nil { panic(err) diff --git a/element/column.go b/element/column.go index fb7b1f5..308edb7 100644 --- a/element/column.go +++ b/element/column.go @@ -207,7 +207,7 @@ func (d *DefaultColumn) AsFloat64() (float64, error) { } // ByteSize Byte size -func ByteSize(src interface{}) int { +func ByteSize(src any) int { switch data := src.(type) { case nil: return 0 diff --git a/element/column_test.go b/element/column_test.go index cf107ad..ef8e388 100644 --- a/element/column_test.go +++ b/element/column_test.go @@ -527,7 +527,7 @@ func TestDefaultColumn_Cmp(t *testing.T) { func TestByteSize(t *testing.T) { type args struct { - src interface{} + src any } tests := []struct { name string diff --git a/element/error.go b/element/error.go index 9026e70..aef3272 100644 --- a/element/error.go +++ b/element/error.go @@ -77,7 +77,7 @@ type SetError struct { } // NewSetError Generates a setting error by setting the value i to the specified other type with the error err -func NewSetError(i interface{}, other ColumnType, err error) *SetError { +func NewSetError(i any, other ColumnType, err error) *SetError { for uerr := err; uerr != nil; uerr = errors.Unwrap(err) { err = uerr } diff --git a/element/help_test.go b/element/help_test.go index 22e80b1..3568259 100644 --- a/element/help_test.go +++ b/element/help_test.go @@ -26,7 +26,7 @@ type mockTimeDecoder struct { StringTimeDecoder } -func (m *mockTimeDecoder) TimeDecode(t time.Time) (interface{}, error) { +func (m *mockTimeDecoder) TimeDecode(t time.Time) (any, error) { return time.Time{}, fmt.Errorf("mockTimeDecoder error") } diff --git a/element/number.go b/element/number.go index 979aadc..4a56f65 100644 --- a/element/number.go +++ b/element/number.go @@ -606,6 +606,9 @@ func (c *Converter) ConvertBigInt(s string) (num BigIntNumber, err error) { if len(first) == 0 { first = "0" } + if first == "0" { + sign = "" + } return convertBigInt(sign + first).(BigIntNumber), nil } @@ -685,6 +688,9 @@ func convertDecimal(s string) (num DecimalNumber, err error) { first = "0" } if len(s[pIndex+1:]) == 0 { + if first == "0" { + sign = "" + } return &DecimalStr{ value: sign + first, intLen: len(sign) + len(first), @@ -705,6 +711,7 @@ func convertDecimal(s string) (num DecimalNumber, err error) { if len(first) == 0 { first = "0" } + return convertBigInt(sign + first).(DecimalNumber), nil } diff --git a/element/number_fuzz_test.go b/element/number_fuzz_test.go new file mode 100644 index 0000000..88a350a --- /dev/null +++ b/element/number_fuzz_test.go @@ -0,0 +1,44 @@ +// Copyright 2020 the go-etl Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build go1.18 +// +build go1.18 + +package element + +import ( + "testing" +) + +func FuzzConverterConvertDecimal(f *testing.F) { + for _, t := range testTableDecimalStr { + f.Add(t.short) + } + + f.Fuzz(func(t *testing.T, number string) { + num1, err1 := testNumConverter.ConvertDecimal(number) + num2, err2 := testOldNumConverter.ConvertDecimal(number) + if err1 == nil && err2 != nil { + t.Fatalf("input: %v err1: %v err2: %v", number, err1, err2) + } + if err1 != nil && err2 == nil { + t.Fatalf("input: %v err1: %v err2:%v", number, err1, err2) + } + if err1 == nil && err2 == nil { + if num1.String() != num2.String() { + t.Fatalf("input: %v num1: %v num2: %v", number, num1.String(), num2.String()) + } + } + }) +} diff --git a/element/number_test.go b/element/number_test.go index 96483da..28b5f6d 100644 --- a/element/number_test.go +++ b/element/number_test.go @@ -106,13 +106,14 @@ var testTableInt64 = map[string]string{ "00000000000000000000000000000000000000000000000000": "0", "+00000000000000000000000000000000000000000000000000": "0", "-00000000000000000000000000000000000000000000000000": "0", - "+012345678901234567890": "12345678901234567890", - "+0000000103456789123456789012": "103456789123456789012", - "0000000103456789123456789012": "103456789123456789012", - "+103456789123456789012": "103456789123456789012", - "-103456789123456789012": "-103456789123456789012", - "103456789123456789012": "103456789123456789012", - "-0000000103456789123456789012": "-103456789123456789012", + "-0": "0", + "+012345678901234567890": "12345678901234567890", + "+0000000103456789123456789012": "103456789123456789012", + "0000000103456789123456789012": "103456789123456789012", + "+103456789123456789012": "103456789123456789012", + "-103456789123456789012": "-103456789123456789012", + "103456789123456789012": "103456789123456789012", + "-0000000103456789123456789012": "-103456789123456789012", } var testTableScientificNotation = map[string]string{ @@ -130,6 +131,7 @@ var testTableScientificNotation = map[string]string{ "0e-5": "0", "0.e0": "0", ".0e0": "0", + "-0": "0", "123.456e0": "123.456", "123.456e2": "12345.6", "123.456e10": "1234560000000", @@ -137,6 +139,44 @@ var testTableScientificNotation = map[string]string{ "123456789123456789123456789123456e-2": "1234567891234567891234567891234.56", } +var testErrors = []string{ + "", + "qwert", + "-", + ".", + "-.", + ".-", + "234-.56", + "234-56", + "2-", + "..", + "2..", + "..2", + ".5.2", + "8..2", + "8.1.", + "1e", + "1-e", + "1e9e", + "1ee9", + "1ee", + "1eE", + "1e-", + "1e-.", + "1e1.2", + "123.456e1.3", + "1e-1.2", + "123.456e-1.3", + "123.456Easdf", + "123.456e" + strconv.FormatInt(math.MinInt64, 10), + "123.456e" + strconv.FormatInt(math.MinInt32, 10), + "512.99 USD", + "$99.99", + "51,850.00", + "20_000_000.00", + "$20_000_000.00", +} + var testNumConverter = &Converter{} var testOldNumConverter = &OldConverter{} @@ -263,45 +303,7 @@ func TestOldConverter_ConvertDecimal(t *testing.T) { } } func TestConverter_ConvertNumberErrs(t *testing.T) { - tests := []string{ - "", - "qwert", - "-", - ".", - "-.", - ".-", - "234-.56", - "234-56", - "2-", - "..", - "2..", - "..2", - ".5.2", - "8..2", - "8.1.", - "1e", - "1-e", - "1e9e", - "1ee9", - "1ee", - "1eE", - "1e-", - "1e-.", - "1e1.2", - "123.456e1.3", - "1e-1.2", - "123.456e-1.3", - "123.456Easdf", - "123.456e" + strconv.FormatInt(math.MinInt64, 10), - "123.456e" + strconv.FormatInt(math.MinInt32, 10), - "512.99 USD", - "$99.99", - "51,850.00", - "20_000_000.00", - "$20_000_000.00", - } - - for _, s := range tests { + for _, s := range testErrors { _, err := testNumConverter.ConvertDecimal(s) if err == nil { @@ -311,45 +313,7 @@ func TestConverter_ConvertNumberErrs(t *testing.T) { } func TestOldConverter_ConvertNumberErrs(t *testing.T) { - tests := []string{ - "", - "qwert", - "-", - ".", - "-.", - ".-", - "234-.56", - "234-56", - "2-", - "..", - "2..", - "..2", - ".5.2", - "8..2", - "8.1.", - "1e", - "1-e", - "1e9e", - "1ee9", - "1ee", - "1eE", - "1e-", - "1e-.", - "1e1.2", - "123.456e1.3", - "1e-1.2", - "123.456e-1.3", - "123.456Easdf", - "123.456e" + strconv.FormatInt(math.MinInt64, 10), - "123.456e" + strconv.FormatInt(math.MinInt32, 10), - "512.99 USD", - "$99.99", - "51,850.00", - "20_000_000.00", - "$20_000_000.00", - } - - for _, s := range tests { + for _, s := range testErrors { _, err := testOldNumConverter.ConvertDecimal(s) if err == nil { diff --git a/element/time.go b/element/time.go index 623ac9c..8e216e2 100644 --- a/element/time.go +++ b/element/time.go @@ -24,13 +24,13 @@ var DefaultTimeFormat = "2006-01-02 15:04:05.999999999Z07:00" // TimeDecoder - Time decoder type TimeDecoder interface { - TimeDecode(t time.Time) (interface{}, error) + TimeDecode(t time.Time) (any, error) Layout() string } // TimeEncoder - Time encoder type TimeEncoder interface { - TimeEncode(i interface{}) (time.Time, error) + TimeEncode(i any) (time.Time, error) } // StringTimeEncoder - String time encoder @@ -46,7 +46,7 @@ func NewStringTimeEncoder(layout string) TimeEncoder { } // TimeEncode - Encode to time. If 'i' is not a string or not in the layout format, an error will be reported. -func (e *StringTimeEncoder) TimeEncode(i interface{}) (time.Time, error) { +func (e *StringTimeEncoder) TimeEncode(i any) (time.Time, error) { s, ok := i.(string) if !ok { return time.Time{}, fmt.Errorf("%v is %T, not string", i, i) @@ -67,7 +67,7 @@ func NewStringTimeDecoder(layout string) TimeDecoder { } // TimeDecode - Decode a string time based on the layout of the go time format into a string -func (d *StringTimeDecoder) TimeDecode(t time.Time) (interface{}, error) { +func (d *StringTimeDecoder) TimeDecode(t time.Time) (any, error) { return t.Format(d.layout), nil } diff --git a/element/time_column_value.go b/element/time_column_value.go index cb814b6..ba8bdfe 100644 --- a/element/time_column_value.go +++ b/element/time_column_value.go @@ -84,7 +84,7 @@ func (t *TimeColumnValue) AsDecimal() (DecimalNumber, error) { // AsString Converts to a string func (t *TimeColumnValue) AsString() (s string, err error) { - var i interface{} + var i any i, err = t.TimeDecode(t.val) if err != nil { return "", NewTransformErrorFormColumnTypes(t.Type(), TypeString, fmt.Errorf("val: %v", t.String())) @@ -94,7 +94,7 @@ func (t *TimeColumnValue) AsString() (s string, err error) { // AsBytes Converts to a byte stream func (t *TimeColumnValue) AsBytes() (b []byte, err error) { - var i interface{} + var i any i, err = t.TimeDecode(t.val) if err != nil { return nil, NewTransformErrorFormColumnTypes(t.Type(), TypeString, fmt.Errorf("val: %v", t.String())) diff --git a/element/time_test.go b/element/time_test.go index 0b376e9..51754d0 100644 --- a/element/time_test.go +++ b/element/time_test.go @@ -22,7 +22,7 @@ import ( func TestStringTimeEncoder_TimeEncode(t *testing.T) { type args struct { - i interface{} + i any } tests := []struct { name string diff --git a/storage/database/README.md b/storage/database/README.md index 1e2c024..b22797e 100644 --- a/storage/database/README.md +++ b/storage/database/README.md @@ -103,7 +103,7 @@ type Parameter interface { Table() Table // Table or view TxOptions() *sql.TxOptions // Transaction mode Query([]element.Record) (string, error) // SQL prepare statement - Agrs([]element.Record) ([]interface{}, error) // Prepare parameters + Agrs([]element.Record) ([]any, error) // Prepare parameters } ``` diff --git a/storage/database/README_zh-CN.md b/storage/database/README_zh-CN.md index 49a00c6..27cc5d2 100644 --- a/storage/database/README_zh-CN.md +++ b/storage/database/README_zh-CN.md @@ -104,7 +104,7 @@ type Parameter interface { Table() Table //表或者视图 TxOptions() *sql.TxOptions //事务模式 Query([]element.Record) (string, error) //sql prepare语句 - Agrs([]element.Record) ([]interface{}, error) //prepare参数 + Agrs([]element.Record) ([]any, error) //prepare参数 } ``` diff --git a/storage/database/db.go b/storage/database/db.go index 1ca0b21..ae5be1a 100644 --- a/storage/database/db.go +++ b/storage/database/db.go @@ -135,7 +135,7 @@ func (d *DB) FetchTableWithParam(ctx context.Context, param Parameter) (Table, e // Returns an Error if Any func (d *DB) FetchRecord(ctx context.Context, param Parameter, handler FetchHandler) (err error) { var query string - var agrs []interface{} + var agrs []any if query, agrs, err = getQueryAndAgrs(param, nil); err != nil { return @@ -162,7 +162,7 @@ func (d *DB) FetchRecord(ctx context.Context, param Parameter, handler FetchHand // Returns an Error if Any func (d *DB) FetchRecordWithTx(ctx context.Context, param Parameter, handler FetchHandler) (err error) { var query string - var agrs []interface{} + var agrs []any if query, agrs, err = getQueryAndAgrs(param, nil); err != nil { return @@ -245,12 +245,12 @@ func (d *DB) PingContext(ctx context.Context) error { } // QueryContext Query Multiple Rows of Data through Query -func (d *DB) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) { +func (d *DB) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) { return d.db.QueryContext(ctx, query, args...) } // ExecContext Execute Query and Acquire Result -func (d *DB) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) { +func (d *DB) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) { return d.db.ExecContext(ctx, query, args...) } @@ -264,7 +264,7 @@ func (d *DB) Close() (err error) { func (d *DB) batchExec(ctx context.Context, param Parameter, records []element.Record) (err error) { var query string - var agrs []interface{} + var agrs []any if query, agrs, err = getQueryAndAgrs(param, records); err != nil { return @@ -291,7 +291,7 @@ func (d *DB) batchExecStmt(ctx context.Context, param Parameter, records []eleme }() for _, r := range records { - var valuers []interface{} + var valuers []any if valuers, err = param.Agrs([]element.Record{ r, }); err != nil { @@ -309,7 +309,7 @@ func (d *DB) batchExecStmt(ctx context.Context, param Parameter, records []eleme func (d *DB) batchExecWithTx(ctx context.Context, param Parameter, records []element.Record) (err error) { var query string - var agrs []interface{} + var agrs []any if query, agrs, err = getQueryAndAgrs(param, records); err != nil { return @@ -360,7 +360,7 @@ func (d *DB) batchExecStmtWithTx(ctx context.Context, param Parameter, records [ }() for _, r := range records { - var valuers []interface{} + var valuers []any if valuers, err = param.Agrs([]element.Record{ r, }); err != nil { @@ -394,7 +394,7 @@ func execParam(opts *ParameterOptions) (param Parameter, err error) { return } -func getQueryAndAgrs(param Parameter, records []element.Record) (query string, agrs []interface{}, err error) { +func getQueryAndAgrs(param Parameter, records []element.Record) (query string, agrs []any, err error) { if query, err = param.Query(records); err != nil { err = errors.Errorf("param.Query() err: %v", err) return @@ -440,7 +440,7 @@ func fetchTableByRows(rows *sql.Rows, table Table) (Table, error) { } func readRowsToRecord(rows *sql.Rows, param Parameter, handler FetchHandler) (err error) { - var scanners []interface{} + var scanners []any for _, f := range param.Table().Fields() { scanners = append(scanners, f.Scanner()) } diff --git a/storage/database/db2/decode_chinese_linux_test.go b/storage/database/db2/decode_chinese_linux_test.go index d1227d8..1b5d47c 100644 --- a/storage/database/db2/decode_chinese_linux_test.go +++ b/storage/database/db2/decode_chinese_linux_test.go @@ -24,7 +24,7 @@ import ( func TestScanner_Scan_Chinese(t *testing.T) { type args struct { - src interface{} + src any } tests := []struct { name string diff --git a/storage/database/db2/decode_chinese_windows_test.go b/storage/database/db2/decode_chinese_windows_test.go index 9e08326..871b497 100644 --- a/storage/database/db2/decode_chinese_windows_test.go +++ b/storage/database/db2/decode_chinese_windows_test.go @@ -33,7 +33,7 @@ func gbk(data []byte) []byte { func TestScanner_Scan_Chinese(t *testing.T) { type args struct { - src interface{} + src any } tests := []struct { name string diff --git a/storage/database/db2/field.go b/storage/database/db2/field.go index 9febc54..05b25b0 100644 --- a/storage/database/db2/field.go +++ b/storage/database/db2/field.go @@ -130,7 +130,7 @@ func NewScanner(f *Field) *Scanner { // CHAR and VARCHAR are treated as strings. // BLOB is treated as a byte stream. // BOOLEAN is treated as a boolean value. -func (s *Scanner) Scan(src interface{}) (err error) { +func (s *Scanner) Scan(src any) (err error) { defer s.f.SetError(&err) var cv element.ColumnValue byteSize := element.ByteSize(src) diff --git a/storage/database/db2/field_test.go b/storage/database/db2/field_test.go index 3d143ca..5cef6c6 100644 --- a/storage/database/db2/field_test.go +++ b/storage/database/db2/field_test.go @@ -409,7 +409,7 @@ func TestFieldType_GoType(t *testing.T) { func TestScanner_Scan(t *testing.T) { type args struct { - src interface{} + src any } tests := []struct { name string diff --git a/storage/database/db_help_test.go b/storage/database/db_help_test.go index d254b4d..60d8784 100644 --- a/storage/database/db_help_test.go +++ b/storage/database/db_help_test.go @@ -73,7 +73,7 @@ func (m *mockParameter) Query([]element.Record) (string, error) { return "mock", nil } -func (m *mockParameter) Agrs([]element.Record) ([]interface{}, error) { +func (m *mockParameter) Agrs([]element.Record) ([]any, error) { return nil, m.agrsErr } diff --git a/storage/database/db_test.go b/storage/database/db_test.go index df5761e..8d39837 100644 --- a/storage/database/db_test.go +++ b/storage/database/db_test.go @@ -366,7 +366,7 @@ func Test_getQueryAndAgrs(t *testing.T) { name string args args wantQuery string - wantAgrs []interface{} + wantAgrs []any wantErr bool }{ { diff --git a/storage/database/help_test.go b/storage/database/help_test.go index d7a7d4c..7114355 100644 --- a/storage/database/help_test.go +++ b/storage/database/help_test.go @@ -145,7 +145,7 @@ type mockScanner struct { BaseScanner } -func (m *mockScanner) Scan(src interface{}) error { +func (m *mockScanner) Scan(src any) error { var cv element.ColumnValue switch m.f.Type().DatabaseTypeName() { case strconv.Itoa(int(GoTypeBool)): diff --git a/storage/database/mysql/field.go b/storage/database/mysql/field.go index a055467..4fe20c4 100644 --- a/storage/database/mysql/field.go +++ b/storage/database/mysql/field.go @@ -132,7 +132,7 @@ func NewScanner(f *Field) *Scanner { // DATE, DATETIME, TIMESTAMP are treated as time. // TEXT, LONGTEXT, MEDIUMTEXT, TINYTEXT, CHAR, VARCHAR, TIME are treated as strings. // BLOB, LONGBLOB, MEDIUMBLOB, BINARY, TINYBLOB, VARBINARY are treated as byte streams. -func (s *Scanner) Scan(src interface{}) (err error) { +func (s *Scanner) Scan(src any) (err error) { defer s.f.SetError(&err) var cv element.ColumnValue byteSize := element.ByteSize(src) diff --git a/storage/database/mysql/field_test.go b/storage/database/mysql/field_test.go index c5bb94a..35a56ba 100644 --- a/storage/database/mysql/field_test.go +++ b/storage/database/mysql/field_test.go @@ -384,7 +384,7 @@ func TestFieldType_GoType(t *testing.T) { func TestScanner_Scan(t *testing.T) { type args struct { - src interface{} + src any } tests := []struct { name string diff --git a/storage/database/mysql/table.go b/storage/database/mysql/table.go index a5e7164..7d70cc7 100644 --- a/storage/database/mysql/table.go +++ b/storage/database/mysql/table.go @@ -127,7 +127,7 @@ func (rp *ReplaceParam) Query(records []element.Record) (query string, err error } // Agrs generates a batch of replace into parameters based on multiple records. -func (rp *ReplaceParam) Agrs(records []element.Record) (valuers []interface{}, err error) { +func (rp *ReplaceParam) Agrs(records []element.Record) (valuers []any, err error) { for _, r := range records { for fi, f := range rp.Table().Fields() { var c element.Column @@ -139,7 +139,7 @@ func (rp *ReplaceParam) Agrs(records []element.Record) (valuers []interface{}, e return nil, err } - valuers = append(valuers, interface{}(v)) + valuers = append(valuers, any(v)) } } return diff --git a/storage/database/mysql/table_test.go b/storage/database/mysql/table_test.go index 684dbf9..e0a596e 100644 --- a/storage/database/mysql/table_test.go +++ b/storage/database/mysql/table_test.go @@ -251,7 +251,7 @@ func TestReplaceParam_Agrs(t *testing.T) { name string rp *ReplaceParam args args - wantValuers []interface{} + wantValuers []any wantErr bool }{ { @@ -286,7 +286,7 @@ func TestReplaceParam_Agrs(t *testing.T) { }, t: database.NewBaseTable("db", "", "table"), }, - wantValuers: []interface{}{ + wantValuers: []any{ "1", "2", "3", "5", "4", "6", "9", "7", "8", diff --git a/storage/database/oracle/field.go b/storage/database/oracle/field.go index df05058..c234da5 100644 --- a/storage/database/oracle/field.go +++ b/storage/database/oracle/field.go @@ -132,7 +132,7 @@ func NewScanner(f *Field) *Scanner { // TIMESTAMP, TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE, DATE are treated as time types // CLOB, NCLOB, VARCHAR2, NVARCHAR2, CHAR, NCHAR are treated as string types // BLOB, RAW, LONG RAW, LONG are treated as byte types -func (s *Scanner) Scan(src interface{}) (err error) { +func (s *Scanner) Scan(src any) (err error) { defer s.f.SetError(&err) var cv element.ColumnValue byteSize := element.ByteSize(src) diff --git a/storage/database/oracle/field_test.go b/storage/database/oracle/field_test.go index 8b6f12d..9ced58a 100644 --- a/storage/database/oracle/field_test.go +++ b/storage/database/oracle/field_test.go @@ -259,7 +259,7 @@ func TestFieldType_IsSupportted(t *testing.T) { func TestScanner_Scan(t *testing.T) { type args struct { - src interface{} + src any } tests := []struct { name string diff --git a/storage/database/oracle/table.go b/storage/database/oracle/table.go index 439a889..810a92d 100644 --- a/storage/database/oracle/table.go +++ b/storage/database/oracle/table.go @@ -116,7 +116,7 @@ func (ip *InsertParam) Query(_ []element.Record) (query string, err error) { } // Agrs generates a batch of insert into parameters based on multiple records. -func (ip *InsertParam) Agrs(records []element.Record) (valuers []interface{}, err error) { +func (ip *InsertParam) Agrs(records []element.Record) (valuers []any, err error) { for fi, f := range ip.Table().Fields() { var ba [][]byte var sa []string @@ -138,7 +138,7 @@ func (ip *InsertParam) Agrs(records []element.Record) (valuers []interface{}, er sa = append(sa, data) } } - var a interface{} + var a any if len(ba) > 0 { a = ba diff --git a/storage/database/oracle/table_test.go b/storage/database/oracle/table_test.go index 84f7b3b..77f946f 100644 --- a/storage/database/oracle/table_test.go +++ b/storage/database/oracle/table_test.go @@ -274,7 +274,7 @@ func TestInsertParam_Agrs(t *testing.T) { tests := []struct { name string args args - wantValuers []interface{} + wantValuers []any wantErr bool }{ { @@ -309,7 +309,7 @@ func TestInsertParam_Agrs(t *testing.T) { }, t: NewTable(database.NewBaseTable("db", "schema", "table")), }, - wantValuers: []interface{}{ + wantValuers: []any{ []string{"1", "5", "9"}, [][]byte{nil, []byte("4"), []byte("7")}, []string{"3", "6", "8"}, diff --git a/storage/database/postgres/field.go b/storage/database/postgres/field.go index 5579b5a..dc6058d 100644 --- a/storage/database/postgres/field.go +++ b/storage/database/postgres/field.go @@ -130,7 +130,7 @@ func NewScanner(f *Field) *Scanner { } // Scan - Reads data from a column based on its type. -func (s *Scanner) Scan(src interface{}) (err error) { +func (s *Scanner) Scan(src any) (err error) { defer s.f.SetError(&err) var cv element.ColumnValue byteSize := element.ByteSize(src) diff --git a/storage/database/postgres/field_test.go b/storage/database/postgres/field_test.go index f01a06b..f2452a9 100644 --- a/storage/database/postgres/field_test.go +++ b/storage/database/postgres/field_test.go @@ -345,7 +345,7 @@ func TestFieldType_IsSupportted(t *testing.T) { func TestScanner_Scan(t *testing.T) { type args struct { - src interface{} + src any } tests := []struct { name string diff --git a/storage/database/postgres/table.go b/storage/database/postgres/table.go index b73527d..b1c3ee8 100644 --- a/storage/database/postgres/table.go +++ b/storage/database/postgres/table.go @@ -106,7 +106,7 @@ func (ci *CopyInParam) Query(_ []element.Record) (query string, err error) { } // Agrs generates a batch of copy in parameters based on multiple records. -func (ci *CopyInParam) Agrs(records []element.Record) (valuers []interface{}, err error) { +func (ci *CopyInParam) Agrs(records []element.Record) (valuers []any, err error) { for _, r := range records { for fi, f := range ci.Table().Fields() { var c element.Column @@ -118,7 +118,7 @@ func (ci *CopyInParam) Agrs(records []element.Record) (valuers []interface{}, er return nil, err } - valuers = append(valuers, interface{}(v)) + valuers = append(valuers, any(v)) } } return diff --git a/storage/database/postgres/table_test.go b/storage/database/postgres/table_test.go index 599bef9..9be20ac 100644 --- a/storage/database/postgres/table_test.go +++ b/storage/database/postgres/table_test.go @@ -141,7 +141,7 @@ func TestCopyInParam_Agrs(t *testing.T) { name string input input args args - wantValuers []interface{} + wantValuers []any wantErr bool }{ { @@ -183,7 +183,7 @@ func TestCopyInParam_Agrs(t *testing.T) { }, }, }, - wantValuers: []interface{}{ + wantValuers: []any{ int64(1), "2", "3", int64(5), "4", "6", int64(9), "7", "8", diff --git a/storage/database/sqlserver/field.go b/storage/database/sqlserver/field.go index 92da3b2..caaeec1 100644 --- a/storage/database/sqlserver/field.go +++ b/storage/database/sqlserver/field.go @@ -126,7 +126,7 @@ func NewScanner(f *Field) *Scanner { } // Scan - Reads data from a column based on its type. -func (s *Scanner) Scan(src interface{}) (err error) { +func (s *Scanner) Scan(src any) (err error) { var cv element.ColumnValue byteSize := element.ByteSize(src) switch s.f.Type().DatabaseTypeName() { diff --git a/storage/database/sqlserver/field_test.go b/storage/database/sqlserver/field_test.go index db00d65..139df9e 100644 --- a/storage/database/sqlserver/field_test.go +++ b/storage/database/sqlserver/field_test.go @@ -381,7 +381,7 @@ func TestFieldType_GoType(t *testing.T) { func TestScanner_Scan(t *testing.T) { type args struct { - src interface{} + src any } tests := []struct { name string diff --git a/storage/database/sqlserver/table.go b/storage/database/sqlserver/table.go index 45a5b42..7c36033 100644 --- a/storage/database/sqlserver/table.go +++ b/storage/database/sqlserver/table.go @@ -121,7 +121,7 @@ func (ci *CopyInParam) Query(_ []element.Record) (query string, err error) { } // Agrs generates a batch of copy in parameters based on multiple records. -func (ci *CopyInParam) Agrs(records []element.Record) (valuers []interface{}, err error) { +func (ci *CopyInParam) Agrs(records []element.Record) (valuers []any, err error) { for _, r := range records { for fi, f := range ci.Table().Fields() { var c element.Column @@ -133,7 +133,7 @@ func (ci *CopyInParam) Agrs(records []element.Record) (valuers []interface{}, er return nil, err } - valuers = append(valuers, interface{}(v)) + valuers = append(valuers, any(v)) } } return diff --git a/storage/database/sqlserver/table_test.go b/storage/database/sqlserver/table_test.go index 53af336..94bc315 100644 --- a/storage/database/sqlserver/table_test.go +++ b/storage/database/sqlserver/table_test.go @@ -238,7 +238,7 @@ func TestCopyInParam_Agrs(t *testing.T) { name string input input args args - wantValuers []interface{} + wantValuers []any wantErr bool }{ { @@ -280,7 +280,7 @@ func TestCopyInParam_Agrs(t *testing.T) { }, }, }, - wantValuers: []interface{}{ + wantValuers: []any{ int64(1), "2", "3", int64(5), "4", "6", int64(9), "7", "8", diff --git a/storage/database/table.go b/storage/database/table.go index da78061..bbfaa7d 100644 --- a/storage/database/table.go +++ b/storage/database/table.go @@ -38,11 +38,11 @@ type Table interface { // Parameter Execution parameters for SQL statements with table, transaction mode, and SQL type Parameter interface { - SetTable(Table) // Set table or view - Table() Table // Table or view - TxOptions() *sql.TxOptions // Transaction mode - Query([]element.Record) (string, error) // SQL prepare statement - Agrs([]element.Record) ([]interface{}, error) // Prepare parameters + SetTable(Table) // Set table or view + Table() Table // Table or view + TxOptions() *sql.TxOptions // Transaction mode + Query([]element.Record) (string, error) // SQL prepare statement + Agrs([]element.Record) ([]any, error) // Prepare parameters } // ParameterOptions Options for parameters @@ -194,7 +194,7 @@ func (i *InsertParam) Query(records []element.Record) (query string, err error) } // Args Generate bulk insert parameters from multiple records -func (i *InsertParam) Agrs(records []element.Record) (valuers []interface{}, err error) { +func (i *InsertParam) Agrs(records []element.Record) (valuers []any, err error) { for _, r := range records { for fi, f := range i.Table().Fields() { var c element.Column @@ -206,7 +206,7 @@ func (i *InsertParam) Agrs(records []element.Record) (valuers []interface{}, err return nil, err } - valuers = append(valuers, interface{}(v)) + valuers = append(valuers, any(v)) } } return @@ -232,6 +232,6 @@ func (t *TableQueryParam) Query(_ []element.Record) (s string, err error) { } // Args Generate parameters, but they are empty -func (t *TableQueryParam) Agrs(_ []element.Record) (a []interface{}, err error) { +func (t *TableQueryParam) Agrs(_ []element.Record) (a []any, err error) { return nil, nil } diff --git a/storage/database/table_test.go b/storage/database/table_test.go index affc3b5..1cb5052 100644 --- a/storage/database/table_test.go +++ b/storage/database/table_test.go @@ -267,7 +267,7 @@ func TestInsertParam_Agrs(t *testing.T) { tests := []struct { name string args args - wantValuers []interface{} + wantValuers []any wantErr bool }{ { @@ -302,7 +302,7 @@ func TestInsertParam_Agrs(t *testing.T) { }, t: NewBaseTable("db", "schema", "table"), }, - wantValuers: []interface{}{ + wantValuers: []any{ int64(1), float64(2.0), "3", int64(5), float64(4.0), "6", int64(9), float64(7.0), "8", @@ -464,7 +464,7 @@ func TestTableQueryParam_Agrs(t *testing.T) { name string t *TableQueryParam args args - wantA []interface{} + wantA []any wantErr bool }{ { diff --git a/storage/stream/file/xlsx/stream.go b/storage/stream/file/xlsx/stream.go index 55ff09c..73eeeda 100644 --- a/storage/stream/file/xlsx/stream.go +++ b/storage/stream/file/xlsx/stream.go @@ -224,7 +224,7 @@ func (w *Writer) Write(record element.Record) (err error) { w.conf.Header = append(w.conf.Header, col.Name()) } } - var records []interface{} + var records []any for _, v := range w.conf.Header { records = append(records, v) } @@ -235,7 +235,7 @@ func (w *Writer) Write(record element.Record) (err error) { w.row++ } - var records []interface{} + var records []any for i := 0; i < record.ColumnNumber(); i++ { var col element.Column if col, err = record.GetByIndex(i); err != nil {