Module | DataMapper::Persistence |
In: |
lib/data_mapper/persistence.rb
lib/data_mapper/persistence.rb |
See DataMapper::Persistence::ClassMethods for DataMapper‘s DSL documentation.
loaded_set | [RW] | This probably needs to be protected |
loaded_set | [RW] | This probably needs to be protected |
original_values | [R] | |
original_values | [R] |
Migrates the database schema based on the properties defined within models. This includes removing fields no longer listed in models and adding new ones.
This is destructive. Any data stored in the database will be destroyed when this method is called.
True:: successfully automigrated database False:: an error occured when automigrating the database
@public
# File lib/data_mapper/persistence.rb, line 80 80: def self.auto_migrate! 81: subclasses.each do |subclass| 82: subclass.auto_migrate! 83: end 84: end
Migrates the database schema based on the properties defined within models. This includes removing fields no longer listed in models and adding new ones.
This is destructive. Any data stored in the database will be destroyed when this method is called.
True:: successfully automigrated database False:: an error occured when automigrating the database
@public
# File lib/data_mapper/persistence.rb, line 80 80: def self.auto_migrate! 81: subclasses.each do |subclass| 82: subclass.auto_migrate! 83: end 84: end
Track classes that include this module.
Support::TypedSet:: contains classes that include or inherit from this module
@semipublic
# File lib/data_mapper/persistence.rb, line 116 116: def self.dependencies 117: @dependency_queue || (@dependency_queue = DependencyQueue.new) 118: end
Track classes that include this module.
Support::TypedSet:: contains classes that include or inherit from this module
@semipublic
# File lib/data_mapper/persistence.rb, line 116 116: def self.dependencies 117: @dependency_queue || (@dependency_queue = DependencyQueue.new) 118: end
Drops all tables known by the schema
True:: successfully automigrated database False:: an error occured when automigrating the database
@public
# File lib/data_mapper/persistence.rb, line 94 94: def self.drop_all_tables! 95: database.adapter.schema.each do |table| 96: table.drop! 97: end 98: end
Drops all tables known by the schema
True:: successfully automigrated database False:: an error occured when automigrating the database
@public
# File lib/data_mapper/persistence.rb, line 94 94: def self.drop_all_tables! 95: database.adapter.schema.each do |table| 96: table.drop! 97: end 98: end
# File lib/data_mapper/persistence.rb, line 24 24: def self.included(klass) 25: 26: klass.extend(ClassMethods) 27: klass.extend(ConvenienceMethods::ClassMethods) 28: 29: klass.send(:include, ConvenienceMethods::InstanceMethods) 30: klass.send(:include, Attributes) 31: klass.send(:include, Associations) 32: klass.send(:include, Validations) 33: klass.send(:include, CallbacksHelper) 34: klass.send(:include, Support::Serialization) 35: 36: klass.instance_variable_set('@properties', []) 37: 38: klass.send :extend, AutoMigrations 39: klass.subclasses 40: DataMapper::Persistence::subclasses << klass unless klass == DataMapper::Base 41: klass.send(:undef_method, :id) if method_defined?(:id) 42: 43: # When this class is sub-classed, copy the declared columns. 44: klass.class_eval do 45: def self.subclasses 46: @subclasses || (@subclasses = Support::TypedSet.new(Class)) 47: end 48: 49: def self.inherited(subclass) 50: super_table = database.table(self) 51: 52: if super_table.type_column.nil? 53: super_table.add_column(:type, :class, {}) 54: end 55: 56: subclass.instance_variable_set('@properties', self.instance_variable_get("@properties").dup) 57: subclass.instance_variable_set("@callbacks", self.callbacks.dup) 58: 59: self::subclasses << subclass 60: end 61: 62: def self.persistent? 63: true 64: end 65: end 66: end
# File lib/data_mapper/persistence.rb, line 24 24: def self.included(klass) 25: 26: klass.extend(ClassMethods) 27: klass.extend(ConvenienceMethods::ClassMethods) 28: 29: klass.send(:include, ConvenienceMethods::InstanceMethods) 30: klass.send(:include, Attributes) 31: klass.send(:include, Associations) 32: klass.send(:include, Validations) 33: klass.send(:include, CallbacksHelper) 34: klass.send(:include, Support::Serialization) 35: 36: klass.instance_variable_set('@properties', []) 37: 38: klass.send :extend, AutoMigrations 39: klass.subclasses 40: DataMapper::Persistence::subclasses << klass unless klass == DataMapper::Base 41: klass.send(:undef_method, :id) if method_defined?(:id) 42: 43: # When this class is sub-classed, copy the declared columns. 44: klass.class_eval do 45: def self.subclasses 46: @subclasses || (@subclasses = Support::TypedSet.new(Class)) 47: end 48: 49: def self.inherited(subclass) 50: super_table = database.table(self) 51: 52: if super_table.type_column.nil? 53: super_table.add_column(:type, :class, {}) 54: end 55: 56: subclass.instance_variable_set('@properties', self.instance_variable_get("@properties").dup) 57: subclass.instance_variable_set("@callbacks", self.callbacks.dup) 58: 59: self::subclasses << subclass 60: end 61: 62: def self.persistent? 63: true 64: end 65: end 66: end
# File lib/data_mapper/persistence.rb, line 49 49: def self.inherited(subclass) 50: super_table = database.table(self) 51: 52: if super_table.type_column.nil? 53: super_table.add_column(:type, :class, {}) 54: end 55: 56: subclass.instance_variable_set('@properties', self.instance_variable_get("@properties").dup) 57: subclass.instance_variable_set("@callbacks", self.callbacks.dup) 58: 59: self::subclasses << subclass 60: end
# File lib/data_mapper/persistence.rb, line 49 49: def self.inherited(subclass) 50: super_table = database.table(self) 51: 52: if super_table.type_column.nil? 53: super_table.add_column(:type, :class, {}) 54: end 55: 56: subclass.instance_variable_set('@properties', self.instance_variable_get("@properties").dup) 57: subclass.instance_variable_set("@callbacks", self.callbacks.dup) 58: 59: self::subclasses << subclass 60: end
# File lib/data_mapper/persistence.rb, line 120 120: def initialize(details = nil) 121: check_for_properties! 122: if details 123: initialize_with_attributes(details) 124: end 125: end
# File lib/data_mapper/persistence.rb, line 120 120: def initialize(details = nil) 121: check_for_properties! 122: if details 123: initialize_with_attributes(details) 124: end 125: end
Track classes that include this module.
Support::TypedSet:: contains classes that include or inherit from this module
@semipublic
# File lib/data_mapper/persistence.rb, line 106 106: def self.subclasses 107: @subclasses || (@subclasses = Support::TypedSet.new(Class)) 108: end
Track classes that include this module.
Support::TypedSet:: contains classes that include or inherit from this module
@semipublic
# File lib/data_mapper/persistence.rb, line 106 106: def self.subclasses 107: @subclasses || (@subclasses = Support::TypedSet.new(Class)) 108: end
# File lib/data_mapper/persistence.rb, line 45 45: def self.subclasses 46: @subclasses || (@subclasses = Support::TypedSet.new(Class)) 47: end
# File lib/data_mapper/persistence.rb, line 45 45: def self.subclasses 46: @subclasses || (@subclasses = Support::TypedSet.new(Class)) 47: end
# File lib/data_mapper/persistence.rb, line 818 818: def <=>(other) 819: keys <=> other.keys 820: end
# File lib/data_mapper/persistence.rb, line 818 818: def <=>(other) 819: keys <=> other.keys 820: end
Returns the difference between two objects, in terms of their attributes.
# File lib/data_mapper/persistence.rb, line 839 839: def ^(other) 840: results = {} 841: 842: self_attributes, other_attributes = attributes, other.attributes 843: 844: self_attributes.each_pair do |k,v| 845: other_value = other_attributes[k] 846: unless v == other_value 847: results[k] = [v, other_value] 848: end 849: end 850: 851: results 852: end
Returns the difference between two objects, in terms of their attributes.
# File lib/data_mapper/persistence.rb, line 839 839: def ^(other) 840: results = {} 841: 842: self_attributes, other_attributes = attributes, other.attributes 843: 844: self_attributes.each_pair do |k,v| 845: other_value = other_attributes[k] 846: unless v == other_value 847: results[k] = [v, other_value] 848: end 849: end 850: 851: results 852: end
# File lib/data_mapper/persistence.rb, line 135 135: def check_for_properties! 136: raise IncompleteModelDefinitionError.new("Models must have at least one property to be initialized.") if self.class.properties.empty? 137: end
# File lib/data_mapper/persistence.rb, line 135 135: def check_for_properties! 136: raise IncompleteModelDefinitionError.new("Models must have at least one property to be initialized.") if self.class.properties.empty? 137: end
# File lib/data_mapper/persistence.rb, line 693 693: def database_context 694: @database_context || ( @database_context = database ) 695: end
# File lib/data_mapper/persistence.rb, line 693 693: def database_context 694: @database_context || ( @database_context = database ) 695: end
# File lib/data_mapper/persistence.rb, line 697 697: def database_context=(value) 698: @database_context = value 699: end
# File lib/data_mapper/persistence.rb, line 697 697: def database_context=(value) 698: @database_context = value 699: end
Returns true if the unsaved model has had properties changed since it was loaded from the database. Returns false otherwise.
# File lib/data_mapper/persistence.rb, line 726 726: def dirty?(cleared = Set.new) 727: return false if cleared.include?(self) 728: cleared << self 729: 730: result = database_context.table(self).columns.any? do |column| 731: if column.type == :object 732: Marshal.dump(self.instance_variable_get(column.instance_variable_name)) != original_values[column.name] 733: else 734: self.instance_variable_get(column.instance_variable_name) != original_values[column.name] 735: end 736: end 737: 738: return true if result 739: 740: loaded_associations.any? do |loaded_association| 741: loaded_association.dirty?(cleared) 742: end 743: end
Returns true if the unsaved model has had properties changed since it was loaded from the database. Returns false otherwise.
# File lib/data_mapper/persistence.rb, line 726 726: def dirty?(cleared = Set.new) 727: return false if cleared.include?(self) 728: cleared << self 729: 730: result = database_context.table(self).columns.any? do |column| 731: if column.type == :object 732: Marshal.dump(self.instance_variable_get(column.instance_variable_name)) != original_values[column.name] 733: else 734: self.instance_variable_get(column.instance_variable_name) != original_values[column.name] 735: end 736: end 737: 738: return true if result 739: 740: loaded_associations.any? do |loaded_association| 741: loaded_association.dirty?(cleared) 742: end 743: end
For unsaved models, returns a hash of properties that have had their values changed since it was loaded from the database.
# File lib/data_mapper/persistence.rb, line 747 747: def dirty_attributes 748: pairs = {} 749: 750: database_context.table(self).columns.each do |column| 751: value = instance_variable_get(column.instance_variable_name) 752: if value != original_values[column.name] && (!new_record? || !column.serial?) 753: pairs[column.name] = column.type != :object ? value : YAML.dump(value) 754: end 755: end 756: 757: pairs 758: end
For unsaved models, returns a hash of properties that have had their values changed since it was loaded from the database.
# File lib/data_mapper/persistence.rb, line 747 747: def dirty_attributes 748: pairs = {} 749: 750: database_context.table(self).columns.each do |column| 751: value = instance_variable_get(column.instance_variable_name) 752: if value != original_values[column.name] && (!new_record? || !column.serial?) 753: pairs[column.name] = column.type != :object ? value : YAML.dump(value) 754: end 755: end 756: 757: pairs 758: end
# File lib/data_mapper/persistence.rb, line 827 827: def eql?(other) 828: return false unless other.is_a?(self.class) || self.is_a?(other.class) 829: comparator = keys.empty? ? :private_attributes : :keys 830: send(comparator) == other.send(comparator) 831: end
# File lib/data_mapper/persistence.rb, line 827 827: def eql?(other) 828: return false unless other.is_a?(self.class) || self.is_a?(other.class) 829: comparator = keys.empty? ? :private_attributes : :keys 830: send(comparator) == other.send(comparator) 831: end
# File lib/data_mapper/persistence.rb, line 127 127: def initialize_with_attributes(details) 128: case details 129: when Hash then self.attributes = details 130: when details.respond_to?(:persistent?) then self.private_attributes = details.attributes 131: when Struct then self.private_attributes = details.attributes 132: end 133: end
# File lib/data_mapper/persistence.rb, line 127 127: def initialize_with_attributes(details) 128: case details 129: when Hash then self.attributes = details 130: when details.respond_to?(:persistent?) then self.private_attributes = details.attributes 131: when Struct then self.private_attributes = details.attributes 132: end 133: end
# File lib/data_mapper/persistence.rb, line 783 783: def inspect 784: inspected_attributes = attributes.map { |k,v| "@#{k}=#{v.inspect}" } 785: 786: instance_variables.each do |name| 787: if instance_variable_get(name).kind_of?(Associations::HasManyAssociation) 788: inspected_attributes << "#{name}=#{instance_variable_get(name).inspect}" 789: end 790: end 791: 792: "#<%s:0x%x @new_record=%s, %s>" % [self.class.name, (object_id * 2), new_record?, inspected_attributes.join(', ')] 793: end
# File lib/data_mapper/persistence.rb, line 783 783: def inspect 784: inspected_attributes = attributes.map { |k,v| "@#{k}=#{v.inspect}" } 785: 786: instance_variables.each do |name| 787: if instance_variable_get(name).kind_of?(Associations::HasManyAssociation) 788: inspected_attributes << "#{name}=#{instance_variable_get(name).inspect}" 789: end 790: end 791: 792: "#<%s:0x%x @new_record=%s, %s>" % [self.class.name, (object_id * 2), new_record?, inspected_attributes.join(', ')] 793: end
# File lib/data_mapper/persistence.rb, line 805 805: def key 806: @__key || @__key = begin 807: key_column = database_context.table(self.class).key 808: key_column.type_cast_value(instance_variable_get(key_column.instance_variable_name)) 809: end 810: end
# File lib/data_mapper/persistence.rb, line 805 805: def key 806: @__key || @__key = begin 807: key_column = database_context.table(self.class).key 808: key_column.type_cast_value(instance_variable_get(key_column.instance_variable_name)) 809: end 810: end
# File lib/data_mapper/persistence.rb, line 799 799: def key=(value) 800: key_column = database_context.table(self.class).key 801: @__key = key_column.type_cast_value(value) 802: instance_variable_set(key_column.instance_variable_name, @__key) 803: end
# File lib/data_mapper/persistence.rb, line 799 799: def key=(value) 800: key_column = database_context.table(self.class).key 801: @__key = key_column.type_cast_value(value) 802: instance_variable_set(key_column.instance_variable_name, @__key) 803: end
# File lib/data_mapper/persistence.rb, line 812 812: def keys 813: self.class.table.keys.map do |column| 814: column.type_cast_value(instance_variable_get(column.instance_variable_name)) 815: end.compact 816: end
# File lib/data_mapper/persistence.rb, line 812 812: def keys 813: self.class.table.keys.map do |column| 814: column.type_cast_value(instance_variable_get(column.instance_variable_name)) 815: end.compact 816: end
Lazy-loads the attributes for a loaded_set, then overwrites the accessors for the named methods so that the lazy_loading is skipped the second time.
# File lib/data_mapper/persistence.rb, line 663 663: def lazy_load!(*names) 664: 665: names = names.map { |name| name.to_sym }.reject { |name| lazy_loaded_attributes.include?(name) } 666: 667: reset_attribute = lambda do |instance| 668: singleton_class = (class << instance; self end) 669: names.each do |name| 670: instance.lazy_loaded_attributes << name 671: singleton_class.send(:attr_accessor, name) 672: end 673: end 674: 675: unless names.empty? || new_record? || loaded_set.nil? 676: 677: key = database_context.table(self.class).key.to_sym 678: keys_to_select = loaded_set.map do |instance| 679: instance.send(key) 680: end 681: 682: database_context.all( 683: self.class, 684: :select => ([key] + names), 685: :reload => true, 686: key => keys_to_select 687: ).each(&reset_attribute) 688: else 689: reset_attribute[self] 690: end 691: end
Lazy-loads the attributes for a loaded_set, then overwrites the accessors for the named methods so that the lazy_loading is skipped the second time.
# File lib/data_mapper/persistence.rb, line 663 663: def lazy_load!(*names) 664: 665: names = names.map { |name| name.to_sym }.reject { |name| lazy_loaded_attributes.include?(name) } 666: 667: reset_attribute = lambda do |instance| 668: singleton_class = (class << instance; self end) 669: names.each do |name| 670: instance.lazy_loaded_attributes << name 671: singleton_class.send(:attr_accessor, name) 672: end 673: end 674: 675: unless names.empty? || new_record? || loaded_set.nil? 676: 677: key = database_context.table(self.class).key.to_sym 678: keys_to_select = loaded_set.map do |instance| 679: instance.send(key) 680: end 681: 682: database_context.all( 683: self.class, 684: :select => ([key] + names), 685: :reload => true, 686: key => keys_to_select 687: ).each(&reset_attribute) 688: else 689: reset_attribute[self] 690: end 691: end
Returns a Set containing the properties that have had their :lazy option set to true, or are lazily loaded by default — i.e. text fields.
# File lib/data_mapper/persistence.rb, line 714 714: def lazy_loaded_attributes 715: @lazy_loaded_attributes || @lazy_loaded_attributes = Set.new 716: end
Returns a Set containing the properties that have had their :lazy option set to true, or are lazily loaded by default — i.e. text fields.
# File lib/data_mapper/persistence.rb, line 714 714: def lazy_loaded_attributes 715: @lazy_loaded_attributes || @lazy_loaded_attributes = Set.new 716: end
# File lib/data_mapper/persistence.rb, line 795 795: def loaded_associations 796: @loaded_associations || @loaded_associations = [] 797: end
# File lib/data_mapper/persistence.rb, line 795 795: def loaded_associations 796: @loaded_associations || @loaded_associations = [] 797: end
# File lib/data_mapper/persistence.rb, line 778 778: def loaded_set=(value) 779: value << self 780: @loaded_set = value 781: end
# File lib/data_mapper/persistence.rb, line 778 778: def loaded_set=(value) 779: value << self 780: @loaded_set = value 781: end
Returns true if this model hasn‘t been saved to the database, false otherwise.
# File lib/data_mapper/persistence.rb, line 707 707: def new_record? 708: @new_record.nil? || @new_record 709: end
Returns true if this model hasn‘t been saved to the database, false otherwise.
# File lib/data_mapper/persistence.rb, line 707 707: def new_record? 708: @new_record.nil? || @new_record 709: end
# File lib/data_mapper/persistence.rb, line 770 770: def original_values 771: class << self 772: attr_reader :original_values 773: end 774: 775: @original_values = {} 776: end
# File lib/data_mapper/persistence.rb, line 770 770: def original_values 771: class << self 772: attr_reader :original_values 773: end 774: 775: @original_values = {} 776: end
# File lib/data_mapper/persistence.rb, line 760 760: def original_values=(values) 761: values.each_pair do |k,v| 762: original_values[k] = case v 763: when String, Date, Time then v.dup 764: # when column.type == :object then Marshal.dump(v) 765: else v 766: end 767: end 768: end
# File lib/data_mapper/persistence.rb, line 760 760: def original_values=(values) 761: values.each_pair do |k,v| 762: original_values[k] = case v 763: when String, Date, Time then v.dup 764: # when column.type == :object then Marshal.dump(v) 765: else v 766: end 767: end 768: end