Skip to content

Commit 38b6caf

Browse files
authored
Merge pull request #153 from go-jet/develop
Release 2.8.0
2 parents 6babd43 + 4b720d6 commit 38b6caf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2015
-1265
lines changed

.circleci/config.yml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ jobs:
3333
MYSQL_USER: jet
3434
MYSQL_PASSWORD: jet
3535

36+
- image: cockroachdb/cockroach-unstable:v22.1.0-beta.4
37+
command: ['start-single-node', '--insecure']
38+
environment:
39+
COCKROACH_USER: jet
40+
COCKROACH_PASSWORD: jet
41+
COCKROACH_DATABASE: jetdb
42+
3643
environment: # environment variables for the build itself
3744
TEST_RESULTS: /tmp/test-results # path to where test results will be saved
3845

@@ -82,7 +89,18 @@ jobs:
8289
echo -n .
8390
sleep 1
8491
done
85-
echo Failed waiting for MySQL && exit 1
92+
echo Failed waiting for MySQL && exit 1
93+
94+
- run:
95+
name: Waiting for Cockroach to be ready
96+
command: |
97+
for i in `seq 1 10`;
98+
do
99+
nc -z localhost 26257 && echo Success && exit 0
100+
echo -n .
101+
sleep 1
102+
done
103+
echo Failed waiting for Cockroach && exit 1
86104
87105
- run:
88106
name: Install MySQL CLI;
@@ -122,8 +140,9 @@ jobs:
122140
-coverpkg=github.com/go-jet/jet/v2/postgres/...,github.com/go-jet/jet/v2/mysql/...,github.com/go-jet/jet/v2/sqlite/...,github.com/go-jet/jet/v2/qrm/...,github.com/go-jet/jet/v2/generator/...,github.com/go-jet/jet/v2/internal/... \
123141
-coverprofile=cover.out 2>&1 | go-junit-report > $TEST_RESULTS/results.xml
124142
125-
# run mariaDB tests. No need to collect coverage, because coverage is already included with mysql tests
143+
# run mariaDB and cockroachdb tests. No need to collect coverage, because coverage is already included with mysql and postgres tests
126144
- run: MY_SQL_SOURCE=MariaDB go test -v ./tests/mysql/
145+
- run: PG_SOURCE=COCKROACH_DB go test -v ./tests/postgres/
127146

128147
- save_cache:
129148
key: go-mod-v4-{{ checksum "go.sum" }}

README.md

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
Jet is a complete solution for efficient and high performance database access, consisting of type-safe SQL builder
1111
with code generation and automatic query result data mapping.
12-
Jet currently supports `PostgreSQL`, `MySQL`, `MariaDB` and `SQLite`. Future releases will add support for additional databases.
12+
Jet currently supports `PostgreSQL`, `MySQL`, `CockroachDB`, `MariaDB` and `SQLite`. Future releases will add support for additional databases.
1313

1414
![jet](https://github.com/go-jet/jet/wiki/image/jet.png)
1515
Jet is the easiest, and the fastest way to write complex type-safe SQL queries as a Go code and map database query result
@@ -62,40 +62,37 @@ $ go get -u github.com/go-jet/jet/v2
6262

6363
Jet generator can be installed in one of the following ways:
6464

65-
1) (Go1.16+) Install jet generator using go install:
66-
```sh
67-
go install github.com/go-jet/jet/v2/cmd/jet@latest
68-
```
69-
70-
2) Install jet generator to GOPATH/bin folder:
71-
```sh
72-
cd $GOPATH/src/ && GO111MODULE=off go get -u github.com/go-jet/jet/cmd/jet
73-
```
65+
- (Go1.16+) Install jet generator using go install:
66+
```sh
67+
go install github.com/go-jet/jet/v2/cmd/jet@latest
68+
```
69+
*Jet generator is installed to the directory named by the GOBIN environment variable,
70+
which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH environment variable is not set.*
7471

75-
3) Install jet generator into specific folder:
76-
```sh
77-
git clone https://github.com/go-jet/jet.git
78-
cd jet && go build -o dir_path ./cmd/jet
79-
```
80-
*Make sure that the destination folder is added to the PATH environment variable.*
72+
- Install jet generator to specific folder:
73+
```sh
74+
git clone https://github.com/go-jet/jet.git
75+
cd jet && go build -o dir_path ./cmd/jet
76+
```
77+
*Make sure `dir_path` folder is added to the PATH environment variable.*
8178

8279

8380

8481
### Quick Start
8582
For this quick start example we will use PostgreSQL sample _'dvd rental'_ database. Full database dump can be found in
8683
[./tests/testdata/init/postgres/dvds.sql](https://github.com/go-jet/jet-test-data/blob/master/init/postgres/dvds.sql).
87-
Schema diagram of interest for example can be found [here](./examples/quick-start/diagram.png).
84+
Schema diagram of interest can be found [here](./examples/quick-start/diagram.png).
8885

8986
#### Generate SQL Builder and Model types
90-
To generate jet SQL Builder and Data Model types from postgres database, we need to call `jet` generator with postgres
91-
connection parameters and root destination folder path for generated files.
87+
To generate jet SQL Builder and Data Model types from running postgres database, we need to call `jet` generator with postgres
88+
connection parameters and destination folder path.
9289
Assuming we are running local postgres database, with user `user`, user password `pass`, database `jetdb` and
9390
schema `dvds` we will use this command:
9491
```sh
95-
jet -dsn=postgresql://user:pass@localhost:5432/jetdb -schema=dvds -path=./.gen
92+
jet -dsn=postgresql://user:pass@localhost:5432/jetdb?sslmode=disable -schema=dvds -path=./.gen
9693
```
9794
```sh
98-
Connecting to postgres database: postgresql://user:pass@localhost:5432/jetdb
95+
Connecting to postgres database: postgresql://user:pass@localhost:5432/jetdb?sslmode=disable
9996
Retrieving schema information...
10097
FOUND 15 table(s), 7 view(s), 1 enum(s)
10198
Cleaning up destination directory...
@@ -107,9 +104,10 @@ Generating view model files...
107104
Generating enum model files...
108105
Done
109106
```
110-
Procedure is similar for MySQL, MariaDB and SQLite. For instance:
107+
Procedure is similar for MySQL, CockroachDB, MariaDB and SQLite. For example:
111108
```sh
112109
jet -source=mysql -dsn="user:pass@tcp(localhost:3306)/dbname" -path=./gen
110+
jet -dsn=postgres://user:pass@localhost:26257/jetdb?sslmode=disable -schema=dvds -path=./.gen #cockroachdb
113111
jet -dsn="mariadb://user:pass@tcp(localhost:3306)/dvds" -path=./gen # source flag can be omitted if data source appears in dsn
114112
jet -source=sqlite -dsn="/path/to/sqlite/database/file" -schema=dvds -path=./gen
115113
jet -dsn="file:///path/to/sqlite/database/file" -schema=dvds -path=./gen # sqlite database assumed for 'file' data sources
@@ -168,7 +166,7 @@ and _film category_ is not 'Action'.
168166
stmt := SELECT(
169167
Actor.ActorID, Actor.FirstName, Actor.LastName, Actor.LastUpdate, // or just Actor.AllColumns
170168
Film.AllColumns,
171-
Language.AllColumns.Except(Language.LastUpdate),
169+
Language.AllColumns.Except(Language.LastUpdate), // all language columns except last_update
172170
Category.AllColumns,
173171
).FROM(
174172
Actor.
@@ -186,7 +184,7 @@ stmt := SELECT(
186184
Film.FilmID.ASC(),
187185
)
188186
```
189-
_Package(dot) import is used, so the statements would resemble as much as possible as native SQL._
187+
_Package(dot) import is used, so the statements look as close as possible to the native SQL._
190188
Note that every column has a type. String column `Language.Name` and `Category.Name` can be compared only with
191189
string columns and expressions. `Actor.ActorID`, `FilmActor.ActorID`, `Film.Length` are integer columns
192190
and can be compared only with integer columns and expressions.
@@ -245,7 +243,7 @@ __How to get debug SQL from statement?__
245243
```go
246244
debugSql := stmt.DebugSql()
247245
```
248-
debugSql - this query string can be copy-pasted to sql editor and executed. __It is not intended to be used in production, only for the purpose of debugging!!!__
246+
debugSql - this query string can be copy-pasted to sql editor and executed. __It is not intended to be used in production. For debug purposes only!!!__
249247

250248
<details>
251249
<summary>Click to see debug sql</summary>
@@ -295,8 +293,8 @@ First we have to create desired structure to store query result.
295293
This is done be combining autogenerated model types, or it can be done
296294
by combining custom model types(see [wiki](https://github.com/go-jet/jet/wiki/Query-Result-Mapping-(QRM)#custom-model-types) for more information).
297295

298-
It's possible to overwrite default jet generator behavior, and all the aspects of generated model and SQLBuilder types can be
299-
tailor-made([wiki](https://github.com/go-jet/jet/wiki/Generator#generator-customization)).
296+
_Note that it's possible to overwrite default jet generator behavior. All the aspects of generated model and SQLBuilder types can be
297+
tailor-made([wiki](https://github.com/go-jet/jet/wiki/Generator#generator-customization))._
300298

301299
Let's say this is our desired structure made of autogenerated types:
302300
```go
@@ -315,14 +313,14 @@ var dest []struct {
315313
`Langauge` field is just a single model struct. `Film` can belong to multiple categories.
316314
_*There is no limitation of how big or nested destination can be._
317315

318-
Now lets execute above statement on open database connection (or transaction) db and store result into `dest`.
316+
Now let's execute above statement on open database connection (or transaction) db and store result into `dest`.
319317

320318
```go
321319
err := stmt.Query(db, &dest)
322320
handleError(err)
323321
```
324322

325-
__And thats it.__
323+
__And that's it.__
326324

327325
`dest` now contains the list of all actors(with list of films acted, where each film has information about language and list of belonging categories) that acted in films longer than 180 minutes, film language is 'English'
328326
and film category is not 'Action'.
@@ -528,7 +526,7 @@ The biggest benefit is speed. Speed is being improved in 3 major areas:
528526

529527
##### Speed of development
530528

531-
Writing SQL queries is faster and easier as the developers have help of SQL code completion and SQL type safety directly from Go.
529+
Writing SQL queries is faster and easier, as developers will have help of SQL code completion and SQL type safety directly from Go code.
532530
Automatic scan to arbitrary structure removes a lot of headache and boilerplate code needed to structure database query result.
533531

534532
##### Speed of execution
@@ -539,14 +537,14 @@ Thus handler time lost on latency between server and database can be constant. H
539537
only to the query complexity and the number of rows returned from database.
540538

541539
With Jet, it is even possible to join the whole database and store the whole structured result in one database call.
542-
This is exactly what is being done in one of the tests: [TestJoinEverything](/tests/postgres/chinook_db_test.go#L40).
543-
The whole test database is joined and query result(~10,000 rows) is stored in a structured variable in less than 0.7s.
540+
This is exactly what is being done in one of the tests: [TestJoinEverything](https://github.com/go-jet/jet/blob/6706f4b228f51cf810129f57ba90bbdb60b85fe7/tests/postgres/chinook_db_test.go#L187).
541+
The whole test database is joined and query result(~10,000 rows) is stored in a structured variable in less than 0.5s.
544542

545543
##### How quickly bugs are found
546544

547545
The most expensive bugs are the one discovered on the production, and the least expensive are those found during development.
548546
With automatically generated type safe SQL, not only queries are written faster but bugs are found sooner.
549-
Lets return to quick start example, and take closer look at a line:
547+
Let's return to quick start example, and take closer look at a line:
550548
```go
551549
AND(Film.Length.GT(Int(180))),
552550
```
@@ -573,6 +571,8 @@ To run the tests, additional dependencies are required:
573571
- `github.com/stretchr/testify`
574572
- `github.com/google/go-cmp`
575573
- `github.com/jackc/pgx/v4`
574+
- `github.com/shopspring/decimal`
575+
- `github.com/volatiletech/null/v8`
576576

577577
## Versioning
578578

cmd/jet/main.go

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package main
33
import (
44
"flag"
55
"fmt"
6+
"os"
7+
"strings"
8+
69
"github.com/go-jet/jet/v2/generator/metadata"
710
sqlitegen "github.com/go-jet/jet/v2/generator/sqlite"
811
"github.com/go-jet/jet/v2/generator/template"
@@ -11,8 +14,6 @@ import (
1114
"github.com/go-jet/jet/v2/mysql"
1215
postgres2 "github.com/go-jet/jet/v2/postgres"
1316
"github.com/go-jet/jet/v2/sqlite"
14-
"os"
15-
"strings"
1617

1718
mysqlgen "github.com/go-jet/jet/v2/generator/mysql"
1819
postgresgen "github.com/go-jet/jet/v2/generator/postgres"
@@ -42,7 +43,7 @@ var (
4243
)
4344

4445
func init() {
45-
flag.StringVar(&source, "source", "", "Database system name (postgres, mysql, mariadb or sqlite)")
46+
flag.StringVar(&source, "source", "", "Database system name (postgres, mysql, cockroachdb, mariadb or sqlite)")
4647

4748
flag.StringVar(&dsn, "dsn", "", `Data source name. Unified format for connecting to database.
4849
PostgreSQL: https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING
@@ -59,7 +60,7 @@ func init() {
5960
flag.StringVar(&user, "user", "", "Database user. Used only if dsn is not set.")
6061
flag.StringVar(&password, "password", "", "The user’s password. Used only if dsn is not set.")
6162
flag.StringVar(&dbName, "dbname", "", "Database name. Used only if dsn is not set.")
62-
flag.StringVar(&schemaName, "schema", "public", `Database schema name. Used only if dsn is not set. (default "public")(PostgreSQL only)`)
63+
flag.StringVar(&schemaName, "schema", "public", `Database schema name. (default "public")(PostgreSQL only)`)
6364
flag.StringVar(&params, "params", "", "Additional connection string parameters(optional). Used only if dsn is not set.")
6465
flag.StringVar(&sslmode, "sslmode", "disable", `Whether or not to use SSL. Used only if dsn is not set. (optional)(default "disable")(PostgreSQL only)`)
6566
flag.StringVar(&ignoreTables, "ignore-tables", "", `Comma-separated list of tables to ignore`)
@@ -70,33 +71,7 @@ func init() {
7071
}
7172

7273
func main() {
73-
74-
flag.Usage = func() {
75-
fmt.Println("Jet generator 2.7.0")
76-
fmt.Println()
77-
fmt.Println("Usage:")
78-
79-
order := []string{
80-
"source", "dsn", "host", "port", "user", "password", "dbname", "schema", "params", "sslmode",
81-
"path",
82-
"ignore-tables", "ignore-views", "ignore-enums",
83-
}
84-
for _, name := range order {
85-
flagEntry := flag.CommandLine.Lookup(name)
86-
fmt.Printf(" -%s\n", flagEntry.Name)
87-
fmt.Printf("\t%s\n", flagEntry.Usage)
88-
}
89-
90-
fmt.Println()
91-
fmt.Println(`Example command:
92-
93-
$ jet -dsn=postgresql://jet:jet@localhost:5432/jetdb -schema=dvds -path=./gen
94-
$ jet -source=postgres -dsn="user=jet password=jet host=localhost port=5432 dbname=jetdb" -schema=dvds -path=./gen
95-
$ jet -source=mysql -host=localhost -port=3306 -user=jet -password=jet -dbname=jetdb -path=./gen
96-
$ jet -source=sqlite -dsn="file://path/to/sqlite/database/file" -path=./gen
97-
`)
98-
}
99-
74+
flag.Usage = usage
10075
flag.Parse()
10176

10277
if dsn == "" && (source == "" || host == "" || port == 0 || user == "" || dbName == "") {
@@ -111,11 +86,14 @@ func main() {
11186
var err error
11287

11388
switch source {
114-
case "postgresql", "postgres":
89+
case "postgresql", "postgres", "cockroachdb", "cockroach":
90+
generatorTemplate := genTemplate(postgres2.Dialect, ignoreTablesList, ignoreViewsList, ignoreEnumsList)
91+
11592
if dsn != "" {
116-
err = postgresgen.GenerateDSN(dsn, schemaName, destDir)
93+
err = postgresgen.GenerateDSN(dsn, schemaName, destDir, generatorTemplate)
11794
break
11895
}
96+
11997
dbConn := postgresgen.DBConnection{
12098
Host: host,
12199
Port: port,
@@ -131,14 +109,17 @@ func main() {
131109
err = postgresgen.Generate(
132110
destDir,
133111
dbConn,
134-
genTemplate(postgres2.Dialect, ignoreTablesList, ignoreViewsList, ignoreEnumsList),
112+
generatorTemplate,
135113
)
136114

137115
case "mysql", "mysqlx", "mariadb":
116+
generatorTemplate := genTemplate(mysql.Dialect, ignoreTablesList, ignoreViewsList, ignoreEnumsList)
117+
138118
if dsn != "" {
139-
err = mysqlgen.GenerateDSN(dsn, destDir)
119+
err = mysqlgen.GenerateDSN(dsn, destDir, generatorTemplate)
140120
break
141121
}
122+
142123
dbConn := mysqlgen.DBConnection{
143124
Host: host,
144125
Port: port,
@@ -151,12 +132,13 @@ func main() {
151132
err = mysqlgen.Generate(
152133
destDir,
153134
dbConn,
154-
genTemplate(mysql.Dialect, ignoreTablesList, ignoreViewsList, ignoreEnumsList),
135+
generatorTemplate,
155136
)
156137
case "sqlite":
157138
if dsn == "" {
158139
printErrorAndExit("ERROR: required -dsn flag missing.")
159140
}
141+
160142
err = sqlitegen.GenerateDSN(
161143
dsn,
162144
destDir,
@@ -176,6 +158,34 @@ func main() {
176158
}
177159
}
178160

161+
func usage() {
162+
fmt.Println("Jet generator 2.8.0")
163+
fmt.Println()
164+
fmt.Println("Usage:")
165+
166+
order := []string{
167+
"source", "dsn", "host", "port", "user", "password", "dbname", "schema", "params", "sslmode",
168+
"path",
169+
"ignore-tables", "ignore-views", "ignore-enums",
170+
}
171+
172+
for _, name := range order {
173+
flagEntry := flag.CommandLine.Lookup(name)
174+
fmt.Printf(" -%s\n", flagEntry.Name)
175+
fmt.Printf("\t%s\n", flagEntry.Usage)
176+
}
177+
178+
fmt.Println()
179+
fmt.Println(`Example command:
180+
181+
$ jet -dsn=postgresql://jet:jet@localhost:5432/jetdb?sslmode=disable -schema=dvds -path=./gen
182+
$ jet -dsn=postgres://jet:jet@localhost:26257/jetdb?sslmode=disable -schema=dvds -path=./gen #cockroachdb
183+
$ jet -source=postgres -dsn="user=jet password=jet host=localhost port=5432 dbname=jetdb" -schema=dvds -path=./gen
184+
$ jet -source=mysql -host=localhost -port=3306 -user=jet -password=jet -dbname=jetdb -path=./gen
185+
$ jet -source=sqlite -dsn="file://path/to/sqlite/database/file" -path=./gen
186+
`)
187+
}
188+
179189
func printErrorAndExit(error string) {
180190
fmt.Println("\n", error)
181191
fmt.Println()

examples/quick-start/.gen/jetdb/dvds/table/actor.go

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)