geaves

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

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

Go to latest
Published: Jul 28, 2025 License: MIT Imports: 9 Imported by: 0

README

geaves

An zero dependency sqlite eav library for Go

Requirements

  • Go 1.24.5+

Usage

CLI

For demonstration purposes an (almost*) zero dependencies is provided under geaves-cli, this tool is meant to be used for CLI administration of the EAV once set up in a database

For further demo showcase, a geaves-cli/seed.sh is provided which will set up and run commands on it's own to provide an example usecase of the EAV library, along with printing it's final state

After installation, geaves-cli contains comprehensive help commands, simply run ./geaves-cli help to find out how to use the program

Once you have geaves-cli, you will need to set an environment variable GEAVE_CONNECTION which contains the connection to open sqlite on

Installation

Using git is currently the easiest installation method, this will change in the future

$ git clone https://github.com/Asfolny/geaves.git
$ cd geaves/geaves-cli
$ go build -o geaves ./...
seed.sh

It is worth nothing that seed.sh will not exit on error seed.sh is entirely self-contained and can just be run on it's own

$ ./seed.sh

seed.sh will leave a test.sql you can inspect with an sqlite3 test.sql if you so desire

seed.sh will also build geaves-cli into a binary called geaves

geaves

To use geaves you must set up an sqlite database for it to be used on, geaves-cli provides a handy command to generate the needed SQL, this has not been adopted to other ways of using a DB except raw sql and goose

The easiest way to get set up with the table, even on an existing database, is to simply run geaves-cli generate | sqlite <database>, (see geaves-cli/seed.sh for the full example)

geaves itself is a library has to be integrated into another system to shine, geaves-cli is an excellent example of how to do this

Rationale

But what is an eav?

An Entity Attribute Value system is a mapping of Entities (types) -> Attributes (properties) -> Values (data)

Okay but who is this for?

An EAV is very useful for when you need system managers (who may not be programmers)

Or when significant time could be saved by allowing the data to give itself shape, rather than deploying database and code changes to update properteis of stored items

Terminology

Not everything is as it seems, because I like my naming to be different, this EAV names things slightly different

  • Entity
  • Attribute
  • EntityAttribute
  • Item
  • ItemAttribute

Entity and Attribute are self-describing, EntitiyAttribute is the "link" that puts that attribute on all Items that are of Entity (as an Entity is like a Type)

Item is the link between concrete data and Entity (it's data type if you will)

ItemAttribute is the Value that an Item has and an Attribute describes

Limitations

Due to Go's generic system, a programmer must in advance decide what type a generic must be before attempting to use it

This causes one large pain point in this library in particular, ItemAttributes (the V in EAV) are generic, and can be one of many types (see the docs (TODO LINK)), the programmer using this library must at least twice implement a large switch ... case, once to put data into the sqlite value ANY column and once again to pull data out of the value ANY column, so that ItemAttribute is properly types as to what the data actually is

Attribution

geaves itself has 0 dependencies outside of Go 1.24.4 and the Go standard library, these are licensed under MIT, read here

geaves-cli

geaves-cli depends on geaves as well as modernc.org/sqlite for it's sqlite driver, which has a license of BSD 3 clause, read here

Documentation

Index

Constants

View Source
const (
	BoolType     AttributeType = "bool"
	StringType                 = "string"
	IntType                    = "int"
	Int8Type                   = "int8"
	Int16Type                  = "int16"
	Int32Type                  = "int32"
	Int64Type                  = "int64"
	UintType                   = "uint"
	Uint8Type                  = "uint8"
	Uint16Type                 = "uint16"
	Uint32Type                 = "uint32"
	Uint64Type                 = "uint64"
	ByteType                   = "byte"
	RuneType                   = "rune"
	Float32Type                = "float32"
	Float64Type                = "float64"
	BlobType                   = "blob"
	DateType                   = "date"
	TimeType                   = "time"
	DatetimeType               = "datetime"
)

Variables

This section is empty.

Functions

func ResetSQL

func ResetSQL() string

func SetupSQL

func SetupSQL() string

func ValidAttributeType

func ValidAttributeType(t string) bool

Types

type Attribute

type Attribute struct {
	ID   int64
	Name string
	Slug string
	Type AttributeType
	// contains filtered or unexported fields
}

func NewAttribute

func NewAttribute(name string, slug string, attrType AttributeType) *Attribute

func (*Attribute) GetEntities

func (a *Attribute) GetEntities(ctx context.Context, q *Queries) ([]attributeEntityEmbed, error)

type AttributeType

type AttributeType string

type CreateAttributeParam

type CreateAttributeParam struct {
	Name string
	Slug string
	Type AttributeType
}

type CreateEntityParam

type CreateEntityParam struct {
	Name string
	Slug string
}

type DBTX

type DBTX interface {
	ExecContext(context.Context, string, ...any) (sql.Result, error)
	PrepareContext(context.Context, string) (*sql.Stmt, error)
	QueryContext(context.Context, string, ...any) (*sql.Rows, error)
	QueryRowContext(context.Context, string, ...any) *sql.Row
}

type Entity

type Entity struct {
	ID   int64
	Name string
	Slug string
	// contains filtered or unexported fields
}

func NewEntity

func NewEntity(name string, slug string, opts ...EntityOption) *Entity

func (*Entity) GetAttributes

func (e *Entity) GetAttributes(ctx context.Context, q *Queries) ([]EntityAttributeEmbed, error)

func (*Entity) Save

func (e *Entity) Save(q *Queries, ctx context.Context) error

type EntityAttribute

type EntityAttribute struct {
	EntityID    int64
	AttributeID int64
	Required    bool
}

type EntityAttributeEmbed

type EntityAttributeEmbed struct {
	Attribute
	Required bool
}

type EntityOption

type EntityOption func(*Entity)

func WithAttribute

func WithAttribute(attr *Attribute) EntityOption

func WithRequiredAttribute

func WithRequiredAttribute(attr *Attribute) EntityOption

type GetAttributeParam

type GetAttributeParam struct {
	WithEntities bool
	Field        GetType
	Value        any
}

type GetEntityParam

type GetEntityParam struct {
	WithAttributes bool
	Field          GetType
	Value          any
}

type GetType

type GetType string
const (
	BySlug GetType = "slug"
	ByID           = "id"
)

type Item

type Item struct {
	ID       int64
	EntityID int64
	// contains filtered or unexported fields
}

func (*Item) ChangeEntity

func (i *Item) ChangeEntity(ctx context.Context, entity Entity, q *Queries) error

func (*Item) ChangeEntityID

func (i *Item) ChangeEntityID(ctx context.Context, entityId int64, q *Queries) error

func (*Item) Delete

func (i *Item) Delete(ctx context.Context, q *Queries) error

type ItemAttribute

type ItemAttribute[T any] struct {
	ItemID      int64
	AttributeID int64
	Type        AttributeType
	Value       T
}

func (*ItemAttribute[T]) Create

func (ia *ItemAttribute[T]) Create(ctx context.Context, q *Queries) error

func (*ItemAttribute[T]) Load

func (ia *ItemAttribute[T]) Load(ctx context.Context, q *Queries) error

func (*ItemAttribute[T]) Update

func (ia *ItemAttribute[T]) Update(ctx context.Context, q *Queries) error

type Queries

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

func New

func New(db DBTX) *Queries

func (*Queries) CreateAttribute

func (q *Queries) CreateAttribute(ctx context.Context, arg CreateAttributeParam) (Attribute, error)

func (*Queries) CreateEntity

func (q *Queries) CreateEntity(ctx context.Context, arg CreateEntityParam) (Entity, error)

func (*Queries) CreateEntityAttribute

func (q *Queries) CreateEntityAttribute(ctx context.Context, arg EntityAttribute) (EntityAttribute, error)

func (*Queries) CreateItem

func (q *Queries) CreateItem(ctx context.Context, entityId int64) (Item, error)

func (*Queries) DeleteAttribute

func (q *Queries) DeleteAttribute(ctx context.Context, id int64) error

func (*Queries) DeleteEntity

func (q *Queries) DeleteEntity(ctx context.Context, id int64) error

func (*Queries) DeleteEntityAttribute

func (q *Queries) DeleteEntityAttribute(ctx context.Context, entityId int64, attributeId int64) error

func (*Queries) DeleteEntityAttributeByAttribute

func (q *Queries) DeleteEntityAttributeByAttribute(ctx context.Context, attributeId int64) error

func (*Queries) DeleteEntityAttributeByEntity

func (q *Queries) DeleteEntityAttributeByEntity(ctx context.Context, entityId int64) error

func (*Queries) DeleteItem

func (q *Queries) DeleteItem(ctx context.Context, id int64) error

func (*Queries) DeleteItemAttributes

func (q *Queries) DeleteItemAttributes(ctx context.Context, itemId int64, attributeId int64) error

func (*Queries) DeleteItemAttributesByAttribute

func (q *Queries) DeleteItemAttributesByAttribute(ctx context.Context, attributeId int64) error

func (*Queries) DeleteItemAttributesByItem

func (q *Queries) DeleteItemAttributesByItem(ctx context.Context, itemId int64) error

func (*Queries) GetAttribute

func (q *Queries) GetAttribute(ctx context.Context, arg GetAttributeParam) (Attribute, error)

func (*Queries) GetEntity

func (q *Queries) GetEntity(ctx context.Context, arg GetEntityParam) (Entity, error)

func (*Queries) GetItem

func (q *Queries) GetItem(ctx context.Context, id int64) (Item, error)

func (*Queries) ListAttributes

func (q *Queries) ListAttributes(ctx context.Context, withEntities bool) ([]Attribute, error)

func (*Queries) ListEntities

func (q *Queries) ListEntities(ctx context.Context, withAttributes bool) ([]Entity, error)

func (*Queries) ListItemAttributes

func (q *Queries) ListItemAttributes(ctx context.Context, itemId int64) ([]ItemAttribute[*any], error)

func (*Queries) ListItems

func (q *Queries) ListItems(ctx context.Context) ([]Item, error)

func (*Queries) LoadAttributesByEntity

func (q *Queries) LoadAttributesByEntity(ctx context.Context, id int64) ([]EntityAttributeEmbed, error)

func (*Queries) LoadEntitiesByAttribute

func (q *Queries) LoadEntitiesByAttribute(ctx context.Context, id int64) ([]attributeEntityEmbed, error)

func (*Queries) UpdateAttributeName

func (q *Queries) UpdateAttributeName(ctx context.Context, name string, id int64) error

func (*Queries) UpdateAttributeSlug

func (q *Queries) UpdateAttributeSlug(ctx context.Context, slug string, id int64) error

func (*Queries) UpdateAttributeType

func (q *Queries) UpdateAttributeType(ctx context.Context, newType AttributeType, id int64) error

func (*Queries) UpdateEntityName

func (q *Queries) UpdateEntityName(ctx context.Context, name string, id int64) error

func (*Queries) UpdateEntitySlug

func (q *Queries) UpdateEntitySlug(ctx context.Context, slug string, id int64) error

func (*Queries) UpdateItemEntityID

func (q *Queries) UpdateItemEntityID(ctx context.Context, entityId int64, itemId int64) error

func (*Queries) UpdateRequireEntityAttribute

func (q *Queries) UpdateRequireEntityAttribute(ctx context.Context, req bool, entityId int64, attributeId int64) error

func (*Queries) WithTx

func (q *Queries) WithTx(tx *sql.Tx) *Queries

Jump to

Keyboard shortcuts

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