diff --git a/.circleci/config.yml b/.circleci/config.yml index c040498..cc6b208 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -28,9 +28,10 @@ jobs: command: | go get github.com/google/uuid go get github.com/lib/pq - go get github.com/pkg/profile go get gotest.tools/assert + go get github.com/onsi/ginkgo + go get github.com/onsi/gomega go get github.com/davecgh/go-spew/spew go get github.com/jstemmer/go-junit-report diff --git a/README.md b/README.md index 87e71b0..d24c142 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Jet enables writing type safe SQL queries in Go, and has ability to convert data - [Generate sql builder and model files](#generate-sql-builder-and-model-files) - [Lets write some SQL queries in Go](#lets-write-some-sql-queries-in-go) - [Benefits](#benefits) + - [Dependencies](#dependencies) - [Versioning](#versioning) ## Features @@ -471,6 +472,9 @@ because integer columns and expressions can be only compered to other integer co Without Jet these bugs will have to be either caught by some test or by manual testing. +## Dependencies +TODO: + ## Contributing ## Versioning diff --git a/wiki/Generator.md b/wiki/Generator.md index 8d44dc7..45be3db 100644 --- a/wiki/Generator.md +++ b/wiki/Generator.md @@ -181,91 +181,3 @@ var MpaaRating = &struct { } ``` -#### 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`: - -``` -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 -); -``` diff --git a/wiki/Model-data.md b/wiki/Model-data.md new file mode 100644 index 0000000..c0678cf --- /dev/null +++ b/wiki/Model-data.md @@ -0,0 +1,140 @@ +## Model files + +Model files are simple data files used to store result of SQL queries. They are +autogenerated from to database tables and enums. + +### Table model files + +Following rules are applied to generate model files from database tables: + +- for every table there is one Go file generated. File name is in snake case of the table name. +- every model file contains one struct type. + Type name is a camel case of table name. +- for every column of table there is a field in model struct. Field name is camel case of column name. +See below table for type mapping. +- fields are pointer types, if they relate to column that can be NULL. +- fields corresponds 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 [Execution](https://github.com/go-jet/jet/wiki/Execution):_ + + +##### 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 | + +#### Example: + +Sql table `address`: +``` +CREATE TABLE dvds.address +( + address_id serial NOT NULL DEFAULT, + address character varying(50) NOT NULL, + address2 character varying(50), + district character varying(20) NOT NULL, + city_id smallint NOT NULL, + postal_code character varying(10), + phone character varying(20) NOT NULL, + last_update timestamp without time zone NOT NULL DEFAULT now(), + CONSTRAINT address_pkey PRIMARY KEY (address_id) +) +``` + +Autogenerated model file `address.go`: + +``` +package model + +import ( + "time" +) + +type Address struct { + AddressID int32 `sql:"primary_key"` + Address string + Address2 *string + District string + CityID int16 + PostalCode *string + Phone string + LastUpdate time.Time +} +``` + +### Enum model files + +Following rules are applied to generate model files from database enums: + +- for every enum there is one Go file generated. File name is a snake case of enum name. +- every file contains one renamed string type. Type name is a camel case of enum name. +Enum type has two helper methods to: + - initialize correctly from database query result + - easily convert enum to string. +- for every enum value there is one constant defined. +Name of the constant is in format [camel case of enum_name]_[camel case of enum_value_name]. + +#### Example + +Enum `mpaa_rating`: +``` +CREATE TYPE dvds.mpaa_rating AS ENUM + ('G', 'PG', 'PG-13', 'R', 'NC-17'); +``` + +Autogenerated model file `mpaa_rating.go` + +``` +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" +) + +func (e *MpaaRating) Scan(value interface{}) error { + if v, ok := value.(string); !ok { + return errors.New("Invalid data for MpaaRating enum") + } else { + switch string(v) { + case "G": + *e = MpaaRating_G + case "PG": + *e = MpaaRating_Pg + case "PG-13": + *e = MpaaRating_Pg13 + case "R": + *e = MpaaRating_R + case "NC-17": + *e = MpaaRating_Nc17 + default: + return errors.New("Inavlid data " + string(v) + "for MpaaRating enum") + } + + return nil + } +} + +func (e MpaaRating) String() string { + return string(e) +} +``` diff --git a/wiki/SELECT.md b/wiki/SELECT.md index 5a6068d..d111c87 100644 --- a/wiki/SELECT.md +++ b/wiki/SELECT.md @@ -224,7 +224,7 @@ rRatingFilms := Film. WHERE(Film.Rating.EQ(enum.MpaaRating.R)). AsTable("rFilms") ``` -`AsTable("rFilms")` - allows SELECT statements to be seen as table. +`AsTable("rFilms")` - allows SELECT statements to be seen as source table. To use sub-query columns in SELECT statement expressions we have to export column from sub-query, using `From` method. diff --git a/wiki/_Sidebar.md b/wiki/_Sidebar.md index cc97acd..b3e0fc5 100644 --- a/wiki/_Sidebar.md +++ b/wiki/_Sidebar.md @@ -1,7 +1,7 @@ * [Installation](https://github.com/go-jet/jet/wiki/Installation) * [Generator](https://github.com/go-jet/jet/wiki/Generator) -* [Model data](https://github.com/go-jet/jet/wiki/Model-data.md) +* [Model files](https://github.com/go-jet/jet/wiki/Model-data.md) * [Writing SQL in Go]() * [Expressions](https://github.com/go-jet/jet/wiki/Expressions) * [Statements](https://github.com/go-jet/jet/wiki/Statements) @@ -10,4 +10,4 @@ * [UPDATE](https://github.com/go-jet/jet/wiki/UPDATE) * [DELETE](https://github.com/go-jet/jet/wiki/DELETE) * [LOCK](https://github.com/go-jet/jet/wiki/LOCK) -* [Execution]() \ No newline at end of file +* [Execution](https://github.com/go-jet/jet/wiki/Execution) \ No newline at end of file