jdb

package module
v0.0.0-...-4e5a105 Latest Latest
Warning

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

Go to latest
Published: Jun 18, 2018 License: MIT Imports: 13 Imported by: 0

README

jdb

jdb is a simple document database built on the JSON features of MySQL, PostgreSQL, and SQLite.

It provides a migration helper, query builder, and struct mapper.

This package is currently in development and the API is not stable.

Usage

package main

import (
	"context"
	"fmt"
	"time"

	"github.com/silas/jdb"
	_ "github.com/silas/jdb/dialect/sqlite3"
)

type Name struct {
	GivenName  string   `jdb:",omitempty"`
	FamilyName string   `jdb:",omitempty"`
	Aliases    []string `jdb:",omitempty"`
}

type User struct {
	Kind       string    `jdb:"-kind"`
	ID         string    `jdb:"-id"`
	Email      string    `jdb:",uniquestringkey"`
	Name       Name      `jdb:",omitempty"`
	Age        int       `jdb:",omitempty"`
	CreateTime time.Time `jdb:"-createtime"`
	UpdateTime time.Time `jdb:"-updatetime"`
}

func (u User) DatabaseNumericKey() (*float64, bool) {
	if u.Age > 0 {
		age := float64(u.Age)
		return &age, true
	} else {
		return nil, true
	}
}

func main() {
	ctx := context.Background()

	db, err := jdb.Open("sqlite3", "test.db?cache=shared")
	if err != nil {
		panic(err)
	}

	err = db.Migrate(ctx)
	if err != nil {
		panic(err)
	}

	err = db.Tx(ctx, func(tx *jdb.Tx) error {
		user := User{
			ID:    "1",
			Email: "jane@example.com",
			Name: Name{
				GivenName:  "Jane",
				FamilyName: "Doe",
				Aliases:    []string{"Janie", "Roe"},
			},
			Age: 34,
		}

		err = db.Query("user").Insert(user).Exec(ctx, tx)
		if err != nil {
			return err
		}

		return tx.Commit()
	})
	if err != nil {
		panic(err)
	}

	err = db.Tx(ctx, func(tx *jdb.Tx) error {
		var user User
		err = db.Query("user").Get("1").Select().First(ctx, tx, &user)
		if err != nil {
			return err
		}

		fmt.Println(user)

		return nil
	})
	if err != nil {
		panic(err)
	}
}

Run with required sqlite3 flags:

$ go run \
  -tags "libsqlite3 $(uname -s | tr '[:upper:]' '[:lower:]') json1" \
  main.go

This will result in a row that looks something like the following:

sqlite> SELECT * FROM jdb WHERE kind = 'user' AND id = '1';
             kind = user
               id = 1
      parent_kind = ¤
        parent_id = ¤
unique_string_key = jane@example.com
       string_key = ¤
      numeric_key = 34.0
         time_key = ¤
             data = {"Email":"jane@example.com","Name":{"GivenName":"Jane","FamilyName":"Doe","Aliases":["Janie","Roe"]},"Age":34}
      create_time = 2018-06-12 12:41:37.035
      update_time = 2018-06-12 12:41:37.035

With the following schema (in SQLite):

sqlite> .schema
CREATE TABLE jdb (
  kind VARCHAR(64),
  id VARCHAR(64),
  parent_kind VARCHAR(64),
  parent_id VARCHAR(64),
  unique_string_key VARCHAR(255),
  string_key VARCHAR(255),
  numeric_key REAL,
  time_key DATETIME,
  data JSON,
  create_time DATETIME NOT NULL DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')),
  update_time DATETIME NOT NULL DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')),
  PRIMARY KEY (kind, id),
  FOREIGN KEY (parent_kind, parent_id) REFERENCES jdb (kind, id)
);
CREATE INDEX jdb_r2 ON jdb (create_time);
CREATE INDEX jdb_r3 ON jdb (update_time);
CREATE UNIQUE INDEX jdb_r4 ON jdb (kind, unique_string_key);
CREATE INDEX jdb_r5 ON jdb (kind, string_key);
CREATE INDEX jdb_r6 ON jdb (kind, numeric_key);
CREATE INDEX jdb_r7 ON jdb (kind, time_key);
CREATE INDEX jdb_r8 ON jdb (kind, create_time);
CREATE INDEX jdb_r9 ON jdb (kind, update_time);
CREATE INDEX jdb_r10 ON jdb (kind, id, parent_kind);
CREATE INDEX jdb_r11 ON jdb (parent_kind, parent_id, kind, unique_string_key);
CREATE INDEX jdb_r12 ON jdb (parent_kind, parent_id, kind, string_key);
CREATE INDEX jdb_r13 ON jdb (parent_kind, parent_id, kind, numeric_key);
CREATE INDEX jdb_r14 ON jdb (parent_kind, parent_id, kind, time_key);
CREATE INDEX jdb_r15 ON jdb (parent_kind, parent_id, kind, create_time);
CREATE INDEX jdb_r16 ON jdb (parent_kind, parent_id, kind, update_time);

License

This work is licensed under the MIT License (see the LICENSE and NOTICE files).

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrReadOnlyMode = errors.New("jdb: read-only mode")
	ErrIDNotFound   = errors.New("jdb: id not found")
	ErrNotFound     = errors.New("jdb: not found")
)

Functions

func Dialect

func Dialect(driverName string) (dialect.Dialect, error)

func RegisterDialect

func RegisterDialect(driverName string, fn dialect.Dialect)

Types

type Client

type Client struct {
	ID              SelectWhereColumn
	Kind            SelectWhereColumn
	ParentKind      SelectWhereColumn
	ParentId        SelectWhereColumn
	UniqueStringKey WhereColumn
	StringKey       WhereColumn
	NumericKey      WhereColumn
	TimeKey         WhereColumn
	Data            SelectColumn
	CreateTime      SelectWhereColumn
	UpdateTime      SelectWhereColumn
	// contains filtered or unexported fields
}

func Open

func Open(driverName, dataSourceName string, opts ...Option) (*Client, error)

func (*Client) Close

func (c *Client) Close() error

func (*Client) Migrate

func (c *Client) Migrate(ctx context.Context) error

func (*Client) Path

func (c *Client) Path(key ...string) *PathField

func (*Client) Query

func (c *Client) Query(kind string) *Query

func (*Client) Tx

func (c *Client) Tx(ctx context.Context, fn func(*Tx) error) error

type Condition

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

func And

func And(args ...Condition) Condition

func Eq

func Eq(f WhereField, v interface{}) Condition

func False

func False() Condition

func Gt

func Gt(f WhereField, v interface{}) Condition

func Gte

func Gte(f WhereField, v interface{}) Condition

func In

func In(f WhereField, v ...interface{}) Condition

func Like

func Like(f WhereField, v interface{}) Condition

func Lt

func Lt(f WhereField, v interface{}) Condition

func Lte

func Lte(f WhereField, v interface{}) Condition

func NotEq

func NotEq(f WhereField, v interface{}) Condition

func NotIn

func NotIn(f WhereField, v ...interface{}) Condition

func NotLike

func NotLike(f WhereField, v interface{}) Condition

func Or

func Or(args ...Condition) Condition

func True

func True() Condition

type DatabaseNumericKey

type DatabaseNumericKey interface {
	DatabaseNumericKey() (*float64, bool)
}

type DatabaseStringKey

type DatabaseStringKey interface {
	DatabaseStringKey() (*string, bool)
}

type DatabaseTimeKey

type DatabaseTimeKey interface {
	DatabaseTimeKey() (*time.Time, bool)
}

type DatabaseUniqueStringKey

type DatabaseUniqueStringKey interface {
	DatabaseUniqueStringKey() (*string, bool)
}

type DeleteBuilder

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

func (*DeleteBuilder) Exec

func (b *DeleteBuilder) Exec(ctx context.Context, tx *Tx) error

func (*DeleteBuilder) ToSQL

func (b *DeleteBuilder) ToSQL() (string, []interface{}, error)

type Error

type Error = jdberrors.Error

type ErrorType

type ErrorType = jdberrors.ErrorType

type InsertBuilder

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

func (*InsertBuilder) Add

func (b *InsertBuilder) Add(values ...interface{}) *InsertBuilder

func (*InsertBuilder) Exec

func (b *InsertBuilder) Exec(ctx context.Context, tx *Tx) error

func (*InsertBuilder) ToSQL

func (b *InsertBuilder) ToSQL() (string, []interface{}, error)

type Option

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

func ReadOnly

func ReadOnly(readOnly bool) Option

func Table

func Table(table string) Option

type Order

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

func (Order) OrderDesc

func (o Order) OrderDesc() bool

func (Order) OrderField

func (o Order) OrderField() string

type PathField

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

func (PathField) Asc

func (p PathField) Asc() Order

func (PathField) Desc

func (p PathField) Desc() Order

func (PathField) Index

func (p PathField) Index(index int) PathField

func (PathField) Key

func (p PathField) Key(key string) PathField

type Query

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

func (*Query) Count

func (q *Query) Count() *SelectBuilder

func (*Query) Delete

func (q *Query) Delete(ids ...string) *DeleteBuilder

func (*Query) Get

func (q *Query) Get(ids ...string) *WhereBuilder

func (*Query) Insert

func (q *Query) Insert(values ...interface{}) *InsertBuilder

func (*Query) Select

func (q *Query) Select(columns ...SelectField) *SelectBuilder

func (*Query) Update

func (q *Query) Update(value interface{}) *UpdateBuilder

func (*Query) Where

func (q *Query) Where(where ...Condition) *WhereBuilder

type QueryBuilder

type QueryBuilder interface {
	ToSQL() (string, []interface{}, error)
}

type Rows

type Rows struct {
	*sql.Rows
	// contains filtered or unexported fields
}

func (*Rows) Close

func (rs *Rows) Close() error

func (*Rows) Err

func (rs *Rows) Err() error

func (*Rows) Next

func (rs *Rows) Next() bool

func (*Rows) Scan

func (rs *Rows) Scan(dest interface{}) error

func (*Rows) ScanAll

func (rs *Rows) ScanAll(dest interface{}) error

type SelectBuilder

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

func (*SelectBuilder) All

func (b *SelectBuilder) All(ctx context.Context, tx *Tx, dest interface{}) error

func (*SelectBuilder) First

func (b *SelectBuilder) First(ctx context.Context, tx *Tx, dest interface{}) error

func (*SelectBuilder) Limit

func (b *SelectBuilder) Limit(v uint64) *SelectBuilder

func (*SelectBuilder) Offset

func (b *SelectBuilder) Offset(v uint64) *SelectBuilder

func (*SelectBuilder) OrderBy

func (b *SelectBuilder) OrderBy(order ...Order) *SelectBuilder

func (*SelectBuilder) Rows

func (b *SelectBuilder) Rows(ctx context.Context, tx *Tx) (*Rows, error)

func (*SelectBuilder) ToSQL

func (b *SelectBuilder) ToSQL() (string, []interface{}, error)

type SelectColumn

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

type SelectField

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

type SelectWhereColumn

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

func (SelectWhereColumn) Asc

func (c SelectWhereColumn) Asc() Order

func (SelectWhereColumn) Desc

func (c SelectWhereColumn) Desc() Order

type Tx

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

func (*Tx) Commit

func (t *Tx) Commit() error

func (*Tx) Now

func (t *Tx) Now(ctx context.Context) (time.Time, error)

type UpdateBuilder

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

func (*UpdateBuilder) Exec

func (b *UpdateBuilder) Exec(ctx context.Context, tx *Tx) error

func (*UpdateBuilder) ToSQL

func (b *UpdateBuilder) ToSQL() (string, []interface{}, error)

type WhereBuilder

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

func (*WhereBuilder) Count

func (b *WhereBuilder) Count() *SelectBuilder

func (*WhereBuilder) Delete

func (b *WhereBuilder) Delete() *DeleteBuilder

func (*WhereBuilder) Select

func (b *WhereBuilder) Select(columns ...SelectField) *SelectBuilder

func (*WhereBuilder) Where

func (b *WhereBuilder) Where(where ...Condition) *WhereBuilder

type WhereColumn

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

func (WhereColumn) Asc

func (c WhereColumn) Asc() Order

func (WhereColumn) Desc

func (c WhereColumn) Desc() Order

type WhereField

type WhereField interface {
	Asc() Order
	Desc() Order
	// contains filtered or unexported methods
}

Directories

Path Synopsis
internal
json
Package json implements encoding and decoding of JSON as defined in RFC 7159.
Package json implements encoding and decoding of JSON as defined in RFC 7159.
ptr
test
db

Jump to

Keyboard shortcuts

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