lib/partitioned/partitioned_base.rb in partitioned-1.0.1 vs lib/partitioned/partitioned_base.rb in partitioned-1.1.0

- old
+ new

@@ -59,11 +59,11 @@ # define the key value(s) for the constraint check. # # @return [String] the fully qualified name of the database table, ie: foos_partitions.p17 def partition_table_name symbolized_attributes = attributes.symbolize_keys - return self.class.partition_name(*self.class.partition_keys.map{|attribute_name| symbolized_attributes[attribute_name]}) + return self.class.partition_table_name(*self.class.partition_keys.map{|attribute_name| symbolized_attributes[attribute_name]}) end # # Normalize the value to be used for partitioning. This allows, for instance, a class that partitions on # a time field to group the times by month. An integer field might be grouped by every 10mil values, A @@ -117,11 +117,11 @@ @arel_tables ||= {} key_values = self.partition_key_values(values) new_arel_table = @arel_tables[key_values] arel_engine_hash = {:engine => self.arel_engine} arel_engine_hash[:as] = as unless as.blank? - new_arel_table = Arel::Table.new(self.partition_name(*key_values), arel_engine_hash) + new_arel_table = Arel::Table.new(self.partition_table_name(*key_values), arel_engine_hash) return new_arel_table end # # Used by our active record hacks to supply an Arel::Table given this active record's @@ -133,55 +133,31 @@ symbolized_attributes = attributes.symbolize_keys key_values = Hash[*self.class.partition_keys.map{|name| [name,symbolized_attributes[name]]}.flatten] return self.class.dynamic_arel_table(key_values, as) end - # :from_partition_scope is generally not used directly, - # use helper self.from_partition so that the derived class - # can be passed into :from_partition_scope # - # @return [Hash] the from scoping - scope :from_partition_scope, lambda { |target_class, *partition_field| - { - :from => "#{target_class.partition_name(*partition_field)} AS #{target_class.table_name}" - } - } - - # - # Real scope (uses #from_partition_scope). This scope is used to target the + # This scoping is used to target the # active record find() to a specific child table and alias it to the name of the # parent table (so activerecord can generally work with it) # # Use as: # # Foo.from_partition(KEY).find(:first) # # where KEY is the key value(s) used as the check constraint on Foo's table. # - # Because the scope is specific to a class (a class method) but unlike - # class methods is not inherited, one must use this form (#from_partition) instead - # of #from_partition_scope to get the most derived classes specific active record scope. - # # @param [*Array<Object>] partition_field the field values to partition on # @return [Hash] the scoping def self.from_partition(*partition_field) - from_partition_scope(self, *partition_field) + table_alias_name = partition_table_alias_name(*partition_field) + from("#{partition_table_name(*partition_field)} AS #{table_alias_name}"). + tap{|relation| relation.table.table_alias = table_alias_name} end - # :from_partitioned_without_alias_scope is generally not used directly, - # use helper self.from_partitioned_without_alias so that the derived class - # can be passed into :from_partitioned_without_alias_scope # - # @return [Hash] the from scoping - scope :from_partitioned_without_alias_scope, lambda { |target_class, *partition_field| - { - :from => target_class.partition_name(*partition_field) - } - } - - # - # Real scope (uses #from_partitioned_without_alias_scope). This scope is used to target the + # This scope is used to target the # active record find() to a specific child table. Is probably best used in advanced # activerecord queries when a number of tables are involved in the query. # # Use as: # @@ -203,11 +179,13 @@ # of #from_partitioned_without_alias_scope to get the most derived classes specific active record scope. # # @param [*Array<Object>] partition_field the field values to partition on # @return [Hash] the scoping def self.from_partitioned_without_alias(*partition_field) - from_partitioned_without_alias_scope(self, *partition_field) + table_alias_name = partition_table_name(*partition_field) + from(table_alias_name). + tap{|relation| relation.table.table_alias = table_alias_name} end # # Return a object used to read configurator information. # @@ -250,12 +228,28 @@ # # By default this will be the table name of the parent class with a suffix "_partitions". # # For a parent table name foos, that would be foos_partitions # + # N.B.: if the parent table is not in the default schema ("public") the name of the + # partition schema is prefixed by the schema name of the parent table and an + # underscore. That is, if a parent table schema/table name is "other.foos" + # the schema for its partitions will be "other_foos_partitions" + # partition.schema_name lambda {|model| - return model.table_name + '_partitions' + schema_parts = [] + table_parts = model.table_name.split('.') + # table_parts should be either ["table_name"] or ["schema_name", "table_name"] + if table_parts.length == 2 + # XXX should we find the schema_path here and accept anything in the path as "public" + unless table_parts.first == "public" + schema_parts << table_parts.first + end + end + schema_parts << table_parts.last + schema_parts << 'partitions' + return schema_parts.join('_') } # # The table name of the table who is the direct ancestor of a child table. # The child table is defined by the partition key values passed in. @@ -270,11 +264,13 @@ # # The schema name of the table who is the direct ancestor of a child table. # The child table is defined by the partition key values passed in. # partition.parent_table_schema_name lambda {|model, *partition_key_values| - # this should be a connection_adapter thing + table_parts = model.table_name.split('.') + # table_parts should be either ["table_name"] or ["schema_name", "table_name"] + return table_parts.first if table_parts.length == 2 return "public" } # # The prefix for a child table's name. This is typically a letter ('p') so that @@ -307,10 +303,17 @@ configurator = model.configurator return "#{configurator.schema_name}.#{configurator.part_name(*partition_key_values)}" } # + # A reasonable alias for this table + # + partition.table_alias_name lambda {|model, *partition_key_values| + return model.configurator.parent_table_name(*partition_key_values).gsub('.', '_') + } + + # # The name of the child table without a schema name or prefix. this is used to # build child table names for multi-level partitions. # # For a table named foos_partitions.p42, this would be "42" # @@ -365,10 +368,17 @@ def self.add_parent_table_rules(*partition_key_values) partition_manager.add_parent_table_rules(*partition_key_values) end ## + # :method: archive_old_partitions + # delegated to Partitioned::PartitionedBase::PartitionManager#archive_old_partitions + def self.archive_old_partitions + partition_manager.archive_old_partitions + end + + ## # :method: drop_old_partitions # delegated to Partitioned::PartitionedBase::PartitionManager#drop_old_partitions def self.drop_old_partitions partition_manager.drop_old_partitions end @@ -379,10 +389,17 @@ def self.create_new_partitions partition_manager.create_new_partitions end ## + # :method: archive_old_partition + # delegated to Partitioned::PartitionedBase::PartitionManager#archive_old_partition + def self.archive_old_partition(*partition_key_values) + partition_manager.archive_old_partition(*partition_key_values) + end + + ## # :method: drop_old_partition # delegated to Partitioned::PartitionedBase::PartitionManager#drop_old_partition def self.drop_old_partition(*partition_key_values) partition_manager.drop_old_partition(*partition_key_values) end @@ -418,8 +435,15 @@ ## # :method: partition_name # delegated to Partitioned::PartitionedBase::PartitionManager#partition_table_name def self.partition_name(*partition_key_values) return partition_manager.partition_table_name(*partition_key_values) + end + + ## + # :method: partition_table_alias_name + # delegated to Partitioned::PartitionedBase::PartitionManager#partition_table_alias_name + def self.partition_table_alias_name(*partition_key_values) + return partition_manager.partition_table_alias_name(*partition_key_values) end end end