Class: Hold::Sequel::IdentitySetRepository
- Inherits:
-
Object
- Object
- Hold::Sequel::IdentitySetRepository
- Extended by:
- Wirer::Factory::Interface
- Includes:
- IdentitySetRepository
- Defined in:
- lib/hold/sequel/identity_set_repository.rb,
lib/hold/sequel/with_polymorphic_type_column.rb
Direct Known Subclasses
Defined Under Namespace
Classes: WithPolymorphicTypeColumn
Constant Summary collapse
- JUST_ID =
[:id].freeze
Instance Attribute Summary collapse
-
#db ⇒ Object
readonly
Returns the value of attribute db.
-
#default_properties ⇒ Object
readonly
Returns the value of attribute default_properties.
-
#id_sequence_table ⇒ Object
readonly
Returns the value of attribute id_sequence_table.
-
#identity_mapper ⇒ Object
readonly
Returns the value of attribute identity_mapper.
-
#identity_property ⇒ Object
readonly
Returns the value of attribute identity_property.
-
#main_table ⇒ Object
readonly
Returns the value of attribute main_table.
-
#property_mappers ⇒ Object
readonly
Returns the value of attribute property_mappers.
Class Method Summary collapse
- .constructor_dependencies ⇒ Object
- .inject_dependency(instance, dep_name, value) ⇒ Object
- .model_class ⇒ Object
- .new_from_dependencies(deps, *p) ⇒ Object
- .property_mapper_args ⇒ Object
- .provides_class ⇒ Object
- .provides_features ⇒ Object
- .setter_dependencies(instance = nil) ⇒ Object
- .tables ⇒ Object
Instance Method Summary collapse
-
#add_observer(observer) ⇒ Object
see Hold::Sequel::RepositoryObserver for the interface you need to expose to be an observer here.
- #allocates_ids? ⇒ Boolean
-
#array_cell_for_dataset(&b) ⇒ Object
ArrayCells for top-level collections.
-
#can_construct_from_id_alone?(properties) ⇒ Boolean
this determines if an optimisation can be done whereby if only the ID property is requested to be loaded, the object(s) can be constructed directly from their ids without needing to be fetched from the database.
-
#can_get_class?(model_class) ⇒ Boolean
is this repository capable of loading instances of the given model class? repositories which support polymorhpic loading may override this.
-
#can_set_class?(model_class) ⇒ Boolean
is this repository capable of storing instances of the given model class? repositories which support polymorhpic writes may override this.
- #columns_aliases_and_tables_for_properties(properties) ⇒ Object
- #construct_entity(property_hash, row = nil) ⇒ Object
- #construct_entity_from_id(id) ⇒ Object
- #contains?(entity) ⇒ Boolean
- #contains_id?(id) ⇒ Boolean
- #count_dataset ⇒ Object
- #dataset_to_select_tables(*tables) ⇒ Object
-
#delete(entity) ⇒ Object
deletes rows for this id in all tables of the repo.
- #delete_id(id) ⇒ Object
- #get_all(options = {}) ⇒ Object
- #get_by_id(id, options = {}) ⇒ Object
- #get_by_property(property, value, options = {}) ⇒ Object
-
#get_many_by_ids(ids, options = {}) ⇒ Object
multi-get via a single SELECT…
- #get_many_by_property(property, value, options = {}) ⇒ Object
-
#get_many_with_dataset(options = {}, &b) ⇒ Object
Can take a block which may add extra conditions, joins, order etc onto the relevant query.
- #get_property(entity, property, options = {}) ⇒ Object
-
#get_repo_dependencies_from(repo_set) ⇒ Object
if you want to avoid the need to manually pass in target_repo parameters for each property mapped by a foreign key mapper etc - this will have the mappers go find the dependency themselves.
-
#get_with_dataset(options = {}, &b) ⇒ Object
like get_many_with_dataset but just gets a single row, or nil if not found.
-
#initialize(db) ⇒ IdentitySetRepository
constructor
A new instance of IdentitySetRepository.
- #inspect ⇒ Object
-
#mapper(name) ⇒ Object
convenience to get a particular property mapper of this repo:.
- #model_class ⇒ Object
-
#post_delete(entity) ⇒ Object
Remember to call super if you override this.
-
#post_insert(entity, rows, insert_id) ⇒ Object
Remember to call super if you override this.
-
#post_update(entity, update_entity, rows) ⇒ Object
Remember to call super if you override this.
-
#pre_delete(entity) ⇒ Object
Remember to call super if you override this.
-
#pre_insert(entity) ⇒ Object
Remember to call super if you override this.
-
#pre_update(entity, update_entity) ⇒ Object
Remember to call super if you override this.
-
#query(properties = nil, &b) ⇒ Object
This is the main mechanism to retrieve stuff from the repo via custom queries.
-
#store(entity) ⇒ Object
Calls one of store_new (insert) or update as appropriate.
-
#store_new(entity) ⇒ Object
inserts rows into all relevant tables for the given entity.
- #table_id_column(table) ⇒ Object
- #transaction(*p, &b) ⇒ Object
- #update(entity, update_entity = entity) ⇒ Object
- #update_by_id(id, update_entity) ⇒ Object
Methods included from IdentitySetRepository
#cell, #id_cell, #load, #reload
Constructor Details
#initialize(db) ⇒ IdentitySetRepository
Returns a new instance of IdentitySetRepository.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 105 def initialize(db) raise "abstract superclass" if instance_of?(IdentitySetRepository) @db = db @tables = [] @tables_id_columns = {} self.class.tables.each do |name,| @tables << name @tables_id_columns[name] = [:id_column] @id_sequence_table = name if [:id_sequence] @main_table = name if [:default] end @main_table ||= @tables.first @property_mappers = {} @default_properties = {} # map the identity_property @identity_property = :id # todo make this configurable @identity_mapper = @property_mappers[@identity_property] = PropertyMapper::Identity.new(self, @identity_property) self.class.property_mapper_args.each do |property_name, mapper_class, , block| @property_mappers[property_name] = mapper_class.new(self, property_name, , &block) @default_properties[property_name] = true if mapper_class <= PropertyMapper::Column # for foreign key properties, by default we only load the ID (which is already present on the parent result row): @default_properties[property_name] = JUST_ID if mapper_class <= PropertyMapper::ForeignKey end @property_mappers.freeze end |
Instance Attribute Details
#db ⇒ Object (readonly)
Returns the value of attribute db.
102 103 104 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 102 def db @db end |
#default_properties ⇒ Object (readonly)
Returns the value of attribute default_properties.
102 103 104 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 102 def default_properties @default_properties end |
#id_sequence_table ⇒ Object (readonly)
Returns the value of attribute id_sequence_table.
102 103 104 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 102 def id_sequence_table @id_sequence_table end |
#identity_mapper ⇒ Object (readonly)
Returns the value of attribute identity_mapper.
102 103 104 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 102 def identity_mapper @identity_mapper end |
#identity_property ⇒ Object (readonly)
Returns the value of attribute identity_property.
102 103 104 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 102 def identity_property @identity_property end |
#main_table ⇒ Object (readonly)
Returns the value of attribute main_table.
102 103 104 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 102 def main_table @main_table end |
#property_mappers ⇒ Object (readonly)
Returns the value of attribute property_mappers.
102 103 104 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 102 def property_mappers @property_mappers end |
Class Method Details
.constructor_dependencies ⇒ Object
30 31 32 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 30 def constructor_dependencies {:database => Wirer::Dependency.new_from_args(Sequel::Database)} end |
.inject_dependency(instance, dep_name, value) ⇒ Object
60 61 62 63 64 65 66 67 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 60 def inject_dependency(instance, dep_name, value) if dep_name == :observers value.each {|observer| instance.add_observer(observer)} else mapper_name, dep_name = dep_name.to_s.split('__', 2) instance.mapper(mapper_name.to_sym).send("#{dep_name}=", value) end end |
.model_class ⇒ Object
16 17 18 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 16 def model_class @model_class ||= (superclass.model_class if superclass < IdentitySetRepository) end |
.new_from_dependencies(deps, *p) ⇒ Object
34 35 36 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 34 def new_from_dependencies(deps, *p) new(deps[:database], *p) end |
.property_mapper_args ⇒ Object
24 25 26 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 24 def property_mapper_args @property_mapper_args ||= (superclass < IdentitySetRepository ? superclass.property_mapper_args.dup : []) end |
.provides_class ⇒ Object
38 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 38 def provides_class; self; end |
.provides_features ⇒ Object
40 41 42 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 40 def provides_features [[:get_class, model_class]] end |
.setter_dependencies(instance = nil) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 44 def setter_dependencies(instance=nil) dependencies = {:observers => Wirer::Dependency.new( :module => Hold::Sequel::RepositoryObserver, :features => [[:observes_repo_for_class, model_class]], :multiple => true, :optional => true )} property_mapper_args.each do |property_name, mapper_class, , block| mapper_class.setter_dependencies_for(, &block).each do |dep_name, dep_args| mapper_dep_name = :"#{property_name}__#{dep_name}" dependencies[mapper_dep_name] = Wirer::Dependency.new_from_arg_or_args_list(dep_args) end end dependencies end |
.tables ⇒ Object
20 21 22 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 20 def tables @tables ||= (superclass < IdentitySetRepository ? superclass.tables.dup : []) end |
Instance Method Details
#add_observer(observer) ⇒ Object
see Hold::Sequel::RepositoryObserver for the interface you need to expose to be an observer here.
If you’re using Wirer to construct the repository, a better way to hook the repo up with observers is to add RepositoryObservers to the Wirer::Container and have them provide feature [:observes_repo_for_class, model_class]. They’ll then get picked up by our multiple setter_dependency and added as an observer just after construction.
163 164 165 166 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 163 def add_observer(observer) @observers ||= [] @observers << observer end |
#allocates_ids? ⇒ Boolean
142 143 144 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 142 def allocates_ids? !!@id_sequence_table end |
#array_cell_for_dataset(&b) ⇒ Object
ArrayCells for top-level collections
548 549 550 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 548 def array_cell_for_dataset(&b) QueryArrayCell.new(self, &b) end |
#can_construct_from_id_alone?(properties) ⇒ Boolean
this determines if an optimisation can be done whereby if only the ID property is requested to be loaded, the object(s) can be constructed directly from their ids without needing to be fetched from the database.
257 258 259 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 257 def can_construct_from_id_alone?(properties) properties == JUST_ID end |
#can_get_class?(model_class) ⇒ Boolean
is this repository capable of loading instances of the given model class? repositories which support polymorhpic loading may override this.
148 149 150 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 148 def can_get_class?(model_class) model_class == self.model_class end |
#can_set_class?(model_class) ⇒ Boolean
is this repository capable of storing instances of the given model class? repositories which support polymorhpic writes may override this.
154 155 156 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 154 def can_set_class?(model_class) model_class == self.model_class end |
#columns_aliases_and_tables_for_properties(properties) ⇒ Object
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 269 def columns_aliases_and_tables_for_properties(properties) columns_by_property = {}; aliased_columns = []; tables = [] properties.each do |p| next if p == @identity_property # this gets special handling cs, as, ts = mapper(p).columns_aliases_and_tables_for_select columns_by_property[p] = cs aliased_columns.concat(as) tables.concat(ts) end tables.unshift(@main_table) if tables.delete(@main_table) # the identity mapper gets called last, so that it can get a hint about what # tables are already required for the other columns. (seeing as how an identity column # needs to be present on every table used for a given repo, it should never need to # add an extra table just in order to select the ID) id_cols, id_aliases, id_tables = @identity_mapper.columns_aliases_and_tables_for_select(tables.first || @main_table) columns_by_property[@identity_property] = id_cols aliased_columns.concat(id_aliases) tables.concat(id_tables) aliased_columns.uniq!; tables.uniq! return columns_by_property, aliased_columns, tables end |
#construct_entity(property_hash, row = nil) ⇒ Object
239 240 241 242 243 244 245 246 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 239 def construct_entity(property_hash, row=nil) # new_skipping_checks is supported by ThinModels::Struct(::Typed) and skips any type checks or # attribute name checks on the supplied attributes. @model_class_new_method ||= model_class.respond_to?(:new_skipping_checks) ? :new_skipping_checks : :new model_class.send(@model_class_new_method, property_hash) do |model, property| get_property(model, property) end end |
#construct_entity_from_id(id) ⇒ Object
248 249 250 251 252 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 248 def construct_entity_from_id(id) model_class.new(@identity_property => id) do |model, property| get_property(model, property) end end |
#contains?(entity) ⇒ Boolean
379 380 381 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 379 def contains?(entity) id = entity.id and contains_id?(id) end |
#contains_id?(id) ⇒ Boolean
373 374 375 376 377 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 373 def contains_id?(id) dataset = dataset_to_select_tables(@main_table) id_filter = @identity_mapper.make_filter(id, [@tables_id_columns[@main_table]]) dataset.filter(id_filter).select(1).limit(1).single_value ? true : false end |
#count_dataset ⇒ Object
552 553 554 555 556 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 552 def count_dataset dataset = dataset_to_select_tables(@main_table) dataset = yield dataset if block_given? dataset.count end |
#dataset_to_select_tables(*tables) ⇒ Object
261 262 263 264 265 266 267 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 261 def dataset_to_select_tables(*tables) main_table, *other_tables = tables main_id = @identity_mapper.qualified_column_name(main_table) other_tables.inject(@db[main_table]) do |dataset, table| dataset.join(table, @identity_mapper.qualified_column_name(table) => main_id) end end |
#delete(entity) ⇒ Object
deletes rows for this id in all tables of the repo.
note: order of deletes is important here if you have foreign key dependencies between the ID columns of the different tables; this goes in the reverse order to that used for inserts by store_new, which in turn is determined by the order of your use_table declarations
511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 511 def delete(entity) id = entity.id or raise Hold::MissingIdentity transaction do pre_delete(entity) @property_mappers.each do |name, mapper| mapper.pre_delete(entity) end @tables.reverse_each do |table| id_filter = @identity_mapper.make_filter(id, [@tables_id_columns[table]]) @db[table].filter(id_filter).delete end @property_mappers.each do |name, mapper| mapper.post_delete(entity) end post_delete(entity) end end |
#delete_id(id) ⇒ Object
541 542 543 544 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 541 def delete_id(id) entity = construct_entity(@identity_property => id) delete(entity) end |
#get_all(options = {}) ⇒ Object
310 311 312 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 310 def get_all(={}) query([:properties]).to_a([:lazy]) end |
#get_by_id(id, options = {}) ⇒ Object
336 337 338 339 340 341 342 343 344 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 336 def get_by_id(id, ={}) properties = [:properties] return construct_entity_from_id(id) if can_construct_from_id_alone?(properties) query(properties) do |dataset, property_columns| filter = @identity_mapper.make_filter(id, property_columns[@identity_property]) dataset.filter(filter) end.single_result end |
#get_by_property(property, value, options = {}) ⇒ Object
369 370 371 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 369 def get_by_property(property, value, ={}) get_many_by_property(property, value, ).first end |
#get_many_by_ids(ids, options = {}) ⇒ Object
multi-get via a single SELECT… WHERE id IN (1,2,3,4)
347 348 349 350 351 352 353 354 355 356 357 358 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 347 def get_many_by_ids(ids, ={}) properties = [:properties] return ids.map {|id| construct_entity_from_id(id)} if can_construct_from_id_alone?(properties) results_by_id = {} results = query([:properties]) do |ds,mapping| id_filter = @identity_mapper.make_multi_filter(ids.uniq, mapping[@identity_property]) ds.filter(id_filter) end.to_a([:lazy]) results.each {|object| results_by_id[object.id] = object} ids.map {|id| results_by_id[id]} end |
#get_many_by_property(property, value, options = {}) ⇒ Object
360 361 362 363 364 365 366 367 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 360 def get_many_by_property(property, value, ={}) properties_to_fetch ||= @default_properties.dup properties_to_fetch[property] = true query([:properties]) do |dataset, property_columns| filter = mapper(property).make_filter(value, property_columns[property]) dataset.filter(filter) end.to_a([:lazy]) end |
#get_many_with_dataset(options = {}, &b) ⇒ Object
Can take a block which may add extra conditions, joins, order etc onto the relevant query.
306 307 308 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 306 def get_many_with_dataset(={}, &b) query([:properties], &b).to_a([:lazy]) end |
#get_property(entity, property, options = {}) ⇒ Object
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 320 def get_property(entity, property, ={}) unless property.is_a? Symbol fail ArgumentError, 'get_property must suppy a symbol' end begin result = query(property => [:properties]) do |dataset, property_columns| filter = @identity_mapper.make_filter(entity.id, property_columns[@identity_property]) dataset.filter(filter) end.single_result rescue TypeError # catches test errors caught by []ing a string post 1.8 raise ArgumentError, 'get_property caught a type error, check options' end result && result[property] end |
#get_repo_dependencies_from(repo_set) ⇒ Object
if you want to avoid the need to manually pass in target_repo parameters for each property mapped by a foreign key mapper etc - this will have the mappers go find the dependency themselves.
176 177 178 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 176 def get_repo_dependencies_from(repo_set) @property_mappers.each_value {|mapper| mapper.get_repo_dependencies_from(repo_set)} end |
#get_with_dataset(options = {}, &b) ⇒ Object
like get_many_with_dataset but just gets a single row, or nil if not found. adds limit(1) to the dataset for you.
316 317 318 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 316 def get_with_dataset(={}, &b) query([:properties], &b).single_result end |
#inspect ⇒ Object
138 139 140 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 138 def inspect "<##{self.class}: #{model_class}>" end |
#mapper(name) ⇒ Object
convenience to get a particular property mapper of this repo:
169 170 171 172 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 169 def mapper(name) raise ArgumentError unless name.is_a?(Symbol) @property_mappers[name] or raise "#{self.class}: no such property mapper #{name.inspect}" end |
#model_class ⇒ Object
100 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 100 def model_class; self.class.model_class; end |
#post_delete(entity) ⇒ Object
Remember to call super if you override this. If you do any extra deleting in an overridden post_delete, call super afterwards
537 538 539 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 537 def post_delete(entity) @observers.each {|observer| observer.post_delete(self, entity)} if @observers end |
#post_insert(entity, rows, insert_id) ⇒ Object
Remember to call super if you override this. If you do any extra inserting in an overridden post_insert, call super afterwards
458 459 460 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 458 def post_insert(entity, rows, insert_id) @observers.each {|observer| observer.post_insert(self, entity, rows, insert_id)} if @observers end |
#post_update(entity, update_entity, rows) ⇒ Object
Remember to call super if you override this. If you do any extra updating in an overridden post_update, call super afterwards
495 496 497 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 495 def post_update(entity, update_entity, rows) @observers.each {|observer| observer.post_update(self, entity, update_entity, rows)} if @observers end |
#pre_delete(entity) ⇒ Object
Remember to call super if you override this. If you do any extra deleting in an overridden pre_delete, call super beforehand
531 532 533 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 531 def pre_delete(entity) @observers.each {|observer| observer.pre_delete(self, entity)} if @observers end |
#pre_insert(entity) ⇒ Object
Remember to call super if you override this. If you do any extra inserting in an overridden pre_insert, call super beforehand
452 453 454 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 452 def pre_insert(entity) @observers.each {|observer| observer.pre_insert(self, entity)} if @observers end |
#pre_update(entity, update_entity) ⇒ Object
Remember to call super if you override this. If you do any extra updating in an overridden pre_update, call super beforehand
489 490 491 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 489 def pre_update(entity, update_entity) @observers.each {|observer| observer.pre_update(self, entity, update_entity)} if @observers end |
#query(properties = nil, &b) ⇒ Object
This is the main mechanism to retrieve stuff from the repo via custom queries.
299 300 301 302 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 299 def query(properties=nil, &b) properties = @default_properties if properties == true || properties.nil? Query.new(self, properties, &b) end |
#store(entity) ⇒ Object
Calls one of store_new (insert) or update as appropriate.
Where the repo allocates_ids, you can supply an entity without an ID and store_new will be called.
If the entity has an ID, it will check whether it’s currently contained in the repository before calling store_new or update as appropriate.
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 392 def store(entity) id = entity.id if id transaction do if contains_id?(id) update(entity) else store_new(entity) end end else if allocates_ids? store_new(entity) else raise Hold::MissingIdentity end end entity end |
#store_new(entity) ⇒ Object
inserts rows into all relevant tables for the given entity. ensures that where one of the tables is used for an id sequence, that this row is inserted first and the resulting insert_id obtained is passed when building subsequent rows.
note: order of inserts is important here if you have foreign key dependencies between the ID columns of the different tables; if so you’ll need to order your use_table declarations accordingly.
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 420 def store_new(entity) transaction do rows = {}; insert_id = nil pre_insert(entity) @property_mappers.each_value {|mapper| mapper.pre_insert(entity)} if @id_sequence_table row = insert_row_for_entity(entity, @id_sequence_table) insert_id = translate_exceptions {@db[@id_sequence_table].insert(row)} rows[@id_sequence_table] = row end # note: order is important here if you have foreign key dependencies, order # your use_table declarations appropriately: @tables.each do |table| next if table == @id_sequence_table # done that already row = insert_row_for_entity(entity, table, insert_id) translate_exceptions {@db[table].insert(row)} rows[table] = row end # identity_mapper should be called first, so that other mappers have the new ID # available on the entity when called. @identity_mapper.post_insert(entity, rows, insert_id) @property_mappers.each_value do |mapper| next if mapper == @identity_mapper mapper.post_insert(entity, rows, insert_id) end post_insert(entity, rows, insert_id) entity end end |
#table_id_column(table) ⇒ Object
180 181 182 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 180 def table_id_column(table) @tables_id_columns[table] end |
#transaction(*p, &b) ⇒ Object
292 293 294 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 292 def transaction(*p, &b) @db.transaction(*p, &b) end |
#update(entity, update_entity = entity) ⇒ Object
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 462 def update(entity, update_entity=entity) id = entity.id or raise Hold::MissingIdentity transaction do rows = {}; data_from_mappers = {} pre_update(entity, update_entity) @property_mappers.each do |name, mapper| data_from_mappers[name] = mapper.pre_update(entity, update_entity) end @tables.each do |table| row = update_row_for_entity(id, update_entity, table) unless row.empty? id_filter = @identity_mapper.make_filter(id, [@tables_id_columns[table]]) translate_exceptions {@db[table].filter(id_filter).update(row)} end rows[table] = row end @property_mappers.each do |name, mapper| mapper.post_update(entity, update_entity, rows, data_from_mappers[name]) end post_update(entity, update_entity, rows) entity.merge!(update_entity) if entity.respond_to?(:merge!) entity end end |
#update_by_id(id, update_entity) ⇒ Object
499 500 501 502 |
# File 'lib/hold/sequel/identity_set_repository.rb', line 499 def update_by_id(id, update_entity) entity = construct_entity(@identity_property => id) update(entity, update_entity) end |