github.com/bhojpur/cache@v0.0.4/pkg/file/database/methods.go (about) 1 package database 2 3 // Copyright (c) 2018 Bhojpur Consulting Private Limited, India. All rights reserved. 4 5 // Permission is hereby granted, free of charge, to any person obtaining a copy 6 // of this software and associated documentation files (the "Software"), to deal 7 // in the Software without restriction, including without limitation the rights 8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 // copies of the Software, and to permit persons to whom the Software is 10 // furnished to do so, subject to the following conditions: 11 12 // The above copyright notice and this permission notice shall be included in 13 // all copies or substantial portions of the Software. 14 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 // THE SOFTWARE. 22 23 import ( 24 "errors" 25 26 "github.com/bhojpur/cache/pkg/file/types" 27 memcache "github.com/bhojpur/cache/pkg/memory" 28 ) 29 30 // generateEntry generates an ID-file/shard pair for the DB. 31 func generateEntry(item interface{}) (ID, []byte, error) { 32 // Type assertion (disambiguation) 33 if t, ok := item.(types.File); ok { 34 return ID(t.Hash), t.Bytes(), nil 35 } else if t, ok := item.(types.Shard); ok { 36 return ID(t.Hash), t.Serialize(), nil 37 } else { 38 return ID{}, nil, errors.New("invalid type to store in database") 39 } 40 } 41 42 // PutItem adds a new item to the database. 43 func (db *Database) PutItem(item interface{}) (ID, error) { 44 var t ID // Temporary nil item ID 45 if db.open == false { // Make sure the DB is open 46 return t, errors.New("database is closed") 47 } 48 49 // Extract the data for the database 50 id, data, err := generateEntry(item) 51 if err != nil { 52 return ID{}, err 53 } 54 55 // Write the item to the bucket 56 err = db.DB.Update(func(tx *memcache.Tx) error { 57 b := tx.Bucket(db.bucket) // Fetch the bucket 58 59 // Put necessary data into the bucket 60 return b.Put(id.Bytes(), data) 61 }) 62 63 return id, err 64 } 65 66 // GetItem gets an item from the database. 67 func (db *Database) GetItem(id ID) (interface{}, error) { 68 if db.open == false { // Make sure the DB is open 69 return nil, errors.New("db is closed") 70 } 71 72 // Initialize buffer 73 var buffer []byte 74 75 // Read from the database 76 err := db.DB.View(func(tx *memcache.Tx) error { 77 b := tx.Bucket(db.bucket) // Fetch the bucket 78 dbRead := b.Get(id.Bytes()) // Read the item from the db 79 if dbRead == nil { // Check the item not nil 80 return errors.New( 81 "item '" + id.String() + "' not found in db '" + db.Name + "'", 82 ) // Return err if nil 83 } 84 85 buffer = make([]byte, len(dbRead)) // Init the buffer size 86 copy(buffer, dbRead) // Copy the item to the buffer 87 return nil 88 }) 89 if err != nil { 90 return nil, err 91 } 92 93 // Construct corresponding type from bytes and return 94 switch db.DBType { 95 case FILEDB: 96 return types.FileFromBytes(buffer) 97 case NSHARDDB: 98 return types.ShardFromBytes(buffer) 99 } 100 101 // Throw for undefined behavior 102 return nil, errors.New("invalid database type was used") 103 }