Method: Factbase#txn
- Defined in:
- lib/factbase.rb
#txn ⇒ Factbase::Churn
Run an ACID transaction, which will either modify the factbase or rollback in case of an error.
If necessary to terminate a transaction and rollback all changes, you should raise the Factbase::Rollback exception:
fb = Factbase.new
fb.txn do |fbt|
fbt.insert. = 42
raise Factbase::Rollback
end
At the end of this script, the factbase will be empty. No facts will be inserted and all changes that happened in the block will be rolled back.
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/factbase.rb', line 167 def txn pairs = {} before = @maps.map do |m| n = m.transform_values(&:dup) # rubocop:disable Lint/HashCompareByIdentity pairs[n.object_id] = m.object_id # rubocop:enable Lint/HashCompareByIdentity n end require_relative 'factbase/taped' taped = Factbase::Taped.new(before) begin require_relative 'factbase/light' yield Factbase::Light.new(Factbase.new(taped)) rescue Factbase::Rollback return 0 end require_relative 'factbase/churn' churn = Factbase::Churn.new taped.inserted.each do |oid| b = taped.find_by_object_id(oid) next if b.nil? @maps << b churn.append(1, 0, 0) end garbage = [] taped.added.each do |oid| b = taped.find_by_object_id(oid) next if b.nil? garbage << pairs[oid] @maps << b churn.append(0, 0, 1) end taped.deleted.each do |oid| garbage << pairs[oid] churn.append(0, 1, 0) end @maps.delete_if { |m| garbage.include?(m.object_id) } churn end |