diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/go-queryset.iml b/.idea/go-queryset.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/go-queryset.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..0b2b865 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 7c6d06b..4231e38 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# go-queryset [![GoDoc](https://godoc.org/github.com/jirfag/go-queryset?status.png)](http://godoc.org/github.com/jirfag/go-queryset) [![Go Report Card](https://goreportcard.com/badge/github.com/jirfag/go-queryset)](https://goreportcard.com/report/github.com/jirfag/go-queryset) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/04f432950cbc4e8cb0ec4ef36f4e90bb)](https://www.codacy.com/app/jirfag/go-queryset?utm_source=github.com&utm_medium=referral&utm_content=jirfag/go-queryset&utm_campaign=Badge_Grade) [![Maintainability](https://api.codeclimate.com/v1/badges/8a726af72f338e8998bd/maintainability)](https://codeclimate.com/github/jirfag/go-queryset/maintainability) [![Build Status](https://travis-ci.org/jirfag/go-queryset.svg?branch=master)](https://travis-ci.org/jirfag/go-queryset) [![Coverage Status](https://coveralls.io/repos/github/jirfag/go-queryset/badge.svg?branch=master)](https://coveralls.io/github/jirfag/go-queryset?branch=master) +# go-queryset [![GoDoc](https://godoc.org/github.com/zhaoshuyi-s0221/go-queryset?status.png)](http://godoc.org/github.com/zhaoshuyi-s0221/go-queryset) [![Go Report Card](https://goreportcard.com/badge/github.com/zhaoshuyi-s0221/go-queryset)](https://goreportcard.com/report/github.com/zhaoshuyi-s0221/go-queryset) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/04f432950cbc4e8cb0ec4ef36f4e90bb)](https://www.codacy.com/app/zhaoshuyi-s0221/go-queryset?utm_source=github.com&utm_medium=referral&utm_content=zhaoshuyi-s0221/go-queryset&utm_campaign=Badge_Grade) [![Maintainability](https://api.codeclimate.com/v1/badges/8a726af72f338e8998bd/maintainability)](https://codeclimate.com/github/zhaoshuyi-s0221/go-queryset/maintainability) [![Build Status](https://travis-ci.org/zhaoshuyi-s0221/go-queryset.svg?branch=master)](https://travis-ci.org/zhaoshuyi-s0221/go-queryset) [![Coverage Status](https://coveralls.io/repos/github/zhaoshuyi-s0221/go-queryset/badge.svg?branch=master)](https://coveralls.io/github/zhaoshuyi-s0221/go-queryset?branch=master) 100% type-safe ORM for Go (Golang) with code generation and MySQL, PostgreSQL, Sqlite3, SQL Server support. GORM under the hood. @@ -29,12 +29,12 @@ # Installation ```bash -go get -u github.com/jirfag/go-queryset/cmd/goqueryset +go get -u github.com/zhaoshuyi-s0221/go-queryset/cmd/goqueryset ``` # Usage ## Define models -Imagine you have model `User` in your [`models.go`](https://github.com/jirfag/go-queryset/blob/master/examples/comparison/gorm1/gorm1.go#L16) file: +Imagine you have model `User` in your [`models.go`](https://github.com/zhaoshuyi-s0221/go-queryset/blob/master/examples/comparison/gorm1/gorm1.go#L16) file: ```go type User struct { @@ -44,7 +44,7 @@ type User struct { } ``` -Now transform it by [adding comments for query set generation](https://github.com/jirfag/go-queryset/blob/master/examples/comparison/gorm4/gorm4.go#L15): +Now transform it by [adding comments for query set generation](https://github.com/zhaoshuyi-s0221/go-queryset/blob/master/examples/comparison/gorm4/gorm4.go#L15): ```go //go:generate goqueryset -in models.go @@ -64,7 +64,7 @@ Then execute next shell command: go generate ./... ``` -And you will get file [`autogenerated_models.go`](https://github.com/jirfag/go-queryset/blob/master/examples/comparison/gorm4/autogenerated_gorm4.go) in the same directory (and package) as `models.go`. +And you will get file [`autogenerated_models.go`](https://github.com/zhaoshuyi-s0221/go-queryset/blob/master/examples/comparison/gorm4/autogenerated_gorm4.go) in the same directory (and package) as `models.go`. In this autogenerated file you will find a lot of autogenerated typesafe methods like these: ```go @@ -93,7 +93,7 @@ func (qs UserQuerySet) OrderAscByCreatedAt() UserQuerySet { } ``` -See full autogenerated file [here](https://github.com/jirfag/go-queryset/blob/master/examples/comparison/gorm4/autogenerated_gorm4.go). +See full autogenerated file [here](https://github.com/zhaoshuyi-s0221/go-queryset/blob/master/examples/comparison/gorm4/autogenerated_gorm4.go). Now you can use this queryset for creating/reading/updating/deleting. Let's take a look at these operations. @@ -127,7 +127,7 @@ u := User{ } err := u.Create(getGormDB()) ``` -Under the hood `Create` method [just calls `db.Create(&u)`](https://github.com/jirfag/go-queryset/blob/master/examples/comparison/gorm4/autogenerated_gorm4.go#L38). +Under the hood `Create` method [just calls `db.Create(&u)`](https://github.com/zhaoshuyi-s0221/go-queryset/blob/master/examples/comparison/gorm4/autogenerated_gorm4.go#L38). ## Select It's the most powerful feature of query set. Let's execute some queries: @@ -210,8 +210,8 @@ u := User{ err := u.Update(getGormDB(), UserDBSchema.Rating) ``` -Goqueryset generates DB names for struct fields into [`UserDBSchema`](https://github.com/jirfag/go-queryset/blob/master/examples/comparison/gorm4/autogenerated_gorm4.go#L414) variable. -In this example we used [`UserDBSchema.Rating`](https://github.com/jirfag/go-queryset/blob/master/examples/comparison/gorm4/autogenerated_gorm4.go#L419). +Goqueryset generates DB names for struct fields into [`UserDBSchema`](https://github.com/zhaoshuyi-s0221/go-queryset/blob/master/examples/comparison/gorm4/autogenerated_gorm4.go#L414) variable. +In this example we used [`UserDBSchema.Rating`](https://github.com/zhaoshuyi-s0221/go-queryset/blob/master/examples/comparison/gorm4/autogenerated_gorm4.go#L419). And this code generates next SQL: ```sql @@ -392,7 +392,7 @@ func (u UserUpdater) Update() error ``` # Golang version -Golang >= 1.8 is required. Tested on go 1.8, 1.9 versions by [Travis CI](https://travis-ci.org/jirfag/go-queryset) +Golang >= 1.8 is required. Tested on go 1.8, 1.9 versions by [Travis CI](https://travis-ci.org/zhaoshuyi-s0221/go-queryset) # Why? ## Why not just use GORM? @@ -406,7 +406,7 @@ It's easy to get `SELECT * FROM t WHERE string_field == 1` SQL in production wit Type-safety, like with GORM. ## Why not any ORM? -I didn't see any ORM that properly handles code duplication. GORM is the best with `Scopes` support, but even it's far from ideal. E.g. we have GORM and [next typical code](https://github.com/jirfag/go-queryset/blob/master/examples/comparison/gorm1/gorm1.go#L16): +I didn't see any ORM that properly handles code duplication. GORM is the best with `Scopes` support, but even it's far from ideal. E.g. we have GORM and [next typical code](https://github.com/zhaoshuyi-s0221/go-queryset/blob/master/examples/comparison/gorm1/gorm1.go#L16): ```go type User struct { gorm.Model @@ -435,7 +435,7 @@ func GetUsersRegisteredToday(limit int) ([]User, error) { At one moment PM asks us to implement new function, returning list of users registered today AND sorted by rating. Copy-paste way is to add `Order("rating DESC")` to `GetUsersRegisteredToday`. But it leads to typical copy-paste troubles: when we change rating calculation logics (e.g. to `.Where("rating_marks >= ?", 10).Order("rating DESC")`) we must change it in two places. -How to solve it? First idea is to [make reusable functions](https://github.com/jirfag/go-queryset/blob/master/examples/comparison/gorm2/gorm2.go#L27): +How to solve it? First idea is to [make reusable functions](https://github.com/zhaoshuyi-s0221/go-queryset/blob/master/examples/comparison/gorm2/gorm2.go#L27): ```go func queryUsersWithMaxRating(db *gorm.DB, limit int) *gorm.DB { return db.Order("rating DESC").Limit(limit) @@ -473,7 +473,7 @@ func GetUsersRegisteredTodayWithMaxRating(limit int) ([]User, error) { } ``` -We can use GORM [Scopes](http://jinzhu.me/gorm/crud.html#scopes) to improve [how it looks](https://github.com/jirfag/go-queryset/blob/master/examples/comparison/gorm3/gorm3.go#L64): +We can use GORM [Scopes](http://jinzhu.me/gorm/crud.html#scopes) to improve [how it looks](https://github.com/zhaoshuyi-s0221/go-queryset/blob/master/examples/comparison/gorm3/gorm3.go#L64): ```go func queryUsersWithMaxRating(db *gorm.DB) *gorm.DB { return db.Order("rating DESC") @@ -498,7 +498,7 @@ func GetUsersRegisteredTodayWithMaxRating(limit int) ([]User, error) { Looks nice, but we loosed ability to parametrize our reusable GORM queries (scopes): they must have only one argument of type `*gorm.DB`. It means that we must move out `Limit` from them (let's say we get it from user). If we need to implement query `QueryUsersRegisteredAfter(db *gorm.DB, t time.Time)` - we can't do it. -Now compare it with [go-queryset solution](https://github.com/jirfag/go-queryset/blob/master/examples/comparison/gorm4/gorm4.go#L30): +Now compare it with [go-queryset solution](https://github.com/zhaoshuyi-s0221/go-queryset/blob/master/examples/comparison/gorm4/gorm4.go#L30): ```go // UserQuerySet is an autogenerated struct with a lot of typesafe methods. // We can define any methods on it because it's in the same package @@ -565,7 +565,7 @@ QuerySet pattern is similar to: # Features * 100% typesafe: there is no one method with `interface{}` arguments. -* QuerySet pattern allows to reuse queries by defining [custom methods](https://github.com/jirfag/go-queryset/blob/master/examples/comparison/gorm4/gorm4.go#L30) on it. +* QuerySet pattern allows to reuse queries by defining [custom methods](https://github.com/zhaoshuyi-s0221/go-queryset/blob/master/examples/comparison/gorm4/gorm4.go#L30) on it. * Supports all DBMS that GORM supports: MySQL, PostgreSQL, Sqlite3, SQL Server. * Supports creating, selecting, updating, deleting of objects. diff --git a/cmd/goqueryset/goqueryset.go b/cmd/goqueryset/goqueryset.go index 8b5321c..fda7498 100644 --- a/cmd/goqueryset/goqueryset.go +++ b/cmd/goqueryset/goqueryset.go @@ -7,8 +7,8 @@ import ( "path/filepath" "time" - "github.com/jirfag/go-queryset/internal/parser" - "github.com/jirfag/go-queryset/internal/queryset/generator" + "github.com/zhaoshuyi-s0221/go-queryset/internal/parser" + "github.com/zhaoshuyi-s0221/go-queryset/internal/queryset/generator" ) func main() { diff --git a/go.mod b/go.mod index 7fd83ac..fd5e602 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/jirfag/go-queryset +module github.com/zhaoshuyi-s0221/go-queryset require ( cloud.google.com/go v0.37.0 // indirect diff --git a/internal/queryset/generator/generator.go b/internal/queryset/generator/generator.go index a0bf12f..6968391 100644 --- a/internal/queryset/generator/generator.go +++ b/internal/queryset/generator/generator.go @@ -9,7 +9,7 @@ import ( "os" "path/filepath" - "github.com/jirfag/go-queryset/internal/parser" + "github.com/zhaoshuyi-s0221/go-queryset/internal/parser" "github.com/pkg/errors" "golang.org/x/tools/imports" ) @@ -59,7 +59,7 @@ import ( "strings" "time" - "github.com/jinzhu/gorm" + "gorm.io/gorm" ) ` diff --git a/internal/queryset/generator/methodsbuilder.go b/internal/queryset/generator/methodsbuilder.go index 514be3e..11727f1 100644 --- a/internal/queryset/generator/methodsbuilder.go +++ b/internal/queryset/generator/methodsbuilder.go @@ -1,9 +1,9 @@ package generator import ( - "github.com/jirfag/go-queryset/internal/parser" - "github.com/jirfag/go-queryset/internal/queryset/field" - "github.com/jirfag/go-queryset/internal/queryset/methods" + "github.com/zhaoshuyi-s0221/go-queryset/internal/parser" + "github.com/zhaoshuyi-s0221/go-queryset/internal/queryset/field" + "github.com/zhaoshuyi-s0221/go-queryset/internal/queryset/methods" ) type methodsBuilder struct { diff --git a/internal/queryset/generator/queryset.go b/internal/queryset/generator/queryset.go index a469f80..a39d369 100644 --- a/internal/queryset/generator/queryset.go +++ b/internal/queryset/generator/queryset.go @@ -9,9 +9,9 @@ import ( "sort" "strings" - "github.com/jirfag/go-queryset/internal/parser" - "github.com/jirfag/go-queryset/internal/queryset/field" - "github.com/jirfag/go-queryset/internal/queryset/methods" + "github.com/zhaoshuyi-s0221/go-queryset/internal/parser" + "github.com/zhaoshuyi-s0221/go-queryset/internal/queryset/field" + "github.com/zhaoshuyi-s0221/go-queryset/internal/queryset/methods" ) type querySetStructConfig struct { diff --git a/internal/queryset/generator/queryset_test.go b/internal/queryset/generator/queryset_test.go index 95d7414..59d93de 100644 --- a/internal/queryset/generator/queryset_test.go +++ b/internal/queryset/generator/queryset_test.go @@ -16,11 +16,11 @@ import ( "testing" "time" - "github.com/jirfag/go-queryset/internal/parser" + "github.com/zhaoshuyi-s0221/go-queryset/internal/parser" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" - "github.com/jirfag/go-queryset/internal/queryset/generator/test" + "github.com/zhaoshuyi-s0221/go-queryset/internal/queryset/generator/test" assert "github.com/stretchr/testify/require" sqlmock "gopkg.in/DATA-DOG/go-sqlmock.v1" diff --git a/internal/queryset/generator/test/autogenerated_models.go b/internal/queryset/generator/test/autogenerated_models.go index 21f6a4e..4edd246 100644 --- a/internal/queryset/generator/test/autogenerated_models.go +++ b/internal/queryset/generator/test/autogenerated_models.go @@ -8,7 +8,7 @@ import ( "time" "github.com/jinzhu/gorm" - "github.com/jirfag/go-queryset/internal/queryset/generator/tmp" + "github.com/zhaoshuyi-s0221/go-queryset/internal/queryset/generator/tmp" ) // ===== BEGIN of all query sets diff --git a/internal/queryset/generator/test/models.go b/internal/queryset/generator/test/models.go index 7ec12fe..86b8607 100644 --- a/internal/queryset/generator/test/models.go +++ b/internal/queryset/generator/test/models.go @@ -2,7 +2,7 @@ package test import ( "github.com/jinzhu/gorm" - "github.com/jirfag/go-queryset/internal/queryset/generator/tmp" + "github.com/zhaoshuyi-s0221/go-queryset/internal/queryset/generator/tmp" ) //go:generate go run ../../../../cmd/goqueryset/goqueryset.go -in models.go diff --git a/internal/queryset/generator/test/pkgimport/autogenerated_models.go b/internal/queryset/generator/test/pkgimport/autogenerated_models.go index 47d15ae..da47d08 100644 --- a/internal/queryset/generator/test/pkgimport/autogenerated_models.go +++ b/internal/queryset/generator/test/pkgimport/autogenerated_models.go @@ -7,7 +7,7 @@ import ( "strings" "github.com/jinzhu/gorm" - forex "github.com/jirfag/go-queryset/internal/queryset/generator/test/pkgimport/forex/v1" + forex "github.com/zhaoshuyi-s0221/go-queryset/internal/queryset/generator/test/pkgimport/forex/v1" ) // ===== BEGIN of all query sets diff --git a/internal/queryset/generator/test/pkgimport/models.go b/internal/queryset/generator/test/pkgimport/models.go index 3cb8171..7db3a8b 100644 --- a/internal/queryset/generator/test/pkgimport/models.go +++ b/internal/queryset/generator/test/pkgimport/models.go @@ -3,8 +3,8 @@ package models //go:generate goqueryset -in models.go import ( - forex "github.com/jirfag/go-queryset/internal/queryset/generator/test/pkgimport/forex/v1" - forexAlias "github.com/jirfag/go-queryset/internal/queryset/generator/test/pkgimport/forex/v1" + forex "github.com/zhaoshuyi-s0221/go-queryset/internal/queryset/generator/test/pkgimport/forex/v1" + forexAlias "github.com/zhaoshuyi-s0221/go-queryset/internal/queryset/generator/test/pkgimport/forex/v1" ) // Example is a test struct diff --git a/internal/queryset/methods/context.go b/internal/queryset/methods/context.go index 93582f1..92dfbb0 100644 --- a/internal/queryset/methods/context.go +++ b/internal/queryset/methods/context.go @@ -1,8 +1,8 @@ package methods import ( - "github.com/jirfag/go-queryset/internal/parser" - "github.com/jirfag/go-queryset/internal/queryset/field" + "github.com/zhaoshuyi-s0221/go-queryset/internal/parser" + "github.com/zhaoshuyi-s0221/go-queryset/internal/queryset/field" ) type QsStructContext struct { diff --git a/internal/queryset/methods/queryset.go b/internal/queryset/methods/queryset.go index b42395b..ac82773 100644 --- a/internal/queryset/methods/queryset.go +++ b/internal/queryset/methods/queryset.go @@ -353,8 +353,8 @@ func NewCountMethod(qsTypeName string) CountMethod { return CountMethod{ baseQuerySetMethod: newBaseQuerySetMethod(qsTypeName), namedMethod: newNamedMethod("Count"), - constRetMethod: newConstRetMethod("(int, error)"), - constBodyMethod: newConstBodyMethod(`var count int + constRetMethod: newConstRetMethod("(int64, error)"), + constBodyMethod: newConstBodyMethod(`var count int64 err := %s.Count(&count).Error return count, err`, qsDbName), } @@ -396,7 +396,7 @@ func NewOffsetMethod(qsTypeName string) StructOperationOneArgMethod { // NewAllMethod creates All method func NewAllMethod(structName, qsTypeName string) SelectMethod { - return newSelectMethod("All", "Find", fmt.Sprintf("*[]%s", structName), qsTypeName) + return newSelectMethod("All", "Find", fmt.Sprintf("*[]*%s", structName), qsTypeName) } // NewOneMethod creates One method