partitioned 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/Gemfile +17 -0
  2. data/LICENSE +30 -0
  3. data/PARTITIONING_EXPLAINED.txt +351 -0
  4. data/README +111 -0
  5. data/Rakefile +27 -0
  6. data/examples/README +23 -0
  7. data/examples/company_id.rb +417 -0
  8. data/examples/company_id_and_created_at.rb +689 -0
  9. data/examples/created_at.rb +590 -0
  10. data/examples/created_at_referencing_awards.rb +1000 -0
  11. data/examples/id.rb +475 -0
  12. data/examples/lib/by_company_id.rb +11 -0
  13. data/examples/lib/command_line_tool_mixin.rb +71 -0
  14. data/examples/lib/company.rb +29 -0
  15. data/examples/lib/get_options.rb +44 -0
  16. data/examples/lib/roman.rb +41 -0
  17. data/examples/start_date.rb +621 -0
  18. data/init.rb +1 -0
  19. data/lib/monkey_patch_activerecord.rb +92 -0
  20. data/lib/monkey_patch_postgres.rb +73 -0
  21. data/lib/partitioned.rb +26 -0
  22. data/lib/partitioned/active_record_overrides.rb +34 -0
  23. data/lib/partitioned/bulk_methods_mixin.rb +288 -0
  24. data/lib/partitioned/by_created_at.rb +13 -0
  25. data/lib/partitioned/by_foreign_key.rb +21 -0
  26. data/lib/partitioned/by_id.rb +35 -0
  27. data/lib/partitioned/by_integer_field.rb +32 -0
  28. data/lib/partitioned/by_monthly_time_field.rb +23 -0
  29. data/lib/partitioned/by_time_field.rb +65 -0
  30. data/lib/partitioned/by_weekly_time_field.rb +30 -0
  31. data/lib/partitioned/multi_level.rb +20 -0
  32. data/lib/partitioned/multi_level/configurator/data.rb +14 -0
  33. data/lib/partitioned/multi_level/configurator/dsl.rb +32 -0
  34. data/lib/partitioned/multi_level/configurator/reader.rb +162 -0
  35. data/lib/partitioned/multi_level/partition_manager.rb +47 -0
  36. data/lib/partitioned/partitioned_base.rb +354 -0
  37. data/lib/partitioned/partitioned_base/configurator.rb +6 -0
  38. data/lib/partitioned/partitioned_base/configurator/data.rb +62 -0
  39. data/lib/partitioned/partitioned_base/configurator/dsl.rb +628 -0
  40. data/lib/partitioned/partitioned_base/configurator/reader.rb +209 -0
  41. data/lib/partitioned/partitioned_base/partition_manager.rb +138 -0
  42. data/lib/partitioned/partitioned_base/sql_adapter.rb +286 -0
  43. data/lib/partitioned/version.rb +3 -0
  44. data/lib/tasks/desirable_tasks.rake +4 -0
  45. data/partitioned.gemspec +21 -0
  46. data/spec/dummy/.rspec +1 -0
  47. data/spec/dummy/README.rdoc +261 -0
  48. data/spec/dummy/Rakefile +7 -0
  49. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  50. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  51. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  52. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  53. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  54. data/spec/dummy/config.ru +4 -0
  55. data/spec/dummy/config/application.rb +51 -0
  56. data/spec/dummy/config/boot.rb +10 -0
  57. data/spec/dummy/config/database.yml +32 -0
  58. data/spec/dummy/config/environment.rb +5 -0
  59. data/spec/dummy/config/environments/development.rb +30 -0
  60. data/spec/dummy/config/environments/production.rb +60 -0
  61. data/spec/dummy/config/environments/test.rb +39 -0
  62. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  63. data/spec/dummy/config/initializers/inflections.rb +10 -0
  64. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  65. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  66. data/spec/dummy/config/initializers/session_store.rb +8 -0
  67. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  68. data/spec/dummy/config/locales/en.yml +5 -0
  69. data/spec/dummy/config/routes.rb +58 -0
  70. data/spec/dummy/public/404.html +26 -0
  71. data/spec/dummy/public/422.html +26 -0
  72. data/spec/dummy/public/500.html +26 -0
  73. data/spec/dummy/public/favicon.ico +0 -0
  74. data/spec/dummy/script/rails +6 -0
  75. data/spec/dummy/spec/spec_helper.rb +27 -0
  76. data/spec/monkey_patch_posgres_spec.rb +176 -0
  77. data/spec/partitioned/bulk_methods_mixin_spec.rb +512 -0
  78. data/spec/partitioned/by_created_at_spec.rb +62 -0
  79. data/spec/partitioned/by_foreign_key_spec.rb +95 -0
  80. data/spec/partitioned/by_id_spec.rb +97 -0
  81. data/spec/partitioned/by_integer_field_spec.rb +143 -0
  82. data/spec/partitioned/by_monthly_time_field_spec.rb +100 -0
  83. data/spec/partitioned/by_time_field_spec.rb +182 -0
  84. data/spec/partitioned/by_weekly_time_field_spec.rb +100 -0
  85. data/spec/partitioned/multi_level/configurator/dsl_spec.rb +88 -0
  86. data/spec/partitioned/multi_level/configurator/reader_spec.rb +147 -0
  87. data/spec/partitioned/partitioned_base/configurator/dsl_spec.rb +459 -0
  88. data/spec/partitioned/partitioned_base/configurator/reader_spec.rb +513 -0
  89. data/spec/partitioned/partitioned_base/sql_adapter_spec.rb +204 -0
  90. data/spec/partitioned/partitioned_base_spec.rb +173 -0
  91. data/spec/spec_helper.rb +32 -0
  92. data/spec/support/shared_example_spec_helper_for_integer_key.rb +137 -0
  93. data/spec/support/shared_example_spec_helper_for_time_key.rb +147 -0
  94. data/spec/support/tables_spec_helper.rb +47 -0
  95. 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