Codebase list golang-github-boltdb-bolt / a901cf6
Clean up API. Ben Johnson 10 years ago
10 changed file(s) with 128 addition(s) and 60 deletion(s). Raw diff Collapse all Expand all
00 package bolt
1
2 const MaxBucketNameSize = 255
31
42 type Bucket struct {
53 *bucket
00 package bolt
11
2 const Version = 1
2 const version = 1
33
44 const (
5 MaxKeySize = 0x8000
6 MaxDataSize = 0xffffffff
5 MaxBucketNameSize = 255
6 MaxKeySize = 32768
7 MaxDataSize = 4294967295
78 )
1212 )
1313
1414 const minPageSize = 0x1000
15
16 var (
17 DatabaseNotOpenError = &Error{"db is not open", nil}
18 DatabaseAlreadyOpenedError = &Error{"db already open", nil}
19 TransactionInProgressError = &Error{"writable transaction is already in progress", nil}
20 )
2115
2216 type DB struct {
2317 sync.Mutex
156150 // Initialize the meta page.
157151 m := p.meta()
158152 m.magic = magic
159 m.version = Version
153 m.version = version
160154 m.pageSize = uint32(db.pageSize)
161 m.version = Version
155 m.version = version
162156 m.free = 2
163157 m.sys = 3
164158 m.pgid = 4
238232 return t, nil
239233 }
240234
235 // Bucket retrieves a reference to a bucket.
236 func (db *DB) Bucket(name string) (*Bucket, error) {
237 t, err := db.Transaction()
238 if err != nil {
239 return nil, err
240 }
241 defer t.Close()
242 return t.Bucket(name), nil
243 }
244
245 // Buckets retrieves a list of all buckets in the database.
246 func (db *DB) Buckets() ([]*Bucket, error) {
247 t, err := db.Transaction()
248 if err != nil {
249 return nil, err
250 }
251 defer t.Close()
252 return t.Buckets(), nil
253 }
254
255 // CreateBucket creates a new bucket in the database.
256 func (db *DB) CreateBucket(name string) error {
257 t, err := db.RWTransaction()
258 if err != nil {
259 return err
260 }
261
262 if err := t.CreateBucket(name); err != nil {
263 t.Rollback()
264 return err
265 }
266
267 return t.Commit()
268 }
269
270 // DeleteBucket removes a bucket from the database.
271 func (db *DB) DeleteBucket(name string) error {
272 t, err := db.RWTransaction()
273 if err != nil {
274 return err
275 }
276
277 if err := t.DeleteBucket(name); err != nil {
278 t.Rollback()
279 return err
280 }
281
282 return t.Commit()
283 }
284
285 // Get retrieves the value for a key in a bucket.
286 func (db *DB) Get(name string, key []byte) ([]byte, error) {
287 t, err := db.Transaction()
288 if err != nil {
289 return nil, err
290 }
291 defer t.Close()
292 return t.Get(name, key), nil
293 }
294
295 // Put sets the value for a key in a bucket.
296 func (db *DB) Put(name string, key []byte, value []byte) error {
297 t, err := db.RWTransaction()
298 if err != nil {
299 return err
300 }
301 if err := t.Put(name, key, value); err != nil {
302 t.Rollback()
303 return err
304 }
305 return t.Commit()
306 }
307
308 // Delete removes a key from a bucket.
309 func (db *DB) Delete(name string, key []byte) error {
310 t, err := db.RWTransaction()
311 if err != nil {
312 return err
313 }
314 if err := t.Delete(name, key); err != nil {
315 t.Rollback()
316 return err
317 }
318 return t.Commit()
319 }
320
241321 // page retrieves a page reference from the mmap based on the current page size.
242322 func (db *DB) page(id pgid) *page {
243323 return (*page)(unsafe.Pointer(&db.data[id*pgid(db.pageSize)]))
122122 withMockDB(func(db *DB, mockos *mockos, mocksyscall *mocksyscall, path string) {
123123 var m meta
124124 m.magic = magic
125 m.version = Version
125 m.version = version
126126 m.pageSize = 0x8000
127127
128128 // Create a file with bad magic.
129129 b := make([]byte, 0x10000)
130130 p0, p1 := (*page)(unsafe.Pointer(&b[0x0000])), (*page)(unsafe.Pointer(&b[0x8000]))
131131 p0.meta().magic = 0
132 p0.meta().version = Version
132 p0.meta().version = version
133133 p1.meta().magic = magic
134 p1.meta().version = Version
134 p1.meta().version = version
135135
136136 // Mock file access.
137137 file, metafile := &mockfile{}, &mockfile{}
0 package bolt
1
2 // TODO(benbjohnson)
00 package bolt
1
2 var (
3 InvalidError = &Error{"Invalid database", nil}
4 VersionMismatchError = &Error{"version mismatch", nil}
5 DatabaseNotOpenError = &Error{"db is not open", nil}
6 DatabaseAlreadyOpenedError = &Error{"db already open", nil}
7 TransactionInProgressError = &Error{"writable transaction is already in progress", nil}
8 InvalidTransactionError = &Error{"txn is invalid", nil}
9 BucketAlreadyExistsError = &Error{"bucket already exists", nil}
10 )
111
212 type Error struct {
313 message string
00 package bolt
11
2 var (
3 InvalidError = &Error{"Invalid database", nil}
4 VersionMismatchError = &Error{"version mismatch", nil}
5 )
6
72 const magic uint32 = 0xDEADC0DE
8 const version uint32 = 1
93
104 type meta struct {
115 magic uint32
2115 func (m *meta) validate() error {
2216 if m.magic != magic {
2317 return InvalidError
24 } else if m.version != Version {
18 } else if m.version != version {
2519 return VersionMismatchError
2620 }
2721 return nil
7878 return nil
7979 }
8080
81 func (t *RWTransaction) Delete(key []byte) error {
81 func (t *RWTransaction) Delete(name string, key []byte) error {
8282 // TODO: Traverse to the correct node.
8383 // TODO: If missing, exit.
8484 // TODO: Remove node from page.
115115 return nil
116116 }
117117
118 func (t *RWTransaction) Rollback() error {
119 return t.close()
120 }
121
122 func (t *RWTransaction) close() error {
118 func (t *RWTransaction) Rollback() {
119 t.close()
120 }
121
122 func (t *RWTransaction) close() {
123123 // Clear temporary pages.
124124 t.leafs = nil
125125
126126 // TODO: Release writer lock.
127
128 return nil
129127 }
130128
131129 // allocate returns a contiguous block of memory starting at a given page.
1818 func TestTransactionCreateBucket(t *testing.T) {
1919 withOpenDB(func(db *DB, path string) {
2020 // Create a bucket.
21 txn, _ := db.RWTransaction()
22 err := txn.CreateBucket("widgets")
21 err := db.CreateBucket("widgets")
2322 assert.NoError(t, err)
2423
25 // Commit the transaction.
26 err = txn.Commit()
24 // Read the bucket through a separate transaction.
25 b, err := db.Bucket("widgets")
26 assert.NotNil(t, b)
2727 assert.NoError(t, err)
28
29 // Open a separate read-only transaction.
30 rtxn, err := db.Transaction()
31 assert.NotNil(t, txn)
32 assert.NoError(t, err)
33
34 b := rtxn.Bucket("widgets")
35 assert.NoError(t, err)
36 if assert.NotNil(t, b) {
37 assert.Equal(t, b.Name(), "widgets")
38 }
3928 })
4029 }
41
42 // Ensure that an existing bucket cannot be created.
43 func TestTransactionCreateExistingBucket(t *testing.T) {
44 t.Skip("pending")
45 }
00 package bolt
1
2 var (
3 InvalidTransactionError = &Error{"txn is invalid", nil}
4 BucketAlreadyExistsError = &Error{"bucket already exists", nil}
5 )
61
72 const (
83 ps_modify = 1
3126 t.sys.read(t.page(t.meta.sys))
3227 }
3328
34 func (t *Transaction) Close() error {
29 func (t *Transaction) Close() {
3530 // TODO: Close buckets.
36 return nil
3731 }
3832
3933 func (t *Transaction) DB() *DB {
5549 }
5650 }
5751
52 // Buckets retrieves a list of all buckets.
53 func (t *Transaction) Buckets() []*Bucket {
54 warn("[pending] Transaction.Buckets()") // TODO
55 return nil
56 }
57
5858 // Cursor creates a cursor associated with a given bucket.
5959 func (t *Transaction) Cursor(name string) *Cursor {
6060 b := t.Bucket(name)
7373 return c.Get(key)
7474 }
7575
76 // Stat returns information about a bucket's internal structure.
77 func (t *Transaction) Stat(name string) *Stat {
76 // stat returns information about a bucket's internal structure.
77 func (t *Transaction) stat(name string) *Stat {
7878 // TODO
7979 return nil
8080 }