partitioned 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +17 -0
- data/LICENSE +30 -0
- data/PARTITIONING_EXPLAINED.txt +351 -0
- data/README +111 -0
- data/Rakefile +27 -0
- data/examples/README +23 -0
- data/examples/company_id.rb +417 -0
- data/examples/company_id_and_created_at.rb +689 -0
- data/examples/created_at.rb +590 -0
- data/examples/created_at_referencing_awards.rb +1000 -0
- data/examples/id.rb +475 -0
- data/examples/lib/by_company_id.rb +11 -0
- data/examples/lib/command_line_tool_mixin.rb +71 -0
- data/examples/lib/company.rb +29 -0
- data/examples/lib/get_options.rb +44 -0
- data/examples/lib/roman.rb +41 -0
- data/examples/start_date.rb +621 -0
- data/init.rb +1 -0
- data/lib/monkey_patch_activerecord.rb +92 -0
- data/lib/monkey_patch_postgres.rb +73 -0
- data/lib/partitioned.rb +26 -0
- data/lib/partitioned/active_record_overrides.rb +34 -0
- data/lib/partitioned/bulk_methods_mixin.rb +288 -0
- data/lib/partitioned/by_created_at.rb +13 -0
- data/lib/partitioned/by_foreign_key.rb +21 -0
- data/lib/partitioned/by_id.rb +35 -0
- data/lib/partitioned/by_integer_field.rb +32 -0
- data/lib/partitioned/by_monthly_time_field.rb +23 -0
- data/lib/partitioned/by_time_field.rb +65 -0
- data/lib/partitioned/by_weekly_time_field.rb +30 -0
- data/lib/partitioned/multi_level.rb +20 -0
- data/lib/partitioned/multi_level/configurator/data.rb +14 -0
- data/lib/partitioned/multi_level/configurator/dsl.rb +32 -0
- data/lib/partitioned/multi_level/configurator/reader.rb +162 -0
- data/lib/partitioned/multi_level/partition_manager.rb +47 -0
- data/lib/partitioned/partitioned_base.rb +354 -0
- data/lib/partitioned/partitioned_base/configurator.rb +6 -0
- data/lib/partitioned/partitioned_base/configurator/data.rb +62 -0
- data/lib/partitioned/partitioned_base/configurator/dsl.rb +628 -0
- data/lib/partitioned/partitioned_base/configurator/reader.rb +209 -0
- data/lib/partitioned/partitioned_base/partition_manager.rb +138 -0
- data/lib/partitioned/partitioned_base/sql_adapter.rb +286 -0
- data/lib/partitioned/version.rb +3 -0
- data/lib/tasks/desirable_tasks.rake +4 -0
- data/partitioned.gemspec +21 -0
- data/spec/dummy/.rspec +1 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +9 -0
- data/spec/dummy/app/assets/stylesheets/application.css +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +51 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +32 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +30 -0
- data/spec/dummy/config/environments/production.rb +60 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/spec/spec_helper.rb +27 -0
- data/spec/monkey_patch_posgres_spec.rb +176 -0
- data/spec/partitioned/bulk_methods_mixin_spec.rb +512 -0
- data/spec/partitioned/by_created_at_spec.rb +62 -0
- data/spec/partitioned/by_foreign_key_spec.rb +95 -0
- data/spec/partitioned/by_id_spec.rb +97 -0
- data/spec/partitioned/by_integer_field_spec.rb +143 -0
- data/spec/partitioned/by_monthly_time_field_spec.rb +100 -0
- data/spec/partitioned/by_time_field_spec.rb +182 -0
- data/spec/partitioned/by_weekly_time_field_spec.rb +100 -0
- data/spec/partitioned/multi_level/configurator/dsl_spec.rb +88 -0
- data/spec/partitioned/multi_level/configurator/reader_spec.rb +147 -0
- data/spec/partitioned/partitioned_base/configurator/dsl_spec.rb +459 -0
- data/spec/partitioned/partitioned_base/configurator/reader_spec.rb +513 -0
- data/spec/partitioned/partitioned_base/sql_adapter_spec.rb +204 -0
- data/spec/partitioned/partitioned_base_spec.rb +173 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/support/shared_example_spec_helper_for_integer_key.rb +137 -0
- data/spec/support/shared_example_spec_helper_for_time_key.rb +147 -0
- data/spec/support/tables_spec_helper.rb +47 -0
- metadata +250 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
module Partitioned
|
2
|
+
class MultiLevel
|
3
|
+
class PartitionManager < Partitioned::PartitionedBase::PartitionManager
|
4
|
+
#
|
5
|
+
# the once called function to prepare a parent table for partitioning as well
|
6
|
+
# as create the schema that the child tables will be placed in.
|
7
|
+
#
|
8
|
+
def create_infrastructure(enumerable = [[]])
|
9
|
+
super()
|
10
|
+
enumerable.each do |*partition_key_values|
|
11
|
+
create_partition_schema(*partition_key_values)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
#
|
18
|
+
# create a specific child table that does not currently
|
19
|
+
# exist and whose schema (the schema that the table exists in)
|
20
|
+
# also already exists (#create_infrastructure is designed to
|
21
|
+
# create this).
|
22
|
+
#
|
23
|
+
def create_new_partition(*partition_key_values)
|
24
|
+
create_partition_table(*partition_key_values)
|
25
|
+
if is_leaf_partition?(*partition_key_values)
|
26
|
+
add_partition_table_index(*partition_key_values)
|
27
|
+
add_references_to_partition_table(*partition_key_values)
|
28
|
+
else
|
29
|
+
add_parent_table_rules(*partition_key_values)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# is the table a child table without itself having any children.
|
35
|
+
# generally leaf tables are where all indexes and foreign key
|
36
|
+
# constraints will be placed because that is where the data will be.
|
37
|
+
#
|
38
|
+
# Non leaf tables will typically have a rule placed on them
|
39
|
+
# (via add_parent_table_rules) that prevents any inserts from occuring
|
40
|
+
# on them.
|
41
|
+
#
|
42
|
+
def is_leaf_partition?(*partition_key_values)
|
43
|
+
return partition_key_values.length == parent_table_class.configurator.on_fields.length
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,354 @@
|
|
1
|
+
#
|
2
|
+
# :include: ../../README
|
3
|
+
#
|
4
|
+
module Partitioned
|
5
|
+
#
|
6
|
+
# used by PartitionedBase class methods that must be overidden.
|
7
|
+
#
|
8
|
+
class MethodNotImplemented < StandardError
|
9
|
+
def initialize(model, method_name, is_class_method = true)
|
10
|
+
super("#{model.name}#{is_class_method ? '.' : '#'}#{method_name}")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
# PartitionedBase
|
16
|
+
# an ActiveRecord::Base class that can be partitioned.
|
17
|
+
#
|
18
|
+
# Uses a domain specific language to configure, see Partitioned::PartitionedBase::Configurator
|
19
|
+
# for more information
|
20
|
+
#
|
21
|
+
# Extends Partitioned::BulkMethodsMixin to provide create_many and update_many
|
22
|
+
#
|
23
|
+
# Uses PartitionManager to manage creation of child tables
|
24
|
+
#
|
25
|
+
# Monkey patches some ActiveRecord routines to call back to this class when INSERT and UPDATE
|
26
|
+
# statements are built (to determine the table_name with respect to values being inserted or updated)
|
27
|
+
#
|
28
|
+
class PartitionedBase < ActiveRecord::Base
|
29
|
+
include ActiveRecordOverrides
|
30
|
+
extend Partitioned::BulkMethodsMixin
|
31
|
+
|
32
|
+
self.abstract_class = true
|
33
|
+
|
34
|
+
#
|
35
|
+
# returns an array of attribute names (strings) used to fetch the key value(s)
|
36
|
+
# the determine this specific partition table.
|
37
|
+
#
|
38
|
+
def self.partition_keys
|
39
|
+
return configurator.on_fields
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# the specific values for a partition of this active record's type which are defined by
|
44
|
+
# #partition_keys
|
45
|
+
#
|
46
|
+
def self.partition_key_values(values)
|
47
|
+
symbolized_values = values.symbolize_keys
|
48
|
+
return self.partition_keys.map{|key| symbolized_values[key.to_sym]}
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# the name of the current partition table determined by this active records attributes that
|
53
|
+
# define the key value(s) for the constraint check.
|
54
|
+
#
|
55
|
+
def partition_table_name
|
56
|
+
symbolized_attributes = attributes.symbolize_keys
|
57
|
+
return self.class.partition_name(*self.class.partition_keys.map{|attribute_name| symbolized_attributes[attribute_name]})
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# normalize the value to be used for partitioning. This allows, for instance, a class that partitions on
|
62
|
+
# a time field to group the times by month. An integer field might be grouped by every 10mil values, A
|
63
|
+
# string field might be grouped by its first character.
|
64
|
+
#
|
65
|
+
def self.partition_normalize_key_value(value)
|
66
|
+
return value
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# range generation provided for methods like created_infrastructure that need a set of partition key values
|
71
|
+
# to operate on.
|
72
|
+
#
|
73
|
+
def self.partition_generate_range(start_value, end_value, step = 1)
|
74
|
+
return Range.new(start_value, end_value).step(step)
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# return an instance of this partition table's table manager.
|
79
|
+
#
|
80
|
+
def self.partition_manager
|
81
|
+
@partition_manager = self::PartitionManager.new(self) unless @partition_manager.present?
|
82
|
+
return @partition_manager
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# return an instance of this partition table's sql_adapter (used by the partition manage to
|
87
|
+
# create SQL statements)
|
88
|
+
#
|
89
|
+
def self.sql_adapter
|
90
|
+
@sql_adapter = self::SqlAdapter.new(self) unless @sql_adapter.present?
|
91
|
+
return @sql_adapter
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# in activerecord 3.0 we need to supply an Arel::Table for the key value(s) used
|
96
|
+
# to determine the specific child table to access.
|
97
|
+
#
|
98
|
+
def self.dynamic_arel_table(values, as = nil)
|
99
|
+
@arel_tables ||= {}
|
100
|
+
key_values = self.partition_key_values(values)
|
101
|
+
new_arel_table = @arel_tables[key_values]
|
102
|
+
arel_engine_hash = {:engine => self.arel_engine}
|
103
|
+
arel_engine_hash[:as] = as unless as.blank?
|
104
|
+
new_arel_table = Arel::Table.new(self.partition_name(*key_values), arel_engine_hash)
|
105
|
+
return new_arel_table
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
# used by our active record hacks to supply an Arel::Table given this active record's
|
110
|
+
# current attributes.
|
111
|
+
#
|
112
|
+
def dynamic_arel_table(as = nil)
|
113
|
+
symbolized_attributes = attributes.symbolize_keys
|
114
|
+
key_values = Hash[*self.class.partition_keys.map{|name| [name,symbolized_attributes[name]]}.flatten]
|
115
|
+
return self.class.dynamic_arel_table(key_values, as)
|
116
|
+
end
|
117
|
+
|
118
|
+
# :from_partition_scope is generally not used directly,
|
119
|
+
# use helper self.from_partition so that the derived class
|
120
|
+
# can be passed into :from_partition_scope
|
121
|
+
scope :from_partition_scope, lambda { |target_class, *partition_field|
|
122
|
+
{
|
123
|
+
:from => "#{target_class.partition_name(*partition_field)} AS #{target_class.table_name}"
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
#
|
128
|
+
# real scope (uses #from_partition_scope). This scope is used to target the
|
129
|
+
# active record find() to a specific child table and alias it to the name of the
|
130
|
+
# parent table (so activerecord can generally work with it)
|
131
|
+
#
|
132
|
+
# Use as:
|
133
|
+
#
|
134
|
+
# Foo.from_partition(KEY).find(:first)
|
135
|
+
#
|
136
|
+
# where KEY is the key value(s) used as the check constraint on Foo's table.
|
137
|
+
#
|
138
|
+
# Because the scope is specific to a class (a class method) but unlike
|
139
|
+
# class methods is not inherited, one must use this form (#from_partition) instead
|
140
|
+
# of #from_partition_scope to get the most derived classes specific active record scope.
|
141
|
+
#
|
142
|
+
def self.from_partition(*partition_field)
|
143
|
+
from_partition_scope(self, *partition_field)
|
144
|
+
end
|
145
|
+
|
146
|
+
# :from_partitioned_without_alias_scope is generally not used directly,
|
147
|
+
# use helper self.from_partitioned_without_alias so that the derived class
|
148
|
+
# can be passed into :from_partitioned_without_alias_scope
|
149
|
+
scope :from_partitioned_without_alias_scope, lambda { |target_class, *partition_field|
|
150
|
+
{
|
151
|
+
:from => target_class.partition_name(*partition_field)
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
#
|
156
|
+
# real scope (uses #from_partitioned_without_alias_scope). This scope is used to target the
|
157
|
+
# active record find() to a specific child table. Is probably best used in advanced
|
158
|
+
# activerecord queries when a number of tables are involved in the query.
|
159
|
+
#
|
160
|
+
# Use as:
|
161
|
+
#
|
162
|
+
# Foo.from_partitioned_without_alias(KEY).find(:all, :select => "*")
|
163
|
+
#
|
164
|
+
# where KEY is the key value(s) used as the check constraint on Foo's table.
|
165
|
+
#
|
166
|
+
# it's not obvious why :select => "*" is supplied. note activerecord wants
|
167
|
+
# to use the name of parent table for access to any attributes, so without
|
168
|
+
# the :select argument the sql result would be something like:
|
169
|
+
#
|
170
|
+
# SELECT foos.* FROM foos_partitions.pXXX
|
171
|
+
#
|
172
|
+
# which fails because table foos is not referenced. using the form #from_partition
|
173
|
+
# is almost always the correct thing when using activerecord.
|
174
|
+
#
|
175
|
+
# Because the scope is specific to a class (a class method) but unlike
|
176
|
+
# class methods is not inherited, one must use this form (#from_partitioned_without_alias) instead
|
177
|
+
# of #from_partitioned_without_alias_scope to get the most derived classes specific active record scope.
|
178
|
+
#
|
179
|
+
def self.from_partitioned_without_alias(*partition_field)
|
180
|
+
from_partitioned_without_alias_scope(self, *partition_field)
|
181
|
+
end
|
182
|
+
|
183
|
+
#
|
184
|
+
# return a object used to read configurator information
|
185
|
+
#
|
186
|
+
def self.configurator
|
187
|
+
unless @configurator
|
188
|
+
@configurator = self::Configurator::Reader.new(self)
|
189
|
+
end
|
190
|
+
return @configurator
|
191
|
+
end
|
192
|
+
|
193
|
+
#
|
194
|
+
# yields an object used to configure the ActiveRecord class for partitioning
|
195
|
+
# using the Configurator Domain Specific Language.
|
196
|
+
#
|
197
|
+
# usage:
|
198
|
+
# partitioned do |partition|
|
199
|
+
# partition.on :company_id
|
200
|
+
# partition.index :id, :unique => true
|
201
|
+
# partition.foreign_key :company_id
|
202
|
+
# end
|
203
|
+
#
|
204
|
+
def self.partitioned
|
205
|
+
@configurator_dsl ||= self::Configurator::Dsl.new(self)
|
206
|
+
yield @configurator_dsl
|
207
|
+
end
|
208
|
+
|
209
|
+
#
|
210
|
+
# returns the configurator DSL object
|
211
|
+
#
|
212
|
+
def self.configurator_dsl
|
213
|
+
return @configurator_dsl
|
214
|
+
end
|
215
|
+
|
216
|
+
partitioned do |partition|
|
217
|
+
#
|
218
|
+
# the schema name to place all child tables.
|
219
|
+
#
|
220
|
+
# by default this will be the table name of the parent class with a suffix "_partitions".
|
221
|
+
# for a parent table name foos, that would be foos_partitions
|
222
|
+
#
|
223
|
+
partition.schema_name lambda {|model|
|
224
|
+
return model.table_name + '_partitions'
|
225
|
+
}
|
226
|
+
|
227
|
+
#
|
228
|
+
# the table name of the table who is the direct ancestor of a child table.
|
229
|
+
# The child table is defined by the partition key values passed in.
|
230
|
+
#
|
231
|
+
# By default this is just the active record's notion of the name of the class.
|
232
|
+
# Multi Level partitiong requires more work.
|
233
|
+
#
|
234
|
+
partition.parent_table_name lambda {|model, *partition_key_values|
|
235
|
+
return model.table_name
|
236
|
+
}
|
237
|
+
|
238
|
+
#
|
239
|
+
# the schema name of the table who is the direct ancestor of a child table.
|
240
|
+
# The child table is defined by the partition key values passed in.
|
241
|
+
#
|
242
|
+
partition.parent_table_schema_name lambda {|model, *partition_key_values|
|
243
|
+
# this should be a connection_adapter thing
|
244
|
+
return "public"
|
245
|
+
}
|
246
|
+
|
247
|
+
#
|
248
|
+
# the prefix for a child table's name. This is typically a letter ('p') so that
|
249
|
+
# the base_name of the table can be a number generated programtically from
|
250
|
+
# the partition key values.
|
251
|
+
#
|
252
|
+
# for instance, a child table of the table 'foos' may be partitioned on
|
253
|
+
# the column company_id whose value is 42. specific child table would be named
|
254
|
+
# 'foos_partitions.p42'
|
255
|
+
#
|
256
|
+
# the 'p' is the name_prefix because 'foos_partitions.42' is not a valid table name
|
257
|
+
# (without quoting).
|
258
|
+
#
|
259
|
+
partition.name_prefix lambda {|model, *partition_key_values|
|
260
|
+
return "p"
|
261
|
+
}
|
262
|
+
|
263
|
+
#
|
264
|
+
# the child tables name without the schema name
|
265
|
+
#
|
266
|
+
partition.part_name lambda {|model, *partition_key_values|
|
267
|
+
configurator = model.configurator
|
268
|
+
return "#{configurator.name_prefix}#{configurator.base_name(*partition_key_values)}"
|
269
|
+
}
|
270
|
+
|
271
|
+
#
|
272
|
+
# the full name of a child table defined by the partition key values
|
273
|
+
#
|
274
|
+
partition.table_name lambda {|model, *partition_key_values|
|
275
|
+
configurator = model.configurator
|
276
|
+
return "#{configurator.schema_name}.#{configurator.part_name(*partition_key_values)}"
|
277
|
+
}
|
278
|
+
|
279
|
+
#
|
280
|
+
# the name of the child table without a schema name or prefix. this is used to
|
281
|
+
# build child table names for multi-level partitions.
|
282
|
+
#
|
283
|
+
# for a table named foos_partitions.p42, this would be "42"
|
284
|
+
#
|
285
|
+
partition.base_name lambda { |model, *partition_key_values|
|
286
|
+
return model.partition_normalize_key_value(*partition_key_values).to_s
|
287
|
+
}
|
288
|
+
end
|
289
|
+
|
290
|
+
##
|
291
|
+
# :singleton-method: drop_partition_table
|
292
|
+
# delegated to Partitioned::PartitionedBase::PartitionManager#drop_partition_table
|
293
|
+
|
294
|
+
##
|
295
|
+
# :singleton-method: create_partition_table
|
296
|
+
# delegated to Partitioned::PartitionedBase::PartitionManager#create_partition_table
|
297
|
+
|
298
|
+
##
|
299
|
+
# :singleton-method: add_partition_table_index
|
300
|
+
# delegated to Partitioned::PartitionedBase::PartitionManager#add_partition_table_index
|
301
|
+
|
302
|
+
##
|
303
|
+
# :singleton-method: add_references_to_partition_table
|
304
|
+
# delegated to Partitioned::PartitionedBase::PartitionManager#add_references_to_partition_table
|
305
|
+
|
306
|
+
##
|
307
|
+
# :method: create_partition_schema
|
308
|
+
# delegated to Partitioned::PartitionedBase::PartitionManager#create_partition_schema
|
309
|
+
|
310
|
+
##
|
311
|
+
# :singleton-method: add_parent_table_rules
|
312
|
+
# delegated to Partitioned::PartitionedBase::PartitionManager#add_parent_table_rules
|
313
|
+
|
314
|
+
##
|
315
|
+
# :method: drop_old_partitions
|
316
|
+
# delegated to Partitioned::PartitionedBase::PartitionManager#drop_old_partitions
|
317
|
+
|
318
|
+
##
|
319
|
+
# :method: create_new_partitions
|
320
|
+
# delegated to Partitioned::PartitionedBase::PartitionManager#create_new_partitions
|
321
|
+
|
322
|
+
##
|
323
|
+
# :method: drop_old_partition
|
324
|
+
# delegated to Partitioned::PartitionedBase::PartitionManager#drop_old_partition
|
325
|
+
|
326
|
+
##
|
327
|
+
# :method: create_new_partition
|
328
|
+
# delegated to Partitioned::PartitionedBase::PartitionManager#create_new_partition
|
329
|
+
|
330
|
+
##
|
331
|
+
# :method: create_new_partition_tables
|
332
|
+
# delegated to Partitioned::PartitionedBase::PartitionManager#create_new_partition_tables
|
333
|
+
|
334
|
+
##
|
335
|
+
# :method: create_infrastructure
|
336
|
+
# delegated to Partitioned::PartitionedBase::PartitionManager#create_infrastructure
|
337
|
+
|
338
|
+
##
|
339
|
+
# :method: partition_table_name
|
340
|
+
# delegated to Partitioned::PartitionedBase::PartitionManager#partition_table_name
|
341
|
+
|
342
|
+
##
|
343
|
+
# :method: partition_name
|
344
|
+
# delegated to Partitioned::PartitionedBase::PartitionManager#partition_table_name
|
345
|
+
|
346
|
+
extend SingleForwardable
|
347
|
+
def_delegators :partition_manager, :drop_partition_table, :create_partition_table,
|
348
|
+
:add_partition_table_index, :add_references_to_partition_table,
|
349
|
+
:create_partition_schema, :add_parent_table_rules, :drop_old_partitions,
|
350
|
+
:create_new_partitions, :drop_old_partition, :create_new_partition,
|
351
|
+
:create_new_partition_tables, :create_infrastructure, :partition_table_name
|
352
|
+
def_delegator :partition_manager, :partition_table_name, :partition_name
|
353
|
+
end
|
354
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Partitioned
|
2
|
+
class PartitionedBase
|
3
|
+
module Configurator
|
4
|
+
#
|
5
|
+
# the state configured by the Dsl and read by Reader
|
6
|
+
#
|
7
|
+
class Data
|
8
|
+
class Index
|
9
|
+
attr_accessor :field, :options
|
10
|
+
def initialize(field, options = {})
|
11
|
+
@field = field
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
end
|
15
|
+
class ForeignKey
|
16
|
+
attr_accessor :referencing_field, :referenced_table, :referenced_field
|
17
|
+
def initialize(referencing_field, referenced_table = nil, referenced_field = :id)
|
18
|
+
@referencing_field = referencing_field
|
19
|
+
@referenced_table = if referenced_table.nil?
|
20
|
+
self.class.foreign_key_to_foreign_table_name(referencing_field)
|
21
|
+
else
|
22
|
+
referenced_table
|
23
|
+
end
|
24
|
+
@referenced_field = referenced_field
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.foreign_key_to_foreign_table_name(foreign_key_field)
|
28
|
+
return ActiveSupport::Inflector::pluralize(foreign_key_field.to_s.sub(/_id$/,''))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_accessor :on_field, :indexes, :foreign_keys, :last_partitions_order_by_clause,
|
33
|
+
:schema_name, :name_prefix, :base_name,
|
34
|
+
:part_name, :table_name, :parent_table_schema_name,
|
35
|
+
:parent_table_name, :check_constraint, :encoded_name
|
36
|
+
|
37
|
+
def initialize
|
38
|
+
@on_field = nil
|
39
|
+
@indexes = []
|
40
|
+
@foreign_keys = []
|
41
|
+
@last_partitions_order_by_clause = nil
|
42
|
+
|
43
|
+
@schema_name = nil
|
44
|
+
|
45
|
+
@name_prefix = nil
|
46
|
+
@base_name = nil
|
47
|
+
|
48
|
+
@part_name = nil
|
49
|
+
|
50
|
+
@table_name = nil
|
51
|
+
|
52
|
+
@parent_table_schema_name = nil
|
53
|
+
@parent_table_name = nil
|
54
|
+
|
55
|
+
@check_constraint = nil
|
56
|
+
|
57
|
+
@encoded_name = nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|