From 45a05028b5f6144e2f0af6f029e310db898e5efc Mon Sep 17 00:00:00 2001 From: qydysky Date: Mon, 11 Nov 2024 22:06:51 +0800 Subject: [PATCH] 1 --- README.md | 2 +- sql/Sql.go | 50 ++++++++++++++++++++---------------- sql/Sql_test.go | 68 ++++++++++++++++++++++++------------------------- 3 files changed, 63 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 1d899bc..ed0ca29 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ --- #### 介绍 -自己编写/收集的一些go组件,增加复用 +自己编写/收集的一些go组件,不保证向后兼容性,增加复用 buf map变量的save,load,get,set diff --git a/sql/Sql.go b/sql/Sql.go index 82941fa..a1bae58 100644 --- a/sql/Sql.go +++ b/sql/Sql.go @@ -10,17 +10,21 @@ import ( ) const ( - null = iota + null Type = iota Execf Queryf ) +type Type int + type CanTx interface { BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) } type BeforeF[T any] func(ctxVP *T, sqlf *SqlFunc[T], e *error) type AfterEF[T any] func(ctxVP *T, result sql.Result, e *error) + +// func(ctxVP *T, rows *sql.Rows, e *error) type AfterQF[T any] func(ctxVP *T, rows *sql.Rows, e *error) type SqlTx[T any] struct { @@ -32,9 +36,11 @@ type SqlTx[T any] struct { } type SqlFunc[T any] struct { - Ty int + // Execf or Queryf, default: auto detection + Ty Type + // default: use transaction Ctx Ctx context.Context - Query string + Sql string Args []any SkipSqlErr bool beforeF BeforeF[T] @@ -53,10 +59,10 @@ func BeginTx[T any](canTx CanTx, ctx context.Context, opts ...*sql.TxOptions) *S return &tx } -func (t *SqlTx[T]) SimpleDo(query string, args ...any) *SqlTx[T] { +func (t *SqlTx[T]) SimpleDo(sql string, args ...any) *SqlTx[T] { t.sqlFuncs = append(t.sqlFuncs, &SqlFunc[T]{ - Query: query, - Args: args, + Sql: sql, + Args: args, }) return t } @@ -67,16 +73,16 @@ func (t *SqlTx[T]) Do(sqlf SqlFunc[T]) *SqlTx[T] { } // PlaceHolder will replaced by ? -func (t *SqlTx[T]) SimplePlaceHolderA(query string, ptr any) *SqlTx[T] { +func (t *SqlTx[T]) SimplePlaceHolderA(sql string, ptr any) *SqlTx[T] { return t.DoPlaceHolder(SqlFunc[T]{ - Query: query, + Sql: sql, }, ptr) } // PlaceHolder will replaced by $%d -func (t *SqlTx[T]) SimplePlaceHolderB(query string, ptr any) *SqlTx[T] { +func (t *SqlTx[T]) SimplePlaceHolderB(sql string, ptr any) *SqlTx[T] { return t.DoPlaceHolder(SqlFunc[T]{ - Query: query, + Sql: sql, }, ptr, func(index int, holder string) (replaceTo string) { return fmt.Sprintf("$%d", index+1) }) @@ -89,11 +95,11 @@ func (t *SqlTx[T]) DoPlaceHolder(sqlf SqlFunc[T], ptr any, replaceF ...func(inde field := dataR.Field(i) if field.IsValid() && field.CanSet() { replaceS := "{" + dataR.Type().Field(i).Name + "}" - if strings.Contains(sqlf.Query, replaceS) { + if strings.Contains(sqlf.Sql, replaceS) { if len(replaceF) == 0 { - sqlf.Query = strings.ReplaceAll(sqlf.Query, replaceS, "?") + sqlf.Sql = strings.ReplaceAll(sqlf.Sql, replaceS, "?") } else { - sqlf.Query = strings.ReplaceAll(sqlf.Query, replaceS, replaceF[0](index, replaceS)) + sqlf.Sql = strings.ReplaceAll(sqlf.Sql, replaceS, replaceF[0](index, replaceS)) index += 1 } sqlf.Args = append(sqlf.Args, field.Interface()) @@ -143,12 +149,12 @@ func (t *SqlTx[T]) Fin() (ctxVP T, e error) { if sqlf.beforeF != nil { sqlf.beforeF(&ctxVP, sqlf, &e) if e != nil { - e = errors.Join(e, fmt.Errorf("%s; >> %s", sqlf.Query, err)) + e = errors.Join(e, fmt.Errorf("%s; >> %s", sqlf.Sql, err)) hasErr = true } } - if strings.TrimSpace(sqlf.Query) == "" { + if strings.TrimSpace(sqlf.Sql) == "" { continue } @@ -158,36 +164,36 @@ func (t *SqlTx[T]) Fin() (ctxVP T, e error) { if sqlf.Ty == null { sqlf.Ty = Execf - if uquery := strings.ToUpper(strings.TrimSpace(sqlf.Query)); strings.HasPrefix(uquery, "SELECT") { + if uquery := strings.ToUpper(strings.TrimSpace(sqlf.Sql)); strings.HasPrefix(uquery, "SELECT") { sqlf.Ty = Queryf } } switch sqlf.Ty { case Execf: - if res, err := tx.ExecContext(sqlf.Ctx, sqlf.Query, sqlf.Args...); err != nil { + if res, err := tx.ExecContext(sqlf.Ctx, sqlf.Sql, sqlf.Args...); err != nil { hasErr = true if !sqlf.SkipSqlErr { - e = errors.Join(e, fmt.Errorf("%s; %s >> %s", sqlf.Query, sqlf.Args, err)) + e = errors.Join(e, fmt.Errorf("%s; %s >> %s", sqlf.Sql, sqlf.Args, err)) } } else if sqlf.afterEF != nil { sqlf.afterEF(&ctxVP, res, &e) if e != nil { hasErr = true - e = errors.Join(e, fmt.Errorf("%s; %s >> %s", sqlf.Query, sqlf.Args, err)) + e = errors.Join(e, fmt.Errorf("%s; %s >> %s", sqlf.Sql, sqlf.Args, err)) } } case Queryf: - if res, err := tx.QueryContext(sqlf.Ctx, sqlf.Query, sqlf.Args...); err != nil { + if res, err := tx.QueryContext(sqlf.Ctx, sqlf.Sql, sqlf.Args...); err != nil { hasErr = true if !sqlf.SkipSqlErr { - e = errors.Join(e, fmt.Errorf("%s; %s >> %s", sqlf.Query, sqlf.Args, err)) + e = errors.Join(e, fmt.Errorf("%s; %s >> %s", sqlf.Sql, sqlf.Args, err)) } } else if sqlf.afterQF != nil { sqlf.afterQF(&ctxVP, res, &e) if e != nil { hasErr = true - e = errors.Join(e, fmt.Errorf("%s; %s >> %s", sqlf.Query, sqlf.Args, err)) + e = errors.Join(e, fmt.Errorf("%s; %s >> %s", sqlf.Sql, sqlf.Args, err)) } } } diff --git a/sql/Sql_test.go b/sql/Sql_test.go index 6b9ad28..38c9e78 100644 --- a/sql/Sql_test.go +++ b/sql/Sql_test.go @@ -29,35 +29,35 @@ func TestMain(t *testing.T) { tx = tx.Do(SqlFunc[[]string]{ Ty: Execf, Ctx: ctx, - Query: "create table log (msg text)", + Sql: "create table log (msg text)", SkipSqlErr: true, }) tx = tx.Do(SqlFunc[[]string]{ Ty: Execf, Ctx: ctx, - Query: "create table log2 (msg text)", + Sql: "create table log2 (msg text)", SkipSqlErr: true, }) tx = tx.Do(SqlFunc[[]string]{ - Ty: Execf, - Ctx: ctx, - Query: "delete from log", + Ty: Execf, + Ctx: ctx, + Sql: "delete from log", }) tx = tx.Do(SqlFunc[[]string]{ - Ty: Execf, - Ctx: ctx, - Query: "delete from log2", + Ty: Execf, + Ctx: ctx, + Sql: "delete from log2", }) tx = tx.Do(SqlFunc[[]string]{ - Ty: Execf, - Ctx: ctx, - Query: "insert into log values (?)", - Args: []any{dateTime}, + Ty: Execf, + Ctx: ctx, + Sql: "insert into log values (?)", + Args: []any{dateTime}, }) tx = tx.Do(SqlFunc[[]string]{ - Ty: Queryf, - Ctx: ctx, - Query: "select msg from log", + Ty: Queryf, + Ctx: ctx, + Sql: "select msg from log", }).AfterQF(func(dataP *[]string, rows *sql.Rows, err *error) { names := make([]string, 0) for rows.Next() { @@ -80,13 +80,13 @@ func TestMain(t *testing.T) { Ty: Execf, Ctx: ctx, }).BeforeF(func(dataP *[]string, sqlf *SqlFunc[[]string], txE *error) { - sqlf.Query = "insert into log2 values (?)" + sqlf.Sql = "insert into log2 values (?)" sqlf.Args = append(sqlf.Args, (*dataP)[0]) }) tx = tx.Do(SqlFunc[[]string]{ - Ty: Queryf, - Ctx: ctx, - Query: "select msg from log2", + Ty: Queryf, + Ctx: ctx, + Sql: "select msg from log2", }).AfterQF(func(dataP *[]string, rows *sql.Rows, err *error) { names := make([]string, 0) for rows.Next() { @@ -122,8 +122,8 @@ func TestMain2(t *testing.T) { conn, _ := db.Conn(context.Background()) if _, e := BeginTx[any](conn, context.Background(), &sql.TxOptions{}).Do(SqlFunc[any]{ - Ty: Execf, - Query: "create table log123 (msg text)", + Ty: Execf, + Sql: "create table log123 (msg text)", }).Fin(); e != nil { t.Fatal(e) } @@ -137,9 +137,9 @@ func TestMain2(t *testing.T) { go func() { x := BeginTx[any](db, context.Background(), &sql.TxOptions{}) x.Do(SqlFunc[any]{ - Ty: Execf, - Query: "insert into log123 values (?)", - Args: []any{"1"}, + Ty: Execf, + Sql: "insert into log123 values (?)", + Args: []any{"1"}, }) if _, e := x.Fin(); e != nil { res <- e.Error() @@ -167,7 +167,7 @@ func TestMain3(t *testing.T) { { tx := BeginTx[any](db, context.Background()) - tx.Do(SqlFunc[any]{Query: "create table log123 (msg INT,msg2 text)"}) + tx.Do(SqlFunc[any]{Sql: "create table log123 (msg INT,msg2 text)"}) if _, e := tx.Fin(); e != nil { t.Fatal(e) } @@ -178,7 +178,7 @@ func TestMain3(t *testing.T) { Msg2 string } - insertLog123 := SqlFunc[any]{Query: "insert into log123 values ({Msg},{Msg2})"} + insertLog123 := SqlFunc[any]{Sql: "insert into log123 values ({Msg},{Msg2})"} { tx := BeginTx[any](db, context.Background()) tx.DoPlaceHolder(insertLog123, &logg{Msg: 1, Msg2: "a"}) @@ -192,7 +192,7 @@ func TestMain3(t *testing.T) { } } { - selectLog123 := SqlFunc[[]logg]{Query: "select msg as Msg, msg2 as Msg2 from log123 where msg = {Msg}"} + selectLog123 := SqlFunc[[]logg]{Sql: "select msg as Msg, msg2 as Msg2 from log123 where msg = {Msg}"} tx := BeginTx[[]logg](db, context.Background()) tx.DoPlaceHolder(selectLog123, &logg{Msg: 2, Msg2: "b"}) tx.AfterQF(func(ctxVP *[]logg, rows *sql.Rows, txE *error) { @@ -238,16 +238,16 @@ func TestMain4(t *testing.T) { conn, _ := db.Conn(context.Background()) if _, e := BeginTx[any](conn, context.Background(), &sql.TxOptions{}).Do(SqlFunc[any]{ - Ty: Execf, - Query: "create table log123 (msg text)", + Ty: Execf, + Sql: "create table log123 (msg text)", }).Fin(); e != nil { t.Fatal(e) } conn.Close() tx1 := BeginTx[any](db, context.Background(), &sql.TxOptions{}).Do(SqlFunc[any]{ - Ty: Execf, - Query: "insert into log123 values ('1')", + Ty: Execf, + Sql: "insert into log123 values ('1')", }) if _, e := tx1.Fin(); e != nil { @@ -277,14 +277,14 @@ func Local_TestPostgresql(t *testing.T) { } if _, e := BeginTx[any](db, pctx.GenTOCtx(time.Second), &sql.TxOptions{}).Do(SqlFunc[any]{ - Query: "create table test (created varchar(20))", + Sql: "create table test (created varchar(20))", SkipSqlErr: true, }).Fin(); e != nil { t.Fatal(e) } if _, e := BeginTx[any](db, context.Background(), &sql.TxOptions{}).DoPlaceHolder(SqlFunc[any]{ - Query: "insert into test (created) values ({Created})", + Sql: "insert into test (created) values ({Created})", }, &test1{"1"}, func(index int, holder string) (replaceTo string) { return fmt.Sprintf("$%d", index+1) }).Fin(); e != nil { @@ -292,7 +292,7 @@ func Local_TestPostgresql(t *testing.T) { } if _, e := BeginTx[any](db, context.Background(), &sql.TxOptions{}).Do(SqlFunc[any]{ - Query: "select created as sss from test", + Sql: "select created as sss from test", afterQF: func(_ *any, rows *sql.Rows, txE *error) { if rowsP, e := DealRows[test1](rows, func() test1 { return test1{} }); e != nil { *txE = e -- 2.39.2