Skip to content

Commit

Permalink
Initial steps on db layer rework - planning and prototyping
Browse files Browse the repository at this point in the history
  • Loading branch information
Frostman committed Jun 22, 2018
1 parent a846a21 commit 36e210d
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 0 deletions.
48 changes: 48 additions & 0 deletions pkg/runtime/db/driver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package db

import (
"fmt"
"sync"
)

type Driver interface {
GetName() string
Open(dataSourceName string) (Store, error)
Close() error
}

var (
driversMu sync.RWMutex
drivers = make(map[string]Driver)
)

func RegisterDriver(driver Driver) {
driversMu.Lock()
defer driversMu.Unlock()

if driver == nil {
panic("db: can't register nil driver")
}

name := driver.GetName()
if len(name) == 0 {
panic(fmt.Sprintf("db: can't register driver with empty name: %T", driver))
}

if _, duplicated := drivers[name]; duplicated {
panic("db: register called twice for driver: " + name)
}

drivers[name] = driver
}

func Open(name string, dataSourceName string) (Store, error) {
driversMu.RLock()
defer driversMu.RUnlock()

if driver, exists := drivers[name]; exists {
return driver.Open(dataSourceName)
} else {
return nil, fmt.Errorf("can't find driver: %s", name)
}
}
4 changes: 4 additions & 0 deletions pkg/runtime/db/index.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package db

// list of participating values for specific index
type Index func(name string, value Storable) ([]interface{}, error)
17 changes: 17 additions & 0 deletions pkg/runtime/db/store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package db

type Store interface {
Get(result Storable, key string) error
List(result []Storable, query ...*Query) error

// using key if provided or getting key from obj
Delete(obj Storable, key string) error

// do we need DeleteMatching(dataType Storable, query *Query) error
// hm, choose needed from Insert, Update, UpdateMatching, Upsert

Update(obj Storable, inPlace bool) error
}

type Query struct {
}
12 changes: 12 additions & 0 deletions pkg/runtime/db/todo.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// todo separate index types and implement only needed
// like
// * first / last with field value (for getting last version or first / last revision for specific status or policy version)
// * list with field value (for getting all revisions for specific policy)
// current name -> reference
// no namespace in default object, only in policy objects
// ... -> key (ns/name or ns or "system" for revision/policy/etc.)
// use binary.LittleEndian.PutUint64 to form bolt keys (optimization)
// no need for Deleted interface, just have this field in policy objects and change it with saving it by in place update
// create automatic index that stores last version of the versioned object aka type=last
// get should use index to get last version (if versioned)
// finding & setting new generation should be in the same tx with actual update
76 changes: 76 additions & 0 deletions pkg/runtime/db/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package db

import (
"fmt"
"sync"
)

type Kind = string
type Key = string

type Storable interface {
GetKind() Kind
GetKey() Key
}

type Versioned interface {
Storable
GetVersion()
SetVersion()
}

type TypeInfo interface {
Kind() Kind
Indexes() map[string]Index
IsVersioned() bool
//New() Storable
//NewSlice() []Storable
}

var (
typeInfosMu sync.RWMutex
typeInfos = make(map[Kind]TypeInfo)
)

func RegisterType(storable Storable, indexes ...*Index) {
typeInfosMu.Lock()
defer typeInfosMu.Unlock()

if storable == nil {
panic("db: can't register nil type")
}

kind := storable.GetKind()
if len(kind) == 0 {
panic(fmt.Sprintf("db: can't register type with empty kind: %T", storable))
}

if _, duplicated := typeInfos[kind]; duplicated {
panic(fmt.Sprintf("db: register called twice for type: %T", storable))
}

typeInfos[kind] = buildTypeInfo(storable, indexes)
}

func buildTypeInfo(storable Storable, indexes []*Index) TypeInfo {
// todo verify object, indexes and fill in the type info object
return &reflectTypeInfo{}
}

type reflectTypeInfo struct {
kind Kind
indexes map[string]Index
isVersioned bool
}

func (info *reflectTypeInfo) Kind() Kind {
return info.kind
}

func (info *reflectTypeInfo) Indexes() map[string]Index {
return info.indexes
}

func (info *reflectTypeInfo) IsVersioned() bool {
return info.isVersioned
}

0 comments on commit 36e210d

Please sign in to comment.