Remove unnecessary use of reflection

pull/2/head
Vinícius Garcia 2020-09-11 18:47:42 -03:00
parent 2f651581ea
commit 38ce8a9b0e
4 changed files with 67 additions and 78 deletions

8
go.mod Normal file
View File

@ -0,0 +1,8 @@
module github.com/vingarcia/kiss-orm
go 1.14
require (
github.com/ditointernet/go-assert v0.0.0-20200120164340-9e13125a7018
github.com/jinzhu/gorm v1.9.16
)

35
go.sum Normal file
View File

@ -0,0 +1,35 @@
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/ditointernet/go-assert v0.0.0-20200120164340-9e13125a7018 h1:QsFkVafcKOaZoAB4WcyUHdkPbwh+VYwZgYJb/rU6EIM=
github.com/ditointernet/go-assert v0.0.0-20200120164340-9e13125a7018/go.mod h1:5C3SWkut69TSdkerzRDxXMRM5x73PGWNcRLe/xKjXhs=
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
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.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA=
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@ -2,32 +2,25 @@ package gpostgres
import (
"context"
"fmt"
"reflect"
"strings"
"github.com/jinzhu/gorm"
)
type metaCache struct {
TableName string
}
type TableNamer interface {
TableName() string
}
// Client ...
type Client struct {
db *gorm.DB
metadata map[reflect.Type]*metaCache
tableName string
db *gorm.DB
}
func NewClient() Client {
// NewClient ...
func NewClient(tableName string) Client {
return Client{
metadata: map[reflect.Type]*metaCache{},
tableName: tableName,
}
}
// Get one instance from the database, the input struct
// must be passed by reference.
func (c Client) Get(
ctx context.Context,
item interface{},
@ -38,6 +31,10 @@ func (c Client) Get(
return it.Error
}
// Insert one or more instances on the database
//
// If the original instances have been passed by reference
// the ID is automatically updated after insertion is completed.
func (c Client) Insert(
ctx context.Context,
items ...interface{},
@ -46,19 +43,8 @@ func (c Client) Insert(
return nil
}
m, err := c.getMetadata(items[0])
if err != nil {
return err
}
vItems := reflect.ValueOf(items)
for i := 0; i < vItems.Len(); i++ {
v := vItems.Index(i).Elem()
if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
return fmt.Errorf("entity type must be a pointer to struct, not: %T", v.Interface())
}
r := c.db.Table(m.TableName).Create(v.Interface())
for _, item := range items {
r := c.db.Table(c.tableName).Create(item)
if r.Error != nil {
return r.Error
}
@ -66,33 +52,3 @@ func (c Client) Insert(
return nil
}
func (c *Client) getMetadata(entity interface{}) (*metaCache, error) {
t := reflect.TypeOf(entity)
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
if t.Kind() != reflect.Struct {
return nil, fmt.Errorf("entity type must be a struct or a struct pointer, not: %T", entity)
}
metadata, found := c.metadata[t]
if found {
return metadata, nil
}
metadata = &metaCache{}
if tNamer, ok := entity.(TableNamer); ok {
metadata.TableName = tNamer.TableName()
} else {
n := t.Name()
if n[len(n)-1] != 's' {
n += "s"
}
metadata.TableName = strings.ToLower(n)
}
return metadata, nil
}

View File

@ -2,8 +2,6 @@ package gpostgres
import (
"context"
"fmt"
"reflect"
"testing"
"time"
@ -29,7 +27,10 @@ func TestGet(t *testing.T) {
defer db.Close()
ctx := context.Background()
c := Client{db: db}
c := Client{
db: db,
tableName: "users",
}
u := User{}
err := c.Get(ctx, &u, `SELECT * FROM users WHERE id=1;`)
assert.Equal(t, err, nil)
@ -46,7 +47,8 @@ func TestGet(t *testing.T) {
ctx := context.Background()
c := Client{
db: db,
db: db,
tableName: "users",
}
u := User{}
err = c.Get(ctx, &u, `SELECT * FROM users WHERE name='Bia';`)
@ -66,11 +68,11 @@ func TestInsert(t *testing.T) {
t.Run("should ignore empty lists of users", func(t *testing.T) {
db := connectDB(t)
defer db.Close()
db.LogMode(true)
ctx := context.Background()
c := Client{
db: db,
db: db,
tableName: "users",
}
user := User{}
@ -84,7 +86,8 @@ func TestInsert(t *testing.T) {
ctx := context.Background()
c := Client{
db: db,
db: db,
tableName: "users",
}
u := User{
@ -95,7 +98,6 @@ func TestInsert(t *testing.T) {
assert.Equal(t, err, nil)
result := User{}
fmt.Println("ID: ", u.ID)
it := c.db.Raw("SELECT * FROM users WHERE id=?", u.ID)
it.Scan(&result)
assert.Equal(t, it.Error, nil)
@ -104,18 +106,6 @@ func TestInsert(t *testing.T) {
})
}
func TestGetMetadata(t *testing.T) {
t.Run("it should get the struct name correctly", func(t *testing.T) {
c := &Client{
metadata: map[reflect.Type]*metaCache{},
}
m, err := c.getMetadata(User{})
assert.Equal(t, nil, err)
assert.Equal(t, "users", m.TableName)
})
}
func createTable() error {
db, err := gorm.Open("sqlite3", "/tmp/test.db")
if err != nil {