FluentKV

module
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: Jun 22, 2023 License: MIT

README

FluentKV

Purpose a fluent toolkit for using a KV database.

Architecture

Interface and abstraction

The interface IRelationalDB defines a set of raw operation must be implemented by the implementation and some more simple operation already implemented (but it could be overridden) by the abstraction. See the file reldb/relational.go for more details.

The abstraction AbstractRelDB extend IRelationalDB. It pre implement the key filler system and all other operations with the usage of raw operations provide by the implementation. See the file reldb/abstract.go for more details.

IObject and ObjWrapper

The IObject interface define operations needed to this architecture. Some of them are basically implemented with the DBObject abstraction (like Equals,Hash). But the TableName operation need to be manually implement. This least is used to make the key associated with data.

The ObjWrapper object is an helper to store a value and his unique id. It is commonly used across this toolkit to provide the IObject with the db or for return the value with the corresponding id.

Implementation

At this time, there is only one implementation for a KV Database :

Collection

This purpose a simple way to make some operation on a list items provided by a TableName.

In SQL, you have some operation applied on a list of row. List of row are, in main case, provided with FROM command. The constructor of Collection take a DBObject type to build the corresponding objects array with the TableName.

Many operations can be simply done with a Go code and loop. Because of that Collection not provide all SQL operations: you can easily get the underlying array with the GetArray() functions and make your logic on it.

Collection provide:

  • Distinct: Eliminate all duplicate.
  • Sort: Take the logic of sorting and sort the collection.
  • Filter: Take a predicate function and eliminate all not valid items.
  • Where: Like a JOIN but use the link concept of this library is used here.
[TODO] Handlers

Register functions that will be executed on some event like Insert, Delete or Update.

Usage

This section explain basic usage with preparation of type and, first of usage and more advanced use case. You can also see the tests sources for additional information.

Prepare your types

In first time, you can declare a type like this:

type Person struct {
    DBObject // Note this, is for the default implementation.
    Firstname  string
    Lastname  string
    Age int
}

IObject has four operations (Equals, Hash, ToString, TableName), DBObject implement Equals and Hash. You can override this implementation, but you need to implement ToString and TableName. You can simply use the helpers like this:

func (t Person) ToString() string  { return reldb.ToString(t) }

func (t Person) TableName() string { return reldb.NameOfStruct[Person]() }

To simplify the construction of IObject is recommended to make a constructor (it can internally affect the DBObject with the new instance created):

func NewPerson(firstname string, lastname string, age int) Person {
    person := Person{Firstname: firstname, Lastname: lastname, Age: age}
    person.IObject = person // Mandatory (here or manualy before using).
    
	return person
}

In last time, you need to register your type to Gob (the binary serializer used) like this (simply do it before use):

gob.Register(Person{})
Basic operations
// Initialize db
AutoKeyBuffer = 10
db, _ := NewBadgerDB("data")
  • Insert, Get, Set: There is the basic operation to store and use data from the db.

    person := NewPerson("Foo", "Bar", 42)
    personWrapped = Insert(db, person) // Insert a DBObject in db. 
    // This operation return an ObjWrapper[Person]
    
    // Get the Person object from the id:
    valueWrp := Get[Person](db, personWrapped.ID)
    
    // Change the value at the index personWrapped.ID:
    Set(db, NewPerson("Bar", "Foo", 1), personWrapped.ID)
    
  • Update: Allows you to edit the saved object without recreating it. Useful if the object has many fields and you want to edit only one for example.

    Update(db, personWrapped.ID, func (person *Person) {
        person.Age = 12
    })
    
  • Exist, Count:

    Count[Person](db)                   // Count = 1
    Exist[Person](db, personWrapped.ID) // Exist = true
    
  • Link, LinkNew, UnlinkAll, RemoveLink, RemoveAllLink: Link concept allows to retrieve an object of another table linked to the current one.

    // It supposed we have a struct Address(Street string, City string) for example.
    
    addressWrp := Insert(db, NewAddress("", ""))
    Link(addressWrp, true, personWrapped)
    // We can do this instead of:
    // addressWrp := LinkNew(NewAddress("", ""), true, personWrapped)
    
    AllFromLink[Person, Address](personWrapped) // Result is an array with only addressWrp.
    
    RemoveLink(addressWrp, personWrapped)
    
  • Delete, DeepDelete:

    
    
  • FindFirst, FindAll:

    
    
  • Visit, Foreach:

    
    
[TODO] More advanced operations

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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