Class: CouchPillow::Document
- Inherits:
-
Object
- Object
- CouchPillow::Document
- Extended by:
- Attributive
- Defined in:
- lib/couchpillow/document.rb
Constant Summary collapse
- RESERVED_KEYS =
%i[_id _type _created_at _updated_at]
- DEFAULT_TYPE =
"couchpillow".freeze
Instance Attribute Summary collapse
-
#id ⇒ Object
readonly
Returns the value of attribute id.
Class Method Summary collapse
-
.db(conn) ⇒ Object
Set a DB connection.
-
.get(id) ⇒ Object
Get a Document given an id.
-
.rename(from, to) ⇒ Object
Rename an existing key to a new key.
-
.type(value) ⇒ Object
Sets the type of this Document.
Instance Method Summary collapse
- #[](key) ⇒ Object
- #[]=(key, value) ⇒ Object
-
#assign_defaults! ⇒ Object
Assign default values.
-
#auto_convert! ⇒ Object
Auto convert.
-
#delete! ⇒ Object
Delete this document from the server.
-
#doc_type ⇒ Object
Helper to get the type of this Document.
-
#has?(key) ⇒ Boolean
Check if this Document has the key.
-
#initialize(hash = {}, id = "#{self.class.doc_type}::#{SecureRandom.hex}") ⇒ Document
constructor
A new instance of Document.
-
#rename! ⇒ Object
Rename the keys in this Document as specified by the Document.rename directive.
-
#save!(opts = {}) ⇒ Object
Save this document to the server.
-
#sort! ⇒ Object
Sort keys on this document.
-
#to_hash ⇒ Object
Convert this Document to a Hash.
-
#to_json(*a) ⇒ Object
Convert this Document to a JSON string.
-
#update(hash) ⇒ Object
Updates the attributes in the document.
-
#update! ⇒ Object
Attempt to update this Document.
-
#validate! ⇒ Object
Go through each attribute, and validate the values.
-
#wait ⇒ Object
Blocks until all pending tasks has completed.
-
#whitelist! ⇒ Object
Cleanup the @data hash so it only contains relevant fields.
Methods included from Attributive
attribute, attributes, inherited
Constructor Details
#initialize(hash = {}, id = "#{self.class.doc_type}::#{SecureRandom.hex}") ⇒ Document
Returns a new instance of Document.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/couchpillow/document.rb', line 29 def initialize hash = {}, id = "#{self.class.doc_type}::#{SecureRandom.hex}" @data = self.class.symbolize(hash) @id = id time = Time.now.utc @data[:_created_at] ||= time @data[:_updated_at] = time @futures = [] rename! whitelist! assign_defaults! auto_convert! end |
Instance Attribute Details
#id ⇒ Object (readonly)
Returns the value of attribute id.
7 8 9 |
# File 'lib/couchpillow/document.rb', line 7 def id @id end |
Class Method Details
.db(conn) ⇒ Object
Set a DB connection. Overrides the default CouchPillow.db connection for the first time this method gets called. Subsequent calls will set secondary connections, which will only be used for write only.
Example:
db primary_db # use for both read and write
db backup_db1 # write only
db backup_db2 # write only
282 283 284 285 286 287 288 289 290 |
# File 'lib/couchpillow/document.rb', line 282 def self.db conn # set the primary db connection @primary_db ||= conn # insert as backup db connections if conn && @primary_db && conn != @primary_db secondary_dbs << conn end end |
.get(id) ⇒ Object
Get a Document given an id.
246 247 248 249 250 251 252 |
# File 'lib/couchpillow/document.rb', line 246 def self.get id result = default_db.get(id) and type = result[:_type] || result["_type"] and type == doc_type and new(result, id) or nil end |
.rename(from, to) ⇒ Object
Rename an existing key to a new key. This is invoked right after initialize.
258 259 260 261 262 263 |
# File 'lib/couchpillow/document.rb', line 258 def self.rename from, to raise ArgumentError, "Cannot rename reserved keys" if RESERVED_KEYS.include?(from) || RESERVED_KEYS.include?(to) rename_keys << [from.to_s.to_sym, to.to_s.to_sym] end |
.type(value) ⇒ Object
Sets the type of this Document.
268 269 270 |
# File 'lib/couchpillow/document.rb', line 268 def self.type value @type = value.to_s end |
Instance Method Details
#[](key) ⇒ Object
46 47 48 |
# File 'lib/couchpillow/document.rb', line 46 def [] key @data[key.to_s.to_sym] end |
#[]=(key, value) ⇒ Object
51 52 53 |
# File 'lib/couchpillow/document.rb', line 51 def []= key, value @data[key.to_s.to_sym] = value end |
#assign_defaults! ⇒ Object
Assign default values.
204 205 206 207 208 |
# File 'lib/couchpillow/document.rb', line 204 def assign_defaults! self.class.attributes.each do |k, attr| @data[k] = attr.trigger_default_directive if !has?(k) && attr.has_default? end end |
#auto_convert! ⇒ Object
Auto convert.
213 214 215 216 217 |
# File 'lib/couchpillow/document.rb', line 213 def auto_convert! self.class.attributes.each do |k, attr| @data[k] = attr.trigger_auto_convert_directive(@data[k]) if has?(k) end end |
#delete! ⇒ Object
Delete this document from the server.
84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/couchpillow/document.rb', line 84 def delete! result = self.class.default_db.delete @id unless self.class.secondary_dbs.empty? @futures << Celluloid::Future.new do self.class.secondary_dbs.each do |db| db.delete @id end end end result end |
#doc_type ⇒ Object
Helper to get the type of this Document. Can’t really name this ‘type`. Need to avoid name conflict with Ruby’s own ‘type` method.
163 164 165 |
# File 'lib/couchpillow/document.rb', line 163 def doc_type self.class.doc_type end |
#has?(key) ⇒ Boolean
Check if this Document has the key
141 142 143 |
# File 'lib/couchpillow/document.rb', line 141 def has? key @data.has_key?(key) end |
#rename! ⇒ Object
Rename the keys in this Document as specified by the rename directive.
184 185 186 187 188 189 190 |
# File 'lib/couchpillow/document.rb', line 184 def rename! self.class.rename_keys.each do |from, to| @data.has_key?(from) and @data[to] = @data[from] and @data.delete(from) end end |
#save!(opts = {}) ⇒ Object
Save this document to the server
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/couchpillow/document.rb', line 58 def save! opts = {} whitelist! sort! validate! to_save = @data.merge({ :_type => self.class.doc_type }) # write to all connections result = self.class.default_db.set(@id, to_save, opts) unless self.class.secondary_dbs.empty? @futures << Celluloid::Future.new do self.class.secondary_dbs.each do |db| db.set(@id, to_save, opts) end end end result end |
#sort! ⇒ Object
Sort keys on this document.
237 238 239 |
# File 'lib/couchpillow/document.rb', line 237 def sort! @data = @data.sort.to_h end |
#to_hash ⇒ Object
Convert this Document to a Hash
155 156 157 |
# File 'lib/couchpillow/document.rb', line 155 def to_hash { :_id => @id, :_type => self.class.doc_type }.merge!(@data) end |
#to_json(*a) ⇒ Object
Convert this Document to a JSON string
148 149 150 |
# File 'lib/couchpillow/document.rb', line 148 def to_json *a to_hash.to_json(*a) end |
#update(hash) ⇒ Object
Updates the attributes in the document. Existing attributes will be overwritten and new ones will be added. Any other existing attributes that are not present in the hash will be ignored.
129 130 131 132 133 134 135 136 |
# File 'lib/couchpillow/document.rb', line 129 def update hash hash.each do |k,v| @data[k.to_sym] = v end rename! whitelist! auto_convert! end |
#update! ⇒ Object
Attempt to update this Document. Fails if this Document does not yet exist in the database.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/couchpillow/document.rb', line 102 def update! whitelist! sort! validate! to_save = @data.merge({ :_type => self.class.doc_type }) result = self.class.default_db.replace @id, to_save unless self.class.secondary_dbs.empty? @futures << Celluloid::Future.new do self.class.secondary_dbs.each do |db| db.replace @id, to_save end end end result end |
#validate! ⇒ Object
Go through each attribute, and validate the values. Validation also perform auto-conversion if auto-conversion is enabled for that attribute.
223 224 225 226 227 228 229 230 231 232 |
# File 'lib/couchpillow/document.rb', line 223 def validate! self.class.attributes.each do |k, attr| if has?(k) @data[k] = attr.validate(@data[k]) else @data[k] = attr.trigger_default_directive if attr.has_default? raise ValidationError, "Attribute '#{k}' is required" if attr.required? && !has?(k) end end end |
#wait ⇒ Object
Blocks until all pending tasks has completed. Returns the result of those tasks in an array.
171 172 173 174 175 176 177 178 179 |
# File 'lib/couchpillow/document.rb', line 171 def wait result = [] until @futures.empty? f = @futures.shift result << f.value end result end |
#whitelist! ⇒ Object
Cleanup the @data hash so it only contains relevant fields.
195 196 197 198 199 |
# File 'lib/couchpillow/document.rb', line 195 def whitelist! @data.delete_if do |k, v| !self.class.attributes.has_key?(k) end end |