Module: Webhookdb::Postgres::ModelUtilities::InstanceMethods
- Defined in:
- lib/webhookdb/postgres/model_utilities.rb
Instance Method Summary collapse
-
#after_create ⇒ Object
Sequel hook – send an asynchronous event after the model is saved.
-
#after_destroy ⇒ Object
Sequel hook – send an event after a transaction that destroys the object is committed.
-
#after_update ⇒ Object
Sequel hook – send an asynchronous event after the save is committed.
-
#error_messages ⇒ Object
Return the objects validation errors as full messages joined with commas.
-
#event_prefix ⇒ Object
Return the string used as a topic for events sent from the receiving object.
-
#inspect ⇒ Object
Return a human-readable representation of the object as a String suitable for debugging.
- #inspect_time(t) ⇒ Object
-
#lock? ⇒ Boolean
Run a SELECT FOR UPDATE SKIP LOCKED.
-
#publish_deferred(type, *payload) ⇒ Object
Publish an event in the current db’s/transaction’s
after_commit
hook. -
#publish_immediate(type, *payload) ⇒ Object
Publish an event from the receiving object of the specified
type
and with the givenpayload
. -
#resource_lock! ⇒ Object
Take an exclusive lock on the receiver, ensuring nothing else has updated the object in the meantime.
Instance Method Details
#after_create ⇒ Object
Sequel hook – send an asynchronous event after the model is saved.
335 336 337 338 |
# File 'lib/webhookdb/postgres/model_utilities.rb', line 335 def after_create super self.publish_deferred("created", self.id, prep_amigo_payload(self.values)) end |
#after_destroy ⇒ Object
Sequel hook – send an event after a transaction that destroys the object is committed.
347 348 349 350 |
# File 'lib/webhookdb/postgres/model_utilities.rb', line 347 def after_destroy super self.publish_deferred("destroyed", self.id, prep_amigo_payload(self.values)) end |
#after_update ⇒ Object
Sequel hook – send an asynchronous event after the save is committed.
341 342 343 344 |
# File 'lib/webhookdb/postgres/model_utilities.rb', line 341 def after_update super self.publish_deferred("updated", self.id, prep_amigo_payload(self.previous_changes)) end |
#error_messages ⇒ Object
Return the objects validation errors as full messages joined with commas.
254 255 256 |
# File 'lib/webhookdb/postgres/model_utilities.rb', line 254 def return self.errors..join(", ") end |
#event_prefix ⇒ Object
Return the string used as a topic for events sent from the receiving object.
259 260 261 262 |
# File 'lib/webhookdb/postgres/model_utilities.rb', line 259 def event_prefix prefix = self.class.name or return # No events for anonymous classes return prefix.gsub("::", ".").downcase end |
#inspect ⇒ Object
Return a human-readable representation of the object as a String suitable for debugging.
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/webhookdb/postgres/model_utilities.rb', line 202 def inspect values = self.values.reject do |k, v| v.blank? || k.to_s.end_with?("_currency") end begin encrypted = self.class.send(:column_encryption_metadata).to_set { |(col, _)| col.to_s } rescue NoMethodError encrypted = Set.new end text_search_col = self.class.respond_to?(:text_search_column) && self.class.text_search_column values = values.map do |(k, v)| next "#{k}: {#{v.size}}" if k == text_search_col k = k.to_s v = if v.is_a?(Time) self.inspect_time(v) elsif v.respond_to?(:db_type) && v.db_type.to_s == "tstzrange" "%s%s...%s%s" % [ v.exclude_begin? ? "(" : "[", v.begin ? self.inspect_time(v.begin) : "nil", v.end ? self.inspect_time(v.end) : "nil", v.exclude_end? ? ")" : "]", ] elsif k.end_with?("_cents") accessor = k.match(/^([a-z_]+)_cents/)[1] k = accessor self.send(accessor).format elsif encrypted.include?(k) # Render encrypted fields as xyz...abc, or if a URL, hide the user/password. unenc = self.send(k) if unenc.length < 10 "\"...\"" elsif unenc.include?("://") uri = URI(unenc) uri.user = "*" uri.password = "*" uri.to_s.inspect else "\"#{unenc[..2]}...#{unenc[-3..]}\"" end else v.inspect end "#{k}: #{v}" end return "#<%p %s>" % [self.class, values.join(", ")] end |
#inspect_time(t) ⇒ Object
249 250 251 |
# File 'lib/webhookdb/postgres/model_utilities.rb', line 249 def inspect_time(t) return t.in_time_zone(Time.zone).strftime("%Y-%m-%d %H:%M:%S") end |
#lock? ⇒ Boolean
Run a SELECT FOR UPDATE SKIP LOCKED. If the model row is already locked, return false. Otherwise, acquire the lock and return true.
If the lock is acquired, callers may want to refresh the receiver to make sure it has the newest values.
302 303 304 305 306 307 308 309 310 311 312 |
# File 'lib/webhookdb/postgres/model_utilities.rb', line 302 def lock? raise Webhookdb::LockFailed, "must be in a transaction" unless self.db.in_transaction? pk = self[self.class.primary_key] got_lock = self.class.dataset. select(1). where(self.class.primary_key => pk). for_update. skip_locked. first return !got_lock.nil? end |
#publish_deferred(type, *payload) ⇒ Object
Publish an event in the current db’s/transaction’s after_commit
hook.
273 274 275 276 277 |
# File 'lib/webhookdb/postgres/model_utilities.rb', line 273 def publish_deferred(type, *payload) Webhookdb::Postgres.defer_after_commit(self.db) do self.publish_immediate(type, *payload) end end |
#publish_immediate(type, *payload) ⇒ Object
Publish an event from the receiving object of the specified type
and with the given payload
. This does not wait for the transaction to complete, so subscribers may not be able to observe any model changes in the database. You probably want to use published_deferred.
267 268 269 270 |
# File 'lib/webhookdb/postgres/model_utilities.rb', line 267 def publish_immediate(type, *payload) prefix = self.event_prefix or return Amigo.publish(prefix + "." + type.to_s, *payload) end |
#resource_lock! ⇒ Object
Take an exclusive lock on the receiver, ensuring nothing else has updated the object in the meantime. If the updated_at changed from what’s on the receiver, to after it acquired the lock, raise LockFailed. Save changes and touch updated_at after calling the given block.
282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/webhookdb/postgres/model_utilities.rb', line 282 def resource_lock! self.db.transaction do old_updated = self.round_time(self.updated_at) self.lock! new_updated = self.round_time(self.updated_at) raise Webhookdb::LockFailed if old_updated != new_updated result = yield(self) self.updated_at = Time.now self.save_changes return result end end |