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.
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