octobe

package module
v2.0.0 Latest Latest
Warning

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

Go to latest
Published: Dec 22, 2023 License: MIT Imports: 2 Imported by: 0

README

Alt text

License Tag Version Codacy Badge Go Reference

A slim golang package for programmers that love to write raw SQL, but has a problem with boilerplate code. This package will help you structure and the way you work with your database.

The main advantage with this library is to enable developers to build a predictable and consistent database layer without losing the feeling of freedom. The octobe library draws inspiration from http handlers, but where handlers interface with the database instead.

Read package documentation at https://pkg.golang.ir/github.com/Kansuler/octobe

Usage

Postgres Example
package main

import (
	"context"
	"github.com/Kansuler/octobe/v2"
	"github.com/Kansuler/octobe/v2/driver/postgres"
	"github.com/google/uuid"
	"os"
)

func main() {
    ctx := context.Background()
    dsn := os.Getenv("DSN")
    if dsn == "" {
        panic("DSN is not set")
    }

    // Create a new octobe instance with a postgres driver, insert optional options for configuration that applies to
    // every session.
    o, err := octobe.New(postgres.Open(ctx, dsn, postgres.WithTransaction(postgres.TxOptions{})))
    if err != nil {
        panic(err)
    }

    // Begin a new session, since `postgres.WithTransaction` is set, this will start a postgres transaction.
    session, err := o.Begin(context.Background())
    if err != nil {
        panic(err)
    }

    // WatchRollback will rollback the transaction if var err is not nil when the function returns.
    defer session.WatchRollback(func() error {
        return err
    })

    name := uuid.New().String()

    // Insert a new product into the database, and return a Product struct.
    product1, err := postgres.Execute(session, AddProduct(name))
    if err != nil {
        panic(err)
    }

    // Select the product from the database by name, and return a Product struct.
    product2, err := postgres.Execute(session, ProductByName(name))
    if err != nil {
        panic(err)
    }

    // Commit the transaction, if err is not nil, the transaction will be rolled back via WatchRollback.
    err = session.Commit()
    if err != nil {
        panic(err)
    }
}

// Product is a model that represents a product in the database
type Product struct {
    ID   int
    Name string
}

// AddProduct is an octobe handler that will insert a product into the database, and return a product model.
// In the octobe.Handler signature the first generic is the type of driver builder, and the second is the returned type.
func AddProduct(name string) postgres.Handler[Product] {
    return func(builder postgres.Builder) (Product, error) {
        var product Product
        query := builder(`
            INSERT INTO products (name) VALUES ($1) RETURNING id, name;
        `)

        query.Arguments(name)
        err := query.QueryRow(&product.ID, &product.Name)
        return product, err
    }
}


// ProductByName is an octobe handler that will select a product from the database by name, and return a product model.
// In the octobe.Handler signature the first generic is the type of driver builder, and the second is the returned type.
func ProductByName(name string) postgres.Handler[Product] {
	return func(builder postgres.Builder) (Product, error) {
		var product Product
		query := builder(`
			SELECT id, name FROM products WHERE name = $1;
		`)

		query.Arguments(name)
		err := query.QueryRow(&product.ID, &product.Name)
		return product, err
	}
}

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrAlreadyUsed = errors.New("query already used")

Functions

This section is empty.

Types

type Driver

type Driver[DRIVER any, CONFIG any, BUILDER any] interface {
	Begin(ctx context.Context, opts ...Option[CONFIG]) (Session[BUILDER], error)
}

Driver is a signature that holds the specific driver in the Octobe context.

type Octobe

type Octobe[DRIVER any, CONFIG any, BUILDER any] struct {
	// contains filtered or unexported fields
}

Octobe struct that holds the database session

func New

func New[DRIVER any, CONFIG any, BUILDER any](init Open[DRIVER, CONFIG, BUILDER]) (*Octobe[DRIVER, CONFIG, BUILDER], error)

New creates a new Octobe instance.

func (*Octobe[DRIVER, CONFIG, BUILDER]) Begin

func (ob *Octobe[DRIVER, CONFIG, BUILDER]) Begin(ctx context.Context, opts ...Option[CONFIG]) (Session[BUILDER], error)

Begin a new session of queries, this will return a Session instance that can be used for handling queries. Options can be passed to the driver for specific configuration that overwrites the default configuration given at instantiation of the Octobe instance.

type Open

type Open[DRIVER any, CONFIG any, BUILDER any] func() (Driver[DRIVER, CONFIG, BUILDER], error)

Open is a signature that can be used for opening a driver, it should always return a driver with set signature of types for the local driver.

type Option

type Option[CONFIG any] func(cfg *CONFIG)

Option is a signature that can be used for passing options to a driver

type Session

type Session[BUILDER any] interface {
	// Commit will commit the transaction.
	Commit() error

	// Rollback will rollback the transaction.
	Rollback() error

	// WatchRollback will watch for error within the function, if it's set WatchRollback will rollback the transaction.
	WatchRollback(func() error)

	// Builder returns a new builder from the driver that is used to build queries for that specific driver.
	Builder() BUILDER
}

Session is a signature that has a

type Void

type Void *struct{}

Void is a type that can be used for returning nothing from a handler.

Directories

Path Synopsis
driver

Jump to

Keyboard shortcuts

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