nidhi

package module
v0.0.0-...-e254655 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2022 License: MIT Imports: 18 Imported by: 0

README

nidhi

Go Reference Go Report Card

PostgreSQL powered document database. WIP.

Roadmap

  • [ - ] Well-Known Types
  • Finish README

Documentation

Index

Constants

View Source
const (
	ColId   = "id"
	ColDoc  = "document"
	ColRev  = `"revision"`
	ColMeta = "metadata"
	ColDel  = "deleted"
)

Variables

This section is empty.

Functions

func Ptr

func Ptr[T any](v T) *T

Ptr is a helper function to use along with various conds. It returns a pointer to a value.

Eg:

&StringCond{Eq: Ptr("nidhi")}

Types

type BoolCond

type BoolCond struct {
	Eq *bool
}

BoolCond is a Cond for [bool] type.

func (*BoolCond) AppendCond

func (c *BoolCond) AppendCond(name string, sb io.StringWriter, args *[]any) error

AppendCond implements Cond for BoolCond

type BoolSliceCond

type BoolSliceCond = SliceCond[string, []string]

BoolSliceCond is convenient alias

type Cond

type Cond interface {
	// AppendCond appends a condition to a query.
	// [field] is the selector on which the condition is applied on.
	AppendCond(field string, w io.StringWriter, args *[]any) error
}

Cond represents a filtering condition like >, <, =.

type Conj

type Conj[F Field] Query[F]

func (*Conj[F]) And

func (q *Conj[F]) And() *Query[F]

func (*Conj[F]) Or

func (q *Conj[F]) Or() *Query[F]

func (*Conj[F]) ReplaceArgs

func (q *Conj[F]) ReplaceArgs(args []any) (*Conj[F], error)

func (*Conj[F]) ToSql

func (q *Conj[F]) ToSql() (string, []any, error)

type CreateOptions

type CreateOptions struct {
	CreateMetadata Metadata
	// Replace is only used if the document with the id already exists.
	// In that scenario,
	// If set to true, will replace the document
	// If set to false, will return an error (default)
	Replace bool
	// ReplaceMetadata is the metadata used for the replace operation.
	// This is only use if Replace is set to true and document already exists.
	ReplaceMetadata Metadata
}

CreateOptions are options for the `Create` operation.

type CreateResult

type CreateResult struct{}

CreateResult is the result of the create call. It doesn't have any fields as of now.

Having an explicit result type will not break future code.

type DeleteManyOptions

type DeleteManyOptions struct {
	// Metadata is the metadata of the document.
	// This will be merged with existing metadata.
	//
	// NOTE: This is a no op if `Permanent` is set.
	Metadata Metadata
	// Permanent if set will hard delete the document.
	Permanent bool
}

DeleteManyOptions are options for the `DeleteMany` operation

type DeleteManyResult

type DeleteManyResult struct {
	// DeleteCount is the number of documents that were deleted.
	DeleteCount int64
}

DeleteManyResult is the result of the delete many call.

type DeleteOptions

type DeleteOptions struct {
	// Metadata is the metadata of the document.
	// This will be merged with existing metadata.
	//
	// NOTE: This is a no op if `Permanent` is set.
	Metadata Metadata
	// Permanent if set will hard delete the document.
	Permanent bool
}

DeleteOptions are options for the `Delete` operation

type DeleteResult

type DeleteResult struct{}

DeleteResult is the result of the delete call. It doesn't have any fields as of now.

Having an explicit result type will not break future changes.

type Document

type Document[T any] struct {
	// Value is the resource.
	Value *T
	// Revision is the revision of this document.
	Revision int64
	// Metadata is the metadata of the document
	Metadata Metadata
	// Deleted indicates whether it a deleted document.
	Deleted bool
}

Document is wrapper for a resource.

type Error

type Error string

Error is the underlying error type returned by functions/methods of this package.

Should always be checked using `errors.Is`. They are almost always wrapped by another error.

const (
	// ErrInvalidCursor is returned when the pagination cursor is invalid.
	ErrInvalidCursor Error = "invalid-cursor"
	// ErrNotFound is returned when a document is not found.
	ErrNotFound Error = "not-found"
	// ErrInvalidCond is returned by Cond in an invalid state.
	ErrInvalidCond Error = "invalid-cond"
)

func (Error) Error

func (e Error) Error() string

Error implements the error interface

type Field

type Field interface {
	// Selector returns the selector expression for this field.
	// Eg: For a field named `title`
	//		JSON_VALUE('$.title' RETURNING JSONB DEFAULT '{}' ON EMPTY)
	Selector() string
}

Field represents a field of a document.

type FloatCond

type FloatCond = OrderedCond[float64]

FloatCond is a Cond for [float64].

type FloatSliceCond

type FloatSliceCond = SliceCond[string, []string]

FloatSliceCond is convenient alias

type GetOptions

type GetOptions struct {
	// ViewMask if set will only populate fields listed in the mask.
	// Only top level fields are supported.
	ViewMask []string
}

GetOptions are options for `Get` operation.

type GetResult

type GetResult[T any] struct {
	Document[T]
}

QueryResult is the result of the get call.

type HookContext

type HookContext struct {
	context.Context
	// contains filtered or unexported fields
}

HookContext is the context passed to Hooks

func NewHookContext

func NewHookContext[T any](ctx context.Context, store *Store[T]) *HookContext

NewHookContext returns a HookContext.

func (*HookContext) Id

func (s *HookContext) Id(v any) string

Id returns the id of the document

func (*HookContext) SetId

func (s *HookContext) SetId(v any, id string)

SetId sets the id field of the document.

type Hooks

type Hooks struct {
	// OnCreate is called on [Store.Create].
	OnCreate OnCreateHook
	// OnGet is called on [Store.Get].
	OnGet OnGetHook
	// OnQuery is called on [Store.Query].
	OnQuery OnQueryHook
	// OnDelete is called on [Store.Delete].
	OnDelete OnDeleteHook
	// OnDeleteMany is called on [Store.DeleteMany].
	OnDeleteMany OnDeleteManyHook
	// OnReplace is called on [Store.Replace].
	OnReplace OnReplaceHook
	// OnUpdate is called on [Store.Update].
	OnUpdate OnUpdateHook
	// OnUpdateMany is called on [Store.UpdateMany].
	OnUpdateMany OnUpdateManyHook
}

Hooks are callbacks that are called on store operations.

The passed values can if modified will change for the op.

type IdFn

type IdFn[T any] func(*T) string

IdFn should return the unique id of a document.

type IntCond

type IntCond = OrderedCond[int64]

IntCond is a Cond for [int64].

type IntSliceCond

type IntSliceCond = SliceCond[string, []string]

IntSliceCond is convenient alias

type JsonCond

type JsonCond struct {
	Any any
}

func (JsonCond) AppendCond

func (f JsonCond) AppendCond(name string, w io.StringWriter, args *[]any) error

type Metadata

type Metadata map[string]MetadataPart

Metadata is the metadata stored against a document.

Metadata is designed to be extendible. These should typically be document agnostic information. Eg:

  • Activity log (create, update timestamps)
  • Common information extracted from the document

type MetadataField

type MetadataField struct {
	Part    string
	Type    string
	Default string
}

MetadataField is a Field for metadata parts

Metadata parts can return a MetadataField

func (*MetadataField) Selector

func (f *MetadataField) Selector() string

type MetadataPart

type MetadataPart interface {
	// MarshalMD marshals the metadata.
	MarshalMDP(w *jsoniter.Stream)
	// UnmarshalMD unmarshals the metdata.
	UnmarshalMDP(r *jsoniter.Iterator)
}

type OnCreateHook

type OnCreateHook func(*HookContext, any, *CreateOptions)

OnCreateHook is the signature of [Hooks.OnCreate] hook.

type OnDeleteHook

type OnDeleteHook func(*HookContext, string, *DeleteOptions)

OnDeleteHook is the function signature for the [Hooks.OnDelete] hook.

type OnDeleteManyHook

type OnDeleteManyHook func(*HookContext, Sqlizer, *DeleteManyOptions)

OnDeleteManyHook is the function signature for the [Hooks.OnDeleteMany] hook.

type OnGetHook

type OnGetHook func(*HookContext, string, *GetOptions)

OnGetHook is the signature of [Hooks.OnGet] hook.

type OnQueryHook

type OnQueryHook func(*HookContext, Sqlizer, *QueryOptions)

OnQueryHook is the signature of [Hooks.OnQuery] hook.

type OnReplaceHook

type OnReplaceHook func(*HookContext, any, *ReplaceOptions)

OnReplaceHook is the signature for the [Hooks.OnReplace] hook.

type OnUpdateHook

type OnUpdateHook func(*HookContext, string, any, *UpdateOptions)

OnUpdateHook is the signature for the [Hooks.OnUpdate] hook.

type OnUpdateManyHook

type OnUpdateManyHook func(*HookContext, any, Sqlizer, *UpdateManyOptions)

OnUpdateManyHook is the signature for the [Hooks.OnUpdateMany] hook.

type OrderBy

type OrderBy struct {
	// Field is the field by which the document should be ordered.
	Field Orderer
	// Desc if set, will order in descending order according to the natural of the
	// field type.
	//
	// Defaults to false. (Ascending)
	Desc bool
}

OrderBy represents an order by modifer in `Query` operation

type OrderByFloat

type OrderByFloat string

func (OrderByFloat) Decode

func (OrderByFloat) Decode(cursor string) (any, string, error)

func (OrderByFloat) Encode

func (OrderByFloat) Encode(v any, id string) string

func (OrderByFloat) Name

func (i OrderByFloat) Name() string

func (OrderByFloat) New

func (OrderByFloat) New() any

type OrderByInt

type OrderByInt string

func (OrderByInt) Decode

func (OrderByInt) Decode(cursor string) (any, string, error)

func (OrderByInt) Encode

func (OrderByInt) Encode(v any, id string) string

func (OrderByInt) Name

func (i OrderByInt) Name() string

func (OrderByInt) New

func (OrderByInt) New() any

type OrderByString

type OrderByString string

func (OrderByString) Decode

func (OrderByString) Decode(cursor string) (any, string, error)

func (OrderByString) Encode

func (OrderByString) Encode(v any, id string) string

func (OrderByString) Name

func (i OrderByString) Name() string

func (OrderByString) New

func (OrderByString) New() any

type OrderByTime

type OrderByTime string

func (OrderByTime) Decode

func (OrderByTime) Decode(cursor string) (any, string, error)

func (OrderByTime) Encode

func (OrderByTime) Encode(v any, id string) string

func (OrderByTime) Name

func (i OrderByTime) Name() string

func (OrderByTime) New

func (OrderByTime) New() any

type OrderedCond

type OrderedCond[T constraints.Ordered | time.Time] struct {
	Eq       *T
	Lte, Gte *T
	Lt, Gt   *T
}

OrderedCond is a Cond for ordered (=, <=, >=, <, >) types.

func (*OrderedCond[T]) AppendCond

func (c *OrderedCond[T]) AppendCond(name string, sb io.StringWriter, args *[]any) error

AppendCond implements Cond for OrderedCond

type Orderer

type Orderer interface {
	Name() string
	Encode(v any, id string) string
	Decode(cursor string) (any, string, error)
	New() any
}

type PaginationOptions

type PaginationOptions struct {
	// Cursor is the pagination cursor that the result should begin from.
	// This is typically returned via the result of the operation.
	Cursor string
	// Limit is the limit of pagination result.
	Limit uint64
	// Backward indicates the direction to fetch results from the cursor.
	// The same result can be achieved by reversing the order.
	//
	// As an example, for documents ordered by their creation time,
	// With the cursor at the 50th record, one can keep fetching the next 50, and the next 50, and so on
	// until they reach the end. Let's say the end is 1000th record.
	// At this point the records can be fetched backwards with the same order.
	Backward bool
}

PaginationOptions are options for paginating results.

type Query

type Query[F Field] struct {
	// contains filtered or unexported fields
}

func (*Query[F]) Not

func (q *Query[F]) Not() *Query[F]

func (*Query[F]) Paren

func (q *Query[F]) Paren(iq *Conj[F]) *Conj[F]

func (*Query[F]) Reset

func (q *Query[F]) Reset()

func (*Query[F]) Where

func (q *Query[F]) Where(f F, c Cond) *Conj[F]

func (*Query[F]) WhereMetadata

func (q *Query[F]) WhereMetadata(f *MetadataField, c Cond) *Conj[F]

type QueryOptions

type QueryOptions struct {
	// PaginationOptions if set will return paginated results.
	PaginationOptions *PaginationOptions
	// ViewMask if set will only populate fields listed in the mask.
	// Only top level fields are supported.
	ViewMask []string
	// OrderBy if empty and pagination options field is set
	// will default to sorting by id asc i.e. [{"id", false}]
	OrderBy []OrderBy
	// IncludeDeleted if set will include the soft deleted documents.
	IncludeDeleted bool
	// LoadMetadataParts is slice of metadata parts that need to be loaded.
	LoadMetadataParts []string
}

QueryOptions are options for the `Query` operation

type QueryResult

type QueryResult[T any] struct {
	// Docs is the resulted docs for the query.
	Docs []*Document[T]
	// LastCursor is the token of the last element of the result.
	// It can be used to continue the search result.
	LastCursor string
	// HasMore tells if there are more fields.
	HasMore bool
}

QueryResult is the result of the query call.

type ReplaceOptions

type ReplaceOptions struct {
	// Metadata is the metadata of the document.
	// This will be merged with existing metadata.
	Metadata Metadata
	// Revision if set (>0), the document will only be replaced if the revision also matches.
	Revision int64
}

ReplaceOptions are options for `Replace` operation.

type ReplaceResult

type ReplaceResult struct{}

ReplaceResult is the result of the replace call. It doesn't have any fields as of now.

Having an explicit result type will not break future changes.

type SetIdFn

type SetIdFn[T any] func(*T, string)

SetIdFn should set the unique id of a document.

type SliceCond

type SliceCond[E any, S ~[]E] struct {
	// Equal (=), Not Equal (<>), Less than (<), Greater Than (>), Less than Equal (<=), Greater Than Equal (>=), Contains (@>), Contained By (<@), Overlap (&&)
	Eq, Neq, Lt, Gt, Lte, Gte, Ct, Ctb, Ovl S
}

TimeCond is a Cond for slice types.

func (*SliceCond[E, S]) AppendCond

func (s *SliceCond[E, S]) AppendCond(name string, sb io.StringWriter, args *[]any) error

type Sqlizer

type Sqlizer = sq.Sqlizer

Sqlizer is the type expected by a store to query documents.

ToSql returns a SQL representation of the Sqlizer, along with a slice of args as passed to e.g. database/sql.Exec. It can also return an error.

type Store

type Store[T any] struct {
	// contains filtered or unexported fields
}

Store is the collection of documents

func NewStore

func NewStore[T any](
	ctx context.Context,
	db *sql.DB,
	schema, table string,
	fields []string,
	idFn IdFn[T],
	setIdFn SetIdFn[T],
	opts StoreOptions,
) (*Store[T], error)

NewStore returns a new store.

Typically this is never directly called. It is called via a more concrete generated function. See protoc-gen-nidhi.

func (*Store[T]) Create

func (s *Store[T]) Create(ctx context.Context, doc *T, opts CreateOptions) (*CreateResult, error)

Create creates a new document.

See `CreateOptions` for replacing documents if already present.

func (*Store[T]) Delete

func (s *Store[T]) Delete(ctx context.Context, id string, opts DeleteOptions) (*DeleteResult, error)

Delete deletes a single record from the store using its id.

By default all deletes are soft deletes. To hard delete, see `DeleteOptions`

func (*Store[T]) DeleteMany

func (s *Store[T]) DeleteMany(ctx context.Context, q Sqlizer, opts DeleteManyOptions) (*DeleteManyResult, error)

func (*Store[T]) Get

func (s *Store[T]) Get(ctx context.Context, id string, opts GetOptions) (*GetResult[T], error)

Get is used to get a document from the store.

func (*Store[T]) Query

func (s *Store[T]) Query(ctx context.Context, q Sqlizer, opts QueryOptions) (*QueryResult[T], error)

Query queries the store and returns all matching documents.

func (*Store[T]) Replace

func (s *Store[T]) Replace(ctx context.Context, doc *T, opts ReplaceOptions) (*ReplaceResult, error)

Replace replaces a document, matched using it's id, in the store.

Returns a NotFound error, if the document doesn't exist or the revision doesn't exist.

func (*Store[T]) Update

func (s *Store[T]) Update(ctx context.Context, id string, updates any, opts UpdateOptions) (*UpdateResult, error)

Update updates a document, matched using it's id, in the store.

Returns a NotFound error on id and revision mismatch.

func (*Store[T]) UpdateMany

func (s *Store[T]) UpdateMany(ctx context.Context, updates any, q Sqlizer, opts UpdateManyOptions) (*UpdateManyResult, error)

UpdateMany updates all the documents that match the given query.

type StoreOptions

type StoreOptions struct {
	// MetadataRegistry is the registry of metadata parts.
	MetadataRegistry map[string]func() MetadataPart
	// Hooks for the store operations.
	Hooks []Hooks
}

StoreOptions are options for a Store.

type StringCond

type StringCond struct {
	Like *string
	Eq   *string
	In   []string
}

StringCond is a Cond for [string] type. It supports equality, like and in operations.

func (*StringCond) AppendCond

func (s *StringCond) AppendCond(name string, sb io.StringWriter, args *[]any) error

AppendCond implements Cond for StringCond

type StringSliceCond

type StringSliceCond = SliceCond[string, []string]

StringSliceCond is convenient alias

type TimeCond

type TimeCond = OrderedCond[time.Time]

TimeCond is a Cond for time.Time.

type TimeSliceCond

type TimeSliceCond = SliceCond[string, []string]

TimeSliceCond is convenient alias

type UpdateManyOptions

type UpdateManyOptions struct {
	// Metadata is the metadata of the document.
	// This will be merged with existing metadata.
	Metadata Metadata
}

UpdateManyOptions are options for *Store.UpdateMany operation.

type UpdateManyResult

type UpdateManyResult struct {
	// UpdateCount is the number of documents that were updated.
	UpdateCount int64
}

UpdateManyResult is the result of the *Store.UpdateMany call.

type UpdateOptions

type UpdateOptions struct {
	// Metadata is the metadata of the document.
	// This will be merged with existing metadata.
	Metadata Metadata
	// Revision if set (>0), the document will only be replaced if the revision also matches.
	Revision int64
}

UpdateOptions are options for *Store.Update operation.

type UpdateResult

type UpdateResult struct{}

UpdateResult is the result of the *Store.Update call. It doesn't have any fields as of now.

Having an explicit result type will not break future changes.

Directories

Path Synopsis
cmd
gen
internal

Jump to

Keyboard shortcuts

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