depot

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Apr 3, 2021 License: Apache-2.0 Imports: 5 Imported by: 0

README

depot

CI Status Go Report Card Package Doc Releases

depot is a thin abstraction layer for accessing relational databases using Golang (technically, the concepts used by depot should be applicable to other databases as well).

depot is implemented to provide a more convenient API to applications while stil remaining what I consider to be idiomatic go.

depot is under heavy development and not ready for production systems.

Usage

Installation

$ go get github.com/halimath/depot

API

The fundamental type to interact with depot is the Session. A Session is bound to a Context and wraps a database transaction. To obtain a session, you use a SessionFactory which in turn wraps a sql.DB. You may create a SessionFactory either by calling the depot.Open function passing in the same arguments you would pass to sql.Open, or you create a sql.DB value yourself (i.e. if you want to configure connection pooling) and pass this to depot.NewSessionFactory.

Once you have a factory, call its Session method to create a session.

The Session provides methods to commit or rollback the wrapped transaction. Make sure you call one of these methods to finish the transaction.


factory := depot.Open("sqlite3", "./test.db")

ctx := context.Background()
session, ctx, err := factory.Session(ctx)

err := session.Insert(depot.Into("test"), depot.Values{
    "id": 1,
    "message": "hello, world",
})
if err != nil {
    log.Fatal(err)
}

if err := session.CommitIfNoError(); err != nil {
    log.Fatal(err)
}

See acceptance-test.go for an almost complete API example.

Code Generator

The code generator provided by depot can be used to generate data access types - called repositories - for Go-struct types.

In order to generate a repository the struct's fields must be tagged using standard Go tags with the key depot. The value is the column name to map the field to.

See the example app for a working example.

Open Issues

depot is under heavy development. Expect a lot of bugs. A list of open features can be found in TODO.md.

License

Copyright 2021 Alexander Metzner.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Documentation

Overview

Package depot implements a small abstraction layer for accessing sql (and potentially other) databases.

depot is build around two concepts: values and clauses. See the respective descriptions for details.

depot also provides a code generator used to generate repository types from regulare go structs with field tags. The resulting code uses no reflection and provides a typesafe interface to interact with the database.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoResult is returned when queries execpted to match (at least) on row
	// match no row at all.
	ErrNoResult = errors.New("no result")
	// ErrMarkedForRollback is returned when trying to commit a Session which is
	// already marked for rollback only.
	ErrMarkedForRollback = errors.New("session has been marked for rollback")
)

Functions

This section is empty.

Types

type Clause

type Clause interface {
	// SQL returns the SQL query part expressed by this clause.
	SQL() string

	// Args returns any positional arguments used by this clause.
	Args() []interface{}
}

Clause defines the interface implemented by all clauses used to describe different parts of a query. A clause captures optional arguments.

type ColsClause

type ColsClause interface {
	Clause

	// Names returns the list of column names to select in query order.
	Names() []string
	// contains filtered or unexported methods
}

ColsClause defines a Clause used to select columns.

func Cols

func Cols(cols ...string) ColsClause

Cols implements a factory for a ColsClause.

type Factory

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

Factory provides functions to create new Sessions.

func NewSessionFactory

func NewSessionFactory(pool *sql.DB) *Factory

NewSessionFactory creates a new Factory using connections from the given pool.

func Open

func Open(driver, dsn string) (*Factory, error)

Open opens a new database pool and wraps it as a SessionFactory.

func (*Factory) Close

func (f *Factory) Close()

Close closes the factory and the underlying pool

func (*Factory) Session

func (f *Factory) Session(ctx context.Context) (*Session, context.Context, error)

Session creates a new Session and binds it to the given context.

type OrderByClause

type OrderByClause interface {
	Clause
	// contains filtered or unexported methods
}

OrderByClause defines the interface used to sort rows.

func Asc

func Asc(column string) OrderByClause

Asc returns an OrderByClause sorting by the given column in ascending order.

func Desc

func Desc(column string) OrderByClause

Desc returns an OrderByClause sorting by the given column in descending order.

func OrderBy

func OrderBy(column string, asc bool) OrderByClause

OrderBy constructs a new OrderByClause.

type Scanner

type Scanner interface {
	Scan(vals ...interface{}) error
}

Scanner defines the Scan method provided by sql.Rows and sql.Row, as the sql package does not define such an interface.

type Session

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

A session defines an interaction session with the database. A session uses a single transaction and is bound to a single Context. A session provides an abstract interface built around Values and Clauses.

func GetSession

func GetSession(ctx context.Context) *Session

GetSession returns the Session associated with the given Context. This function panics when no Session has been stored in the Context.

func (*Session) Commit

func (s *Session) Commit() error

Commit commits the session's transaction and returns an error if the commit fails.

func (*Session) CommitIfNoError

func (s *Session) CommitIfNoError() error

CommitIfNoError tries to commit the transaction but performs a rollback in case an error has been logged before.

func (*Session) DeleteMany

func (s *Session) DeleteMany(from TableClause, where ...Clause) error

DeleteMany deletes all matching rows from the database.

func (*Session) Error

func (s *Session) Error(err error)

Error marks the transaction as failed so it cannot be committed later on. Calling Error with a nil error clears the error state of the transaction.

func (*Session) InsertOne

func (s *Session) InsertOne(into TableClause, values Values) error

InsertOne inserts a single row.

func (*Session) QueryCount

func (s *Session) QueryCount(from TableClause, clauses ...Clause) (count int, err error)

QueryCount executes a counting query and returns the number of matching rows.

func (*Session) QueryMany

func (s *Session) QueryMany(cols ColsClause, from TableClause, clauses ...Clause) ([]Values, error)

QueryMany executes a query that is expected to match any number of rows. The rows are returned as Values. If the query did not match any row an empty slice is returned.

func (*Session) QueryOne

func (s *Session) QueryOne(cols ColsClause, from TableClause, where ...Clause) (Values, error)

QueryOne executes a query that is expected to return a single result. The columns, table and selection criteria are given as Clauses. QueryOne returns the selected values which is never nil. ErrNoResult is returned when the query did not match any rows.

func (*Session) Rollback

func (s *Session) Rollback() error

Rollback rolls the session's transaction back and returns any error raised during the rollback.

func (*Session) UpdateMany

func (s *Session) UpdateMany(table TableClause, values Values, where ...Clause) error

UpdateMany updates all matching rows with the same values given.

type TableClause

type TableClause interface {
	Clause
	// contains filtered or unexported methods
}

TableClause implements a clause used to name a table.

func From

func From(table string) TableClause

From is an alias for Table supporting a more DSL style interface.

func Into

func Into(table string) TableClause

Into is an alias for Table supporting a more DSL style interface.

func Table

func Table(table string) TableClause

Table creates a TableClause from the single table name.

type Values

type Values map[string]interface{}

Values contains the persistent column values for an entity either after reading the values from the database to re-create the entity value or to persist the entity's values in the database (either for insertion or update).

type WhereClause

type WhereClause interface {
	Clause
	// contains filtered or unexported methods
}

WhereClause defines the interface implemented by all clauses that contribute a "where" condition.

func EQ

func EQ(column string, value interface{}) WhereClause

EQ creates a WhereClause comparing a column's value for equality.

func GE

func GE(column string, value interface{}) WhereClause

GE creates a WhereClause comparing a column's value for greater or equal.

func GT

func GT(column string, value interface{}) WhereClause

GT creates a WhereClause comparing a column's value for greater than.

func In

func In(column string, values ...interface{}) WhereClause

In creates a WhereClause using the `in` operator.

func LE

func LE(column string, value interface{}) WhereClause

LE creates a WhereClause comparing a column's value for less equal.

func LT

func LT(column string, value interface{}) WhereClause

LT creates a WhereClause comparing a column's value for less than.

func Where

func Where(column string, value interface{}) WhereClause

Where is an alias for EQ.

Directories

Path Synopsis
cmd
depot command
internal
generate
Package generate implements code generation for repository types.
Package generate implements code generation for repository types.

Jump to

Keyboard shortcuts

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