sqlgen

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Jan 10, 2019 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Example (TagOverride)

You can override how values are serialized via struct tags. The following tags are available:

string (encoding.TextMarshaler, encoding.TextUnmarshaler), binary (encoding.BinaryMarshaler, encoding.BinaryUnmarshaler, gogoproto.Marshaler, gogoproto.Unmarshaler), json (json.Marshaler, json.Unmarshaler).

package main

import (
	"context"
	"fmt"
	"net"
	"reflect"

	"github.com/samsarahq/thunder/internal/testfixtures"
	"github.com/samsarahq/thunder/sqlgen"
	uuid "github.com/satori/go.uuid"
)

type UUID uuid.UUID

func (u UUID) MarshalBinary() ([]byte, error) {
	return u[:], nil
}

func (u *UUID) UnmarshalBinary(b []byte) error {
	copy(u[:], b)
	return nil
}

// You can override how values are serialized via struct tags. The following tags are available:
//
// string (encoding.TextMarshaler, encoding.TextUnmarshaler), binary (encoding.BinaryMarshaler,
// encoding.BinaryUnmarshaler, gogoproto.Marshaler, gogoproto.Unmarshaler), json (json.Marshaler,
// json.Unmarshaler).
func main() {
	testDb, _ := testfixtures.NewTestDatabase()
	defer testDb.Close()

	_, err := testDb.Exec(`
		CREATE TABLE users (
			uuid          BINARY(16) PRIMARY KEY,
			name          VARCHAR(255),
			ip            VARCHAR(255),
			configuration BLOB
		)
	`)
	if err != nil {
		panic(err)
	}

	ctx := context.TODO()

	type User struct {
		UUID          UUID `sql:"uuid,primary,binary"`
		Name          string
		IP            net.IP                 `sql:"ip,string"`
		Configuration map[string]interface{} `sql:"configuration,json"`
	}

	schema := sqlgen.NewSchema()
	schema.MustRegisterType("users", sqlgen.UniqueId, User{})

	db := sqlgen.NewDB(testDb.DB, schema)
	uuid, _ := uuid.NewV4()

	initialUser := &User{
		UUID: UUID(uuid),             // => BINARY (via uuid.MarshalBinary())
		Name: "Jean",                 // => VARCHAR
		IP:   net.IPv4(127, 0, 0, 1), // => VARCHAR (via ip.MarshalText())
		Configuration: map[string]interface{}{ // => JSON (via json.Marshal(configuration))
			"darkmode": true,
		},
	}
	_, err = db.InsertRow(ctx, initialUser)
	if err != nil {
		panic(err)
	}

	user := &User{UUID: UUID(uuid)}
	err = db.QueryRow(ctx, &user, nil, nil)
	if err != nil {
		panic(err)
	}

	if reflect.DeepEqual(*user, *initialUser) {
		fmt.Println("They match!")
	}
}
Output:

They match!

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func CopySingletonSlice

func CopySingletonSlice(result interface{}, rows []interface{}) error

func CopySlice

func CopySlice(result interface{}, rows []interface{}) error

Types

type BaseSelectQuery

type BaseSelectQuery struct {
	Table   *Table
	Filter  Filter
	Options *SelectOptions
}

func (*BaseSelectQuery) MakeSelectQuery

func (b *BaseSelectQuery) MakeSelectQuery() (*SelectQuery, error)

type Column

type Column struct {
	Name    string
	Primary bool

	Descriptor *fields.Descriptor

	Index []int
	Order int
}

type DB

type DB struct {
	Conn   *sql.DB
	Schema *Schema
	// contains filtered or unexported fields
}

DB uses a *sql.DB connection that is established by its owner. DB assumes the database connection exists and is alive at all times during the lifecycle of the object.

func NewDB

func NewDB(conn *sql.DB, schema *Schema) *DB

func (*DB) BaseQuery

func (db *DB) BaseQuery(ctx context.Context, query *BaseSelectQuery) ([]interface{}, error)

func (*DB) DeleteRow

func (db *DB) DeleteRow(ctx context.Context, row interface{}) error

DeleteRow deletes a single row from the database, identified by the row's primary key

row should be a pointer to a struct, for example:

user := &User{Id; 10}
if err := db.DeleteRow(ctx, user); err != nil {

func (*DB) HasTx

func (db *DB) HasTx(ctx context.Context) bool

func (*DB) InsertRow

func (db *DB) InsertRow(ctx context.Context, row interface{}) (sql.Result, error)

InsertRow inserts a single row into the database

row should be a pointer to a struct, for example:

user := &User{Name: "foo"}
if err := db.InsertRow(ctx, user); err != nil {

func (*DB) Query

func (db *DB) Query(ctx context.Context, result interface{}, filter Filter, options *SelectOptions) error

Query fetches a collection of rows from the database

result should be a pointer to a slice of pointers to structs, for example:

var users []*User
if err := db.Query(ctx, &users, nil, nil); err != nil {

func (*DB) QueryExecer

func (db *DB) QueryExecer(ctx context.Context) QueryExecer

func (*DB) QueryRow

func (db *DB) QueryRow(ctx context.Context, result interface{}, filter Filter, options *SelectOptions) error

QueryRow fetches a single row from the database

result should be a pointer to a pointer to a struct, for example:

var user *User
if err := db.Query(ctx, &user, Filter{"id": 10}, nil); err != nil {

func (*DB) UpdateRow

func (db *DB) UpdateRow(ctx context.Context, row interface{}) error

UpdateRow updates a single row in the database, identified by the row's primary key

row should be a pointer to a struct, for example:

user := &User{Id; 10, Name: "bar"}
if err := db.UpdateRow(ctx, user); err != nil {

func (*DB) UpsertRow

func (db *DB) UpsertRow(ctx context.Context, row interface{}) (sql.Result, error)

UpsertRow inserts a single row into the database

row should be a pointer to a struct, for example:

user := &User{Name: "foo"}
if err := db.UpsertRow(ctx, user); err != nil {

func (*DB) WithExistingTx

func (db *DB) WithExistingTx(ctx context.Context, tx *sql.Tx) (context.Context, error)

func (*DB) WithTx

func (db *DB) WithTx(ctx context.Context) (context.Context, *sql.Tx, error)

type DeleteQuery

type DeleteQuery struct {
	Table string
	Where *SimpleWhere
}

DeleteQuery represents a DELETE query

func (*DeleteQuery) ToSQL

func (q *DeleteQuery) ToSQL() (string, []interface{})

ToSQL builds a parameterized DELETE FROM x WHERE a = ? AND b = ? statement

type Filter

type Filter map[string]interface{}

type InsertQuery

type InsertQuery struct {
	Table   string
	Columns []string
	Values  []interface{}
}

InsertQuery represents a INSERT query

func (*InsertQuery) ToSQL

func (q *InsertQuery) ToSQL() (string, []interface{})

ToSQL builds a parameterized INSERT INTO x (a, b) VALUES (?, ?) statement

type NullBytes

type NullBytes struct {
	Bytes []byte
	Valid bool
}

func (*NullBytes) Scan

func (b *NullBytes) Scan(value interface{}) error

func (*NullBytes) Value

func (b *NullBytes) Value() (driver.Value, error)

type PrimaryKeyType

type PrimaryKeyType int
const (
	AutoIncrement PrimaryKeyType = iota
	UniqueId
)

type QueryExecer

type QueryExecer interface {
	Query(query string, args ...interface{}) (*sql.Rows, error)
	QueryRow(query string, args ...interface{}) *sql.Row
	Exec(query string, args ...interface{}) (sql.Result, error)

	QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
	QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
	ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
}

A QueryExecer is either a *sql.Tx or a *sql.DB.

type SQLQuery

type SQLQuery interface {
	ToSQL() (string, []interface{})
}

type Schema

type Schema struct {
	ByName map[string]*Table
	ByType map[reflect.Type]*Table
}

func NewSchema

func NewSchema() *Schema

func (*Schema) BuildStruct added in v0.5.0

func (s *Schema) BuildStruct(tableName string, row []driver.Value) (interface{}, error)

BuildStruct scans a row in struct's column order into a struct pointer.

func (*Schema) MakeDeleteRow

func (s *Schema) MakeDeleteRow(row interface{}) (*DeleteQuery, error)

MakeDeleteRow builds a new DeleteQuery to delete row

func (*Schema) MakeInsertRow

func (s *Schema) MakeInsertRow(row interface{}) (*InsertQuery, error)

MakeInsertRow builds a new InsertQuery to insert row

func (*Schema) MakeSelect

func (s *Schema) MakeSelect(result interface{}, filter Filter, options *SelectOptions) (*BaseSelectQuery, error)

func (*Schema) MakeSelectRow

func (s *Schema) MakeSelectRow(result interface{}, filter Filter, options *SelectOptions) (*BaseSelectQuery, error)

func (*Schema) MakeTester

func (s *Schema) MakeTester(table string, filter Filter) (Tester, error)

func (*Schema) MakeUpdateRow

func (s *Schema) MakeUpdateRow(row interface{}) (*UpdateQuery, error)

MakeUpdateRow builds a new UpdateQuery to update row

func (*Schema) MakeUpsertRow

func (s *Schema) MakeUpsertRow(row interface{}) (*UpsertQuery, error)

MakeUpsertRow builds a new UpsertQuery to upsqrt row

func (*Schema) MustRegisterType

func (s *Schema) MustRegisterType(table string, primaryKeyType PrimaryKeyType, value interface{})

func (*Schema) ParseRows

func (s *Schema) ParseRows(query *SelectQuery, res *sql.Rows) ([]interface{}, error)

func (*Schema) RegisterType

func (s *Schema) RegisterType(table string, primaryKeyType PrimaryKeyType, value interface{}) error

func (*Schema) UnbuildStruct added in v0.5.0

func (s *Schema) UnbuildStruct(tableName string, strct interface{}) ([]interface{}, error)

UnbuildStruct extracts SQL values from a struct.

type SelectOptions

type SelectOptions struct {
	Where  string
	Values []interface{}

	OrderBy string
	Limit   int
}

func (*SelectOptions) IncludeFilter

func (s *SelectOptions) IncludeFilter(table *Table, filter Filter) error

type SelectQuery

type SelectQuery struct {
	Table   string
	Columns []string

	Options *SelectOptions
}

SelectQuery represents a SELECT query

func (*SelectQuery) ToSQL

func (q *SelectQuery) ToSQL() (string, []interface{})

ToSQL builds a parameterized SELECT a, b, c FROM x ... statement

type SimpleWhere

type SimpleWhere struct {
	Columns []string
	Values  []interface{}
}

SimpleWhere represents a simple WHERE clause

func (*SimpleWhere) ToSQL

func (w *SimpleWhere) ToSQL() (string, []interface{})

ToSQL builds a `a = ? AND b = ?` clause

type Table

type Table struct {
	Name           string
	Type           reflect.Type
	PrimaryKeyType PrimaryKeyType

	Columns       []*Column
	ColumnsByName map[string]*Column

	Scanners *sync.Pool
}

type Tester

type Tester interface {
	Test(row interface{}) bool
}

type UpdateQuery

type UpdateQuery struct {
	Table   string
	Columns []string
	Values  []interface{}
	Where   *SimpleWhere
}

UpdateQuery represents a UPDATE query

func (*UpdateQuery) ToSQL

func (q *UpdateQuery) ToSQL() (string, []interface{})

ToSQL builds a parameterized UPDATE x SET a = ?, b = ? WHERE c = ? statement

type UpsertQuery

type UpsertQuery struct {
	Table   string
	Columns []string
	Values  []interface{}
}

UpsertQuery represents a INSERT ... ON DUPLICATE KEY UPDATE query

func (*UpsertQuery) ToSQL

func (q *UpsertQuery) ToSQL() (string, []interface{})

ToSQL builds a parameterized INSERT INTO x (a, b) VALUES (?, ?) statement

Jump to

Keyboard shortcuts

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