Add initial implementation of multiple stores
This commit is contained in:
parent
89b71cbe72
commit
ac26ec8451
8 changed files with 486 additions and 0 deletions
66
stores/boltdb/boltdb.go
Normal file
66
stores/boltdb/boltdb.go
Normal file
|
@ -0,0 +1,66 @@
|
|||
// Copyright © 2016 Abcum Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package boltdb
|
||||
|
||||
import (
|
||||
"github.com/abcum/surreal/cnf"
|
||||
"github.com/abcum/surreal/stores"
|
||||
"github.com/boltdb/bolt"
|
||||
)
|
||||
|
||||
func init() {
|
||||
stores.Register("boltdb", New)
|
||||
}
|
||||
|
||||
type Store struct {
|
||||
ctx cnf.Context
|
||||
db bolt.DB
|
||||
}
|
||||
|
||||
func New(ctx cnf.Context) (stores.Store, error) {
|
||||
|
||||
if ctx.DbPath == "" {
|
||||
ctx.DbPath = "data/bolt.db"
|
||||
}
|
||||
|
||||
db, err := bolt.Open(ctx.DbPath, 0600, nil)
|
||||
|
||||
defer db.Close()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
store := Store{ctx: ctx, db: *db}
|
||||
|
||||
return &store, nil
|
||||
|
||||
}
|
||||
|
||||
func (store *Store) Get(key interface{}) stores.KeyValue {
|
||||
return stores.KeyValue{}
|
||||
}
|
||||
|
||||
func (store *Store) Put(key, val interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (store *Store) Del(key interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (store *Store) Scan(beg, end interface{}, max int64) []stores.KeyValue {
|
||||
return []stores.KeyValue{}
|
||||
}
|
66
stores/cockroachdb/cockroachdb.go
Normal file
66
stores/cockroachdb/cockroachdb.go
Normal file
|
@ -0,0 +1,66 @@
|
|||
// Copyright © 2016 Abcum Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cockroachdb
|
||||
|
||||
import (
|
||||
"github.com/abcum/surreal/cnf"
|
||||
"github.com/abcum/surreal/stores"
|
||||
"github.com/cockroachdb/cockroach/client"
|
||||
"github.com/cockroachdb/cockroach/util/stop"
|
||||
)
|
||||
|
||||
func init() {
|
||||
stores.Register("cockroachdb", New)
|
||||
}
|
||||
|
||||
type Store struct {
|
||||
ctx cnf.Context
|
||||
db client.DB
|
||||
}
|
||||
|
||||
func New(ctx cnf.Context) (stores.Store, error) {
|
||||
|
||||
stopper := stop.NewStopper()
|
||||
|
||||
defer stopper.Stop()
|
||||
|
||||
db, err := client.Open(stopper, ctx.DbPath)
|
||||
|
||||
if err != nil {
|
||||
stopper.Stop()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
store := Store{ctx: ctx, db: *db}
|
||||
|
||||
return &store, nil
|
||||
|
||||
}
|
||||
|
||||
func (store *Store) Get(key interface{}) stores.KeyValue {
|
||||
return stores.KeyValue{}
|
||||
}
|
||||
|
||||
func (store *Store) Put(key, val interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (store *Store) Del(key interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (store *Store) Scan(beg, end interface{}, max int64) []stores.KeyValue {
|
||||
return []stores.KeyValue{}
|
||||
}
|
34
stores/common.go
Normal file
34
stores/common.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright © 2016 Abcum Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package stores
|
||||
|
||||
import (
|
||||
"github.com/abcum/surreal/cnf"
|
||||
)
|
||||
|
||||
// KeyValue is a specific object stored in the backend store
|
||||
type KeyValue struct {
|
||||
Key interface{}
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
type Store interface {
|
||||
Get(key interface{}) KeyValue
|
||||
Put(key, val interface{}) error
|
||||
Del(key interface{}) error
|
||||
Scan(beg, end interface{}, max int64) []KeyValue
|
||||
}
|
||||
|
||||
type Storer func(ctx cnf.Context) (Store, error)
|
64
stores/leveldb/leveldb.go
Normal file
64
stores/leveldb/leveldb.go
Normal file
|
@ -0,0 +1,64 @@
|
|||
// Copyright © 2016 Abcum Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package leveldb
|
||||
|
||||
import (
|
||||
"github.com/abcum/surreal/cnf"
|
||||
"github.com/abcum/surreal/stores"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
)
|
||||
|
||||
func init() {
|
||||
stores.Register("leveldb", New)
|
||||
}
|
||||
|
||||
type Store struct {
|
||||
ctx cnf.Context
|
||||
db leveldb.DB
|
||||
}
|
||||
|
||||
func New(ctx cnf.Context) (stores.Store, error) {
|
||||
|
||||
if ctx.DbPath == "" {
|
||||
ctx.DbPath = "data/level.db"
|
||||
}
|
||||
|
||||
db, err := leveldb.OpenFile(ctx.DbPath, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
store := Store{ctx: ctx, db: *db}
|
||||
|
||||
return &store, nil
|
||||
|
||||
}
|
||||
|
||||
func (store *Store) Get(key interface{}) stores.KeyValue {
|
||||
return stores.KeyValue{}
|
||||
}
|
||||
|
||||
func (store *Store) Put(key, val interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (store *Store) Del(key interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (store *Store) Scan(beg, end interface{}, max int64) []stores.KeyValue {
|
||||
return []stores.KeyValue{}
|
||||
}
|
73
stores/memory/memory.go
Normal file
73
stores/memory/memory.go
Normal file
|
@ -0,0 +1,73 @@
|
|||
// Copyright © 2016 Abcum Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package memory
|
||||
|
||||
import (
|
||||
"github.com/abcum/surreal/cnf"
|
||||
"github.com/abcum/surreal/stores"
|
||||
"github.com/steveyen/gkvlite"
|
||||
)
|
||||
|
||||
func init() {
|
||||
stores.Register("memory", New)
|
||||
}
|
||||
|
||||
type Store struct {
|
||||
ctx cnf.Context
|
||||
db gkvlite.Collection
|
||||
}
|
||||
|
||||
func New(ctx cnf.Context) (stores.Store, error) {
|
||||
|
||||
db, err := gkvlite.NewStore(nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
store := Store{ctx: ctx, db: *db.SetCollection(ctx.Base, nil)}
|
||||
|
||||
return &store, nil
|
||||
|
||||
}
|
||||
|
||||
func (store *Store) Get(key interface{}) stores.KeyValue {
|
||||
val, _ := store.db.Get([]byte(key.(string)))
|
||||
return stores.KeyValue{
|
||||
Key: key.(string),
|
||||
Value: string(val),
|
||||
}
|
||||
}
|
||||
|
||||
func (store *Store) Put(key, val interface{}) error {
|
||||
return store.db.Set([]byte(key.(string)), []byte(val.(string)))
|
||||
}
|
||||
|
||||
func (store *Store) Del(key interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (store *Store) Scan(beg, end interface{}, max int64) []stores.KeyValue {
|
||||
return []stores.KeyValue{}
|
||||
// store.db.VisitItemsAscend([]byte(key.(string)), true, func(i *gkvlite.Item) bool {
|
||||
// // This visitor callback will be invoked with every item
|
||||
// // with key "ford" and onwards, in key-sorted order.
|
||||
// // So: "mercedes", "tesla" are visited, in that ascending order,
|
||||
// // but not "bmw".
|
||||
// // If we want to stop visiting, return false;
|
||||
// // otherwise return true to keep visiting.
|
||||
// return true
|
||||
// })
|
||||
}
|
59
stores/mongodb/mongodb.go
Normal file
59
stores/mongodb/mongodb.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
// Copyright © 2016 Abcum Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package mongodb
|
||||
|
||||
import (
|
||||
"github.com/abcum/surreal/cnf"
|
||||
"github.com/abcum/surreal/stores"
|
||||
m "gopkg.in/mgo.v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
stores.Register("mongodb", New)
|
||||
}
|
||||
|
||||
type Store struct {
|
||||
ctx cnf.Context
|
||||
db m.Session
|
||||
}
|
||||
|
||||
func New(ctx cnf.Context) (stores.Store, error) {
|
||||
|
||||
db, err := m.Dial(ctx.DbPath)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
store := Store{ctx: ctx, db: *db}
|
||||
|
||||
return &store, nil
|
||||
}
|
||||
|
||||
func (store *Store) Get(key interface{}) stores.KeyValue {
|
||||
return stores.KeyValue{}
|
||||
}
|
||||
|
||||
func (store *Store) Put(key, val interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (store *Store) Del(key interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (store *Store) Scan(beg, end interface{}, max int64) []stores.KeyValue {
|
||||
return []stores.KeyValue{}
|
||||
}
|
63
stores/rethinkdb/rethinkdb.go
Normal file
63
stores/rethinkdb/rethinkdb.go
Normal file
|
@ -0,0 +1,63 @@
|
|||
// Copyright © 2016 Abcum Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package rethinkdb
|
||||
|
||||
import (
|
||||
"github.com/abcum/surreal/cnf"
|
||||
"github.com/abcum/surreal/stores"
|
||||
r "github.com/dancannon/gorethink"
|
||||
)
|
||||
|
||||
func init() {
|
||||
stores.Register("rethinkdb", New)
|
||||
}
|
||||
|
||||
type Store struct {
|
||||
ctx cnf.Context
|
||||
db r.Session
|
||||
}
|
||||
|
||||
func New(ctx cnf.Context) (stores.Store, error) {
|
||||
|
||||
db, err := r.Connect(r.ConnectOpts{
|
||||
Address: ctx.DbPath,
|
||||
Database: ctx.DbName,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
store := Store{ctx: ctx, db: *db}
|
||||
|
||||
return &store, nil
|
||||
|
||||
}
|
||||
|
||||
func (store *Store) Get(key interface{}) stores.KeyValue {
|
||||
return stores.KeyValue{}
|
||||
}
|
||||
|
||||
func (store *Store) Put(key, val interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (store *Store) Del(key interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (store *Store) Scan(beg, end interface{}, max int64) []stores.KeyValue {
|
||||
return []stores.KeyValue{}
|
||||
}
|
61
stores/stores.go
Normal file
61
stores/stores.go
Normal file
|
@ -0,0 +1,61 @@
|
|||
// Copyright © 2016 Abcum Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package stores
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/abcum/surreal/cnf"
|
||||
)
|
||||
|
||||
var store Store
|
||||
|
||||
var stores = make(map[string]Storer)
|
||||
|
||||
const DBRegex = `(((([^:]+):\/\/)?((([^:]+):([^@]+)@)?([^:]+):([^\/]+)))\/(.+))$`
|
||||
|
||||
// Setup initialises the selected backend for the database
|
||||
func Setup(ctx cnf.Context) (e error) {
|
||||
|
||||
_, exists := stores[ctx.Db]
|
||||
|
||||
if !exists {
|
||||
return errors.New("Store '" + ctx.Db + "' is not registered")
|
||||
}
|
||||
|
||||
store, e = stores[ctx.Db](ctx)
|
||||
|
||||
return e
|
||||
|
||||
}
|
||||
|
||||
// Register registers a new backend with the database
|
||||
func Register(name string, constructor Storer) (e error) {
|
||||
|
||||
_, exists := stores[name]
|
||||
|
||||
if exists {
|
||||
return errors.New("Store '" + name + "' is already registered")
|
||||
}
|
||||
|
||||
stores[name] = constructor
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// Backend retrieves the currently selected backend
|
||||
func Backend() Store {
|
||||
return store
|
||||
}
|
Loading…
Reference in a new issue