-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial steps on db layer rework - planning and prototyping
- Loading branch information
Showing
5 changed files
with
157 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |