Replace all ocurrencies of `KissORM` for `KissSQL`

pull/2/head
Vinícius Garcia 2021-03-08 11:18:52 -03:00
parent 0bd858efee
commit 568c61bdba
15 changed files with 212 additions and 212 deletions

View File

@ -1,9 +1,9 @@
# KissORM
# KissSQL
Welcome to the KissORM project, the Keep It Stupid Simple - ORM.
Welcome to the KissSQL project, the Keep It Stupid Simple sql package.
This ORM was created to be used by any developer efficiently and safely.
This package was created to be used by any developer efficiently and safely.
The goals were:
- To be easy to use
@ -19,11 +19,11 @@ Currently we only support 2 Drivers:
- `"postgres"`
- `"sqlite3"`
### Why KissORM?
### Why KissSQL?
> Note: If you want numbers see our Benchmark section below
KissORM was created to fill a hole between the complexity
KissSQL was created to fill a hole between the complexity
we find in the tools I've seen so far, namely:
- ORMs such as `GORM` that do a lot and have literally hundreds
@ -43,9 +43,9 @@ So the goal was to be high level enough that it would
avoid the complications from the `sql` package and
at the same time to be simple enough to avoid
the big learning curve and complexity of the hundreds
of functions offered by more complete ORMs.
of functions offered by ORMs.
That said, KissORM attempts to apply the Kiss principle,
That said, KissSQL attempts to apply the Kiss principle,
in order to save development time for your team, i.e.:
- Less time spent learning (few methods to learn)
@ -59,8 +59,8 @@ The current interface is as follows and we plan to keep
it with as little functions as possible, so don't expect many additions:
```go
// ORMProvider describes the public behavior of this ORM
type ORMProvider interface {
// SQLProvider describes the public behavior of this ORM
type SQLProvider interface {
Insert(ctx context.Context, records ...interface{}) error
Delete(ctx context.Context, ids ...interface{}) error
Update(ctx context.Context, records ...interface{}) error
@ -70,7 +70,7 @@ type ORMProvider interface {
QueryChunks(ctx context.Context, parser ChunkParser) error
Exec(ctx context.Context, query string, params ...interface{}) error
Transaction(ctx context.Context, fn func(ORMProvider) error) error
Transaction(ctx context.Context, fn func(SQLProvider) error) error
}
```
@ -87,24 +87,24 @@ import (
"fmt"
_ "github.com/mattn/go-sqlite3"
"github.com/vingarcia/kissorm"
"github.com/vingarcia/kissorm/nullable"
"github.com/vingarcia/kisssql"
"github.com/vingarcia/kisssql/nullable"
)
type User struct {
ID int `kissorm:"id"`
Name string `kissorm:"name"`
Age int `kissorm:"age"`
ID int `kisssql:"id"`
Name string `kisssql:"name"`
Age int `kisssql:"age"`
// This field will be saved as JSON in the database
Address Address `kissorm:"address,json"`
Address Address `kisssql:"address,json"`
}
type PartialUpdateUser struct {
ID int `kissorm:"id"`
Name *string `kissorm:"name"`
Age *int `kissorm:"age"`
Address *Address `kissorm:"address,json"`
ID int `kisssql:"id"`
Name *string `kisssql:"name"`
Age *int `kisssql:"age"`
Address *Address `kisssql:"address,json"`
}
type Address struct {
@ -114,7 +114,7 @@ type Address struct {
func main() {
ctx := context.Background()
db, err := kissorm.New("sqlite3", "/tmp/hello.sqlite", 1, "users")
db, err := kisssql.New("sqlite3", "/tmp/hello.sqlite", 1, "users")
if err != nil {
panic(err.Error())
}
@ -178,8 +178,8 @@ func main() {
// Partial update technique 1:
err = db.Update(ctx, struct {
ID int `kissorm:"id"`
Age int `kissorm:"age"`
ID int `kisssql:"id"`
Age int `kisssql:"age"`
}{ID: cris.ID, Age: 28})
if err != nil {
panic(err.Error())
@ -216,9 +216,9 @@ func main() {
This library has a few helper functions for helping your tests:
- `kissorm.FillStructWith(struct interface{}, dbRow map[string]interface{}) error`
- `kissorm.FillSliceWith(structSlice interface{}, dbRows []map[string]interface{}) error`
- `kissorm.StructToMap(struct interface{}) (map[string]interface{}, error)`
- `kisssql.FillStructWith(struct interface{}, dbRow map[string]interface{}) error`
- `kisssql.FillSliceWith(structSlice interface{}, dbRows []map[string]interface{}) error`
- `kisssql.StructToMap(struct interface{}) (map[string]interface{}, error)`
If you want to see examples (we have examples for all the public functions) just
read the example tests available on our [example service](./examples/example_service)
@ -232,16 +232,16 @@ $ make bench TIME=3s
go test -bench=. -benchtime=3s
goos: linux
goarch: amd64
pkg: github.com/vingarcia/kissorm
pkg: github.com/vingarcia/kisssql
cpu: Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
BenchmarkInsert/kissorm-setup/insert-one-4 4302 776648 ns/op
BenchmarkInsert/kisssql-setup/insert-one-4 4302 776648 ns/op
BenchmarkInsert/sqlx-setup/insert-one-4 4716 762358 ns/op
BenchmarkQuery/kissorm-setup/single-row-4 12204 293858 ns/op
BenchmarkQuery/kissorm-setup/multiple-rows-4 11145 323571 ns/op
BenchmarkQuery/kisssql-setup/single-row-4 12204 293858 ns/op
BenchmarkQuery/kisssql-setup/multiple-rows-4 11145 323571 ns/op
BenchmarkQuery/sqlx-setup/single-row-4 12440 290937 ns/op
BenchmarkQuery/sqlx-setup/multiple-rows-4 10000 310314 ns/op
PASS
ok github.com/vingarcia/kissorm 34.251s
ok github.com/vingarcia/kisssql 34.251s
```
### TODO List

View File

@ -1,4 +1,4 @@
package kissorm_test
package kisssql_test
import (
"context"
@ -9,16 +9,16 @@ import (
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
"github.com/vingarcia/kissorm"
"github.com/vingarcia/kisssql"
)
func BenchmarkInsert(b *testing.B) {
ctx := context.Background()
driver := "postgres"
connStr := "host=localhost port=5432 user=postgres password=postgres dbname=kissorm sslmode=disable"
connStr := "host=localhost port=5432 user=postgres password=postgres dbname=kisssql sslmode=disable"
kissormDB, err := kissorm.New(driver, connStr, kissorm.Config{
kisssqlDB, err := kisssql.New(driver, connStr, kisssql.Config{
MaxOpenConns: 1,
TableName: "users",
})
@ -27,12 +27,12 @@ func BenchmarkInsert(b *testing.B) {
}
type User struct {
ID int `kissorm:"id" db:"id"`
Name string `kissorm:"name" db:"name"`
Age int `kissorm:"age" db:"age"`
ID int `kisssql:"id" db:"id"`
Name string `kisssql:"name" db:"name"`
Age int `kisssql:"age" db:"age"`
}
b.Run("kissorm-setup", func(b *testing.B) {
b.Run("kisssql-setup", func(b *testing.B) {
err := recreateTable(connStr)
if err != nil {
b.Fatalf("error creating table: %s", err.Error())
@ -40,7 +40,7 @@ func BenchmarkInsert(b *testing.B) {
b.Run("insert-one", func(b *testing.B) {
for i := 0; i < b.N; i++ {
err := kissormDB.Insert(ctx, &User{
err := kisssqlDB.Insert(ctx, &User{
Name: strconv.Itoa(i),
Age: i,
})
@ -88,9 +88,9 @@ func BenchmarkQuery(b *testing.B) {
ctx := context.Background()
driver := "postgres"
connStr := "host=localhost port=5432 user=postgres password=postgres dbname=kissorm sslmode=disable"
connStr := "host=localhost port=5432 user=postgres password=postgres dbname=kisssql sslmode=disable"
kissormDB, err := kissorm.New(driver, connStr, kissorm.Config{
kisssqlDB, err := kisssql.New(driver, connStr, kisssql.Config{
MaxOpenConns: 1,
TableName: "users",
})
@ -99,12 +99,12 @@ func BenchmarkQuery(b *testing.B) {
}
type User struct {
ID int `kissorm:"id" db:"id"`
Name string `kissorm:"name" db:"name"`
Age int `kissorm:"age" db:"age"`
ID int `kisssql:"id" db:"id"`
Name string `kisssql:"name" db:"name"`
Age int `kisssql:"age" db:"age"`
}
b.Run("kissorm-setup", func(b *testing.B) {
b.Run("kisssql-setup", func(b *testing.B) {
err := recreateTable(connStr)
if err != nil {
b.Fatalf("error creating table: %s", err.Error())
@ -118,7 +118,7 @@ func BenchmarkQuery(b *testing.B) {
b.Run("single-row", func(b *testing.B) {
for i := 0; i < b.N; i++ {
var user User
err := kissormDB.QueryOne(ctx, &user, `SELECT * FROM users OFFSET $1 LIMIT 1`, i%100)
err := kisssqlDB.QueryOne(ctx, &user, `SELECT * FROM users OFFSET $1 LIMIT 1`, i%100)
if err != nil {
b.Fatalf("query error: %s", err.Error())
}
@ -128,7 +128,7 @@ func BenchmarkQuery(b *testing.B) {
b.Run("multiple-rows", func(b *testing.B) {
for i := 0; i < b.N; i++ {
var users []User
err := kissormDB.Query(ctx, &users, `SELECT * FROM users OFFSET $1 LIMIT 10`, i%90)
err := kisssqlDB.Query(ctx, &users, `SELECT * FROM users OFFSET $1 LIMIT 10`, i%90)
if err != nil {
b.Fatalf("query error: %s", err.Error())
}

View File

@ -1,4 +1,4 @@
package kissorm
package kisssql
import (
"context"
@ -9,13 +9,13 @@ import (
)
// ErrRecordNotFound ...
var ErrRecordNotFound error = errors.Wrap(sql.ErrNoRows, "kissorm: the query returned no results")
var ErrRecordNotFound error = errors.Wrap(sql.ErrNoRows, "kisssql: the query returned no results")
// ErrAbortIteration ...
var ErrAbortIteration error = fmt.Errorf("kissorm: abort iteration, should only be used inside QueryChunks function")
var ErrAbortIteration error = fmt.Errorf("kisssql: abort iteration, should only be used inside QueryChunks function")
// ORMProvider describes the public behavior of this ORM
type ORMProvider interface {
// SQLProvider describes the public behavior of this ORM
type SQLProvider interface {
Insert(ctx context.Context, records ...interface{}) error
Delete(ctx context.Context, ids ...interface{}) error
Update(ctx context.Context, records ...interface{}) error
@ -25,7 +25,7 @@ type ORMProvider interface {
QueryChunks(ctx context.Context, parser ChunkParser) error
Exec(ctx context.Context, query string, params ...interface{}) error
Transaction(ctx context.Context, fn func(ORMProvider) error) error
Transaction(ctx context.Context, fn func(SQLProvider) error) error
}
// ChunkParser stores the arguments of the QueryChunks function

View File

@ -1,4 +1,4 @@
package kissorm
package kisssql
import "strconv"

View File

@ -5,26 +5,26 @@ import (
"fmt"
_ "github.com/mattn/go-sqlite3"
"github.com/vingarcia/kissorm"
"github.com/vingarcia/kissorm/nullable"
"github.com/vingarcia/kisssql"
"github.com/vingarcia/kisssql/nullable"
)
// User ...
type User struct {
ID int `kissorm:"id"`
Name string `kissorm:"name"`
Age int `kissorm:"age"`
ID int `kisssql:"id"`
Name string `kisssql:"name"`
Age int `kisssql:"age"`
// This field will be saved as JSON in the database
Address Address `kissorm:"address,json"`
Address Address `kisssql:"address,json"`
}
// PartialUpdateUser ...
type PartialUpdateUser struct {
ID int `kissorm:"id"`
Name *string `kissorm:"name"`
Age *int `kissorm:"age"`
Address *Address `kissorm:"address,json"`
ID int `kisssql:"id"`
Name *string `kisssql:"name"`
Age *int `kisssql:"age"`
Address *Address `kisssql:"address,json"`
}
// Address ...
@ -35,7 +35,7 @@ type Address struct {
func main() {
ctx := context.Background()
db, err := kissorm.New("sqlite3", "/tmp/hello.sqlite", kissorm.Config{
db, err := kisssql.New("sqlite3", "/tmp/hello.sqlite", kisssql.Config{
MaxOpenConns: 1,
TableName: "users",
})
@ -102,8 +102,8 @@ func main() {
// Partial update technique 1:
err = db.Update(ctx, struct {
ID int `kissorm:"id"`
Age int `kissorm:"age"`
ID int `kisssql:"id"`
Age int `kisssql:"age"`
}{ID: cris.ID, Age: 28})
if err != nil {
panic(err.Error())

View File

@ -4,13 +4,13 @@ import (
"context"
"time"
"github.com/vingarcia/kissorm"
"github.com/vingarcia/kissorm/nullable"
"github.com/vingarcia/kisssql"
"github.com/vingarcia/kisssql/nullable"
)
// Service ...
type Service struct {
usersTable kissorm.ORMProvider
usersTable kisssql.SQLProvider
streamChunkSize int
}
@ -25,12 +25,12 @@ type Service struct {
// If this is not the case, it might be a good idea
// to create a DTO struct to receive select queries.
type UserEntity struct {
ID int `kissorm:"id"`
Name *string `kissorm:"name"`
Age *int `kissorm:"age"`
Score *int `kissorm:"score"`
LastPayment time.Time `kissorm:"last_payment"`
Address *Address `kissorm:"address,json"`
ID int `kisssql:"id"`
Name *string `kisssql:"name"`
Age *int `kisssql:"age"`
Score *int `kisssql:"score"`
LastPayment time.Time `kisssql:"last_payment"`
Address *Address `kisssql:"address,json"`
}
// Address contains the user's address
@ -42,7 +42,7 @@ type Address struct {
}
// NewUserService ...
func NewUserService(usersTable kissorm.ORMProvider) Service {
func NewUserService(usersTable kisssql.SQLProvider) Service {
return Service{
usersTable: usersTable,
streamChunkSize: 100,
@ -58,7 +58,7 @@ func (s Service) CreateUser(ctx context.Context, u UserEntity) error {
// user score. Defaults to 0 if not set.
func (s Service) UpdateUserScore(ctx context.Context, uID int, scoreChange int) error {
var scoreRow struct {
Score int `kissorm:"score"`
Score int `kisssql:"score"`
}
err := s.usersTable.QueryOne(ctx, &scoreRow, "SELECT score FROM users WHERE id = ?", uID)
if err != nil {
@ -74,7 +74,7 @@ func (s Service) UpdateUserScore(ctx context.Context, uID int, scoreChange int)
// ListUsers returns a page of users
func (s Service) ListUsers(ctx context.Context, offset, limit int) (total int, users []UserEntity, err error) {
var countRow struct {
Count int `kissorm:"count"`
Count int `kisssql:"count"`
}
err = s.usersTable.QueryOne(ctx, &countRow, "SELECT count(*) as count FROM users")
if err != nil {
@ -91,7 +91,7 @@ func (s Service) ListUsers(ctx context.Context, offset, limit int) (total int, u
// function only when the ammount of data loaded might exceed the available memory and/or
// when you can't put an upper limit on the number of values returned.
func (s Service) StreamAllUsers(ctx context.Context, sendUser func(u UserEntity) error) error {
return s.usersTable.QueryChunks(ctx, kissorm.ChunkParser{
return s.usersTable.QueryChunks(ctx, kisssql.ChunkParser{
Query: "SELECT * FROM users",
Params: []interface{}{},
ChunkSize: s.streamChunkSize,

View File

@ -7,17 +7,17 @@ import (
gomock "github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
"github.com/tj/assert"
"github.com/vingarcia/kissorm"
"github.com/vingarcia/kissorm/nullable"
"github.com/vingarcia/kissorm/structs"
"github.com/vingarcia/kisssql"
"github.com/vingarcia/kisssql/nullable"
"github.com/vingarcia/kisssql/structs"
)
func TestCreateUser(t *testing.T) {
t.Run("should call kissorm.Insert correctly", func(t *testing.T) {
t.Run("should call kisssql.Insert correctly", func(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
usersTableMock := NewMockORMProvider(controller)
usersTableMock := NewMockSQLProvider(controller)
s := Service{
usersTable: usersTableMock,
@ -43,7 +43,7 @@ func TestCreateUser(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
usersTableMock := NewMockORMProvider(controller)
usersTableMock := NewMockSQLProvider(controller)
s := Service{
usersTable: usersTableMock,
@ -54,8 +54,8 @@ func TestCreateUser(t *testing.T) {
usersTableMock.EXPECT().Insert(gomock.Any(), gomock.Any()).
DoAndReturn(func(ctx context.Context, records ...interface{}) error {
for _, record := range records {
// The StructToMap function will convert a struct with `kissorm` tags
// into a map using the kissorm attr names as keys.
// The StructToMap function will convert a struct with `kisssql` tags
// into a map using the kisssql attr names as keys.
//
// If you are inserting an anonymous struct (not usual) this function
// can make your tests shorter:
@ -79,11 +79,11 @@ func TestCreateUser(t *testing.T) {
}
func TestUpdateUserScore(t *testing.T) {
t.Run("should call kissorm.QueryOne() & Update() correctly", func(t *testing.T) {
t.Run("should call kisssql.QueryOne() & Update() correctly", func(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
usersTableMock := NewMockORMProvider(controller)
usersTableMock := NewMockSQLProvider(controller)
s := Service{
usersTable: usersTableMock,
@ -97,7 +97,7 @@ func TestUpdateUserScore(t *testing.T) {
// This function will use reflection to fill the
// struct fields with the values from the map
return structs.FillStructWith(result, map[string]interface{}{
// Use int this map the keys you set on the kissorm tags, e.g. `kissorm:"score"`
// Use int this map the keys you set on the kisssql tags, e.g. `kisssql:"score"`
// Each of these fields represent the database rows returned
// by the query.
"score": 42,
@ -123,11 +123,11 @@ func TestUpdateUserScore(t *testing.T) {
}
func TestListUsers(t *testing.T) {
t.Run("should call kissorm.QueryOne() & Query() correctly", func(t *testing.T) {
t.Run("should call kisssql.QueryOne() & Query() correctly", func(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
usersTableMock := NewMockORMProvider(controller)
usersTableMock := NewMockSQLProvider(controller)
s := Service{
usersTable: usersTableMock,
@ -140,7 +140,7 @@ func TestListUsers(t *testing.T) {
// This function will use reflection to fill the
// struct fields with the values from the map
return structs.FillStructWith(result, map[string]interface{}{
// Use int this map the keys you set on the kissorm tags, e.g. `kissorm:"score"`
// Use int this map the keys you set on the kisssql tags, e.g. `kisssql:"score"`
// Each of these fields represent the database rows returned
// by the query.
"count": 420,
@ -185,11 +185,11 @@ func TestListUsers(t *testing.T) {
}
func TestStreamAllUsers(t *testing.T) {
t.Run("should call kissorm.QueryChunks correctly", func(t *testing.T) {
t.Run("should call kisssql.QueryChunks correctly", func(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
usersTableMock := NewMockORMProvider(controller)
usersTableMock := NewMockSQLProvider(controller)
s := Service{
usersTable: usersTableMock,
@ -197,7 +197,7 @@ func TestStreamAllUsers(t *testing.T) {
}
usersTableMock.EXPECT().QueryChunks(gomock.Any(), gomock.Any()).
DoAndReturn(func(ctx context.Context, parser kissorm.ChunkParser) error {
DoAndReturn(func(ctx context.Context, parser kisssql.ChunkParser) error {
fn, ok := parser.ForEachChunk.(func(users []UserEntity) error)
require.True(t, ok)
// Chunk 1:
@ -259,11 +259,11 @@ func TestStreamAllUsers(t *testing.T) {
}
func TestDeleteUser(t *testing.T) {
t.Run("should call kissorm.Delete correctly", func(t *testing.T) {
t.Run("should call kisssql.Delete correctly", func(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
usersTableMock := NewMockORMProvider(controller)
usersTableMock := NewMockSQLProvider(controller)
s := Service{
usersTable: usersTableMock,

View File

@ -9,34 +9,34 @@ import (
reflect "reflect"
gomock "github.com/golang/mock/gomock"
kissorm "github.com/vingarcia/kissorm"
kisssql "github.com/vingarcia/kisssql"
)
// MockORMProvider is a mock of ORMProvider interface.
type MockORMProvider struct {
// MockSQLProvider is a mock of SQLProvider interface.
type MockSQLProvider struct {
ctrl *gomock.Controller
recorder *MockORMProviderMockRecorder
recorder *MockSQLProviderMockRecorder
}
// MockORMProviderMockRecorder is the mock recorder for MockORMProvider.
type MockORMProviderMockRecorder struct {
mock *MockORMProvider
// MockSQLProviderMockRecorder is the mock recorder for MockSQLProvider.
type MockSQLProviderMockRecorder struct {
mock *MockSQLProvider
}
// NewMockORMProvider creates a new mock instance.
func NewMockORMProvider(ctrl *gomock.Controller) *MockORMProvider {
mock := &MockORMProvider{ctrl: ctrl}
mock.recorder = &MockORMProviderMockRecorder{mock}
// NewMockSQLProvider creates a new mock instance.
func NewMockSQLProvider(ctrl *gomock.Controller) *MockSQLProvider {
mock := &MockSQLProvider{ctrl: ctrl}
mock.recorder = &MockSQLProviderMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockORMProvider) EXPECT() *MockORMProviderMockRecorder {
func (m *MockSQLProvider) EXPECT() *MockSQLProviderMockRecorder {
return m.recorder
}
// Delete mocks base method.
func (m *MockORMProvider) Delete(ctx context.Context, ids ...interface{}) error {
func (m *MockSQLProvider) Delete(ctx context.Context, ids ...interface{}) error {
m.ctrl.T.Helper()
varargs := []interface{}{ctx}
for _, a := range ids {
@ -48,14 +48,14 @@ func (m *MockORMProvider) Delete(ctx context.Context, ids ...interface{}) error
}
// Delete indicates an expected call of Delete.
func (mr *MockORMProviderMockRecorder) Delete(ctx interface{}, ids ...interface{}) *gomock.Call {
func (mr *MockSQLProviderMockRecorder) Delete(ctx interface{}, ids ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{ctx}, ids...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockORMProvider)(nil).Delete), varargs...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockSQLProvider)(nil).Delete), varargs...)
}
// Exec mocks base method.
func (m *MockORMProvider) Exec(ctx context.Context, query string, params ...interface{}) error {
func (m *MockSQLProvider) Exec(ctx context.Context, query string, params ...interface{}) error {
m.ctrl.T.Helper()
varargs := []interface{}{ctx, query}
for _, a := range params {
@ -67,14 +67,14 @@ func (m *MockORMProvider) Exec(ctx context.Context, query string, params ...inte
}
// Exec indicates an expected call of Exec.
func (mr *MockORMProviderMockRecorder) Exec(ctx, query interface{}, params ...interface{}) *gomock.Call {
func (mr *MockSQLProviderMockRecorder) Exec(ctx, query interface{}, params ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{ctx, query}, params...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exec", reflect.TypeOf((*MockORMProvider)(nil).Exec), varargs...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exec", reflect.TypeOf((*MockSQLProvider)(nil).Exec), varargs...)
}
// Insert mocks base method.
func (m *MockORMProvider) Insert(ctx context.Context, records ...interface{}) error {
func (m *MockSQLProvider) Insert(ctx context.Context, records ...interface{}) error {
m.ctrl.T.Helper()
varargs := []interface{}{ctx}
for _, a := range records {
@ -86,14 +86,14 @@ func (m *MockORMProvider) Insert(ctx context.Context, records ...interface{}) er
}
// Insert indicates an expected call of Insert.
func (mr *MockORMProviderMockRecorder) Insert(ctx interface{}, records ...interface{}) *gomock.Call {
func (mr *MockSQLProviderMockRecorder) Insert(ctx interface{}, records ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{ctx}, records...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Insert", reflect.TypeOf((*MockORMProvider)(nil).Insert), varargs...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Insert", reflect.TypeOf((*MockSQLProvider)(nil).Insert), varargs...)
}
// Query mocks base method.
func (m *MockORMProvider) Query(ctx context.Context, records interface{}, query string, params ...interface{}) error {
func (m *MockSQLProvider) Query(ctx context.Context, records interface{}, query string, params ...interface{}) error {
m.ctrl.T.Helper()
varargs := []interface{}{ctx, records, query}
for _, a := range params {
@ -105,14 +105,14 @@ func (m *MockORMProvider) Query(ctx context.Context, records interface{}, query
}
// Query indicates an expected call of Query.
func (mr *MockORMProviderMockRecorder) Query(ctx, records, query interface{}, params ...interface{}) *gomock.Call {
func (mr *MockSQLProviderMockRecorder) Query(ctx, records, query interface{}, params ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{ctx, records, query}, params...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockORMProvider)(nil).Query), varargs...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockSQLProvider)(nil).Query), varargs...)
}
// QueryChunks mocks base method.
func (m *MockORMProvider) QueryChunks(ctx context.Context, parser kissorm.ChunkParser) error {
func (m *MockSQLProvider) QueryChunks(ctx context.Context, parser kisssql.ChunkParser) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "QueryChunks", ctx, parser)
ret0, _ := ret[0].(error)
@ -120,13 +120,13 @@ func (m *MockORMProvider) QueryChunks(ctx context.Context, parser kissorm.ChunkP
}
// QueryChunks indicates an expected call of QueryChunks.
func (mr *MockORMProviderMockRecorder) QueryChunks(ctx, parser interface{}) *gomock.Call {
func (mr *MockSQLProviderMockRecorder) QueryChunks(ctx, parser interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryChunks", reflect.TypeOf((*MockORMProvider)(nil).QueryChunks), ctx, parser)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryChunks", reflect.TypeOf((*MockSQLProvider)(nil).QueryChunks), ctx, parser)
}
// QueryOne mocks base method.
func (m *MockORMProvider) QueryOne(ctx context.Context, record interface{}, query string, params ...interface{}) error {
func (m *MockSQLProvider) QueryOne(ctx context.Context, record interface{}, query string, params ...interface{}) error {
m.ctrl.T.Helper()
varargs := []interface{}{ctx, record, query}
for _, a := range params {
@ -138,14 +138,14 @@ func (m *MockORMProvider) QueryOne(ctx context.Context, record interface{}, quer
}
// QueryOne indicates an expected call of QueryOne.
func (mr *MockORMProviderMockRecorder) QueryOne(ctx, record, query interface{}, params ...interface{}) *gomock.Call {
func (mr *MockSQLProviderMockRecorder) QueryOne(ctx, record, query interface{}, params ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{ctx, record, query}, params...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryOne", reflect.TypeOf((*MockORMProvider)(nil).QueryOne), varargs...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryOne", reflect.TypeOf((*MockSQLProvider)(nil).QueryOne), varargs...)
}
// Transaction mocks base method.
func (m *MockORMProvider) Transaction(ctx context.Context, fn func(kissorm.ORMProvider) error) error {
func (m *MockSQLProvider) Transaction(ctx context.Context, fn func(kisssql.SQLProvider) error) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Transaction", ctx, fn)
ret0, _ := ret[0].(error)
@ -153,13 +153,13 @@ func (m *MockORMProvider) Transaction(ctx context.Context, fn func(kissorm.ORMPr
}
// Transaction indicates an expected call of Transaction.
func (mr *MockORMProviderMockRecorder) Transaction(ctx, fn interface{}) *gomock.Call {
func (mr *MockSQLProviderMockRecorder) Transaction(ctx, fn interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Transaction", reflect.TypeOf((*MockORMProvider)(nil).Transaction), ctx, fn)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Transaction", reflect.TypeOf((*MockSQLProvider)(nil).Transaction), ctx, fn)
}
// Update mocks base method.
func (m *MockORMProvider) Update(ctx context.Context, records ...interface{}) error {
func (m *MockSQLProvider) Update(ctx context.Context, records ...interface{}) error {
m.ctrl.T.Helper()
varargs := []interface{}{ctx}
for _, a := range records {
@ -171,8 +171,8 @@ func (m *MockORMProvider) Update(ctx context.Context, records ...interface{}) er
}
// Update indicates an expected call of Update.
func (mr *MockORMProviderMockRecorder) Update(ctx interface{}, records ...interface{}) *gomock.Call {
func (mr *MockSQLProviderMockRecorder) Update(ctx interface{}, records ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{ctx}, records...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockORMProvider)(nil).Update), varargs...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockSQLProvider)(nil).Update), varargs...)
}

2
go.mod
View File

@ -1,4 +1,4 @@
module github.com/vingarcia/kissorm
module github.com/vingarcia/kisssql
go 1.14

View File

@ -1,4 +1,4 @@
package kissorm
package kisssql
import (
"database/sql/driver"

View File

@ -1,4 +1,4 @@
package kissorm
package kisssql
import (
"context"
@ -8,12 +8,12 @@ import (
"strings"
"github.com/pkg/errors"
"github.com/vingarcia/kissorm/structs"
"github.com/vingarcia/kisssql/structs"
)
// DB represents the kissorm client responsible for
// DB represents the kisssql client responsible for
// interfacing with the "database/sql" package implementing
// the Kissorm interface `ORMProvider`.
// the KissSQL interface `SQLProvider`.
type DB struct {
driver string
dialect dialect
@ -21,7 +21,7 @@ type DB struct {
db sqlProvider
// Most dbs have a single primary key,
// But in future kissorm should work with compound keys as well
// But in future kisssql should work with compound keys as well
idCols []string
insertMethod insertMethod
@ -41,7 +41,7 @@ const (
)
// Config describes the optional arguments accepted
// by the kissorm.New() function.
// by the kisssql.New() function.
type Config struct {
// MaxOpenCons defaults to 1 if not set
MaxOpenConns int
@ -55,7 +55,7 @@ type Config struct {
IDColumns []string
}
// New instantiates a new Kissorm client
// New instantiates a new KissSQL client
func New(
dbDriver string,
connectionString string,
@ -124,7 +124,7 @@ func (c DB) Query(
slicePtr := reflect.ValueOf(records)
slicePtrType := slicePtr.Type()
if slicePtrType.Kind() != reflect.Ptr {
return fmt.Errorf("kissorm: expected to receive a pointer to slice of structs, but got: %T", records)
return fmt.Errorf("kisssql: expected to receive a pointer to slice of structs, but got: %T", records)
}
sliceType := slicePtrType.Elem()
slice := slicePtr.Elem()
@ -198,11 +198,11 @@ func (c DB) QueryOne(
) error {
t := reflect.TypeOf(record)
if t.Kind() != reflect.Ptr {
return fmt.Errorf("kissorm: expected to receive a pointer to struct, but got: %T", record)
return fmt.Errorf("kisssql: expected to receive a pointer to struct, but got: %T", record)
}
t = t.Elem()
if t.Kind() != reflect.Struct {
return fmt.Errorf("kissorm: expected to receive a pointer to struct, but got: %T", record)
return fmt.Errorf("kisssql: expected to receive a pointer to struct, but got: %T", record)
}
rows, err := c.db.QueryContext(ctx, query, params...)
@ -509,7 +509,7 @@ func (c DB) Delete(
func normalizeIDsAsMaps(idNames []string, ids []interface{}) ([]map[string]interface{}, error) {
if len(idNames) == 0 {
return nil, fmt.Errorf("internal kissorm error: missing idNames")
return nil, fmt.Errorf("internal kisssql error: missing idNames")
}
idMaps := []map[string]interface{}{}
@ -698,7 +698,7 @@ func (c DB) Exec(ctx context.Context, query string, params ...interface{}) error
}
// Transaction just runs an SQL command on the database returning no rows.
func (c DB) Transaction(ctx context.Context, fn func(ORMProvider) error) error {
func (c DB) Transaction(ctx context.Context, fn func(SQLProvider) error) error {
switch db := c.db.(type) {
case *sql.Tx:
return fn(c)
@ -736,7 +736,7 @@ func (c DB) Transaction(ctx context.Context, fn func(ORMProvider) error) error {
return tx.Commit()
default:
return fmt.Errorf("unexpected error on kissorm: db attribute has an invalid type")
return fmt.Errorf("unexpected error on kisssql: db attribute has an invalid type")
}
}
@ -789,14 +789,14 @@ func scanRows(rows *sql.Rows, record interface{}) error {
v := reflect.ValueOf(record)
t := v.Type()
if t.Kind() != reflect.Ptr {
return fmt.Errorf("kissorm: expected record to be a pointer to struct, but got: %T", record)
return fmt.Errorf("kisssql: expected record to be a pointer to struct, but got: %T", record)
}
v = v.Elem()
t = t.Elem()
if t.Kind() != reflect.Struct {
return fmt.Errorf("kissorm: expected record to be a pointer to struct, but got: %T", record)
return fmt.Errorf("kisssql: expected record to be a pointer to struct, but got: %T", record)
}
info := structs.GetTagInfo(t)

View File

@ -1,4 +1,4 @@
package kissorm
package kisssql
import (
"context"
@ -12,15 +12,15 @@ import (
"github.com/ditointernet/go-assert"
_ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3"
"github.com/vingarcia/kissorm/nullable"
"github.com/vingarcia/kisssql/nullable"
)
type User struct {
ID uint `kissorm:"id"`
Name string `kissorm:"name"`
Age int `kissorm:"age"`
ID uint `kisssql:"id"`
Name string `kisssql:"name"`
Age int `kisssql:"age"`
Address Address `kissorm:"address,json"`
Address Address `kisssql:"address,json"`
}
type Address struct {
@ -702,9 +702,9 @@ func TestUpdate(t *testing.T) {
c := newTestDB(db, driver, "users")
type partialUser struct {
ID uint `kissorm:"id"`
Name string `kissorm:"name"`
Age *int `kissorm:"age"`
ID uint `kisssql:"id"`
Name string `kisssql:"name"`
Age *int `kisssql:"age"`
}
u := partialUser{
Name: "Letícia",
@ -743,9 +743,9 @@ func TestUpdate(t *testing.T) {
c := newTestDB(db, driver, "users")
type partialUser struct {
ID uint `kissorm:"id"`
Name string `kissorm:"name"`
Age *int `kissorm:"age"`
ID uint `kisssql:"id"`
Name string `kisssql:"name"`
Age *int `kisssql:"age"`
}
u := partialUser{
Name: "Letícia",
@ -1210,7 +1210,7 @@ func TestTransaction(t *testing.T) {
_ = c.Insert(ctx, &User{Name: "User2"})
var users []User
err = c.Transaction(ctx, func(db ORMProvider) error {
err = c.Transaction(ctx, func(db SQLProvider) error {
db.Query(ctx, &users, "SELECT * FROM users ORDER BY id ASC")
return nil
})
@ -1238,7 +1238,7 @@ func TestTransaction(t *testing.T) {
_ = c.Insert(ctx, &u1)
_ = c.Insert(ctx, &u2)
err = c.Transaction(ctx, func(db ORMProvider) error {
err = c.Transaction(ctx, func(db SQLProvider) error {
err = db.Insert(ctx, &User{Name: "User3"})
assert.Equal(t, nil, err)
err = db.Insert(ctx, &User{Name: "User4"})
@ -1309,11 +1309,11 @@ func TestScanRows(t *testing.T) {
assert.Equal(t, true, rows.Next())
var user struct {
ID int `kissorm:"id"`
Age int `kissorm:"age"`
ID int `kisssql:"id"`
Age int `kisssql:"age"`
// Omitted for testing purposes:
// Name string `kissorm:"name"`
// Name string `kisssql:"name"`
}
err = scanRows(rows, &user)
assert.Equal(t, nil, err)
@ -1379,8 +1379,8 @@ func TestScanRows(t *testing.T) {
}
var connectionString = map[string]string{
"postgres": "host=localhost port=5432 user=postgres password=postgres dbname=kissorm sslmode=disable",
"sqlite3": "/tmp/kissorm.db",
"postgres": "host=localhost port=5432 user=postgres password=postgres dbname=kisssql sslmode=disable",
"sqlite3": "/tmp/kisssql.db",
}
func createTable(driver string) error {

View File

@ -1,11 +1,11 @@
package kissorm
package kisssql
import "context"
var _ ORMProvider = MockORMProvider{}
var _ SQLProvider = MockSQLProvider{}
// MockORMProvider ...
type MockORMProvider struct {
// MockSQLProvider ...
type MockSQLProvider struct {
InsertFn func(ctx context.Context, records ...interface{}) error
DeleteFn func(ctx context.Context, ids ...interface{}) error
UpdateFn func(ctx context.Context, records ...interface{}) error
@ -15,45 +15,45 @@ type MockORMProvider struct {
QueryChunksFn func(ctx context.Context, parser ChunkParser) error
ExecFn func(ctx context.Context, query string, params ...interface{}) error
TransactionFn func(ctx context.Context, fn func(db ORMProvider) error) error
TransactionFn func(ctx context.Context, fn func(db SQLProvider) error) error
}
// Insert ...
func (m MockORMProvider) Insert(ctx context.Context, records ...interface{}) error {
func (m MockSQLProvider) Insert(ctx context.Context, records ...interface{}) error {
return m.InsertFn(ctx, records...)
}
// Delete ...
func (m MockORMProvider) Delete(ctx context.Context, ids ...interface{}) error {
func (m MockSQLProvider) Delete(ctx context.Context, ids ...interface{}) error {
return m.DeleteFn(ctx, ids...)
}
// Update ...
func (m MockORMProvider) Update(ctx context.Context, records ...interface{}) error {
func (m MockSQLProvider) Update(ctx context.Context, records ...interface{}) error {
return m.UpdateFn(ctx, records...)
}
// Query ...
func (m MockORMProvider) Query(ctx context.Context, records interface{}, query string, params ...interface{}) error {
func (m MockSQLProvider) Query(ctx context.Context, records interface{}, query string, params ...interface{}) error {
return m.QueryFn(ctx, records, query, params...)
}
// QueryOne ...
func (m MockORMProvider) QueryOne(ctx context.Context, record interface{}, query string, params ...interface{}) error {
func (m MockSQLProvider) QueryOne(ctx context.Context, record interface{}, query string, params ...interface{}) error {
return m.QueryOneFn(ctx, record, query, params...)
}
// QueryChunks ...
func (m MockORMProvider) QueryChunks(ctx context.Context, parser ChunkParser) error {
func (m MockSQLProvider) QueryChunks(ctx context.Context, parser ChunkParser) error {
return m.QueryChunksFn(ctx, parser)
}
// Exec ...
func (m MockORMProvider) Exec(ctx context.Context, query string, params ...interface{}) error {
func (m MockSQLProvider) Exec(ctx context.Context, query string, params ...interface{}) error {
return m.ExecFn(ctx, query, params...)
}
// Transaction ...
func (m MockORMProvider) Transaction(ctx context.Context, fn func(db ORMProvider) error) error {
func (m MockSQLProvider) Transaction(ctx context.Context, fn func(db SQLProvider) error) error {
return m.TransactionFn(ctx, fn)
}

View File

@ -68,7 +68,7 @@ func getCachedTagInfo(tagInfoCache map[reflect.Type]structInfo, key reflect.Type
}
// StructToMap converts any struct type to a map based on
// the tag named `kissorm`, i.e. `kissorm:"map_key_name"`
// the tag named `kisssql`, i.e. `kisssql:"map_key_name"`
//
// Valid pointers are dereferenced and copied to the map,
// null pointers are ignored.
@ -111,7 +111,7 @@ func StructToMap(obj interface{}) (map[string]interface{}, error) {
// FillStructWith is meant to be used on unit tests to mock
// the response from the database.
//
// The first argument is any struct you are passing to a kissorm func,
// The first argument is any struct you are passing to a kisssql func,
// and the second is a map representing a database row you want
// to use to update this struct.
func FillStructWith(record interface{}, dbRow map[string]interface{}) error {
@ -139,7 +139,7 @@ func FillStructWith(record interface{}, dbRow map[string]interface{}) error {
for colName, rawSrc := range dbRow {
fieldInfo := info.ByName(colName)
if !fieldInfo.Valid {
// Ignore columns not tagged with `kissorm:"..."`
// Ignore columns not tagged with `kisssql:"..."`
continue
}
@ -242,7 +242,7 @@ func (p PtrConverter) Convert(destType reflect.Type) (reflect.Value, error) {
// FillSliceWith is meant to be used on unit tests to mock
// the response from the database.
//
// The first argument is any slice of structs you are passing to a kissorm func,
// The first argument is any slice of structs you are passing to a kisssql func,
// and the second is a slice of maps representing the database rows you want
// to use to update this struct.
func FillSliceWith(entities interface{}, dbRows []map[string]interface{}) error {
@ -293,7 +293,7 @@ func getTagNames(t reflect.Type) structInfo {
byName: map[string]*fieldInfo{},
}
for i := 0; i < t.NumField(); i++ {
name := t.Field(i).Tag.Get("kissorm")
name := t.Field(i).Tag.Get("kisssql")
if name == "" {
continue
}

View File

@ -4,13 +4,13 @@ import (
"testing"
"github.com/ditointernet/go-assert"
"github.com/vingarcia/kissorm/nullable"
"github.com/vingarcia/kisssql/nullable"
)
func TestStructToMap(t *testing.T) {
type S1 struct {
Name string `kissorm:"name_attr"`
Age int `kissorm:"age_attr"`
Name string `kisssql:"name_attr"`
Age int `kisssql:"age_attr"`
}
t.Run("should convert plain structs to maps", func(t *testing.T) {
m, err := StructToMap(S1{
@ -39,8 +39,8 @@ func TestStructToMap(t *testing.T) {
})
type S2 struct {
Name *string `kissorm:"name"`
Age *int `kissorm:"age"`
Name *string `kisssql:"name"`
Age *int `kisssql:"age"`
}
t.Run("should not ignore not nil pointers", func(t *testing.T) {
@ -72,8 +72,8 @@ func TestStructToMap(t *testing.T) {
func TestFillStructWith(t *testing.T) {
t.Run("should fill a struct correctly", func(t *testing.T) {
var user struct {
Name string `kissorm:"name"`
Age int `kissorm:"age"`
Name string `kisssql:"name"`
Age int `kisssql:"age"`
}
err := FillStructWith(&user, map[string]interface{}{
"name": "Breno",
@ -87,8 +87,8 @@ func TestFillStructWith(t *testing.T) {
t.Run("should fill ptr fields with ptr values", func(t *testing.T) {
var user struct {
Name *string `kissorm:"name"`
Age *int `kissorm:"age"`
Name *string `kisssql:"name"`
Age *int `kisssql:"age"`
}
err := FillStructWith(&user, map[string]interface{}{
"name": nullable.String("Breno"),
@ -102,8 +102,8 @@ func TestFillStructWith(t *testing.T) {
t.Run("should fill ptr fields with non-ptr values", func(t *testing.T) {
var user struct {
Name *string `kissorm:"name"`
Age *int `kissorm:"age"`
Name *string `kisssql:"name"`
Age *int `kisssql:"age"`
}
err := FillStructWith(&user, map[string]interface{}{
"name": "Breno",
@ -117,8 +117,8 @@ func TestFillStructWith(t *testing.T) {
t.Run("should fill non ptr fields with ptr values", func(t *testing.T) {
var user struct {
Name string `kissorm:"name"`
Age int `kissorm:"age"`
Name string `kisssql:"name"`
Age int `kisssql:"age"`
}
err := FillStructWith(&user, map[string]interface{}{
"name": nullable.String("Breno"),
@ -132,8 +132,8 @@ func TestFillStructWith(t *testing.T) {
t.Run("should fill ptr fields with nil when necessary", func(t *testing.T) {
var user struct {
Name *string `kissorm:"name"`
Age *int `kissorm:"age"`
Name *string `kisssql:"name"`
Age *int `kisssql:"age"`
}
err := FillStructWith(&user, map[string]interface{}{
"name": nil,
@ -147,8 +147,8 @@ func TestFillStructWith(t *testing.T) {
t.Run("should interpret nil fields as zero values when necessary", func(t *testing.T) {
var user struct {
Name string `kissorm:"name"`
Age int `kissorm:"age"`
Name string `kisssql:"name"`
Age int `kisssql:"age"`
}
user.Name = "not empty"
user.Age = 42
@ -165,9 +165,9 @@ func TestFillStructWith(t *testing.T) {
t.Run("should ignore extra or missing fields", func(t *testing.T) {
var user struct {
Name string `kissorm:"name"`
Age int `kissorm:"age"`
Missing string `kissorm:"missing"`
Name string `kisssql:"name"`
Age int `kisssql:"age"`
Missing string `kisssql:"missing"`
}
user.Missing = "should be untouched"
@ -187,8 +187,8 @@ func TestFillStructWith(t *testing.T) {
func TestFillSliceWith(t *testing.T) {
t.Run("should fill a list correctly", func(t *testing.T) {
var users []struct {
Name string `kissorm:"name"`
Age int `kissorm:"age"`
Name string `kisssql:"name"`
Age int `kisssql:"age"`
}
err := FillSliceWith(&users, []map[string]interface{}{
{