Skip to content

Commit

Permalink
fix(sqlbuilder): sort columns in SetMap for PrepareStmt performance
Browse files Browse the repository at this point in the history
  • Loading branch information
cnlangzi committed Feb 25, 2024
1 parent 41f0abf commit 8eac526
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 34 deletions.
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- added `BitBool` for mysql bit type (#11)
- added `sharding` feature (#12)
- added `On` on `DB` to enable AutoSharding feature(#13)
- added `On` on `SQLBuilder` to enable AutoRotation feature(#13)
- added `On` on `DB` to enable AutoSharding feature (#13)
- added `On` on `SQLBuilder` to enable AutoRotation feature (#13)

### Fixed
- fixed parameterized placeholder for postgresql(#12)
- fixed parameterized placeholder for postgresql (#12)
- sorted columns in `SetMap` for PrepareStmt performance (#14)

## [1.1.0] - 2024-02-13
### Added
Expand Down
35 changes: 35 additions & 0 deletions sqlbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sqle

import (
"errors"
"sort"
"strings"

"github.com/yaitoo/sqle/shardid"
Expand Down Expand Up @@ -178,6 +179,40 @@ func (b *Builder) Delete(table string) *Builder {
return b
}

func (b *Builder) sortColumns(m map[string]any, opts ...BuilderOption) []string {

bo := &BuilderOptions{}
for _, opt := range opts {
opt(bo)
}

hasCustomizedColumns := len(bo.Columns) > 0

for n, v := range m {

name := n

if bo.ToName != nil {
name = bo.ToName(name)
if name != n {
m[name] = v
}

}

if !hasCustomizedColumns {
bo.Columns = append(bo.Columns, name)
}
}

if !hasCustomizedColumns {
sort.Strings(bo.Columns)
}

return bo.Columns

}

func (b *Builder) On(id shardid.ID) *Builder {
rn := id.RotateName()
if rn != "" {
Expand Down
17 changes: 2 additions & 15 deletions sqlbuilder_insert.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,9 @@ func (ib *InsertBuilder) SetMap(m map[string]any, opts ...BuilderOption) *Insert
return ib
}

bo := &BuilderOptions{}
for _, opt := range opts {
opt(bo)
}

for n, v := range m {
if bo.ToName != nil {
sn := bo.ToName(n)
if sn != n {
delete(m, n)
m[sn] = v
}
}
}
columns := ib.b.sortColumns(m, opts...)

for _, n := range bo.Columns {
for _, n := range columns {
v, ok := m[n]
if ok {
ib.Set(n, v)
Expand Down
44 changes: 44 additions & 0 deletions sqlbuilder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,50 @@ func TestBuilder(t *testing.T) {

},
},
{
name: "build_with_map_should_be_sorted",
build: func() *Builder {
m := make(map[string]any)

m["user_id"] = "x1234"
m["id"] = 1

b := New().Insert("users").SetMap(m).End()

return b
},
assert: func(t *testing.T, b *Builder) {
s, vars, err := b.Build()
require.NoError(t, err)
require.Equal(t, "INSERT INTO `users` (`id`, `user_id`) VALUES (?, ?)", s)
require.Len(t, vars, 2)
require.Equal(t, 1, vars[0])
require.Equal(t, "x1234", vars[1])

},
},
{
name: "build_with_map_and_allow_should_not_be_sorted",
build: func() *Builder {
m := make(map[string]any)

m["user_id"] = "x1234"
m["id"] = 1

b := New().Insert("users").SetMap(m, WithAllow("user_id", "id")).End()

return b
},
assert: func(t *testing.T, b *Builder) {
s, vars, err := b.Build()
require.NoError(t, err)
require.Equal(t, "INSERT INTO `users` (`user_id`, `id`) VALUES (?, ?)", s)
require.Len(t, vars, 2)
require.Equal(t, "x1234", vars[0])
require.Equal(t, 1, vars[1])

},
},
}

for _, test := range tests {
Expand Down
21 changes: 5 additions & 16 deletions sqlbuilder_update.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package sqle

import "reflect"
import (
"reflect"
)

type UpdateBuilder struct {
*Builder
Expand Down Expand Up @@ -42,22 +44,9 @@ func (ub *UpdateBuilder) SetMap(m map[string]any, opts ...BuilderOption) *Update
return ub
}

bo := &BuilderOptions{}
for _, opt := range opts {
opt(bo)
}

for n, v := range m {
if bo.ToName != nil {
sn := bo.ToName(n)
if sn != n {
delete(m, n)
m[sn] = v
}
}
}
columns := ub.sortColumns(m, opts...)

for _, n := range bo.Columns {
for _, n := range columns {
v, ok := m[n]
if ok {
ub.Set(n, v)
Expand Down

0 comments on commit 8eac526

Please sign in to comment.