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

3
import (
Jeromy's avatar
Jeromy committed
4
	"io"
5 6
	"log"

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

// Here are some basic datastore implementations.

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

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

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

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

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

Steven Allen's avatar
Steven Allen committed
45 46 47 48 49 50 51 52
// 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
53
// Delete implements Datastore.Delete
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
54
func (d *MapDatastore) Delete(key Key) (err error) {
55 56 57
	if _, found := d.values[key]; !found {
		return ErrNotFound
	}
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
58 59
	delete(d.values, key)
	return nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
60 61
}

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

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

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
81 82 83 84 85
// 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
86
// NewNullDatastore constructs a null datastoe
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
87 88
func NewNullDatastore() *NullDatastore {
	return &NullDatastore{}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
89 90
}

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

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

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

Steven Allen's avatar
Steven Allen committed
106 107 108 109 110
// 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
111
// Delete implements Datastore.Delete
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
112
func (d *NullDatastore) Delete(key Key) (err error) {
Juan Batiz-Benet's avatar
go fmt  
Juan Batiz-Benet committed
113
	return nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
114 115
}

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

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

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

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
129 130
// LogDatastore logs all accesses through the datastore.
type LogDatastore struct {
Jeromy's avatar
Jeromy committed
131
	Name  string
Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
132 133 134 135 136 137 138 139
	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
140 141
}

Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
142
// NewLogDatastore constructs a log datastore.
Jeromy's avatar
Jeromy committed
143
func NewLogDatastore(ds Datastore, name string) *LogDatastore {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
144 145 146
	if len(name) < 1 {
		name = "LogDatastore"
	}
Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
147 148 149 150 151 152
	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
153 154
}

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

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

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

Steven Allen's avatar
Steven Allen committed
174 175 176 177 178 179
// 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
180
// Delete implements Datastore.Delete
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
181
func (d *LogDatastore) Delete(key Key) (err error) {
Jeromy's avatar
Jeromy committed
182
	log.Printf("%s: Delete %s\n", d.Name, key)
Juan Batiz-Benet's avatar
linting  
Juan Batiz-Benet committed
183
	return d.child.Delete(key)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
184
}
Jeromy's avatar
Jeromy committed
185

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

192
// Query implements Datastore.Query
193
func (d *LogDatastore) Query(q dsq.Query) (dsq.Results, error) {
194
	log.Printf("%s: Query\n", d.Name)
Łukasz Magiera's avatar
Łukasz Magiera committed
195
	log.Printf("%s: q.Prefix: %s\n", d.Name, q.Prefix)
Steven Allen's avatar
Steven Allen committed
196
	log.Printf("%s: q.KeysOnly: %v\n", d.Name, q.KeysOnly)
Łukasz Magiera's avatar
Łukasz Magiera committed
197 198 199 200
	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)

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

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

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

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

Łukasz Magiera's avatar
Łukasz Magiera committed
226
// Put implements Batch.Put
227
func (d *LogBatch) Put(key Key, value []byte) (err error) {
Łukasz Magiera's avatar
Łukasz Magiera committed
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
	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
245 246 247 248 249 250
func (d *LogDatastore) Close() error {
	log.Printf("%s: Close\n", d.Name)
	if cds, ok := d.child.(io.Closer); ok {
		return cds.Close()
	}
	return nil
Jeromy's avatar
Jeromy committed
251
}
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272

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
}