Add wiki Generator page.
This commit is contained in:
parent
b3ec1139b5
commit
3516d2861c
5 changed files with 298 additions and 13 deletions
|
|
@ -447,8 +447,8 @@ In those cases web server handler execution time is directly proportional to lat
|
||||||
This is not such a big problem if handler calls database couple of times, but what if web server is using ORM to retrieve all data from database.
|
This is not such a big problem if handler calls database couple of times, but what if web server is using ORM to retrieve all data from database.
|
||||||
ORM usually access the database once for every object needed.
|
ORM usually access the database once for every object needed.
|
||||||
Now lets say latency is 30ms and there are 100 different objects required from the database. This handler will last 3s !!!.
|
Now lets say latency is 30ms and there are 100 different objects required from the database. This handler will last 3s !!!.
|
||||||
With Jet, handler time lost on latency between server and database is constant(because we can write complex query and return result in one database call),
|
With Jet, handler time lost on latency between server and database is constant. Because we can write complex query and
|
||||||
and handler execution will be proportional to number or rows returned from database.
|
return result in one database call. Handler execution will be proportional to number or rows returned from database.
|
||||||
ORM example replaced with jet will take just 30ms + 'result scan time' = 31ms (rough estimate).
|
ORM example replaced with jet will take just 30ms + 'result scan time' = 31ms (rough estimate).
|
||||||
|
|
||||||
With Jet you can even join the whole database and store the whole structured result in in one query call.
|
With Jet you can even join the whole database and store the whole structured result in in one query call.
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ import (
|
||||||
"github.com/go-jet/jet"
|
"github.com/go-jet/jet"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var {{camelize .Name}} = new{{.GoStructName}}()
|
||||||
|
|
||||||
type {{.GoStructName}} struct {
|
type {{.GoStructName}} struct {
|
||||||
jet.Table
|
jet.Table
|
||||||
|
|
||||||
|
|
@ -37,7 +39,14 @@ type {{.GoStructName}} struct {
|
||||||
AllColumns jet.ColumnList
|
AllColumns jet.ColumnList
|
||||||
}
|
}
|
||||||
|
|
||||||
var {{camelize .Name}} = new{{.GoStructName}}()
|
// creates new {{.GoStructName}} with assigned alias
|
||||||
|
func (a *{{.GoStructName}}) AS(alias string) *{{.GoStructName}} {
|
||||||
|
aliasTable := new{{.GoStructName}}()
|
||||||
|
|
||||||
|
aliasTable.Table.AS(alias)
|
||||||
|
|
||||||
|
return aliasTable
|
||||||
|
}
|
||||||
|
|
||||||
func new{{.GoStructName}}() *{{.GoStructName}} {
|
func new{{.GoStructName}}() *{{.GoStructName}} {
|
||||||
var (
|
var (
|
||||||
|
|
@ -58,14 +67,6 @@ func new{{.GoStructName}}() *{{.GoStructName}} {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *{{.GoStructName}}) AS(alias string) *{{.GoStructName}} {
|
|
||||||
aliasTable := new{{.GoStructName}}()
|
|
||||||
|
|
||||||
aliasTable.Table.AS(alias)
|
|
||||||
|
|
||||||
return aliasTable
|
|
||||||
}
|
|
||||||
|
|
||||||
`
|
`
|
||||||
|
|
||||||
var dataModelTemplate = `package model
|
var dataModelTemplate = `package model
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
postgres_generator "github.com/go-jet/jet/generator/postgresgen"
|
"github.com/go-jet/jet/generator/postgresgen"
|
||||||
"github.com/go-jet/jet/tests/dbconfig"
|
"github.com/go-jet/jet/tests/dbconfig"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
)
|
)
|
||||||
|
|
@ -33,7 +33,7 @@ func main() {
|
||||||
|
|
||||||
_, err = db.Exec(string(testSampleSql))
|
_, err = db.Exec(string(testSampleSql))
|
||||||
|
|
||||||
err = postgres_generator.Generate("./.gentestdata", postgres_generator.DBConnection{
|
err = postgresgen.Generate("./.gentestdata", postgresgen.DBConnection{
|
||||||
Host: dbconfig.Host,
|
Host: dbconfig.Host,
|
||||||
Port: "5432",
|
Port: "5432",
|
||||||
User: dbconfig.User,
|
User: dbconfig.User,
|
||||||
|
|
|
||||||
271
wiki/Generator.md
Normal file
271
wiki/Generator.md
Normal file
|
|
@ -0,0 +1,271 @@
|
||||||
|
|
||||||
|
Before we can write SQL queries in Go we have to generate necessary Go files.
|
||||||
|
To generate files we need running database instance containing already defined database schema.
|
||||||
|
|
||||||
|
This files can be generated in two ways:
|
||||||
|
|
||||||
|
#### Generating from command line
|
||||||
|
|
||||||
|
Install jetgen to GOPATH bin folder. This will allow generating jet files from the command line.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go install github.com/go-jet/jet/cmd/jetgen
|
||||||
|
```
|
||||||
|
|
||||||
|
Make sure GOPATH bin folder is added to the PATH environment variable.
|
||||||
|
|
||||||
|
Test jetgen can be found in the PATH.
|
||||||
|
```sh
|
||||||
|
jetgen -h
|
||||||
|
Usage of jetgen:
|
||||||
|
-host string
|
||||||
|
Database host path (Example: localhost)
|
||||||
|
-port string
|
||||||
|
Database port
|
||||||
|
-user string
|
||||||
|
Database user
|
||||||
|
-password string
|
||||||
|
The user’s password
|
||||||
|
-dbname string
|
||||||
|
name of the database
|
||||||
|
-schema string
|
||||||
|
Database schema name. (default "public")
|
||||||
|
-path string
|
||||||
|
Destination dir for generated files.
|
||||||
|
-sslmode string
|
||||||
|
Whether or not to use SSL(optional) (default "disable")
|
||||||
|
-params string
|
||||||
|
Additional connection string parameters(optional)
|
||||||
|
```
|
||||||
|
|
||||||
|
Now to generate sample database:
|
||||||
|
```sh
|
||||||
|
jetgen -host=localhost -port=5432 -user=jet -password=jet -dbname=jetdb -schema dvds -path ./gen
|
||||||
|
```
|
||||||
|
```sh
|
||||||
|
Connecting to postgres database: host=localhost port=5432 user=jet password=jet dbname=jetdb sslmode=disable
|
||||||
|
Retrieving schema information...
|
||||||
|
FOUND 15 table(s), 1 enum(s)
|
||||||
|
Cleaning up destination directory...
|
||||||
|
Generating table sql builder files...
|
||||||
|
Generating table model files...
|
||||||
|
Generating enum sql builder files...
|
||||||
|
Generating enum model files...
|
||||||
|
Done
|
||||||
|
```
|
||||||
|
#### Generating from code
|
||||||
|
|
||||||
|
```
|
||||||
|
import "github.com/go-jet/jet/generator/postgresgen"
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
err = postgresgen.Generate("./gen", postgresgen.DBConnection{
|
||||||
|
Host: "localhost",
|
||||||
|
Port: "5432",
|
||||||
|
User: "jet",
|
||||||
|
Password: "jet",
|
||||||
|
DBName: "jetdb",
|
||||||
|
SchemaName: "dvds",
|
||||||
|
SslMode: "disable",
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
In both ways, generator will:
|
||||||
|
- connect to postgres database and retrieve information about the tables and enums of `dvds` schema
|
||||||
|
- delete everything in destination folder `./gen`,
|
||||||
|
- generate sql builder and model Go files for each schema tables and enums into destination folder `./gen`.
|
||||||
|
|
||||||
|
Generated files folder structure will look like this:
|
||||||
|
```sh
|
||||||
|
|-- gen # destination folder
|
||||||
|
| `-- jetdb # database name
|
||||||
|
| `-- dvds # schema name
|
||||||
|
| |-- enum # sql builder folder for enums
|
||||||
|
| | |-- mpaa_rating.go
|
||||||
|
| |-- table # sql builder folder for tables
|
||||||
|
| |-- actor.go
|
||||||
|
| |-- address.go
|
||||||
|
| |-- film.go
|
||||||
|
...
|
||||||
|
| |-- model # Plain Old Data for every enum and table
|
||||||
|
| | |-- actor.go
|
||||||
|
| | |-- address.go
|
||||||
|
| | |-- film.go
|
||||||
|
...
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Table and enums from database schema are used as a template to generate two types of Go files:
|
||||||
|
* SQL builder files: Files used to write type safe SQL statements in Go (enum and table package)
|
||||||
|
* Model files: Files used to store result from database queries (model package)
|
||||||
|
|
||||||
|
#### SQL builder files
|
||||||
|
Part of the sample sql builder file for table `film`.
|
||||||
|
|
||||||
|
```
|
||||||
|
package table
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-jet/jet"
|
||||||
|
)
|
||||||
|
var Film = newFilmTable()
|
||||||
|
|
||||||
|
type FilmTable struct {
|
||||||
|
jet.Table
|
||||||
|
|
||||||
|
//Columns
|
||||||
|
FilmID jet.ColumnInteger
|
||||||
|
Title jet.ColumnString
|
||||||
|
Description jet.ColumnString
|
||||||
|
ReleaseYear jet.ColumnInteger
|
||||||
|
LanguageID jet.ColumnInteger
|
||||||
|
RentalDuration jet.ColumnInteger
|
||||||
|
RentalRate jet.ColumnFloat
|
||||||
|
Length jet.ColumnInteger
|
||||||
|
ReplacementCost jet.ColumnFloat
|
||||||
|
Rating jet.ColumnString
|
||||||
|
LastUpdate jet.ColumnTimestamp
|
||||||
|
SpecialFeatures jet.ColumnString
|
||||||
|
Fulltext jet.ColumnString
|
||||||
|
|
||||||
|
AllColumns jet.ColumnList
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates new FilmTable with assigned alias
|
||||||
|
func (a *FilmTable) AS(alias string) *FilmTable {
|
||||||
|
aliasTable := newFilmTable()
|
||||||
|
|
||||||
|
aliasTable.Table.AS(alias)
|
||||||
|
|
||||||
|
return aliasTable
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Table name and column names are camelized inside sql builder type.
|
||||||
|
`AllColumns` is used as shorthand notation for list of all columns `FilmID, Title, Description,...`.
|
||||||
|
|
||||||
|
Mappings of database types to sql builder column types are following:
|
||||||
|
|
||||||
|
| Database type(postgres) | Sql builder column type |
|
||||||
|
| ----------------------------------------------- | -------------------------------------------------- |
|
||||||
|
| boolean | ColumnBool |
|
||||||
|
| smallint, integer, bigint | ColumnInteger |
|
||||||
|
| real, numeric, decimal, double precision | ColumnFloat |
|
||||||
|
| date | ColumnDate |
|
||||||
|
| timestamp without time zone | ColumnTimestamp |
|
||||||
|
| timestamp with time zone | ColumnTimestampz |
|
||||||
|
| time without time zone | ColumnTime |
|
||||||
|
| time with time zone | ColumnTimez |
|
||||||
|
| enums, text, character, character varying | |
|
||||||
|
| bytea, uuid | |
|
||||||
|
| and all remaining types | ColumnString |
|
||||||
|
|
||||||
|
Sql builder file for enum type `mpaa_rating`:
|
||||||
|
```
|
||||||
|
package enum
|
||||||
|
|
||||||
|
import "github.com/go-jet/jet"
|
||||||
|
|
||||||
|
var MpaaRating = &struct {
|
||||||
|
G jet.StringExpression
|
||||||
|
PG jet.StringExpression
|
||||||
|
PG13 jet.StringExpression
|
||||||
|
R jet.StringExpression
|
||||||
|
NC17 jet.StringExpression
|
||||||
|
}{
|
||||||
|
G: jet.NewEnumValue("G"),
|
||||||
|
PG: jet.NewEnumValue("PG"),
|
||||||
|
PG13: jet.NewEnumValue("PG-13"),
|
||||||
|
R: jet.NewEnumValue("R"),
|
||||||
|
NC17: jet.NewEnumValue("NC-17"),
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
#### Model files
|
||||||
|
|
||||||
|
Sample model file for table `film`:
|
||||||
|
```
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Film struct {
|
||||||
|
FilmID int32 `sql:"primary_key"`
|
||||||
|
Title string
|
||||||
|
Description *string
|
||||||
|
ReleaseYear *int32
|
||||||
|
LanguageID int16
|
||||||
|
RentalDuration int16
|
||||||
|
RentalRate float64
|
||||||
|
Length *int16
|
||||||
|
ReplacementCost float64
|
||||||
|
Rating *MpaaRating
|
||||||
|
LastUpdate time.Time
|
||||||
|
SpecialFeatures *string
|
||||||
|
Fulltext string
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
For every column of table `film` there is appropriate field in model type.
|
||||||
|
Fields corresponding to primary key columns are tagged with `sql:"primary_key"`.
|
||||||
|
This tag is used during query execution to group row results into desired arbitrary structure. See more at TODO:
|
||||||
|
Fields are pointer types, if they relate to column that can be NULL.
|
||||||
|
|
||||||
|
Mappings of database types to Go types:
|
||||||
|
|
||||||
|
| Database type(postgres) | Go type |
|
||||||
|
| ----------------------------------------------- | -------------------------------------------------- |
|
||||||
|
| boolean | bool |
|
||||||
|
| smallint | int16 |
|
||||||
|
| integer | int32 |
|
||||||
|
| bigint | int64 |
|
||||||
|
| real | float32 |
|
||||||
|
| numeric, decimal, double precision | float64 |
|
||||||
|
| date, timestamp, time(with or without timezone) | time.Time |
|
||||||
|
| bytea | []byte |
|
||||||
|
| uuid | uuid.UUID |
|
||||||
|
| enum | enum name |
|
||||||
|
| text, character, character varying, | |
|
||||||
|
| and all remaining types | string |
|
||||||
|
|
||||||
|
|
||||||
|
Part of the sample model file for enum `mpaa_rating`:
|
||||||
|
|
||||||
|
```
|
||||||
|
package model
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
type MpaaRating string
|
||||||
|
|
||||||
|
const (
|
||||||
|
MpaaRating_G MpaaRating = "G"
|
||||||
|
MpaaRating_PG MpaaRating = "PG"
|
||||||
|
MpaaRating_PG13 MpaaRating = "PG-13"
|
||||||
|
MpaaRating_R MpaaRating = "R"
|
||||||
|
MpaaRating_NC17 MpaaRating = "NC-17"
|
||||||
|
)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
For a reference SQL table definition of table `film`:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE dvds.film (
|
||||||
|
film_id integer DEFAULT nextval('dvds.film_film_id_seq'::regclass) NOT NULL,
|
||||||
|
title character varying(255) NOT NULL,
|
||||||
|
description text,
|
||||||
|
release_year dvds.year,
|
||||||
|
language_id smallint NOT NULL,
|
||||||
|
rental_duration smallint DEFAULT 3 NOT NULL,
|
||||||
|
rental_rate numeric(4,2) DEFAULT 4.99 NOT NULL,
|
||||||
|
length smallint,
|
||||||
|
replacement_cost numeric(5,2) DEFAULT 19.99 NOT NULL,
|
||||||
|
rating dvds.mpaa_rating DEFAULT 'G'::dvds.mpaa_rating,
|
||||||
|
last_update timestamp without time zone DEFAULT now() NOT NULL,
|
||||||
|
special_features text[],
|
||||||
|
fulltext tsvector NOT NULL
|
||||||
|
);
|
||||||
|
```
|
||||||
13
wiki/Installation.md
Normal file
13
wiki/Installation.md
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
To install Jet package, you need to install Go and set your Go workspace first.
|
||||||
|
|
||||||
|
[Go](https://golang.org/) **version 1.8+ is required**
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
Use the bellow command to install jet
|
||||||
|
```sh
|
||||||
|
$ go get -u github.com/go-jet/jet
|
||||||
|
```
|
||||||
Loading…
Add table
Add a link
Reference in a new issue