sqlstruct

package module
v0.1.7 Latest Latest
Warning

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

Go to latest
Published: Sep 22, 2022 License: MIT Imports: 13 Imported by: 0

README

Use Go structs with database/sql

Two goals:

  1. Build SQL statements (SELECT, INSERT, UPDATE, DELETE) from structs.

  2. Scan *sql.Row and *sql.Rows into structs.

Principles:

  1. Does two things, and does them well. Not an ORM. Not a framework. Does not take over the entire app.
  2. Handles NULLs and custom types.
  3. Allows to specify which fields to use for every operation (via named field sets that we call facets).
  4. Works with github.com/andreyvit/sqlexpr.

Installation:

go get -u github.com/andreyvit/sqlstruct/cmd/sqlstruct

Example

Given a struct like:

type Post struct {
    ID   int64  `json:"-" db:"id,pk"`

    CreatedAt time.Time `db:"created_at,immutable"`
    UpdatedAt time.Time `db:"updated_at"`
    DeletedAt time.Time `db:"deleted_at,nullable"`

    Title string `db:"title"`
    Body  string `db:"description"`
}

Generates scanning functions that .Scan into this struct:

func scanPost(row *sql.Row, fct facet) (*model.Post, error)
func scanPostInto(row *sql.Row, v *model.Post, fct facet) error

func scanNextPost(rows *sql.Rows, fct facet) (*model.Post, error)
func scanNextPostInto(rows *sql.Rows, v *model.Post, fct facet) error

func scanAllPosts(rows *sql.Rows, fct facet) ([]*model.Post, error)

Generates SQL building functions that build sqlexpr statements for selecting, inserting, updating and deleting:

func buildSelectFromPosts(fct facet) *sqlexpr.Select
func buildInsertPost(v *model.Post, setFct, retFct facet) *sqlexpr.Insert
func buildUpdatePost(v *model.Post, condFct, updateFct, retFct facet) *sqlexpr.Update
func buildDeletePost(v *model.Post, condFct facet) *sqlexpr.Delete

func addPostFields(s sqlexpr.Fieldable, fct facet)
func addPostSetters(s sqlexpr.Settable, v *model.Post, fct facet)
func addPostConditions(s sqlexpr.Whereable, v *model.Post, fct facet)

And generates execution functions that tie all the above together: they generate a statement, call a callback to customize it, then execute it via sqlexpr.Executor (which is an interface that *sql.DB and *sql.Tx conform to), then scan the results:

func fetchPost(ctx context.Context, ex sqlexpr.Executor, fct facet, f func(*sqlexpr.Select)) (*model.Post, error)
func fetchPosts(ctx context.Context, ex sqlexpr.Executor, fct facet, f func(*sqlexpr.Select)) ([]*model.Post, error)
func insertPost(ctx context.Context, ex sqlexpr.Executor, v *model.Post, setFct, retFct facet, f func(*sqlexpr.Insert)) error
func updatePost(ctx context.Context, ex sqlexpr.Executor, v *model.Post, condFct, updateFct, retFct facet, f func(*sqlexpr.Update)) error
func deletePost(ctx context.Context, ex sqlexpr.Executor, v *model.Post, condFct facet, f func(*sqlexpr.Delete)) error

Facet enum is generated based on all facets (hashtags) defined by the structs. The facets determine the list of fields that are used in WHERE, SET, SELECT or RETURNING clauses. Using facets, you can fetch or update only the relevant fields.

Development

Use modd (go get github.com/cortesi/modd/cmd/modd) to re-run tests automatically during development by running modd (recommended).

License

MIT.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Generate

func Generate(src []byte, opt Options) ([]byte, error)

func GeneratePkg

func GeneratePkg(pkgPatterns []string, opt Options) ([]byte, error)

Types

type AliasType

type AliasType struct {
	Name    Name
	AliasOf Type
}

func (AliasType) MakeZeroValue

func (t AliasType) MakeZeroValue(imp importer) string

func (AliasType) MakeZeroValueCheck

func (t AliasType) MakeZeroValueCheck(imp importer, v string) string

func (AliasType) String

func (t AliasType) String() string

func (AliasType) TypeName

func (t AliasType) TypeName() Name

type CodingStrategy

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

type Col

type Col struct {
	IndexInStruct int

	DBNameConst string
	DBName      string
	FieldName   string
	Facets      []*Facet
	Type        Type
	TempVarName string
	CodingStg   CodingStrategy

	ReadOnly         bool
	ExcludeFromAll   bool
	Nullable         bool
	NullableStrategy CodingStrategy
	Immutable        bool
	InsertDefault    bool
}

func (*Col) AddFacet

func (c *Col) AddFacet(fct *Facet)

func (*Col) HasFacet

func (c *Col) HasFacet(f *Facet) bool

func (*Col) IncludedInFacet

func (c *Col) IncludedInFacet(f *Facet) bool

type Embedding

type Embedding struct {
	FieldName string
	Facets    []*Facet
	Struct    *Struct
	Cols      []*Col
	DBPrefix  string
	Nullable  bool
	Immutable bool
}

type Facet

type Facet struct {
	Name  string
	Ident string
	Value int
}

type File added in v0.1.2

type File struct {
	// contains filtered or unexported fields
}

type Logger

type Logger interface {
	Printf(format string, v ...interface{})
}

type Name

type Name struct {
	Pkg   string
	Ident string
}

func (Name) Equal

func (n Name) Equal(o Name) bool

func (Name) FQN

func (n Name) FQN() string

func (Name) String

func (n Name) String() string

type NullWrapping

type NullWrapping struct {
	Type       Type
	ValueType  Type
	ValidField string
	ValueField string
	Next       CodingStrategy
}

type Options

type Options struct {
	PkgName string

	Published bool

	Logger  Logger
	Verbose bool
}

type PtrType

type PtrType struct {
	To Type
}

func (PtrType) MakeZeroValue

func (t PtrType) MakeZeroValue(imp importer) string

func (PtrType) MakeZeroValueCheck

func (t PtrType) MakeZeroValueCheck(imp importer, v string) string

func (PtrType) String

func (t PtrType) String() string

func (PtrType) TypeName

func (t PtrType) TypeName() Name

type PtrWrapping added in v0.1.1

type PtrWrapping struct {
	Type Type
	Next CodingStrategy
}

type Struct

type Struct struct {
	Persistent bool
	IsValue    bool
	Skipped    bool

	Name Name
	File *File

	TableName      string
	TableNameConst string
	SingularIdent  string
	PluralIdent    string

	Cols []*Col

	Embeddings []*Embedding

	Facets []*Facet
	// contains filtered or unexported fields
}

func (*Struct) MakeZeroValue

func (s *Struct) MakeZeroValue(imp importer) string

func (*Struct) MakeZeroValueCheck

func (s *Struct) MakeZeroValueCheck(imp importer, v string) string

func (*Struct) String

func (s *Struct) String() string

func (*Struct) TypeName

func (s *Struct) TypeName() Name

type Type

type Type interface {
	TypeName() Name
	MakeZeroValue(imp importer) string
	// Returns empty string to indicate failure
	MakeZeroValueCheck(imp importer, v string) string
	fmt.Stringer
}

type UnknownType

type UnknownType Name

func (UnknownType) MakeZeroValue

func (t UnknownType) MakeZeroValue(imp importer) string

func (UnknownType) MakeZeroValueCheck

func (t UnknownType) MakeZeroValueCheck(imp importer, v string) string

func (UnknownType) String

func (t UnknownType) String() string

func (UnknownType) TypeName

func (u UnknownType) TypeName() Name

type UnsupportedType

type UnsupportedType struct {
	Name Name
}

func (UnsupportedType) MakeZeroValue

func (t UnsupportedType) MakeZeroValue(imp importer) string

func (UnsupportedType) MakeZeroValueCheck

func (t UnsupportedType) MakeZeroValueCheck(imp importer, v string) string

func (UnsupportedType) String

func (t UnsupportedType) String() string

func (UnsupportedType) TypeName

func (t UnsupportedType) TypeName() Name

type WellKnownPrimitive

type WellKnownPrimitive struct {
	Name      Name
	ZeroValue string
}

func (WellKnownPrimitive) MakeZeroValue

func (t WellKnownPrimitive) MakeZeroValue(imp importer) string

func (WellKnownPrimitive) MakeZeroValueCheck

func (t WellKnownPrimitive) MakeZeroValueCheck(imp importer, v string) string

func (WellKnownPrimitive) String

func (t WellKnownPrimitive) String() string

func (WellKnownPrimitive) TypeName

func (t WellKnownPrimitive) TypeName() Name

type WellKnownStruct

type WellKnownStruct struct {
	Name Name

	IsZeroMethod string
	ValidField   string
	EqualMethod  string
}

func (WellKnownStruct) MakeZeroValue

func (t WellKnownStruct) MakeZeroValue(imp importer) string

func (WellKnownStruct) MakeZeroValueCheck

func (t WellKnownStruct) MakeZeroValueCheck(imp importer, v string) string

func (WellKnownStruct) String

func (t WellKnownStruct) String() string

func (WellKnownStruct) TypeName

func (t WellKnownStruct) TypeName() Name

type WrappedExpr

type WrappedExpr struct {
	Vars   []string
	Before []string
	Value  string
	DBExpr string
	After  []string
}

func (*WrappedExpr) Append

func (we *WrappedExpr) Append(another *WrappedExpr)

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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