jet

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2019 License: Apache-2.0, BSD-3-Clause, MIT Imports: 12 Imported by: 0

README

Jet

Go Report Card Documentation codecov CircleCI

Jet is a framework for writing type-safe SQL queries for PostgreSQL in Go, with ability to easily convert database query result to desired arbitrary structure.
*Support for additional databases will be added in future jet releases.

Contents

Features

  1. Auto-generated type-safe SQL Builder
    • Types - boolean, integers(smallint, integer, bigint), floats(real, numeric, decimal, double precision), strings(text, character, character varying), date, time(z), timestamp(z) and enums.
    • Statements:
      • SELECT (DISTINCT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, OFFSET, FOR, UNION, INTERSECT, EXCEPT, sub-queries)
      • INSERT (VALUES, query, RETURNING),
      • UPDATE (SET, WHERE, RETURNING),
      • DELETE (WHERE, RETURNING),
      • LOCK (IN, NOWAIT)
  2. Auto-generated Data Model types - Go types mapped to database type (table or enum), used to store result of database queries. Can be combined to create desired query result destination.
  3. Query execution with result mapping to arbitrary destination structure.

Getting Started

Prerequisites

To install Jet package, you need to install Go and set your Go workspace first.

Go version 1.8+ is required

Installation

Use the bellow command to install jet

$ go get -u github.com/go-jet/jet

Install jet generator to GOPATH bin folder. This will allow generating jet files from the command line.

go install github.com/go-jet/jet/cmd/jet

Make sure GOPATH bin folder is added to the PATH environment variable.

Quick Start

For this quick start example we will use sample dvd rental database. Full database dump can be found in ./tests/init/data/dvds.sql. Schema diagram of interest for example can be found here.

Generate SQL Builder and Model files

To generate jet SQL Builder and Data Model files from postgres database we need to call jet generator with postgres 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 schema dvds we will use this command:

jet -host=localhost -port=5432 -user=jetuser -password=jetpass -dbname=jetdb -schema=dvds -path=./gen
Connecting to postgres database: host=localhost port=5432 user=jetuser password=jetpass dbname=jetdb sslmode=disable 
Retrieving schema information...
    FOUND 15  table(s),  1  enum(s)
Destination directory: ./gen/jetdb/dvds
Cleaning up schema destination directory...
Generating table sql builder files...
Generating table model files...
Generating enum sql builder files...
Generating enum model files...
Done

*User has to have a permission to read information schema tables

As command output suggest, Jet will:

  • connect to postgres database and retrieve information about the tables and enums of dvds schema
  • delete everything in schema destination folder - ./gen/jetdb/dvds,
  • and finally generate SQL Builder and Model files for each schema table and enum.

Generated files folder structure will look like this:

|-- gen                               # -path
|   `-- 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
|               |-- category.go
|               ...
|           |-- model                 # model files for each table and enum
|           |   |-- actor.go
|           |   |-- address.go
|           |   |-- mpaa_rating.go
|           |   ...

Types from table and enum are used to write type safe SQL in Go, and model types can be combined to store results of the SQL queries.

Lets write some SQL queries in Go

First we need to import jet and generated files from previous step:

import (
	// dot import so that Go code would resemble as much as native SQL
	// dot import is not mandatory
	. "github.com/go-jet/jet"                                           
	. "github.com/go-jet/jet/examples/quick-start/gen/jetdb/dvds/table" 

	"github.com/go-jet/jet/examples/quick-start/gen/jetdb/dvds/model"
)

Lets say we want to retrieve the list of all actors that acted in films longer than 180 minutes, film language is 'English' and film category is not 'Action'.

stmt := SELECT(
    Actor.ActorID, Actor.FirstName, Actor.LastName, Actor.LastUpdate,  // or just Actor.AllColumns
    Film.AllColumns,                                                  
    Language.AllColumns,
    Category.AllColumns,
).FROM(
    Actor.
        INNER_JOIN(FilmActor, Actor.ActorID.EQ(FilmActor.ActorID)).  
        INNER_JOIN(Film, Film.FilmID.EQ(FilmActor.FilmID)).          
        INNER_JOIN(Language, Language.LanguageID.EQ(Film.LanguageID)).
        INNER_JOIN(FilmCategory, FilmCategory.FilmID.EQ(Film.FilmID)).
        INNER_JOIN(Category, Category.CategoryID.EQ(FilmCategory.CategoryID)),
).WHERE(
    Language.Name.EQ(String("English")).             
        AND(Category.Name.NOT_EQ(String("Action"))).  
        AND(Film.Length.GT(Int(180))),               
).ORDER_BY(
    Actor.ActorID.ASC(),
    Film.FilmID.ASC(),
)

With package(dot) import above statements looks almost the same as native SQL. 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 and can be compared only with integer columns and expressions.

How to get parametrized SQL query from statement?

query, args, err := stmt.Sql()

query - parametrized query
args - parameters for the query

Click to see `query` and `args`
SELECT actor.actor_id AS "actor.actor_id",
     actor.first_name AS "actor.first_name",
     actor.last_name AS "actor.last_name",
     actor.last_update AS "actor.last_update",
     film.film_id AS "film.film_id",
     film.title AS "film.title",
     film.description AS "film.description",
     film.release_year AS "film.release_year",
     film.language_id AS "film.language_id",
     film.rental_duration AS "film.rental_duration",
     film.rental_rate AS "film.rental_rate",
     film.length AS "film.length",
     film.replacement_cost AS "film.replacement_cost",
     film.rating AS "film.rating",
     film.last_update AS "film.last_update",
     film.special_features AS "film.special_features",
     film.fulltext AS "film.fulltext",
     language.language_id AS "language.language_id",
     language.name AS "language.name",
     language.last_update AS "language.last_update",
     category.category_id AS "category.category_id",
     category.name AS "category.name",
     category.last_update AS "category.last_update"
FROM dvds.actor
     INNER JOIN dvds.film_actor ON (actor.actor_id = film_actor.actor_id)
     INNER JOIN dvds.film ON (film.film_id = film_actor.film_id)
     INNER JOIN dvds.language ON (language.language_id = film.language_id)
     INNER JOIN dvds.film_category ON (film_category.film_id = film.film_id)
     INNER JOIN dvds.category ON (category.category_id = film_category.category_id)
WHERE ((language.name = $1) AND (category.name != $2)) AND (film.length > $3)
ORDER BY actor.actor_id ASC, film.film_id ASC;
[English Action 180]

How to get debug SQL from statement?

debugSql, err := stmt.DebugSql()

debugSql - query string that can be copy pasted to sql editor and executed. It's not intended to be used in production.

Click to see debug sql
SELECT actor.actor_id AS "actor.actor_id",
     actor.first_name AS "actor.first_name",
     actor.last_name AS "actor.last_name",
     actor.last_update AS "actor.last_update",
     film.film_id AS "film.film_id",
     film.title AS "film.title",
     film.description AS "film.description",
     film.release_year AS "film.release_year",
     film.language_id AS "film.language_id",
     film.rental_duration AS "film.rental_duration",
     film.rental_rate AS "film.rental_rate",
     film.length AS "film.length",
     film.replacement_cost AS "film.replacement_cost",
     film.rating AS "film.rating",
     film.last_update AS "film.last_update",
     film.special_features AS "film.special_features",
     film.fulltext AS "film.fulltext",
     language.language_id AS "language.language_id",
     language.name AS "language.name",
     language.last_update AS "language.last_update",
     category.category_id AS "category.category_id",
     category.name AS "category.name",
     category.last_update AS "category.last_update"
FROM dvds.actor
     INNER JOIN dvds.film_actor ON (actor.actor_id = film_actor.actor_id)
     INNER JOIN dvds.film ON (film.film_id = film_actor.film_id)
     INNER JOIN dvds.language ON (language.language_id = film.language_id)
     INNER JOIN dvds.film_category ON (film_category.film_id = film.film_id)
     INNER JOIN dvds.category ON (category.category_id = film_category.category_id)
WHERE ((language.name = 'English') AND (category.name != 'Action')) AND (film.length > 180)
ORDER BY actor.actor_id ASC, film.film_id ASC;
Execute query and store result

Well formed SQL is just a first half the job. Lets 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.

First we have to create desired structure to store query result set. This is done be combining autogenerated model types or it can be done manually(see wiki for more information).

Let's say this is our desired structure, created by combining auto-generated model types:

var dest []struct {
    model.Actor
    
    Films []struct {
        model.Film
        
        Language    model.Language
        Categories  []model.Category
    }
}

Because one actor can act in multiple films, Films field is a slice, and because each film belongs to one language Langauge field is just a single model struct.
*There is no limitation of how big or nested destination structure can be.

Now lets execute a above statement on open database connection db and store result into dest.

err := stmt.Query(db, &dest)
handleError(err)

And thats it.

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' and film category is not 'Action'.

Lets print dest as a json to see:

jsonText, _ := json.MarshalIndent(dest, "", "\t")
fmt.Println(string(jsonText))
[
	{
		"ActorID": 1,
		"FirstName": "Penelope",
		"LastName": "Guiness",
		"LastUpdate": "2013-05-26T14:47:57.62Z",
		"Films": [
			{
				"FilmID": 499,
				"Title": "King Evolution",
				"Description": "A Action-Packed Tale of a Boy And a Lumberjack who must Chase a Madman in A Baloon",
				"ReleaseYear": 2006,
				"LanguageID": 1,
				"RentalDuration": 3,
				"RentalRate": 4.99,
				"Length": 184,
				"ReplacementCost": 24.99,
				"Rating": "NC-17",
				"LastUpdate": "2013-05-26T14:50:58.951Z",
				"SpecialFeatures": "{Trailers,\"Deleted Scenes\",\"Behind the Scenes\"}",
				"Fulltext": "'action':5 'action-pack':4 'baloon':21 'boy':10 'chase':16 'evolut':2 'king':1 'lumberjack':13 'madman':18 'must':15 'pack':6 'tale':7",
				"Language": {
					"LanguageID": 1,
					"Name": "English             ",
					"LastUpdate": "2006-02-15T10:02:19Z"
				},
				"Categories": [
					{
						"CategoryID": 8,
						"Name": "Family",
						"LastUpdate": "2006-02-15T09:46:27Z"
					}
				]
			}
		]
	},
	{
		"ActorID": 3,
		"FirstName": "Ed",
		"LastName": "Chase",
		"LastUpdate": "2013-05-26T14:47:57.62Z",
		"Films": [
			{
				"FilmID": 996,
				"Title": "Young Language",
				"Description": "A Unbelieveable Yarn of a Boat And a Database Administrator who must Meet a Boy in The First Manned Space Station",
				"ReleaseYear": 2006,
				"LanguageID": 1,
				"RentalDuration": 6,
				"RentalRate": 0.99,
				"Length": 183,
				"ReplacementCost": 9.99,
				"Rating": "G",
				"LastUpdate": "2013-05-26T14:50:58.951Z",
				"SpecialFeatures": "{Trailers,\"Behind the Scenes\"}",
				"Fulltext": "'administr':12 'boat':8 'boy':17 'databas':11 'first':20 'languag':2 'man':21 'meet':15 'must':14 'space':22 'station':23 'unbeliev':4 'yarn':5 'young':1",
				"Language": {
					"LanguageID": 1,
					"Name": "English             ",
					"LastUpdate": "2006-02-15T10:02:19Z"
				},
				"Categories": [
					{
						"CategoryID": 6,
						"Name": "Documentary",
						"LastUpdate": "2006-02-15T09:46:27Z"
					}
				]
			}
		]
	},
	//...(125 more items)
]

What if, we also want to have list of films per category and actors per category, where films are longer than 180 minutes, film language is 'English' and film category is not 'Action'.
In that case we can reuse above statement stmt, and just change our destination:

var dest2 []struct {
    model.Category

    Films []model.Film
    Actors []model.Actor
}

err = stmt.Query(db, &dest2)
handleError(err)
Click to see `dest2` json
[
	{
		"CategoryID": 8,
		"Name": "Family",
		"LastUpdate": "2006-02-15T09:46:27Z",
		"Films": [
			{
				"FilmID": 499,
				"Title": "King Evolution",
				"Description": "A Action-Packed Tale of a Boy And a Lumberjack who must Chase a Madman in A Baloon",
				"ReleaseYear": 2006,
				"LanguageID": 1,
				"RentalDuration": 3,
				"RentalRate": 4.99,
				"Length": 184,
				"ReplacementCost": 24.99,
				"Rating": "NC-17",
				"LastUpdate": "2013-05-26T14:50:58.951Z",
				"SpecialFeatures": "{Trailers,\"Deleted Scenes\",\"Behind the Scenes\"}",
				"Fulltext": "'action':5 'action-pack':4 'baloon':21 'boy':10 'chase':16 'evolut':2 'king':1 'lumberjack':13 'madman':18 'must':15 'pack':6 'tale':7"
			},
			{
				"FilmID": 50,
				"Title": "Baked Cleopatra",
				"Description": "A Stunning Drama of a Forensic Psychologist And a Husband who must Overcome a Waitress in A Monastery",
				"ReleaseYear": 2006,
				"LanguageID": 1,
				"RentalDuration": 3,
				"RentalRate": 2.99,
				"Length": 182,
				"ReplacementCost": 20.99,
				"Rating": "G",
				"LastUpdate": "2013-05-26T14:50:58.951Z",
				"SpecialFeatures": "{Commentaries,\"Behind the Scenes\"}",
				"Fulltext": "'bake':1 'cleopatra':2 'drama':5 'forens':8 'husband':12 'monasteri':20 'must':14 'overcom':15 'psychologist':9 'stun':4 'waitress':17"
			}
		],
		"Actors": [
			{
				"ActorID": 1,
				"FirstName": "Penelope",
				"LastName": "Guiness",
				"LastUpdate": "2013-05-26T14:47:57.62Z"
			},
			{
				"ActorID": 20,
				"FirstName": "Lucille",
				"LastName": "Tracy",
				"LastUpdate": "2013-05-26T14:47:57.62Z"
			},
			{
				"ActorID": 36,
				"FirstName": "Burt",
				"LastName": "Dukakis",
				"LastUpdate": "2013-05-26T14:47:57.62Z"
			},
			{
				"ActorID": 70,
				"FirstName": "Michelle",
				"LastName": "Mcconaughey",
				"LastUpdate": "2013-05-26T14:47:57.62Z"
			},
			{
				"ActorID": 118,
				"FirstName": "Cuba",
				"LastName": "Allen",
				"LastUpdate": "2013-05-26T14:47:57.62Z"
			},
			{
				"ActorID": 187,
				"FirstName": "Renee",
				"LastName": "Ball",
				"LastUpdate": "2013-05-26T14:47:57.62Z"
			},
			{
				"ActorID": 198,
				"FirstName": "Mary",
				"LastName": "Keitel",
				"LastUpdate": "2013-05-26T14:47:57.62Z"
			}
		]
	},
    //...
]

Complete code example can be found at ./examples/quick-start/quick-start.go

This example represent probably the most common use case. Detail info about additional features and use cases can be found at project wiki page.

Benefits

What are the benefits of writing SQL in Go using Jet? The biggest benefit is speed.
Speed is improved in 3 major areas:

Speed of development

Writing SQL queries is much easier directly from Go, because programmer has the help of SQL code completion and SQL type safety directly in Go. Writing code is much faster and code is more robust. Automatic scan to arbitrary structure removes a lot of headache and boilerplate code needed to structure database query result.

Speed of execution

Common web and database server usually are not on the same physical machine, and there is some latency between them. Latency can vary from 5ms to 50+ms. In majority of cases query executed on database is simple query lasting no more than 1ms. In those cases web server handler execution time is directly proportional to latency between server and 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 data from database. ORM sometimes can 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 3 seconds !!!.

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. Handler execution will be only proportional to the number of rows returned from database. 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. This is exactly what is being done in one of the tests: TestJoinEverything. 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

The most expensive bugs are the one 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.
Lets return to quick start example, and take closer look at a line:

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 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 because integer columns and expressions can be only compered to other integer columns and expressions.

Without Jet these bugs will have to be either caught by some test or by manual testing.

Dependencies

At the moment Jet dependence only of:

  • github.com/google/uuid (Used for debug purposes and in data model files)
  • github.com/lib/pq (Used by Jet to read information about database schema types)

To run the tests, additional dependencies are required:

  • github.com/pkg/profile
  • gotest.tools/assert

Versioning

SemVer is used for versioning. For the versions available, see the releases.

License

Copyright 2019 Goran Bjelanovic
Licensed under the Apache License, Version 2.0.

Documentation

Overview

Package jet is a framework for writing type-safe SQL queries for PostgreSQL in Go, with ability to easily convert database query result to desired arbitrary structure.

Index

Constants

View Source
const (
	LOCK_ACCESS_SHARE           = "ACCESS SHARE"
	LOCK_ROW_SHARE              = "ROW SHARE"
	LOCK_ROW_EXCLUSIVE          = "ROW EXCLUSIVE"
	LOCK_SHARE_UPDATE_EXCLUSIVE = "SHARE UPDATE EXCLUSIVE"
	LOCK_SHARE                  = "SHARE"
	LOCK_SHARE_ROW_EXCLUSIVE    = "SHARE ROW EXCLUSIVE"
	LOCK_EXCLUSIVE              = "EXCLUSIVE"
	LOCK_ACCESS_EXCLUSIVE       = "ACCESS EXCLUSIVE"
)

Lock types for LockStatement.

View Source
const (
	// DEFAULT is jet equivalent of SQL DEFAULT
	DEFAULT keywordClause = "DEFAULT"
)

Variables

View Source
var (
	// NULL is jet equivalent of SQL NULL
	NULL = newNullLiteral()
	// STAR is jet equivalent of SQL *
	STAR = newStarLiteral()
)
View Source
var (
	UPDATE        = newLock("UPDATE")
	NO_KEY_UPDATE = newLock("NO KEY UPDATE")
	SHARE         = newLock("SHARE")
	KEY_SHARE     = newLock("KEY SHARE")
)

Select statements lock types

Functions

func CAST

func CAST(expression Expression) cast

CAST wraps expression for casting. For instance: CAST(table.column).AS_BOOL()

Types

type BoolExpression

type BoolExpression interface {
	Expression

	// Check if this expression is equal to rhs
	EQ(rhs BoolExpression) BoolExpression
	// Check if this expression is not equal to rhs
	NOT_EQ(rhs BoolExpression) BoolExpression
	// Check if this expression is distinct to rhs
	IS_DISTINCT_FROM(rhs BoolExpression) BoolExpression
	// Check if this expression is not distinct to rhs
	IS_NOT_DISTINCT_FROM(rhs BoolExpression) BoolExpression

	// Check if this expression is true
	IS_TRUE() BoolExpression
	// Check if this expression is not true
	IS_NOT_TRUE() BoolExpression
	// Check if this expression is false
	IS_FALSE() BoolExpression
	// Check if this expression is not false
	IS_NOT_FALSE() BoolExpression
	// Check if this expression is unknown
	IS_UNKNOWN() BoolExpression
	// Check if this expression is not unknown
	IS_NOT_UNKNOWN() BoolExpression

	// expression AND operator rhs
	AND(rhs BoolExpression) BoolExpression
	// expression OR operator rhs
	OR(rhs BoolExpression) BoolExpression
}

BoolExpression interface

func BOOL_AND

func BOOL_AND(boolExpression BoolExpression) BoolExpression

BOOL_AND is aggregate function. Returns true if all input values are true, otherwise false

func BOOL_OR

func BOOL_OR(boolExpression BoolExpression) BoolExpression

BOOL_OR is aggregate function. Returns true if at least one input value is true, otherwise false

func Bool

func Bool(value bool) BoolExpression

Bool creates new bool literal expression

func BoolExp

func BoolExp(expression Expression) BoolExpression

BoolExp is bool expression wrapper around arbitrary expression. Allows go compiler to see any expression as bool expression. Does not add sql cast to generated sql builder output.

func EVERY

func EVERY(boolExpression BoolExpression) BoolExpression

EVERY is aggregate function. Returns true if all input values are true, otherwise false

func EXISTS

func EXISTS(subQuery SelectStatement) BoolExpression

EXISTS checks for existence of the rows in subQuery

func NOT

NOT returns negation of bool expression result

type CaseOperator

type CaseOperator interface {
	Expression

	WHEN(condition Expression) CaseOperator
	THEN(then Expression) CaseOperator
	ELSE(els Expression) CaseOperator
}

CaseOperator is interface for SQL case operator

func CASE

func CASE(expression ...Expression) CaseOperator

CASE create CASE operator with optional list of expressions

type Column

type Column interface {
	Expression
	// contains filtered or unexported methods
}

Column is common column interface for all types of columns.

type ColumnBool

type ColumnBool interface {
	BoolExpression

	From(subQuery SelectTable) ColumnBool
	// contains filtered or unexported methods
}

ColumnBool is interface for SQL boolean columns.

func BoolColumn

func BoolColumn(name string) ColumnBool

BoolColumn creates named bool column.

type ColumnDate

type ColumnDate interface {
	DateExpression

	From(subQuery SelectTable) ColumnDate
	// contains filtered or unexported methods
}

ColumnDate is interface of SQL date columns.

func DateColumn

func DateColumn(name string) ColumnDate

DateColumn creates named date column.

type ColumnFloat

type ColumnFloat interface {
	FloatExpression

	From(subQuery SelectTable) ColumnFloat
	// contains filtered or unexported methods
}

ColumnFloat is interface for SQL real, numeric, decimal or double precision column.

func FloatColumn

func FloatColumn(name string) ColumnFloat

FloatColumn creates named float column.

type ColumnInteger

type ColumnInteger interface {
	IntegerExpression

	From(subQuery SelectTable) ColumnInteger
	// contains filtered or unexported methods
}

ColumnInteger is interface for SQL smallint, integer, bigint columns.

func IntegerColumn

func IntegerColumn(name string) ColumnInteger

IntegerColumn creates named integer column.

type ColumnList

type ColumnList []Column

ColumnList is redefined type to support list of columns as single projection

func (ColumnList) Name

func (cl ColumnList) Name() string

Name is placeholder for ColumnList to implement Column interface

func (ColumnList) TableName

func (cl ColumnList) TableName() string

TableName is placeholder for ColumnList to implement Column interface

type ColumnString

type ColumnString interface {
	StringExpression

	From(subQuery SelectTable) ColumnString
	// contains filtered or unexported methods
}

ColumnString is interface for SQL text, character, character varying bytea, uuid columns and enums types.

func StringColumn

func StringColumn(name string) ColumnString

StringColumn creates named string column.

type ColumnTime

type ColumnTime interface {
	TimeExpression

	From(subQuery SelectTable) ColumnTime
	// contains filtered or unexported methods
}

ColumnTime is interface for SQL time column.

func TimeColumn

func TimeColumn(name string) ColumnTime

TimeColumn creates named time column

type ColumnTimestamp

type ColumnTimestamp interface {
	TimestampExpression

	From(subQuery SelectTable) ColumnTimestamp
	// contains filtered or unexported methods
}

ColumnTimestamp is interface of SQL timestamp columns.

func TimestampColumn

func TimestampColumn(name string) ColumnTimestamp

TimestampColumn creates named timestamp column

type ColumnTimestampz

type ColumnTimestampz interface {
	TimestampzExpression

	From(subQuery SelectTable) ColumnTimestampz
	// contains filtered or unexported methods
}

ColumnTimestampz is interface of SQL timestamp with timezone columns.

func TimestampzColumn

func TimestampzColumn(name string) ColumnTimestampz

TimestampzColumn creates named timestamp with time zone column.

type ColumnTimez

type ColumnTimez interface {
	TimezExpression

	From(subQuery SelectTable) ColumnTimez
	// contains filtered or unexported methods
}

ColumnTimez is interface of SQL time with time zone columns.

func TimezColumn

func TimezColumn(name string) ColumnTimez

TimezColumn creates named time with time zone column.

type DateExpression

type DateExpression interface {
	Expression

	EQ(rhs DateExpression) BoolExpression
	NOT_EQ(rhs DateExpression) BoolExpression
	IS_DISTINCT_FROM(rhs DateExpression) BoolExpression
	IS_NOT_DISTINCT_FROM(rhs DateExpression) BoolExpression

	LT(rhs DateExpression) BoolExpression
	LT_EQ(rhs DateExpression) BoolExpression
	GT(rhs DateExpression) BoolExpression
	GT_EQ(rhs DateExpression) BoolExpression
}

DateExpression is interface for all SQL date expressions.

func CURRENT_DATE

func CURRENT_DATE() DateExpression

CURRENT_DATE returns current date

func Date

func Date(year, month, day int) DateExpression

Date creates new date expression

func DateExp

func DateExp(expression Expression) DateExpression

DateExp is date expression wrapper around arbitrary expression. Allows go compiler to see any expression as date expression. Does not add sql cast to generated sql builder output.

func TO_DATE

func TO_DATE(dateStr, format StringExpression) DateExpression

TO_DATE converts string to date using format

type DeleteStatement

type DeleteStatement interface {
	Statement

	WHERE(expression BoolExpression) DeleteStatement

	RETURNING(projections ...projection) DeleteStatement
}

DeleteStatement is interface for SQL DELETE statement

type Expression

type Expression interface {

	// Test expression whether it is a NULL value.
	IS_NULL() BoolExpression
	// Test expression whether it is a non-NULL value.
	IS_NOT_NULL() BoolExpression

	// Check if this expressions matches any in expressions list
	IN(expressions ...Expression) BoolExpression
	// Check if this expressions is different of all expressions in expressions list
	NOT_IN(expressions ...Expression) BoolExpression

	// The temporary alias name to assign to the expression
	AS(alias string) projection

	// Expression will be used to sort query result in ascending order
	ASC() orderByClause
	// Expression will be used to sort query result in ascending order
	DESC() orderByClause
	// contains filtered or unexported methods
}

Expression is common interface for all expressions. Can be Bool, Int, Float, String, Date, Time, Timez, Timestamp or Timestampz expressions.

func COALESCE

func COALESCE(value Expression, values ...Expression) Expression

COALESCE function returns the first of its arguments that is not null.

func GREATEST

func GREATEST(value Expression, values ...Expression) Expression

GREATEST selects the largest value from a list of expressions

func LEAST

func LEAST(value Expression, values ...Expression) Expression

LEAST selects the smallest value from a list of expressions

func NULLIF

func NULLIF(value1, value2 Expression) Expression

NULLIF function returns a null value if value1 equals value2; otherwise it returns value1.

func RAW

func RAW(raw string) Expression

RAW can be used for any unsupported functions, operators or expressions. For example: RAW("current_database()")

func ROW

func ROW(expressions ...Expression) Expression

ROW is construct one table row from list of expressions.

func WRAP

func WRAP(expression ...Expression) Expression

WRAP wraps list of expressions with brackets '(' and ')'

type FloatExpression

FloatExpression is interface for SQL float columns

func ABSf

func ABSf(floatExpression FloatExpression) FloatExpression

ABSf calculates absolute value from float expression

func AVG

func AVG(numericExpression NumericExpression) FloatExpression

AVG is aggregate function used to calculate avg value from numeric expression

func CBRT

func CBRT(numericExpression NumericExpression) FloatExpression

CBRT calculates cube root of numeric expression

func CEIL

func CEIL(floatExpression FloatExpression) FloatExpression

CEIL calculates ceil of float expression

func FLOOR

func FLOOR(floatExpression FloatExpression) FloatExpression

FLOOR calculates floor of float expression

func Float

func Float(value float64) FloatExpression

Float creates new float literal expression

func FloatExp

func FloatExp(expression Expression) FloatExpression

FloatExp is date expression wrapper around arbitrary expression. Allows go compiler to see any expression as float expression. Does not add sql cast to generated sql builder output.

func LN

func LN(floatExpression FloatExpression) FloatExpression

LN calculates natural algorithm of float expression

func LOG

func LOG(floatExpression FloatExpression) FloatExpression

LOG calculates logarithm of float expression

func MAXf

func MAXf(floatExpression FloatExpression) FloatExpression

MAXf is aggregate function. Returns maximum value of float expression across all input values

func MINf

func MINf(floatExpression FloatExpression) FloatExpression

MINf is aggregate function. Returns minimum value of float expression across all input values

func ROUND

func ROUND(floatExpression FloatExpression, precision ...IntegerExpression) FloatExpression

ROUND calculates round of a float expressions with optional precision

func SIGN

func SIGN(floatExpression FloatExpression) FloatExpression

SIGN returns sign of float expression

func SQRT

func SQRT(numericExpression NumericExpression) FloatExpression

SQRT calculates square root of numeric expression

func SUMf

func SUMf(floatExpression FloatExpression) FloatExpression

SUMf is aggregate function. Returns sum of expression across all float expressions

func TO_NUMBER

func TO_NUMBER(floatStr, format StringExpression) FloatExpression

TO_NUMBER converts string to numeric using format

func TRUNC

func TRUNC(floatExpression FloatExpression, precision ...IntegerExpression) FloatExpression

TRUNC calculates trunc of float expression with optional precision

type InsertStatement

type InsertStatement interface {
	Statement

	// Insert row of values
	VALUES(value interface{}, values ...interface{}) InsertStatement
	// Insert row of values, where value for each column is extracted from filed of structure data.
	// If data is not struct or there is no field for every column selected, this method will panic.
	MODEL(data interface{}) InsertStatement

	MODELS(data interface{}) InsertStatement

	QUERY(selectStatement SelectStatement) InsertStatement

	RETURNING(projections ...projection) InsertStatement
}

InsertStatement is interface for SQL INSERT statements

type IntegerExpression

type IntegerExpression interface {
	Expression

	// Check if expression is equal to rhs
	EQ(rhs IntegerExpression) BoolExpression
	// Check if expression is not equal to rhs
	NOT_EQ(rhs IntegerExpression) BoolExpression
	// Check if expression is distinct from rhs
	IS_DISTINCT_FROM(rhs IntegerExpression) BoolExpression
	// Check if expression is not distinct from rhs
	IS_NOT_DISTINCT_FROM(rhs IntegerExpression) BoolExpression

	// Check if expression is less then rhs
	LT(rhs IntegerExpression) BoolExpression
	// Check if expression is less then equal rhs
	LT_EQ(rhs IntegerExpression) BoolExpression
	// Check if expression is greater then rhs
	GT(rhs IntegerExpression) BoolExpression
	// Check if expression is greater then equal rhs
	GT_EQ(rhs IntegerExpression) BoolExpression

	// expression + rhs
	ADD(rhs IntegerExpression) IntegerExpression
	// expression - rhs
	SUB(rhs IntegerExpression) IntegerExpression
	// expression * rhs
	MUL(rhs IntegerExpression) IntegerExpression
	// expression / rhs
	DIV(rhs IntegerExpression) IntegerExpression
	// expression % rhs
	MOD(rhs IntegerExpression) IntegerExpression
	// expression ^ rhs
	POW(rhs IntegerExpression) IntegerExpression

	// expression & rhs
	BIT_AND(rhs IntegerExpression) IntegerExpression
	// expression | rhs
	BIT_OR(rhs IntegerExpression) IntegerExpression
	// expression # rhs
	BIT_XOR(rhs IntegerExpression) IntegerExpression
	// expression << rhs
	BIT_SHIFT_LEFT(shift IntegerExpression) IntegerExpression
	// expression >> rhs
	BIT_SHIFT_RIGHT(shift IntegerExpression) IntegerExpression
	// contains filtered or unexported methods
}

IntegerExpression interface

func ABSi

func ABSi(integerExpression IntegerExpression) IntegerExpression

ABSi calculates absolute value from int expression

func BIT_AND

func BIT_AND(integerExpression IntegerExpression) IntegerExpression

BIT_AND is aggregate function used to calculates the bitwise AND of all non-null input values, or null if none.

func BIT_LENGTH

func BIT_LENGTH(stringExpression StringExpression) IntegerExpression

BIT_LENGTH returns number of bits in string expression

func BIT_NOT

BIT_NOT inverts every bit in integer expression result

func BIT_OR

func BIT_OR(integerExpression IntegerExpression) IntegerExpression

BIT_OR is aggregate function used to calculates the bitwise OR of all non-null input values, or null if none.

func CHAR_LENGTH

func CHAR_LENGTH(stringExpression StringExpression) IntegerExpression

CHAR_LENGTH returns number of characters in string expression

func COUNT

func COUNT(expression Expression) IntegerExpression

COUNT is aggregate function. Returns number of input rows for which the value of expression is not null.

func Int

func Int(value int64) IntegerExpression

Int is constructor for integer expressions literals.

func IntExp

func IntExp(expression Expression) IntegerExpression

IntExp is int expression wrapper around arbitrary expression. Allows go compiler to see any expression as int expression. Does not add sql cast to generated sql builder output.

func MAXi

func MAXi(integerExpression IntegerExpression) IntegerExpression

MAXi is aggregate function. Returns maximum value of int expression across all input values

func MINi

func MINi(integerExpression IntegerExpression) IntegerExpression

MINi is aggregate function. Returns minimum value of int expression across all input values

func OCTET_LENGTH

func OCTET_LENGTH(stringExpression StringExpression) IntegerExpression

OCTET_LENGTH returns number of bytes in string expression

func STRPOS

func STRPOS(str, substring StringExpression) IntegerExpression

STRPOS returns location of specified substring (same as position(substring in string), but note the reversed argument order)

func SUMi

func SUMi(integerExpression IntegerExpression) IntegerExpression

SUMi is aggregate function. Returns sum of expression across all integer expression.

type LockStatement

type LockStatement interface {
	Statement

	IN(lockMode TableLockMode) LockStatement
	NOWAIT() LockStatement
}

LockStatement interface for SQL LOCK statement

func LOCK

func LOCK(tables ...WritableTable) LockStatement

LOCK creates lock statement for list of tables.

type NumericExpression

type NumericExpression interface {
	Expression
	// contains filtered or unexported methods
}

NumericExpression is common interface for all integer and float expressions

type ProjectionList

type ProjectionList []projection

ProjectionList is a redefined type, so that ProjectionList can be used as a projection.

type ReadableTable

type ReadableTable interface {
	// contains filtered or unexported methods
}

ReadableTable interface

type SelectLock

type SelectLock interface {
	NOWAIT() SelectLock
	SKIP_LOCKED() SelectLock
	// contains filtered or unexported methods
}

SelectLock is interface for SELECT statement locks

type SelectStatement

type SelectStatement interface {
	Statement
	Expression

	DISTINCT() SelectStatement
	FROM(table ReadableTable) SelectStatement
	WHERE(expression BoolExpression) SelectStatement
	GROUP_BY(groupByClauses ...groupByClause) SelectStatement
	HAVING(boolExpression BoolExpression) SelectStatement
	ORDER_BY(orderByClauses ...orderByClause) SelectStatement
	LIMIT(limit int64) SelectStatement
	OFFSET(offset int64) SelectStatement
	FOR(lock SelectLock) SelectStatement

	UNION(rhs SelectStatement) SelectStatement
	UNION_ALL(rhs SelectStatement) SelectStatement
	INTERSECT(rhs SelectStatement) SelectStatement
	INTERSECT_ALL(rhs SelectStatement) SelectStatement
	EXCEPT(rhs SelectStatement) SelectStatement
	EXCEPT_ALL(rhs SelectStatement) SelectStatement

	AsTable(alias string) SelectTable
	// contains filtered or unexported methods
}

SelectStatement is interface for SQL SELECT statements

func EXCEPT

func EXCEPT(lhs, rhs SelectStatement) SelectStatement

EXCEPT returns all rows that are in the result of query lhs but not in the result of query rhs. It eliminates duplicate rows from its result.

func EXCEPT_ALL

func EXCEPT_ALL(lhs, rhs SelectStatement) SelectStatement

EXCEPT_ALL returns all rows that are in the result of query lhs but not in the result of query rhs. It does not eliminates duplicate rows from its result.

func INTERSECT

func INTERSECT(lhs, rhs SelectStatement, selects ...SelectStatement) SelectStatement

INTERSECT returns all rows that are in query results. It eliminates duplicate rows from its result.

func INTERSECT_ALL

func INTERSECT_ALL(lhs, rhs SelectStatement, selects ...SelectStatement) SelectStatement

INTERSECT_ALL returns all rows that are in query results. It does not eliminates duplicate rows from its result.

func SELECT

func SELECT(projection1 projection, projections ...projection) SelectStatement

SELECT creates new SelectStatement with list of projections

func UNION

func UNION(lhs, rhs SelectStatement, selects ...SelectStatement) SelectStatement

UNION effectively appends the result of sub-queries(select statements) into single query. It eliminates duplicate rows from its result.

func UNION_ALL

func UNION_ALL(lhs, rhs SelectStatement, selects ...SelectStatement) SelectStatement

UNION_ALL effectively appends the result of sub-queries(select statements) into single query. It does not eliminates duplicate rows from its result.

type SelectTable

type SelectTable interface {
	ReadableTable

	Alias() string

	AllColumns() ProjectionList
}

SelectTable is interface for SELECT sub-queries

type Statement

type Statement interface {
	// Sql returns parametrized sql query with list of arguments.
	// err is returned if statement is not composed correctly
	Sql() (query string, args []interface{}, err error)
	// DebugSql returns debug query where every parametrized placeholder is replaced with its argument.
	// Do not use it in production. Use it only for debug purposes.
	// err is returned if statement is not composed correctly
	DebugSql() (query string, err error)

	// Query executes statement over database connection db and stores row result in destination.
	// Destination can be arbitrary structure
	Query(db execution.DB, destination interface{}) error
	// QueryContext executes statement with a context over database connection db and stores row result in destination.
	// Destination can be of arbitrary structure
	QueryContext(context context.Context, db execution.DB, destination interface{}) error

	//Exec executes statement over db connection without returning any rows.
	Exec(db execution.DB) (sql.Result, error)
	//Exec executes statement with context over db connection without returning any rows.
	ExecContext(context context.Context, db execution.DB) (sql.Result, error)
}

Statement is common interface for all statements(SELECT, INSERT, UPDATE, DELETE, LOCK)

type StringExpression

StringExpression interface

func BTRIM

func BTRIM(stringExpression StringExpression, trimChars ...StringExpression) StringExpression

BTRIM removes the longest string consisting only of characters in characters (a space by default) from the start and end of string

func CHR

func CHR(integerExpression IntegerExpression) StringExpression

CHR returns character with the given code.

func CONVERT

func CONVERT(str StringExpression, srcEncoding StringExpression, destEncoding StringExpression) StringExpression

CONVERT converts string to dest_encoding. The original encoding is specified by src_encoding. The string must be valid in this encoding.

func CONVERT_FROM

func CONVERT_FROM(str StringExpression, srcEncoding StringExpression) StringExpression

CONVERT_FROM converts string to the database encoding. The original encoding is specified by src_encoding. The string must be valid in this encoding.

func CONVERT_TO

func CONVERT_TO(str StringExpression, toEncoding StringExpression) StringExpression

CONVERT_TO converts string to dest_encoding.

func DECODE

DECODE decodes binary data from textual representation in string. Options for format are same as in encode.

func ENCODE

ENCODE encodes binary data into a textual representation. Supported formats are: base64, hex, escape. escape converts zero bytes and high-bit-set bytes to octal sequences (\nnn) and doubles backslashes.

func INITCAP

INITCAP converts the first letter of each word to upper case and the rest to lower case. Words are sequences of alphanumeric characters separated by non-alphanumeric characters.

func LEFT

LEFT returns first n characters in the string. When n is negative, return all but last |n| characters.

func LENGTH

func LENGTH(str StringExpression, encoding ...StringExpression) StringExpression

LENGTH returns number of characters in string with a given encoding

func LOWER

func LOWER(stringExpression StringExpression) StringExpression

LOWER returns string expression in lower case

func LPAD

LPAD fills up the string to length length by prepending the characters fill (a space by default). If the string is already longer than length then it is truncated (on the right).

func LTRIM

func LTRIM(str StringExpression, trimChars ...StringExpression) StringExpression

LTRIM removes the longest string containing only characters from characters (a space by default) from the start of string

func MD5

func MD5(stringExpression StringExpression) StringExpression

MD5 calculates the MD5 hash of string, returning the result in hexadecimal

func NewEnumValue

func NewEnumValue(name string) StringExpression

NewEnumValue creates new named enum value

func REPEAT

REPEAT repeats string the specified number of times

func REPLACE

func REPLACE(text, from, to StringExpression) StringExpression

REPLACE replaces all occurrences in string of substring from with substring to

func REVERSE

func REVERSE(stringExpression StringExpression) StringExpression

REVERSE returns reversed string.

RIGHT returns last n characters in the string. When n is negative, return all but first |n| characters.

func RPAD

RPAD fills up the string to length length by appending the characters fill (a space by default). If the string is already longer than length then it is truncated.

func RTRIM

func RTRIM(str StringExpression, trimChars ...StringExpression) StringExpression

RTRIM removes the longest string containing only characters from characters (a space by default) from the end of string

func SUBSTR

SUBSTR extracts substring

func String

func String(value string) StringExpression

String creates new string literal expression

func StringExp

func StringExp(expression Expression) StringExpression

StringExp is string expression wrapper around arbitrary expression. Allows go compiler to see any expression as string expression. Does not add sql cast to generated sql builder output.

func TO_ASCII

func TO_ASCII(str StringExpression, encoding ...StringExpression) StringExpression

TO_ASCII convert string to ASCII from another encoding

func TO_CHAR

func TO_CHAR(expression Expression, format StringExpression) StringExpression

TO_CHAR converts expression to string with format

func TO_HEX

func TO_HEX(number IntegerExpression) StringExpression

TO_HEX converts number to its equivalent hexadecimal representation

func UPPER

func UPPER(stringExpression StringExpression) StringExpression

UPPER returns string expression in upper case

type Table

type Table interface {
	SchemaName() string
	TableName() string
	AS(alias string)
	// contains filtered or unexported methods
}

Table interface

func NewTable

func NewTable(schemaName, name string, columns ...Column) Table

NewTable creates new table with schema name, table name and list of columns

type TableLockMode

type TableLockMode string

TableLockMode is a type of possible SQL table lock

type TimeExpression

type TimeExpression interface {
	Expression

	EQ(rhs TimeExpression) BoolExpression
	NOT_EQ(rhs TimeExpression) BoolExpression
	IS_DISTINCT_FROM(rhs TimeExpression) BoolExpression
	IS_NOT_DISTINCT_FROM(rhs TimeExpression) BoolExpression

	LT(rhs TimeExpression) BoolExpression
	LT_EQ(rhs TimeExpression) BoolExpression
	GT(rhs TimeExpression) BoolExpression
	GT_EQ(rhs TimeExpression) BoolExpression
}

TimeExpression interface

func LOCALTIME

func LOCALTIME(precision ...int) TimeExpression

LOCALTIME returns local time of day using optional precision

func Time

func Time(hour, minute, second, milliseconds int) TimeExpression

Time creates new time literal expression

func TimeExp

func TimeExp(expression Expression) TimeExpression

TimeExp is time expression wrapper around arbitrary expression. Allows go compiler to see any expression as time expression. Does not add sql cast to generated sql builder output.

type TimestampExpression

TimestampExpression interface

func LOCALTIMESTAMP

func LOCALTIMESTAMP(precision ...int) TimestampExpression

LOCALTIMESTAMP returns current date and time using optional precision

func Timestamp

func Timestamp(year, month, day, hour, minute, second, milliseconds int) TimestampExpression

Timestamp creates new timestamp literal expression

func TimestampExp

func TimestampExp(expression Expression) TimestampExpression

TimestampExp is timestamp expression wrapper around arbitrary expression. Allows go compiler to see any expression as timestamp expression. Does not add sql cast to generated sql builder output.

type TimestampzExpression

TimestampzExpression interface

func CURRENT_TIMESTAMP

func CURRENT_TIMESTAMP(precision ...int) TimestampzExpression

CURRENT_TIMESTAMP returns current timestamp with time zone

func NOW

NOW returns current date and time

func TO_TIMESTAMP

func TO_TIMESTAMP(timestampzStr, format StringExpression) TimestampzExpression

TO_TIMESTAMP converts string to time stamp with time zone using format

func Timestampz

func Timestampz(year, month, day, hour, minute, second, milliseconds, timezone int) TimestampzExpression

Timestampz creates new timestamp with time zone literal expression

func TimestampzExp

func TimestampzExp(expression Expression) TimestampzExpression

TimestampzExp is timestamp with time zone expression wrapper around arbitrary expression. Allows go compiler to see any expression as timestamp with time zone expression. Does not add sql cast to generated sql builder output.

type TimezExpression

type TimezExpression interface {
	Expression

	//EQ
	EQ(rhs TimezExpression) BoolExpression
	//NOT_EQ
	NOT_EQ(rhs TimezExpression) BoolExpression
	//IS_DISTINCT_FROM
	IS_DISTINCT_FROM(rhs TimezExpression) BoolExpression
	//IS_NOT_DISTINCT_FROM
	IS_NOT_DISTINCT_FROM(rhs TimezExpression) BoolExpression

	//LT
	LT(rhs TimezExpression) BoolExpression
	//LT_EQ
	LT_EQ(rhs TimezExpression) BoolExpression
	//GT
	GT(rhs TimezExpression) BoolExpression
	//GT_EQ
	GT_EQ(rhs TimezExpression) BoolExpression
}

TimezExpression interface 'time with time zone'

func CURRENT_TIME

func CURRENT_TIME(precision ...int) TimezExpression

CURRENT_TIME returns current time with time zone

func Timez

func Timez(hour, minute, second, milliseconds, timezone int) TimezExpression

Timez creates new time with time zone literal expression

func TimezExp

func TimezExp(expression Expression) TimezExpression

TimezExp is time with time zone expression wrapper around arbitrary expression. Allows go compiler to see any expression as time with time zone expression. Does not add sql cast to generated sql builder output.

type UpdateStatement

type UpdateStatement interface {
	Statement

	SET(value interface{}, values ...interface{}) UpdateStatement
	MODEL(data interface{}) UpdateStatement

	WHERE(expression BoolExpression) UpdateStatement
	RETURNING(projections ...projection) UpdateStatement
}

UpdateStatement is interface of SQL UPDATE statement

type WritableTable

type WritableTable interface {
	// contains filtered or unexported methods
}

WritableTable interface

Directories

Path Synopsis
cmd
jet
examples
generator
internal
tests

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL