partitioned 0.8.0 → 1.0.1

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.
@@ -4,22 +4,22 @@ module Partitioned
4
4
  #
5
5
  # The Domain Specific Language manager for configuring partitioning.
6
6
  #
7
- # example:
7
+ # @example of use:
8
8
  #
9
- # class Employee < Partitioned::ByCreatedAt
10
- # partitioned do |partition|
11
- # partition.index :id, :unique => true
12
- # partition.foreign_key :company_id
9
+ # class Employee < Partitioned::ByCreatedAt
10
+ # partitioned do |partition|
11
+ # partition.index :id, :unique => true
12
+ # partition.foreign_key :company_id
13
+ # end
13
14
  # end
14
- # end
15
15
  #
16
- # in the above example, block:
16
+ # in the above example, block:
17
17
  #
18
- # partitioned do |partition|
19
- # ...
20
- # end
18
+ # partitioned do |partition|
19
+ # ...
20
+ # end
21
21
  #
22
- # Scopes a set of "partition directives". The directives are accessed via the block parameter 'partition'
22
+ # Scopes a set of "partition directives". The directives are accessed via the block parameter 'partition'
23
23
  #
24
24
  # Directives parameters have two forms, a canonical form which takes a set of parameters
25
25
  # and a dynamic form which takes a single parameter which is either a string that should be interpolated or
@@ -36,10 +36,11 @@ module Partitioned
36
36
  # end
37
37
  #
38
38
  # partitioned do |partition|
39
- # partition.on lambda{|model| return model.partition_time_field}
39
+ # partition.on lambda{ |model| return model.partition_time_field}
40
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
- # }
41
+ # return "#{model.partition_time_field} >= '#{time_field_value.strftime}' and
42
+ # #{model.partition_time_field} < '#{(time_field_value + 1.day).strftime}'"
43
+ # }
43
44
  # end
44
45
  # end
45
46
  #
@@ -134,6 +135,9 @@ module Partitioned
134
135
  # resolve to FavoriteEmployee.index_field and be :baz as expected.
135
136
  #
136
137
  class Dsl
138
+ #
139
+ # raised when a partitioned DSL directive's parameters are considered invalid
140
+ #
137
141
  class InvalidConfiguratorDirectiveValue < StandardError
138
142
  def initialize(model, table_name, directive, value, explanation)
139
143
  super("#{model.name} [#{table_name}] invalid value '#{value}' for partitioned directive '#{directive}'. #{explanation}")
@@ -254,7 +258,8 @@ module Partitioned
254
258
  if referencing_field.is_a? Proc
255
259
  data.foreign_keys << referencing_field
256
260
  else
257
- data.foreign_keys << Partitioned::PartitionedBase::Configurator::Data::ForeignKey.new(referencing_field, referenced_table, referenced_field)
261
+ data.foreign_keys << Partitioned::PartitionedBase::Configurator::Data::ForeignKey.
262
+ new(referencing_field, referenced_table, referenced_field)
258
263
  end
259
264
  end
260
265
 
@@ -1,6 +1,9 @@
1
1
  module Partitioned
2
2
  class PartitionedBase
3
3
  module Configurator
4
+ # coalesces and parses all {Data} objects allowing the
5
+ # {PartitionManager} to request partitioning information froma
6
+ # centralized source.
4
7
  class Reader
5
8
  attr_reader :model
6
9
 
@@ -1,5 +1,9 @@
1
1
  module Partitioned
2
2
  class PartitionedBase < ActiveRecord::Base
3
+ # the configuration manager for partitioning.
4
+ # it supports, the front-end UI (a DSL) using {Dsl}
5
+ # state using {Data}
6
+ # and a parser using {Reader}
3
7
  module Configurator
4
8
  end
5
9
  end
@@ -1,3 +1,5 @@
1
+ require 'forwardable'
2
+
1
3
  module Partitioned
2
4
  class PartitionedBase
3
5
  #
@@ -13,7 +15,7 @@ module Partitioned
13
15
  end
14
16
 
15
17
  #
16
- # drop partitions that are no longer necessary.
18
+ # Drop partitions that are no longer necessary.
17
19
  # uses #old_partition_key_values_set as the list of
18
20
  # partitions to remove.
19
21
  #
@@ -24,7 +26,7 @@ module Partitioned
24
26
  end
25
27
 
26
28
  #
27
- # create partitions that are needed (probably to handle data that
29
+ # Create partitions that are needed (probably to handle data that
28
30
  # will be inserted into the database within the next few weeks).
29
31
  # uses #new_partition_key_value_set to determine the key values
30
32
  # for the specific child tables to create.
@@ -36,7 +38,7 @@ module Partitioned
36
38
  end
37
39
 
38
40
  #
39
- # create any partition tables from a list. the partition tables must
41
+ # Create any partition tables from a list. the partition tables must
40
42
  # not already exist and its schema must already exist.
41
43
  #
42
44
  def create_new_partition_tables(enumerable)
@@ -46,7 +48,7 @@ module Partitioned
46
48
  end
47
49
 
48
50
  #
49
- # the once called function to prepare a parent table for partitioning as well
51
+ # The once called function to prepare a parent table for partitioning as well
50
52
  # as create the schema that the child tables will be placed in.
51
53
  #
52
54
  def create_infrastructure
@@ -56,41 +58,41 @@ module Partitioned
56
58
 
57
59
  protected
58
60
  #
59
- # an array of key values (each key value is an array of keys) that represent
61
+ # An array of key values (each key value is an array of keys) that represent
60
62
  # the child partitions that should be created.
61
63
  #
62
- # used by #create_new_partitions and generally called once a day to update
63
- # the database with new soon-to-be needed child tables
64
+ # Used by #create_new_partitions and generally called once a day to update
65
+ # the database with new soon-to-be needed child tables.
64
66
  #
65
- # typically overridden by the concrete class as this is pure business logic
67
+ # Typically overridden by the concrete class as this is pure business logic.
66
68
  #
67
69
  def new_partition_key_values_set
68
70
  []
69
71
  end
70
72
 
71
73
  #
72
- # an array of key values (each key value is an array of keys) that represent
74
+ # An array of key values (each key value is an array of keys) that represent
73
75
  # the child partitions that should be dropped because they are no longer needed.
74
76
  #
75
- # used by #drop_old_partitions and generally called once a day to clean up
76
- # unneeded child tables
77
+ # Used by #drop_old_partitions and generally called once a day to clean up
78
+ # unneeded child tables.
77
79
  #
78
- # typically overridden by the concrete class as this is pure business logic
80
+ # Typically overridden by the concrete class as this is pure business logic.
79
81
  #
80
82
  def old_partition_key_values_set
81
83
  []
82
84
  end
83
85
 
84
86
  #
85
- # remove a specific partition from the database given
86
- # the key value(s) of its check constraint columns
87
+ # Remove a specific partition from the database given
88
+ # the key value(s) of its check constraint columns.
87
89
  #
88
90
  def drop_old_partition(*partition_key_values)
89
91
  drop_partition_table(*partition_key_values)
90
92
  end
91
93
 
92
94
  #
93
- # create a specific child table that does not currently
95
+ # Create a specific child table that does not currently
94
96
  # exist and whose schema (the schema that the table exists in)
95
97
  # also already exists (#create_infrastructure is designed to
96
98
  # create this).
@@ -1,3 +1,5 @@
1
+ require 'forwardable'
2
+
1
3
  module Partitioned
2
4
  class PartitionedBase
3
5
  #
@@ -12,7 +14,7 @@ module Partitioned
12
14
  end
13
15
 
14
16
  #
15
- # ensure our function for warning about improper partition usage is in place
17
+ # Ensure our function for warning about improper partition usage is in place.
16
18
  #
17
19
  # Name: always_fail_on_insert(text); Type: FUNCTION; Schema: public
18
20
  #
@@ -43,7 +45,7 @@ module Partitioned
43
45
  end
44
46
 
45
47
  #
46
- # does a specific child partition exist
48
+ # Does a specific child partition exist.
47
49
  #
48
50
  def partition_exists?(*partition_key_values)
49
51
  return find(:first,
@@ -56,22 +58,22 @@ module Partitioned
56
58
  end
57
59
 
58
60
  #
59
- # returns an array of partition table names from last to first limited to
61
+ # Returns an array of partition table names from last to first limited to
60
62
  # the number of entries requested by its first parameter.
61
63
  #
62
- # the magic here is in the overridden method "last_n_partitions_order_by_clause"
64
+ # The magic here is in the overridden method "last_n_partitions_order_by_clause"
63
65
  # which is designed to order a list of partition table names (table names without
64
66
  # their schema name) from last to first.
65
67
  #
66
- # if the child table names are the format "pYYYYMMDD" where YYYY is a four digit year, MM is
68
+ # If the child table names are the format "pYYYYMMDD" where YYYY is a four digit year, MM is
67
69
  # a month number and DD is a day number, you would use the following to order from last to
68
70
  # first:
69
71
  # tablename desc
70
72
  #
71
- # for child table names of the format "pXXXX" where XXXX is a number, you may want something like:
73
+ # For child table names of the format "pXXXX" where XXXX is a number, you may want something like:
72
74
  # substring(tablename, 2)::integer desc
73
75
  #
74
- # for clarity, the sql executed is:
76
+ # For clarity, the sql executed is:
75
77
  # select tablename from pg_tables where schemaname = $1 order by $2 limit $3
76
78
  # where:
77
79
  # $1 = the name of schema (foos_partitions)
@@ -88,18 +90,18 @@ module Partitioned
88
90
  end
89
91
 
90
92
  #
91
- # override this or order the tables from last (greatest value? greatest date?) to first
93
+ # Override this or order the tables from last (greatest value? greatest date?) to first.
92
94
  #
93
95
  def last_n_partitions_order_by_clause
94
96
  return configurator.last_n_partitions_order_by_clause
95
97
  end
96
98
 
97
99
  #
98
- # used to create the parent table rule to ensure
100
+ # Used to create the parent table rule to ensure.
99
101
  #
100
- # this will cause an error on attempt to insert into the parent table
102
+ # This will cause an error on attempt to insert into the parent table.
101
103
  #
102
- # we want all records to exist in one of the child tables so the
104
+ # We want all records to exist in one of the child tables so the
103
105
  # query planner can optimize access to the records.
104
106
  #
105
107
  def add_parent_table_rules(*partition_key_values)
@@ -118,14 +120,14 @@ module Partitioned
118
120
  end
119
121
 
120
122
  #
121
- # the name of the table (schemaname.childtablename) given the check constraint values.
123
+ # The name of the table (schemaname.childtablename) given the check constraint values.
122
124
  #
123
125
  def partition_table_name(*partition_key_values)
124
126
  return configurator.table_name(*partition_key_values)
125
127
  end
126
128
 
127
129
  #
128
- # create a single child table.
130
+ # Create a single child table.
129
131
  #
130
132
  def create_partition_table(*partition_key_values)
131
133
  create_table(configurator.table_name(*partition_key_values), {
@@ -137,14 +139,14 @@ module Partitioned
137
139
  end
138
140
 
139
141
  #
140
- # remove a specific single child table
142
+ # Remove a specific single child table.
141
143
  #
142
144
  def drop_partition_table(*partition_key_values)
143
145
  drop_table(configurator.table_name(*partition_key_values))
144
146
  end
145
147
 
146
148
  #
147
- # add indexes that must exist on child tables. Only leaf child tables
149
+ # Add indexes that must exist on child tables. Only leaf child tables
148
150
  # need indexes as parent table indexes are not used in postgres.
149
151
  #
150
152
  def add_partition_table_index(*partition_key_values)
@@ -159,31 +161,31 @@ module Partitioned
159
161
  end
160
162
 
161
163
  #
162
- # used when creating the name of a SQL rule
164
+ # Used when creating the name of a SQL rule.
163
165
  #
164
166
  def parent_table_rule_name(name, suffix = "rule", *partition_key_values)
165
167
  return "#{configurator.parent_table_name(*partition_key_values).gsub(/[.]/, '_')}_#{name}_#{suffix}"
166
168
  end
167
169
 
168
170
  #
169
- # used to create index names
171
+ # Used to create index names.
170
172
  #
171
173
  def index_name(name, *partition_key_values)
172
174
  return "#{configurator.part_name(*partition_key_values)}_#{name}_idx"
173
175
  end
174
176
 
175
177
  #
176
- # used to create index names
178
+ # Used to create index names.
177
179
  #
178
180
  def unique_index_name(name, *partition_key_values)
179
181
  return "#{configurator.part_name(*partition_key_values)}_#{name}_udx"
180
182
  end
181
183
 
182
184
  #
183
- # this is here for derived classes to set up references to added columns
185
+ # This is here for derived classes to set up references to added columns
184
186
  # (or columns in the parent that need foreign key constraints).
185
187
  #
186
- # foreign keys are not inherited in postgres. So, a parent table
188
+ # Foreign keys are not inherited in postgres. So, a parent table
187
189
  # of the form:
188
190
  #
189
191
  # -- this is the referenced table
@@ -211,12 +213,12 @@ module Partitioned
211
213
  # create table employees_of_company_2 ( CHECK ( company_id = 2 ) ) INHERITS (employees);
212
214
  # create table employees_of_company_3 ( CHECK ( company_id = 3 ) ) INHERITS (employees);
213
215
  #
214
- # since postgres does not inherit referential integrity from parent tables, the following
216
+ # Since postgres does not inherit referential integrity from parent tables, the following
215
217
  # insert will work:
216
218
  # insert into employees_of_company_1 (name, company_id, supervisor_id) values ('joe', 1, 10);
217
219
  # even if there is no record in companies with id = 1 and there is no record in employees with id = 10
218
220
  #
219
- # for proper referential integrity handling you must do the following:
221
+ # For proper referential integrity handling you must do the following:
220
222
  # ALTER TABLE employees_of_company_1 add foreign key (company_id) references companies(id)
221
223
  # ALTER TABLE employees_of_company_2 add foreign key (company_id) references companies(id)
222
224
  # ALTER TABLE employees_of_company_3 add foreign key (company_id) references companies(id)
@@ -225,7 +227,7 @@ module Partitioned
225
227
  # ALTER TABLE employees_of_company_2 add foreign key (supervisor_id) references employees_of_company_2(id)
226
228
  # ALTER TABLE employees_of_company_3 add foreign key (supervisor_id) references employees_of_company_3(id)
227
229
  #
228
- # the second set of alter tables brings up a good another consideration about postgres references and partitions.
230
+ # The second set of alter tables brings up a good another consideration about postgres references and partitions.
229
231
  # postgres will not follow references to a child table. So, a foreign key reference to "employees" in this
230
232
  # set of alter statements would not work because postgres would expect the table "employees" to have
231
233
  # the specific referenced record, but the record really exists in a child of employees. So, the alter statement