Update Readme.

This commit is contained in:
go-jet 2021-10-22 18:21:42 +02:00
parent a50d89ff9d
commit 776f308273

View file

@ -9,17 +9,17 @@
Jet is a complete solution for efficient and high performance database access, consisting of type-safe SQL builder Jet is a complete solution for efficient and high performance database access, consisting of type-safe SQL builder
with code generation and automatic query result data mapping. with code generation and automatic query result data mapping.
Jet currently supports `PostgreSQL`, `MySQL` and `MariaDB`. Future releases will add support for additional databases. Jet currently supports `PostgreSQL`, `MySQL`, `MariaDB` and `SQLite`. Future releases will add support for additional databases.
![jet](https://github.com/go-jet/jet/wiki/image/jet.png) ![jet](https://github.com/go-jet/jet/wiki/image/jet.png)
Jet is the easiest and the fastest way to write complex type-safe SQL queries as a Go code and map database query result Jet is the easiest, and the fastest way to write complex type-safe SQL queries as a Go code and map database query result
into complex object composition. __It is not an ORM.__ into complex object composition. __It is not an ORM.__
## Motivation ## Motivation
https://medium.com/@go.jet/jet-5f3667efa0cc https://medium.com/@go.jet/jet-5f3667efa0cc
## Contents ## Contents
- [Features](#features) - [Features](#features)
- [Getting Started](#getting-started) - [Getting Started](#getting-started)
- [Prerequisites](#prerequisites) - [Prerequisites](#prerequisites)
- [Installation](#installation) - [Installation](#installation)
@ -33,24 +33,17 @@ https://medium.com/@go.jet/jet-5f3667efa0cc
- [License](#license) - [License](#license)
## Features ## Features
1) Auto-generated type-safe SQL Builder 1) Auto-generated type-safe SQL Builder. Statements supported:
- PostgreSQL: * [SELECT](https://github.com/go-jet/jet/wiki/SELECT) `(DISTINCT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, OFFSET, FOR, LOCK_IN_SHARE_MODE, UNION, INTERSECT, EXCEPT, WINDOW, sub-queries)`
* [SELECT](https://github.com/go-jet/jet/wiki/SELECT) `(DISTINCT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, OFFSET, FOR, UNION, INTERSECT, EXCEPT, WINDOW, sub-queries)` * [INSERT](https://github.com/go-jet/jet/wiki/INSERT) `(VALUES, MODEL, MODELS, QUERY, ON_CONFLICT/ON_DUPLICATE_KEY_UPDATE, RETURNING)`,
* [INSERT](https://github.com/go-jet/jet/wiki/INSERT) `(VALUES, MODEL, MODELS, QUERY, ON_CONFLICT, RETURNING)`,
* [UPDATE](https://github.com/go-jet/jet/wiki/UPDATE) `(SET, MODEL, WHERE, RETURNING)`, * [UPDATE](https://github.com/go-jet/jet/wiki/UPDATE) `(SET, MODEL, WHERE, RETURNING)`,
* [DELETE](https://github.com/go-jet/jet/wiki/DELETE) `(WHERE, RETURNING)`, * [DELETE](https://github.com/go-jet/jet/wiki/DELETE) `(WHERE, ORDER_BY, LIMIT, RETURNING)`,
* [LOCK](https://github.com/go-jet/jet/wiki/LOCK) `(IN, NOWAIT)` * [LOCK](https://github.com/go-jet/jet/wiki/LOCK) `(IN, NOWAIT)`, `(READ, WRITE)`
* [WITH](https://github.com/go-jet/jet/wiki/WITH)
- MySQL and MariaDB:
* [SELECT](https://github.com/go-jet/jet/wiki/SELECT) `(DISTINCT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, OFFSET, FOR, UNION, LOCK_IN_SHARE_MODE, WINDOW, sub-queries)`
* [INSERT](https://github.com/go-jet/jet/wiki/INSERT) `(VALUES, MODEL, MODELS, ON_DUPLICATE_KEY_UPDATE, query)`,
* [UPDATE](https://github.com/go-jet/jet/wiki/UPDATE) `(SET, MODEL, WHERE)`,
* [DELETE](https://github.com/go-jet/jet/wiki/DELETE) `(WHERE, ORDER_BY, LIMIT)`,
* [LOCK](https://github.com/go-jet/jet/wiki/LOCK) `(READ, WRITE)`
* [WITH](https://github.com/go-jet/jet/wiki/WITH) * [WITH](https://github.com/go-jet/jet/wiki/WITH)
2) Auto-generated Data Model types - Go types mapped to database type (table, view or enum), used to store 2) Auto-generated Data Model types - Go types mapped to database type (table, view or enum), used to store
result of database queries. Can be combined to create desired query result destination. result of database queries. Can be combined to create desired query result destination.
3) Query execution with result mapping to arbitrary destination structure. 3) Query execution with result mapping to arbitrary destination.
## Getting Started ## Getting Started
@ -100,7 +93,7 @@ connection parameters and root destination folder path for generated files.\
Assuming we are running local postgres database, with user `jetuser`, user password `jetpass`, database `jetdb` and Assuming we are running local postgres database, with user `jetuser`, user password `jetpass`, database `jetdb` and
schema `dvds` we will use this command: schema `dvds` we will use this command:
```sh ```sh
jet -source=PostgreSQL -host=localhost -port=5432 -user=jetuser -password=jetpass -dbname=jetdb -schema=dvds -path=./.gen jet -dsn=postgresql://jetuser:jetpass@localhost:5432/jetdb -schema=dvds -path=./.gen
``` ```
```sh ```sh
Connecting to postgres database: host=localhost port=5432 user=jetuser password=jetpass dbname=jetdb sslmode=disable Connecting to postgres database: host=localhost port=5432 user=jetuser password=jetpass dbname=jetdb sslmode=disable
@ -115,8 +108,13 @@ Generating view model files...
Generating enum model files... Generating enum model files...
Done Done
``` ```
Procedure is similar for MySQL or MariaDB, except source should be replaced with `MySql` or `MariaDB` and schema name should Procedure is similar for MySQL, MariaDB and SQLite. For instance:
be omitted (both databases doesn't have schema support). ```sh
jet -source=mysql -dsn="jet:jet@tcp(localhost:3306)/dvds" -path=./gen
jet -dsn="mariadb://jet:jet@tcp(localhost:3306)/dvds" -path=./gen # source flag can be omitted if data source is the same as database
jet -source=sqlite -dsn="/path/to/sqlite/database/file" -schema=dvds -path=./gen
jet -dsn="file:///path/to/sqlite/database/file" -schema=dvds -path=./gen # sqlite database assumed for 'file' data sources
```
_*User has to have a permission to read information schema tables._ _*User has to have a permission to read information schema tables._
As command output suggest, Jet will: As command output suggest, Jet will:
@ -189,7 +187,7 @@ stmt := SELECT(
Film.FilmID.ASC(), Film.FilmID.ASC(),
) )
``` ```
_Package(dot) import is used so that statement would resemble as much as possible as native SQL._ _Package(dot) import is used, so the statements would resemble as much as possible as native SQL._
Note that every column has a type. String column `Language.Name` and `Category.Name` can be compared only with Note that every column has a type. String column `Language.Name` and `Category.Name` can be compared only with
string columns and expressions. `Actor.ActorID`, `FilmActor.ActorID`, `Film.Length` are integer columns string columns and expressions. `Actor.ActorID`, `FilmActor.ActorID`, `Film.Length` are integer columns
and can be compared only with integer columns and expressions. and can be compared only with integer columns and expressions.
@ -291,14 +289,14 @@ ORDER BY actor.actor_id ASC, film.film_id ASC;
#### Execute query and store result #### Execute query and store result
Well formed SQL is just a first half of the job. Lets see how can we make some sense of result set returned executing Well formed SQL is just a first half of the job. Let's see how can we make some sense of result set returned executing
above statement. Usually this is the most complex and tedious work, but with Jet it is the easiest. above statement. Usually this is the most complex and tedious work, but with Jet it is the easiest.
First we have to create desired structure to store query result. First we have to create desired structure to store query result.
This is done be combining autogenerated model types or it can be done This is done be combining autogenerated model types or it can be done
manually(see [wiki](https://github.com/go-jet/jet/wiki/Query-Result-Mapping-(QRM)) for more information). by combining custom model files(see [wiki](https://github.com/go-jet/jet/wiki/Query-Result-Mapping-(QRM)) for more information).
Let's say this is our desired structure: Let's say this is our desired structure made of autogenerated types:
```go ```go
var dest []struct { var dest []struct {
model.Actor model.Actor
@ -315,7 +313,7 @@ var dest []struct {
`Langauge` field is just a single model struct. `Film` can belong to multiple categories. `Langauge` field is just a single model struct. `Film` can belong to multiple categories.
_*There is no limitation of how big or nested destination can be._ _*There is no limitation of how big or nested destination can be._
Now lets execute a above statement on open database connection (or transaction) db and store result into `dest`. Now lets execute above statement on open database connection (or transaction) db and store result into `dest`.
```go ```go
err := stmt.Query(db, &dest) err := stmt.Query(db, &dest)
@ -524,7 +522,7 @@ found at project [Wiki](https://github.com/go-jet/jet/wiki) page.
## Benefits ## Benefits
What are the benefits of writing SQL in Go using Jet? What are the benefits of writing SQL in Go using Jet?
The biggest benefit is speed. Speed is improved in 3 major areas: The biggest benefit is speed. Speed is being improved in 3 major areas:
##### Speed of development ##### Speed of development
@ -538,32 +536,34 @@ Jet will always perform better as developers can write complex query and retriev
Thus handler time lost on latency between server and database can be constant. Handler execution will be proportional Thus handler time lost on latency between server and database can be constant. Handler execution will be proportional
only to the query complexity and the number of rows returned from database. only to the query complexity and the number of rows returned from database.
With Jet it is even possible to join the whole database and store the whole structured result in one database call. With Jet, it is even possible to join the whole database and store the whole structured result in one database call.
This is exactly what is being done in one of the tests: [TestJoinEverything](/tests/postgres/chinook_db_test.go#L40). This is exactly what is being done in one of the tests: [TestJoinEverything](/tests/postgres/chinook_db_test.go#L40).
The whole test database is joined and query result(~10,000 rows) is stored in a structured variable in less than 0.7s. The whole test database is joined and query result(~10,000 rows) is stored in a structured variable in less than 0.7s.
##### How quickly bugs are found ##### How quickly bugs are found
The most expensive bugs are the one on the production and the least expensive are those found during development. The most expensive bugs are the one discovered on the production, and the least expensive are those found during development.
With automatically generated type safe SQL, not only queries are written faster but bugs are found sooner. With automatically generated type safe SQL, not only queries are written faster but bugs are found sooner.
Lets return to quick start example, and take closer look at a line: Lets return to quick start example, and take closer look at a line:
```go ```go
AND(Film.Length.GT(Int(180))), AND(Film.Length.GT(Int(180))),
``` ```
Lets say someone changes column `length` to `duration` from `film` table. The next go build will fail at that line and Let's say someone changes column `length` to `duration` from `film` table. The next go build will fail at that line, and
the bug will be caught at compile time. the bug will be caught at compile time.
Lets say someone changes the type of `length` column to some non integer type. Build will also fail at the same line Let's say someone changes the type of `length` column to some non integer type. Build will also fail at the same line
because integer columns and expressions can be only compered to other integer columns and expressions. because integer columns and expressions can be only compared to other integer columns and expressions.
Build will also fail if someone removes `length` column from `film` table, because `Film` field will be omitted from SQL Builder and Model types, next time `jet` generator is run. Build will also fail if someone removes `length` column from `film` table. `Film` field will be omitted from SQL Builder and Model types,
next time `jet` generator is run.
Without Jet these bugs will have to be either caught by some test or by manual testing. Without Jet these bugs will have to be either caught by some test or by manual testing.
## Dependencies ## Dependencies
At the moment Jet dependence only of: At the moment Jet dependence only of:
- `github.com/lib/pq` _(Used by jet generator to read information about database schema from `PostgreSQL`)_ - `github.com/lib/pq` _(Used by jet generator to read `PostgreSQL` database information)_
- `github.com/go-sql-driver/mysql` _(Used by jet generator to read information about database from `MySQL` and `MariaDB`)_ - `github.com/go-sql-driver/mysql` _(Used by jet generator to read `MySQL` and `MariaDB` database information)_
- `github.com/mattn/go-sqlite3` _(Used by jet generator to read `SQLite` database information)_
- `github.com/google/uuid` _(Used in data model files and for debug purposes)_ - `github.com/google/uuid` _(Used in data model files and for debug purposes)_
To run the tests, additional dependencies are required: To run the tests, additional dependencies are required: