Class: ActiveDocument::Database
- Inherits:
-
Object
- Object
- ActiveDocument::Database
- Defined in:
- lib/active_document/database.rb
Instance Attribute Summary collapse
-
#db ⇒ Object
Returns the value of attribute db.
-
#field ⇒ Object
Returns the value of attribute field.
-
#model_class ⇒ Object
Returns the value of attribute model_class.
-
#suffix ⇒ Object
Returns the value of attribute suffix.
Instance Method Summary collapse
- #close ⇒ Object
- #delete(model) ⇒ Object
- #environment ⇒ Object
- #find(keys, opts = {}, &block) ⇒ Object
-
#initialize(opts) ⇒ Database
constructor
A new instance of Database.
- #name ⇒ Object
- #open ⇒ Object
- #primary_db ⇒ Object
- #save(model, opts = {}) ⇒ Object
- #transaction ⇒ Object
- #unique? ⇒ Boolean
Constructor Details
#initialize(opts) ⇒ Database
Returns a new instance of Database.
2 3 4 5 6 7 |
# File 'lib/active_document/database.rb', line 2 def initialize(opts) @model_class = opts[:model_class] @field = opts[:field] @unique = opts[:unique] @suffix = opts[:suffix] || (@field ? "by_#{@field}" : nil) end |
Instance Attribute Details
#db ⇒ Object
Returns the value of attribute db.
9 10 11 |
# File 'lib/active_document/database.rb', line 9 def db @db end |
#field ⇒ Object
Returns the value of attribute field.
9 10 11 |
# File 'lib/active_document/database.rb', line 9 def field @field end |
#model_class ⇒ Object
Returns the value of attribute model_class.
9 10 11 |
# File 'lib/active_document/database.rb', line 9 def model_class @model_class end |
#suffix ⇒ Object
Returns the value of attribute suffix.
9 10 11 |
# File 'lib/active_document/database.rb', line 9 def suffix @suffix end |
Instance Method Details
#close ⇒ Object
150 151 152 153 154 155 |
# File 'lib/active_document/database.rb', line 150 def close if @db @db.close(0) @db = nil end end |
#delete(model) ⇒ Object
119 120 121 122 |
# File 'lib/active_document/database.rb', line 119 def delete(model) key = Tuple.dump(model.primary_key) db.del(transaction, key, 0) end |
#environment ⇒ Object
15 16 17 |
# File 'lib/active_document/database.rb', line 15 def environment model_class.environment end |
#find(keys, opts = {}, &block) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/active_document/database.rb', line 31 def find(keys, opts = {}, &block) models = block_given? ? BlockArray.new(block) : [] flags = opts[:modify] ? Bdb::DB_RMW : 0 keys.uniq.each do |key| if opts[:partial] and not key.kind_of?(Range) first = [*key] last = first + [true] key = first..last end if key == :all cursor = db.cursor(transaction, 0) if opts[:reverse] k,v = cursor.get(nil, nil, Bdb::DB_LAST | flags) # Start at the last item. iter = lambda {cursor.get(nil, nil, Bdb::DB_PREV | flags)} # Move backward. else k,v = cursor.get(nil, nil, Bdb::DB_FIRST | flags) # Start at the first item. iter = lambda {cursor.get(nil, nil, Bdb::DB_NEXT | flags)} # Move forward. end while k models << Marshal.load(v) break if opts[:limit] and models.size == opts[:limit] k,v = iter.call end cursor.close elsif key.kind_of?(Range) # Fetch a range of keys. cursor = db.cursor(transaction, 0) first = Tuple.dump(key.first) last = Tuple.dump(key.last) # Return false once we pass the end of the range. cond = key.exclude_end? ? lambda {|k| k < last} : lambda {|k| k <= last} if opts[:reverse] # Position the cursor at the end of the range. k,v = cursor.get(last, nil, Bdb::DB_SET_RANGE | flags) while k and not cond.call(k) k,v = iter.call end iter = lambda {cursor.get(nil, nil, Bdb::DB_PREV | flags)} # Move backward. cond = lambda {|k| k >= first} # Change the condition to stop when we move past the start. else k,v = cursor.get(first, nil, Bdb::DB_SET_RANGE | flags) # Start at the beginning of the range. iter = lambda {cursor.get(nil, nil, Bdb::DB_NEXT | flags)} # Move forward. end while k and cond.call(k) models << Marshal.load(v) break if opts[:limit] and models.size == opts[:limit] k,v = iter.call end cursor.close else if unique? # There can only be one item for each key. data = db.get(transaction, Tuple.dump(key), nil, flags) models << Marshal.load(data) if data else # Have to use a cursor because there may be multiple items with each key. cursor = db.cursor(transaction, 0) k,v = cursor.get(Tuple.dump(key), nil, Bdb::DB_SET | flags) while k models << Marshal.load(v) break if opts[:limit] and models.size == opts[:limit] k,v = cursor.get(nil, nil, Bdb::DB_NEXT_DUP | flags) end cursor.close end end break if opts[:limit] and models.size == opts[:limit] end block_given? ? nil : models end |
#name ⇒ Object
23 24 25 |
# File 'lib/active_document/database.rb', line 23 def name @name ||= [model_class.database_name, suffix].compact.join('_') end |
#open ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/active_document/database.rb', line 124 def open if @db.nil? @db = environment.db @db.flags = Bdb::DB_DUPSORT unless unique? @db.open(nil, name, nil, Bdb::Db::BTREE, Bdb::DB_CREATE | Bdb::DB_AUTO_COMMIT, 0) if primary_db index_callback = lambda do |db, key, data| model = Marshal.load(data) return unless model.kind_of?(model_class) index_key = model.send(field) if index_key.kind_of?(Array) # Index multiple keys. If the key is an array, you must wrap it with an outer array. index_key.collect {|k| Tuple.dump(k)} elsif index_key # Index a single key. Tuple.dump(index_key) end end primary_db.associate(nil, @db, 0, index_callback) end end end |
#primary_db ⇒ Object
19 20 21 |
# File 'lib/active_document/database.rb', line 19 def primary_db model_class.database.db if field end |
#save(model, opts = {}) ⇒ Object
110 111 112 113 114 115 116 117 |
# File 'lib/active_document/database.rb', line 110 def save(model, opts = {}) key = Tuple.dump(model.primary_key) data = Marshal.dump(model) flags = opts[:create] ? Bdb::DB_NOOVERWRITE : 0 db.put(transaction, key, data, flags) rescue Bdb::DbError => e raise ActiveDocument::DuplicatePrimaryKey, "primary key #{model.primary_key.inspect} already exists" end |
#transaction ⇒ Object
27 28 29 |
# File 'lib/active_document/database.rb', line 27 def transaction environment.transaction end |
#unique? ⇒ Boolean
11 12 13 |
# File 'lib/active_document/database.rb', line 11 def unique? @unique end |