basic_ds.go 6.13 KB
Newer Older
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
1 2
package datastore

3 4 5
import (
	"log"

Jeromy's avatar
Jeromy committed
6
	dsq "github.com/ipfs/go-datastore/query"
7
)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
8 9 10

// Here are some basic datastore implementations.

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
11
// MapDatastore uses a standard Go map for internal storage.
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
12
type MapDatastore struct {
13
	values map[Key][]byte
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
14 15
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
16
// NewMapDatastore constructs a MapDatastore
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
17
func NewMapDatastore() (d *MapDatastore) {
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
18
	return &MapDatastore{
19
		values: make(map[Key][]byte),
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
20
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
21 22
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
23
// Put implements Datastore.Put
24
func (d *MapDatastore) Put(key Key, value []byte) (err error) {
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
25 26
	d.values[key] = value
	return nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
27 28
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
29
// Get implements Datastore.Get
30
func (d *MapDatastore) Get(key Key) (value []byte, err error) {
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
31 32 33 34 35
	val, found := d.values[key]
	if !found {
		return nil, ErrNotFound
	}
	return val, nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
36 37
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
38
// Has implements Datastore.Has
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
39
func (d *MapDatastore) Has(key Key) (exists bool, err error) {
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
40 41
	_, found := d.values[key]
	return found, nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
42 43
}

Steven Allen's avatar
Steven Allen committed
44 45 46 47 48 49 50 51
// GetSize implements Datastore.GetSize
func (d *MapDatastore) GetSize(key Key) (size int, err error) {
	if v, found := d.values[key]; found {
		return len(v), nil
	}
	return -1, ErrNotFound
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
52
// Delete implements Datastore.Delete
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
53
func (d *MapDatastore) Delete(key Key) (err error) {
54 55 56
	if _, found := d.values[key]; !found {
		return ErrNotFound
	}
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
57 58
	delete(d.values, key)
	return nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
59 60
}

61
// Query implements Datastore.Query
62 63
func (d *MapDatastore) Query(q dsq.Query) (dsq.Results, error) {
	re := make([]dsq.Entry, 0, len(d.values))
64
	for k, v := range d.values {
65
		re = append(re, dsq.Entry{Key: k.String(), Value: v})
Jeromy's avatar
Jeromy committed
66
	}
67 68
	r := dsq.ResultsWithEntries(q, re)
	r = dsq.NaiveQueryApply(q, r)
69
	return r, nil
Jeromy's avatar
Jeromy committed
70 71
}

Jeromy's avatar
Jeromy committed
72 73
func (d *MapDatastore) Batch() (Batch, error) {
	return NewBasicBatch(d), nil
Jeromy's avatar
Jeromy committed
74 75
}

Jeromy's avatar
Jeromy committed
76 77 78 79
func (d *MapDatastore) Close() error {
	return nil
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
80 81 82 83 84
// NullDatastore stores nothing, but conforms to the API.
// Useful to test with.
type NullDatastore struct {
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
85
// NewNullDatastore constructs a null datastoe
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
86 87
func NewNullDatastore() *NullDatastore {
	return &NullDatastore{}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
88 89
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
90
// Put implements Datastore.Put
91
func (d *NullDatastore) Put(key Key, value []byte) (err error) {
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
92
	return nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
93 94
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
95
// Get implements Datastore.Get
96
func (d *NullDatastore) Get(key Key) (value []byte, err error) {
97
	return nil, ErrNotFound
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
98 99
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
100
// Has implements Datastore.Has
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
101
func (d *NullDatastore) Has(key Key) (exists bool, err error) {
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
102
	return false, nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
103 104
}

Steven Allen's avatar
Steven Allen committed
105 106 107 108 109
// Has implements Datastore.GetSize
func (d *NullDatastore) GetSize(key Key) (size int, err error) {
	return -1, ErrNotFound
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
110
// Delete implements Datastore.Delete
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
111
func (d *NullDatastore) Delete(key Key) (err error) {
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
112
	return nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
113 114
}

115
// Query implements Datastore.Query
116 117
func (d *NullDatastore) Query(q dsq.Query) (dsq.Results, error) {
	return dsq.ResultsWithEntries(q, nil), nil
Jeromy's avatar
Jeromy committed
118 119
}

Jeromy's avatar
Jeromy committed
120 121
func (d *NullDatastore) Batch() (Batch, error) {
	return NewBasicBatch(d), nil
Jeromy's avatar
Jeromy committed
122 123
}

Jeromy's avatar
Jeromy committed
124 125 126 127
func (d *NullDatastore) Close() error {
	return nil
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
128 129
// LogDatastore logs all accesses through the datastore.
type LogDatastore struct {
Jeromy's avatar
Jeromy committed
130
	Name  string
Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
131 132 133 134 135 136 137 138
	child Datastore
}

// Shim is a datastore which has a child.
type Shim interface {
	Datastore

	Children() []Datastore
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
139 140
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
141
// NewLogDatastore constructs a log datastore.
Jeromy's avatar
Jeromy committed
142
func NewLogDatastore(ds Datastore, name string) *LogDatastore {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
143 144 145
	if len(name) < 1 {
		name = "LogDatastore"
	}
Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
146 147 148 149 150 151
	return &LogDatastore{Name: name, child: ds}
}

// Children implements Shim
func (d *LogDatastore) Children() []Datastore {
	return []Datastore{d.child}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
152 153
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
154
// Put implements Datastore.Put
155
func (d *LogDatastore) Put(key Key, value []byte) (err error) {
Jeromy's avatar
Jeromy committed
156
	log.Printf("%s: Put %s\n", d.Name, key)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
157
	// log.Printf("%s: Put %s ```%s```", d.Name, key, value)
Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
158
	return d.child.Put(key, value)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
159 160
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
161
// Get implements Datastore.Get
162
func (d *LogDatastore) Get(key Key) (value []byte, err error) {
Jeromy's avatar
Jeromy committed
163
	log.Printf("%s: Get %s\n", d.Name, key)
Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
164
	return d.child.Get(key)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
165 166
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
167
// Has implements Datastore.Has
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
168
func (d *LogDatastore) Has(key Key) (exists bool, err error) {
Jeromy's avatar
Jeromy committed
169
	log.Printf("%s: Has %s\n", d.Name, key)
Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
170
	return d.child.Has(key)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
171 172
}

Steven Allen's avatar
Steven Allen committed
173 174 175 176 177 178
// GetSize implements Datastore.GetSize
func (d *LogDatastore) GetSize(key Key) (size int, err error) {
	log.Printf("%s: GetSize %s\n", d.Name, key)
	return d.child.GetSize(key)
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
179
// Delete implements Datastore.Delete
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
180
func (d *LogDatastore) Delete(key Key) (err error) {
Jeromy's avatar
Jeromy committed
181
	log.Printf("%s: Delete %s\n", d.Name, key)
Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
182
	return d.child.Delete(key)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
183
}
Jeromy's avatar
Jeromy committed
184

185 186
// DiskUsage implements the PersistentDatastore interface.
func (d *LogDatastore) DiskUsage() (uint64, error) {
187 188
	log.Printf("%s: DiskUsage\n", d.Name)
	return DiskUsage(d.child)
189 190
}

191
// Query implements Datastore.Query
192
func (d *LogDatastore) Query(q dsq.Query) (dsq.Results, error) {
193
	log.Printf("%s: Query\n", d.Name)
Łukasz Magiera's avatar
Łukasz Magiera committed
194
	log.Printf("%s: q.Prefix: %s\n", d.Name, q.Prefix)
Steven Allen's avatar
Steven Allen committed
195
	log.Printf("%s: q.KeysOnly: %v\n", d.Name, q.KeysOnly)
Łukasz Magiera's avatar
Łukasz Magiera committed
196 197 198 199
	log.Printf("%s: q.Filters: %d\n", d.Name, len(q.Filters))
	log.Printf("%s: q.Orders: %d\n", d.Name, len(q.Orders))
	log.Printf("%s: q.Offset: %d\n", d.Name, q.Offset)

200
	return d.child.Query(q)
Jeromy's avatar
Jeromy committed
201
}
Jeromy's avatar
Jeromy committed
202

Łukasz Magiera's avatar
Łukasz Magiera committed
203 204 205 206 207 208
// LogBatch logs all accesses through the batch.
type LogBatch struct {
	Name  string
	child Batch
}

Jeromy's avatar
Jeromy committed
209 210
func (d *LogDatastore) Batch() (Batch, error) {
	log.Printf("%s: Batch\n", d.Name)
Jeromy's avatar
Jeromy committed
211
	if bds, ok := d.child.(Batching); ok {
Łukasz Magiera's avatar
Łukasz Magiera committed
212 213 214 215 216 217 218 219 220
		b, err := bds.Batch()

		if err != nil {
			return nil, err
		}
		return &LogBatch{
			Name:  d.Name,
			child: b,
		}, nil
Jeromy's avatar
Jeromy committed
221
	}
Jeromy's avatar
Jeromy committed
222 223 224
	return nil, ErrBatchUnsupported
}

Łukasz Magiera's avatar
Łukasz Magiera committed
225
// Put implements Batch.Put
226
func (d *LogBatch) Put(key Key, value []byte) (err error) {
Łukasz Magiera's avatar
Łukasz Magiera committed
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
	log.Printf("%s: BatchPut %s\n", d.Name, key)
	// log.Printf("%s: Put %s ```%s```", d.Name, key, value)
	return d.child.Put(key, value)
}

// Delete implements Batch.Delete
func (d *LogBatch) Delete(key Key) (err error) {
	log.Printf("%s: BatchDelete %s\n", d.Name, key)
	return d.child.Delete(key)
}

// Commit implements Batch.Commit
func (d *LogBatch) Commit() (err error) {
	log.Printf("%s: BatchCommit\n", d.Name)
	return d.child.Commit()
}

Jeromy's avatar
Jeromy committed
244 245
func (d *LogDatastore) Close() error {
	log.Printf("%s: Close\n", d.Name)
Steven Allen's avatar
Steven Allen committed
246
	return d.child.Close()
Jeromy's avatar
Jeromy committed
247
}
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268

func (d *LogDatastore) Check() error {
	if c, ok := d.child.(CheckedDatastore); ok {
		return c.Check()
	}
	return nil
}

func (d *LogDatastore) Scrub() error {
	if c, ok := d.child.(ScrubbedDatastore); ok {
		return c.Scrub()
	}
	return nil
}

func (d *LogDatastore) CollectGarbage() error {
	if c, ok := d.child.(GCDatastore); ok {
		return c.CollectGarbage()
	}
	return nil
}