Add initial implementation of multiple stores

This commit is contained in:
Tobie Morgan Hitchcock 2016-02-26 17:27:26 +00:00
parent 89b71cbe72
commit ac26ec8451
8 changed files with 486 additions and 0 deletions

66
stores/boltdb/boltdb.go Normal file
View 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{}
}

View 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
View 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
View 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
View 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
View 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{}
}

View 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
View 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
}