partitioned 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,628 @@
|
|
|
1
|
+
module Partitioned
|
|
2
|
+
class PartitionedBase
|
|
3
|
+
module Configurator
|
|
4
|
+
#
|
|
5
|
+
# The Domain Specific Language manager for configuring partitioning.
|
|
6
|
+
#
|
|
7
|
+
# example:
|
|
8
|
+
#
|
|
9
|
+
# class Employee < Partitioned::ByCreatedAt
|
|
10
|
+
# partitioned do |partition|
|
|
11
|
+
# partition.index :id, :unique => true
|
|
12
|
+
# partition.foreign_key :company_id
|
|
13
|
+
# end
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# in the above example, block:
|
|
17
|
+
#
|
|
18
|
+
# partitioned do |partition|
|
|
19
|
+
# ...
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# Scopes a set of "partition directives". The directives are accessed via the block parameter 'partition'
|
|
23
|
+
#
|
|
24
|
+
# Directives parameters have two forms, a canonical form which takes a set of parameters
|
|
25
|
+
# and a dynamic form which takes a single parameter which is either a string that should be interpolated or
|
|
26
|
+
# a lambda.
|
|
27
|
+
#
|
|
28
|
+
# The dynamic forms are expected to return some value(s), similar to the canonical form.
|
|
29
|
+
#
|
|
30
|
+
# DYNAMIC FORM: LAMBDA
|
|
31
|
+
# Lambdas have passed (sometimes) one and (sometimes) two parameters (depending on the directives requirements), as in:
|
|
32
|
+
#
|
|
33
|
+
# class Employee < Partitioned::Base
|
|
34
|
+
# def self.partition_time_field
|
|
35
|
+
# return :created_at
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
# partitioned do |partition|
|
|
39
|
+
# partition.on lambda{|model| return model.partition_time_field}
|
|
40
|
+
# partition.constraint lambda{|model,time_field_value|
|
|
41
|
+
# return "#{model.partition_time_field} >= '#{time_field_value.strftime}' and #{model.partition_time_field} < '#{(time_field_value + 1.day).strftime}'"
|
|
42
|
+
# }
|
|
43
|
+
# end
|
|
44
|
+
# end
|
|
45
|
+
#
|
|
46
|
+
# Single parameter lambdas are passed the most derived Partitioned::PartitionedBase class that defines the
|
|
47
|
+
# model of this partitioned table:
|
|
48
|
+
# lambda {|model| return nil}
|
|
49
|
+
#
|
|
50
|
+
# Arguments:
|
|
51
|
+
# model - the Partitioned::PartitionedBase class that is being partitioned.
|
|
52
|
+
#
|
|
53
|
+
# Multi parameter lambdas are passed the model being partitioned and the values to specify a single child table.
|
|
54
|
+
# lambda {|model,*partition_key_values| return nil}
|
|
55
|
+
#
|
|
56
|
+
# Arguments:
|
|
57
|
+
# model - the Partitioned::PartitionedBase class that is being partitioned.
|
|
58
|
+
# *partition_key_values - the values used to partition a child table.
|
|
59
|
+
#
|
|
60
|
+
# Another example of a lambda that is passed partitioned values would be:
|
|
61
|
+
# lambda {|model,created_at| return nil}
|
|
62
|
+
#
|
|
63
|
+
# This example, which names its parameter 'created_at', is more natural to deal with if
|
|
64
|
+
# you know the parameter passed in will always be a single field and the field's name
|
|
65
|
+
# is 'created_at'.
|
|
66
|
+
#
|
|
67
|
+
# DYNAMIC FORM: STRINGS
|
|
68
|
+
# Strings to be interpolated have access to two parameters:
|
|
69
|
+
# model - the ActiveRecord class that is being partitioned.
|
|
70
|
+
# partition_key_values - an array of values used to partition a child table.
|
|
71
|
+
# field_value - the first element of partition_key_values (for convience)
|
|
72
|
+
#
|
|
73
|
+
# for instance:
|
|
74
|
+
# class Employee < Partitioned::PartitionBase
|
|
75
|
+
# partitioned do |partition|
|
|
76
|
+
# partition.on :foo
|
|
77
|
+
# partition.index :bar
|
|
78
|
+
# partition.index :baz
|
|
79
|
+
# partition.constraint %q!foo = #{field_value}!
|
|
80
|
+
# end
|
|
81
|
+
# end
|
|
82
|
+
#
|
|
83
|
+
# is the same as:
|
|
84
|
+
# class Employee < Partitioned::PartitionBase
|
|
85
|
+
# def self.partitioned_field
|
|
86
|
+
# return :foo
|
|
87
|
+
# end
|
|
88
|
+
# def self.index_field1
|
|
89
|
+
# return :bar
|
|
90
|
+
# end
|
|
91
|
+
# def self.index_field2
|
|
92
|
+
# return :baz
|
|
93
|
+
# end
|
|
94
|
+
# partitioned do |partition|
|
|
95
|
+
# partition.on '#{model.partitioned_field}'
|
|
96
|
+
# partition.index lambda { |model, *partition_key_values|
|
|
97
|
+
# return Configurator::Data::Index.new(model.index_field1, {})
|
|
98
|
+
# }
|
|
99
|
+
# partition.index lambda { |model, *partition_key_values|
|
|
100
|
+
# return Configurator::Data::Index.new(model.index_field2, {})
|
|
101
|
+
# }
|
|
102
|
+
# partition.constraint %q!#{model.partitioned_field} = #{field_value}!
|
|
103
|
+
# end
|
|
104
|
+
# end
|
|
105
|
+
#
|
|
106
|
+
# IMPORTANT: note that lambdas receive, as their first parameter 'model', the most derived class that is being partition.
|
|
107
|
+
# This is not always the same as the class accessible through 'self' because 'self' is evaluated at lambda definition time.
|
|
108
|
+
# Use 'model' for general access to the Partitioned:PartitionedBase model.
|
|
109
|
+
#
|
|
110
|
+
# The follow example shows incorrect access to the model:
|
|
111
|
+
#
|
|
112
|
+
#!bad! class Employee < Partitioned::PartitionBase
|
|
113
|
+
#!bad! def self.index_field
|
|
114
|
+
#!bad! return :bar
|
|
115
|
+
#!bad! end
|
|
116
|
+
#!bad! partitioned do |partition|
|
|
117
|
+
#!bad! partition.on lambda { |model| return index_field }
|
|
118
|
+
#!bad! partition.index lambda { |model, *partition_key_values|
|
|
119
|
+
#!bad! return Configurator::Data::Index.new(self.index_field, {})
|
|
120
|
+
#!bad! }
|
|
121
|
+
#!bad! end
|
|
122
|
+
#!bad! end
|
|
123
|
+
#!bad!
|
|
124
|
+
#!bad! class FavoriteEmployee < Employee
|
|
125
|
+
#!bad! def self.index_field
|
|
126
|
+
#!bad! return :baz
|
|
127
|
+
#!bad! end
|
|
128
|
+
#!bad! end
|
|
129
|
+
#
|
|
130
|
+
# In the above (bad code) the directive 'index' parameter is a lambda using "self.index_field" instead of "model.index_field"
|
|
131
|
+
# and the directive 'on' parameter is a lambda using "index_field" instead of "model.index_field".
|
|
132
|
+
# Since resolution of the self occurs at lambda definition time, self is Employee instead of
|
|
133
|
+
# FavoriteEmployee and index_field will be :bar instead of :baz. model.index_field will
|
|
134
|
+
# resolve to FavoriteEmployee.index_field and be :baz as expected.
|
|
135
|
+
#
|
|
136
|
+
class Dsl
|
|
137
|
+
class InvalidConfiguratorDirectiveValue < StandardError
|
|
138
|
+
def initialize(model, table_name, directive, value, explanation)
|
|
139
|
+
super("#{model.name} [#{table_name}] invalid value '#{value}' for partitioned directive '#{directive}'. #{explanation}")
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
attr_reader :data, :model
|
|
144
|
+
|
|
145
|
+
def initialize(most_derived_activerecord_class, data_class = Partitioned::PartitionedBase::Configurator::Data)
|
|
146
|
+
@model = most_derived_activerecord_class
|
|
147
|
+
@data = data_class.new
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
#
|
|
151
|
+
# The field used to partition child tables
|
|
152
|
+
#
|
|
153
|
+
# arguments:
|
|
154
|
+
# field - the name of the field
|
|
155
|
+
#
|
|
156
|
+
# usage:
|
|
157
|
+
# partitioned do |partition|
|
|
158
|
+
# partition.on :company_id
|
|
159
|
+
# end
|
|
160
|
+
#
|
|
161
|
+
# or:
|
|
162
|
+
#
|
|
163
|
+
# arguments:
|
|
164
|
+
# lambda(model) - proc returning the name of the field to partition child tables
|
|
165
|
+
#
|
|
166
|
+
# usage:
|
|
167
|
+
# partitioned do |partition|
|
|
168
|
+
# partition.on lambda {|model| model.partition_field}
|
|
169
|
+
# end
|
|
170
|
+
#
|
|
171
|
+
# or:
|
|
172
|
+
#
|
|
173
|
+
# arguments:
|
|
174
|
+
# string - a string to be interpolated naming the field to partition child tables
|
|
175
|
+
#
|
|
176
|
+
# usage:
|
|
177
|
+
# partitioned do |partition|
|
|
178
|
+
# partition.on '#{model.partition_field}'
|
|
179
|
+
# end
|
|
180
|
+
#
|
|
181
|
+
# one might use the latter forms to consolidate information about the field name when
|
|
182
|
+
# it might be used in several DSL directives.
|
|
183
|
+
#
|
|
184
|
+
def on(field)
|
|
185
|
+
data.on_field = field
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
#
|
|
189
|
+
# Define an index to be created on all (leaf-) child tables.
|
|
190
|
+
#
|
|
191
|
+
# arguments:
|
|
192
|
+
# field - the name of the field (or an array of fields) to index
|
|
193
|
+
# options - (not required) options passed to add_table_index()
|
|
194
|
+
#
|
|
195
|
+
# usage:
|
|
196
|
+
# partitioned do |partition|
|
|
197
|
+
# partition.index :id, :unique => true
|
|
198
|
+
# end
|
|
199
|
+
#
|
|
200
|
+
# or:
|
|
201
|
+
#
|
|
202
|
+
# arguments:
|
|
203
|
+
# lambda(model, *partition_key_values) - a procedure that will return a Partitioned::PartitionedBase::Configurator::Data::Index
|
|
204
|
+
#
|
|
205
|
+
# usage:
|
|
206
|
+
# partitioned do |partition|
|
|
207
|
+
# partition.index lambda { |model, *partition_key_values|
|
|
208
|
+
# return Configurator::Data::Index.new(model.partition_field, {})
|
|
209
|
+
# }
|
|
210
|
+
# end
|
|
211
|
+
#
|
|
212
|
+
# note: this system only applies indexes to leaf child tables because indexes on parent tables,
|
|
213
|
+
# will not be used by the inherited tables (in postgres).
|
|
214
|
+
#
|
|
215
|
+
def index(field, options = {})
|
|
216
|
+
if field.is_a? Proc
|
|
217
|
+
data.indexes << field
|
|
218
|
+
else
|
|
219
|
+
data.indexes << Partitioned::PartitionedBase::Configurator::Data::Index.new(field, options)
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
#
|
|
224
|
+
# Define a foreign key on a (leaf-) child table.
|
|
225
|
+
#
|
|
226
|
+
# arguments:
|
|
227
|
+
# referencing_field - the local field that references a foreign key
|
|
228
|
+
# referenced_table - (optional: derived from referencing_field) the foreign table that is referenced
|
|
229
|
+
# referenced_field - (optional: default :id) the foreign tables key to reference
|
|
230
|
+
#
|
|
231
|
+
# usage:
|
|
232
|
+
# partitioned do |partition|
|
|
233
|
+
# partition.foreign_key :company_id
|
|
234
|
+
# partition.foreign_key :home_town_id, :cities
|
|
235
|
+
# end
|
|
236
|
+
#
|
|
237
|
+
# or:
|
|
238
|
+
#
|
|
239
|
+
# arguments:
|
|
240
|
+
# proc(model, *partition_key_values) - a procedure that will return an instance of
|
|
241
|
+
# Partitioned::PartitionedBase::Configurator::Data::ForeignKey
|
|
242
|
+
#
|
|
243
|
+
# usage:
|
|
244
|
+
# partitioned do |partition|
|
|
245
|
+
# partition.foreign_key lambda { |model, *partition_key_values|
|
|
246
|
+
# return Configurator::Data::ForeignKey.new(model.foreign_key_field)
|
|
247
|
+
# }
|
|
248
|
+
# end
|
|
249
|
+
#
|
|
250
|
+
# note: as with indexes, foreign key constraints are not inherited by child tables (in postgres).
|
|
251
|
+
# this system only applies foreign keys to leaf tables.
|
|
252
|
+
#
|
|
253
|
+
def foreign_key(referencing_field, referenced_table = nil, referenced_field = :id)
|
|
254
|
+
if referencing_field.is_a? Proc
|
|
255
|
+
data.foreign_keys << referencing_field
|
|
256
|
+
else
|
|
257
|
+
data.foreign_keys << Partitioned::PartitionedBase::Configurator::Data::ForeignKey.new(referencing_field, referenced_table, referenced_field)
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
#
|
|
262
|
+
# Define the check constraint for a given child table.
|
|
263
|
+
#
|
|
264
|
+
# arguments:
|
|
265
|
+
# constraint - a string defining the constraint for all child tables
|
|
266
|
+
#
|
|
267
|
+
# usage:
|
|
268
|
+
# partitioned do |partition|
|
|
269
|
+
# partition.constraint 'company_id = #{field_value}'
|
|
270
|
+
# end
|
|
271
|
+
#
|
|
272
|
+
# note: the usage of single quotes to prevent string interpolation at definition time. This string will be interpolated at
|
|
273
|
+
# run-time and "field_value" will be set to the value of the first element of partition_key_values.
|
|
274
|
+
#
|
|
275
|
+
# or:
|
|
276
|
+
#
|
|
277
|
+
# arguments:
|
|
278
|
+
# lambda(model, *partitioned_key_values) - a procedure returning a string defining the child table's constraint. The
|
|
279
|
+
# child table is defined by the *partitioned key_values.
|
|
280
|
+
#
|
|
281
|
+
# usage:
|
|
282
|
+
# partitioned do |partition|
|
|
283
|
+
# partition.constraint lambda {|model, value|
|
|
284
|
+
# return "#{model.field_to_partition} = #{value}"
|
|
285
|
+
# }
|
|
286
|
+
# end
|
|
287
|
+
#
|
|
288
|
+
def check_constraint(constraint)
|
|
289
|
+
data.check_constraint = constraint
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
#
|
|
293
|
+
# Define the order by clause used to list all child table names in order of "last to be used" to "oldest to have been used".
|
|
294
|
+
#
|
|
295
|
+
# the sql used for a table ORDERS whose child tables exist in ORDERS_PARTITIONS would look like:
|
|
296
|
+
#
|
|
297
|
+
# select tablename from pg_tables where schemaname = 'orders_partitions' order by tablename
|
|
298
|
+
#
|
|
299
|
+
# for instance, if child tables of ORDERS are partitioned by id range (say every 5 values) and have the form orders_partition.pN,
|
|
300
|
+
# where N is the lowest value in the range of ids for that table, the order clause would probably be
|
|
301
|
+
# "substring(tablename, 2)::integer desc" which would result in:
|
|
302
|
+
# p100
|
|
303
|
+
# p95
|
|
304
|
+
# p90
|
|
305
|
+
# p85
|
|
306
|
+
# p80
|
|
307
|
+
# p75
|
|
308
|
+
# p70
|
|
309
|
+
# p65
|
|
310
|
+
# p60
|
|
311
|
+
# p55
|
|
312
|
+
# p50
|
|
313
|
+
# p45
|
|
314
|
+
# p40
|
|
315
|
+
# p35
|
|
316
|
+
# p30
|
|
317
|
+
# p25
|
|
318
|
+
# p20
|
|
319
|
+
# p15
|
|
320
|
+
# p10
|
|
321
|
+
# p5
|
|
322
|
+
# p0
|
|
323
|
+
#
|
|
324
|
+
# this is used in PartitionedBase.last_n_partition_names(limit = 1) which should be used in code that wishes to determine
|
|
325
|
+
# if there are enough room in child tables for future use. such processing code is not apart of
|
|
326
|
+
# partitioned code base, but this helper is here to assist in building such code.
|
|
327
|
+
#
|
|
328
|
+
# one might know that 1 partition is used per day and wish to have 10 partitions available for unforseeable spikes of data load.
|
|
329
|
+
# one might run a script once per day which calls Order.last_n_partition_names(10) and if any of the returned tables have any rows
|
|
330
|
+
# (or the sequence is set into any of the ranges in the child table) it is time to create new child tables
|
|
331
|
+
#
|
|
332
|
+
def order(clause)
|
|
333
|
+
data.last_partitions_order_by_clause = clause
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
#
|
|
337
|
+
# The name of the schema that will contain all child tables.
|
|
338
|
+
#
|
|
339
|
+
# arguments:
|
|
340
|
+
# value - a string, the name of schema
|
|
341
|
+
#
|
|
342
|
+
# usage:
|
|
343
|
+
# partitioned do |partition|
|
|
344
|
+
# partition.schema_name "foos_partitions"
|
|
345
|
+
# end
|
|
346
|
+
#
|
|
347
|
+
# or:
|
|
348
|
+
#
|
|
349
|
+
# arguments:
|
|
350
|
+
# lambda(model, *partitioned_key_values) - a proc returning a string which is the name of the schema
|
|
351
|
+
#
|
|
352
|
+
# usage:
|
|
353
|
+
# partitioned do |partition|
|
|
354
|
+
# partition.schema_name lambda {|model, *value|
|
|
355
|
+
# return "#{model.table_name}_partitions"
|
|
356
|
+
# }
|
|
357
|
+
# end
|
|
358
|
+
#
|
|
359
|
+
# or:
|
|
360
|
+
#
|
|
361
|
+
# arguments:
|
|
362
|
+
# string - to be interpolated at run time
|
|
363
|
+
#
|
|
364
|
+
# usage:
|
|
365
|
+
# partitioned do |partition|
|
|
366
|
+
# partition.schema_name '#{model.table_name}_partitions'
|
|
367
|
+
# end
|
|
368
|
+
#
|
|
369
|
+
# the default is similar to the second usage: TABLENAME_partitions, for a table named 'foos' the schema name will be
|
|
370
|
+
# foos_partitions
|
|
371
|
+
#
|
|
372
|
+
def schema_name(value)
|
|
373
|
+
data.schema_name = value
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
#
|
|
377
|
+
# The prefix for the child table's name.
|
|
378
|
+
#
|
|
379
|
+
# by default this is the (second) 'p' in the fully qualified name 'foos_partitions.p42'
|
|
380
|
+
#
|
|
381
|
+
# arguments:
|
|
382
|
+
# value - a string, the prefix name
|
|
383
|
+
#
|
|
384
|
+
# usage:
|
|
385
|
+
# partitioned do |partition|
|
|
386
|
+
# partition.name_prefix "p"
|
|
387
|
+
# end
|
|
388
|
+
#
|
|
389
|
+
# or:
|
|
390
|
+
#
|
|
391
|
+
# arguments:
|
|
392
|
+
# lambda(model, *partitioned_key_values) - a proc returning a string which is the prefix
|
|
393
|
+
#
|
|
394
|
+
# usage:
|
|
395
|
+
# partitioned do |partition|
|
|
396
|
+
# partition.name_prefix lambda {|model, *value|
|
|
397
|
+
# return "#{model.table_name}_child_"
|
|
398
|
+
# }
|
|
399
|
+
# end
|
|
400
|
+
#
|
|
401
|
+
# or:
|
|
402
|
+
#
|
|
403
|
+
# arguments:
|
|
404
|
+
# string - to be interpolated at run time
|
|
405
|
+
#
|
|
406
|
+
# usage:
|
|
407
|
+
# partitioned do |partition|
|
|
408
|
+
# partition.name_prefix '#{model.table_name}_child_'
|
|
409
|
+
# end
|
|
410
|
+
#
|
|
411
|
+
# the default is 'p'
|
|
412
|
+
#
|
|
413
|
+
def name_prefix(value)
|
|
414
|
+
data.name_prefix = value
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
#
|
|
418
|
+
# The name of the child table without the schema name or name prefix.
|
|
419
|
+
#
|
|
420
|
+
# in the example: 'foos_partitions.p42' the base_name would be 42
|
|
421
|
+
#
|
|
422
|
+
# arguments:
|
|
423
|
+
# value - a string, the base name
|
|
424
|
+
#
|
|
425
|
+
# usage:
|
|
426
|
+
# partitioned do |partition|
|
|
427
|
+
# partition.base_name "42"
|
|
428
|
+
# end
|
|
429
|
+
#
|
|
430
|
+
# arguments:
|
|
431
|
+
# value - a string, the base name child table to be interpolated at runtime
|
|
432
|
+
#
|
|
433
|
+
# usage:
|
|
434
|
+
# partitioned do |partition|
|
|
435
|
+
# partition.base_name '#{model.partition_normalize_key_value(field_value)}'
|
|
436
|
+
# end
|
|
437
|
+
#
|
|
438
|
+
# note: the string passed to partition.base_name is built using single quotes so that the
|
|
439
|
+
# the string will not be interpolated at definition time. Rather, the string will be
|
|
440
|
+
# interpolated at run-time when it will scope the interpolation with the
|
|
441
|
+
# partition_key_values array (and field_value which the the first element of that array)
|
|
442
|
+
#
|
|
443
|
+
# or:
|
|
444
|
+
#
|
|
445
|
+
# arguments:
|
|
446
|
+
# lambda(model, *partitioned_key_values) - a proc returning a string which is the base name of the child table
|
|
447
|
+
#
|
|
448
|
+
# usage:
|
|
449
|
+
# partitioned do |partition|
|
|
450
|
+
# partition.base_name lambda {|model, *partition_key_values|
|
|
451
|
+
# return model.partition_normalize_key_value(*partition_key_values).to_s
|
|
452
|
+
# }
|
|
453
|
+
# end
|
|
454
|
+
#
|
|
455
|
+
# the default is similar to the second usage, that is: normalize the value and call to_s
|
|
456
|
+
#
|
|
457
|
+
def base_name(value)
|
|
458
|
+
data.base_name = value
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
#
|
|
462
|
+
# The child tables name without the schema name.
|
|
463
|
+
#
|
|
464
|
+
# in the example: 'foos_partitions.p42' the part_name would be p42
|
|
465
|
+
#
|
|
466
|
+
# arguments:
|
|
467
|
+
# value - a string, the part name
|
|
468
|
+
#
|
|
469
|
+
# usage:
|
|
470
|
+
# partitioned do |partition|
|
|
471
|
+
# partition.part_name "p42"
|
|
472
|
+
# end
|
|
473
|
+
#
|
|
474
|
+
# or:
|
|
475
|
+
#
|
|
476
|
+
# arguments:
|
|
477
|
+
# value - a string, the part name child table to be interpolated at runtime
|
|
478
|
+
#
|
|
479
|
+
# usage:
|
|
480
|
+
# partitioned do |partition|
|
|
481
|
+
# partition.part_name '#{model.table_name}_child_#{model.partition_normalize_key_value(field_value)}'
|
|
482
|
+
# end
|
|
483
|
+
#
|
|
484
|
+
# note: the string passed to partition.part_name is built using single quotes so that the
|
|
485
|
+
# the string will not be interpolated at definition time. Rather, the string will be
|
|
486
|
+
# interpolated at run-time when it will scope the interpolation with the
|
|
487
|
+
# partition_key_values array (and field_value which the the first element of that array)
|
|
488
|
+
#
|
|
489
|
+
# or:
|
|
490
|
+
#
|
|
491
|
+
# arguments:
|
|
492
|
+
# lambda(model, *partitioned_key_values) - a proc returning a string which is the part name of the child table
|
|
493
|
+
#
|
|
494
|
+
# usage:
|
|
495
|
+
# partitioned do |partition|
|
|
496
|
+
# partition.part_name lambda {|model, *partition_key_values|
|
|
497
|
+
# return "#{model.table_name}_child_#{model.partition_normalize_key_value(field_value)}"
|
|
498
|
+
# }
|
|
499
|
+
# end
|
|
500
|
+
#
|
|
501
|
+
# the default is similar to the third usage
|
|
502
|
+
#
|
|
503
|
+
def part_name(value)
|
|
504
|
+
data.part_name = value
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
#
|
|
508
|
+
# The full name of a child table defined by the partition key values.
|
|
509
|
+
#
|
|
510
|
+
# in the example: 'foos_partitions.p42' the table name would be foos_partitions.p42
|
|
511
|
+
#
|
|
512
|
+
# arguments:
|
|
513
|
+
# value - a string, the table name
|
|
514
|
+
#
|
|
515
|
+
# usage:
|
|
516
|
+
# partitioned do |partition|
|
|
517
|
+
# partition.table_name "foos_partitions.p42"
|
|
518
|
+
# end
|
|
519
|
+
#
|
|
520
|
+
# or:
|
|
521
|
+
#
|
|
522
|
+
# arguments:
|
|
523
|
+
# value - a string, the table name child table to be interpolated at runtime
|
|
524
|
+
#
|
|
525
|
+
# usage:
|
|
526
|
+
# partitioned do |partition|
|
|
527
|
+
# partition.table_name '#{model.table_name}_partitions.#{model.table_name}_child_#{model.partition_normalize_key_value(field_value)}'
|
|
528
|
+
# end
|
|
529
|
+
#
|
|
530
|
+
# or:
|
|
531
|
+
#
|
|
532
|
+
# arguments:
|
|
533
|
+
# lambda(model, *partitioned_key_values) - a proc returning a string which is the table name of the child table
|
|
534
|
+
#
|
|
535
|
+
# usage:
|
|
536
|
+
# partitioned do |partition|
|
|
537
|
+
# partition.table_name lambda {|model, *partition_key_values|
|
|
538
|
+
# return "#{model.table_name}_partitions.#{model.table_name}_child_#{model.partition_normalize_key_value(partition_key_values.first)}"
|
|
539
|
+
# }
|
|
540
|
+
# end
|
|
541
|
+
#
|
|
542
|
+
# the default is similar to the third usage
|
|
543
|
+
#
|
|
544
|
+
def table_name(value)
|
|
545
|
+
data.table_name = value
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
#
|
|
549
|
+
# The table name of the table who is the direct ancestor of a child table.
|
|
550
|
+
#
|
|
551
|
+
# arguments:
|
|
552
|
+
# value - a string, the parent table name
|
|
553
|
+
#
|
|
554
|
+
# usage:
|
|
555
|
+
# partitioned do |partition|
|
|
556
|
+
# partition.parent_table_name "foos"
|
|
557
|
+
# end
|
|
558
|
+
#
|
|
559
|
+
# or:
|
|
560
|
+
#
|
|
561
|
+
# arguments:
|
|
562
|
+
# value - a string, the parent table name child table to be interpolated at runtime
|
|
563
|
+
#
|
|
564
|
+
# usage:
|
|
565
|
+
# partitioned do |partition|
|
|
566
|
+
# partition.table_name '#{model.table_name}'
|
|
567
|
+
# end
|
|
568
|
+
#
|
|
569
|
+
# or:
|
|
570
|
+
#
|
|
571
|
+
# arguments:
|
|
572
|
+
# lambda(model, *partitioned_key_values) - a proc returning a string which is the parent table name of the child table
|
|
573
|
+
#
|
|
574
|
+
# usage:
|
|
575
|
+
# partitioned do |partition|
|
|
576
|
+
# partition.parent_table_name lambda {|model, *partition_key_values|
|
|
577
|
+
# return "#{model.table_name}"
|
|
578
|
+
# }
|
|
579
|
+
# end
|
|
580
|
+
#
|
|
581
|
+
# By default this is just the active record's notion of the name of the class.
|
|
582
|
+
#
|
|
583
|
+
def parent_table_name(value)
|
|
584
|
+
data.parent_table_name = value
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
#
|
|
588
|
+
# The schema name of the table who is the direct ancestor of a child table.
|
|
589
|
+
#
|
|
590
|
+
# arguments:
|
|
591
|
+
# value - a string, the schema name
|
|
592
|
+
#
|
|
593
|
+
# usage:
|
|
594
|
+
# partitioned do |partition|
|
|
595
|
+
# partition.parent_table_schema_name "public"
|
|
596
|
+
# end
|
|
597
|
+
#
|
|
598
|
+
# or:
|
|
599
|
+
#
|
|
600
|
+
# arguments:
|
|
601
|
+
# value - a string, the schema name to be interpolated at runtime
|
|
602
|
+
#
|
|
603
|
+
# usage:
|
|
604
|
+
# partitioned do |partition|
|
|
605
|
+
# partition.parent_table_schema_name '#{model.table_name}'
|
|
606
|
+
# end
|
|
607
|
+
#
|
|
608
|
+
# or:
|
|
609
|
+
#
|
|
610
|
+
# arguments:
|
|
611
|
+
# lambda(model, *partitioned_key_values) - a proc returning a string which is the schema name of the child table
|
|
612
|
+
#
|
|
613
|
+
# usage:
|
|
614
|
+
# partitioned do |partition|
|
|
615
|
+
# partition.parent_table_schema_name lambda {|model, *partition_key_values|
|
|
616
|
+
# return "#{model.table_name}"
|
|
617
|
+
# }
|
|
618
|
+
# end
|
|
619
|
+
#
|
|
620
|
+
# By default this is just the "public".
|
|
621
|
+
#
|
|
622
|
+
def parent_table_schema_name(value)
|
|
623
|
+
data.parent_table_schema_name = value
|
|
624
|
+
end
|
|
625
|
+
end
|
|
626
|
+
end
|
|
627
|
+
end
|
|
628
|
+
end
|