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,590 @@
1
+ #!/usr/bin/env ../spec/dummy/script/rails runner
2
+ # if you use linux, please change previous line to the
3
+ # "#! ../spec/dummy/script/rails runner"
4
+
5
+ # Before running this example you should execute "bundle install" and "rake db:create".
6
+ # To run this example you should open 'example' directory and execute example with one of the following flags:
7
+ # -C cleanup data in database and exit;
8
+ # -F cleanup data in database before creating new data;
9
+ #
10
+ # For example:
11
+ # ./created_at.rb - F
12
+
13
+ # Initial data:
14
+ #
15
+ # Companies table is completed by four companies:
16
+ #
17
+ # create table companies (
18
+ # id serial not null primary key,
19
+ # created_at timestamp not null default now(),
20
+ # updated_at timestamp,
21
+ # name text null
22
+ # );
23
+ #
24
+ # insert into companies (created_at,id,name) values
25
+ # ('2012-03-13 13:26:52.184347',1,'Fluent Mobile, inc.'),
26
+ # ('2012-03-13 13:26:52.184347',2,'Fiksu, inc.'),
27
+ # ('2012-03-13 13:26:52.184347',3,'AppExchanger, inc.'),
28
+ # ('2012-03-13 13:26:52.184347',4,'FreeMyApps, inc.');
29
+ #
30
+ # id | created_at | updated_at | name
31
+ # ---+----------------------------+------------+---------------------
32
+ # 1 | 2012-03-11 13:26:52.184347 | | Fluent Mobile, inc.
33
+ # 2 | 2012-03-11 13:26:52.184347 | | Fiksu, inc.
34
+ # 3 | 2012-03-11 13:26:52.184347 | | AppExchanger, inc.
35
+ # 4 | 2012-03-11 13:26:52.184347 | | FreeMyApps, inc.
36
+ #
37
+ # Employees table is associated with companies table via key - id:
38
+ #
39
+ # create table employees (
40
+ # id serial not null primary key,
41
+ # created_at timestamp not null default now(),
42
+ # updated_at timestamp,
43
+ # name text not null,
44
+ # salary money not null,
45
+ # company_id integer not null
46
+ # );
47
+ #
48
+ # id | created_at | updated_at | name | salary | company_id
49
+ # ----+------------+------------+------+--------+------------
50
+ #
51
+ # Task:
52
+ #
53
+ # To increase the speed of requests to the database and to reduce the time
54
+ # of the request, need to split the Employees table to the partition tables.
55
+ # Break criterion is a created date(created_at).
56
+ #
57
+ # Implementation:
58
+ #
59
+ # Class Employee inherits from the abstract class ByCreatedAt,
60
+ # which supports partitioning.
61
+ #
62
+ # class Employee < Partitioned::ByCreatedAt
63
+ #
64
+ # Indicates a relationship to the companies table.
65
+ # belongs_to :company, :class_name => 'Company'
66
+ #
67
+ # Create a rules for each partition.
68
+ # Id is a unique index. Foreign key is company_id.
69
+ # This imposes a restriction on each of partition, that
70
+ # the column company_id associated with the table of companies
71
+ # and can not have values ​​that are not in the table companies.
72
+ # In this example, set up only 4 records in the table companies,
73
+ # so company_id can not be equal to 5 in any partition
74
+ # until it is an established company with id = 5.
75
+ #
76
+ # partitioned do |partition|
77
+ # partition.index :id, :unique => true
78
+ # partition.foreign_key :company_id
79
+ # end
80
+ # end
81
+ #
82
+ # Create a schema employees_partitions, within which to store all of our partitions:
83
+ #
84
+ # Employee.create_infrastructure
85
+ #
86
+ # Create a partition tables with increments of one week:
87
+ #
88
+ # dates = Employee.partition_generate_range(START_DATE, END_DATE)
89
+ # Employee.create_new_partition_tables(dates)
90
+ #
91
+ # Each of partition has the same structure as that of the employees table:
92
+ #
93
+ # id | created_at | updated_at | name | salary | company_id
94
+ # ----+------------+------------+------+--------+------------
95
+ #
96
+ # CREATE TABLE "employees_partitions"."p20101227" (CHECK (created_at >= '2010-12-27'
97
+ # AND created_at < '2011-01-03')) INHERITS (employees);
98
+ # CREATE INDEX "index_employees_partitions.p20101227_on_created_at"
99
+ # ON "employees_partitions"."p20101227" ("created_at");
100
+ # CREATE UNIQUE INDEX "index_employees_partitions.p20101227_on_id"
101
+ # ON "employees_partitions"."p20101227" ("id");
102
+ # ALTER TABLE employees_partitions.p20101227 add foreign key (company_id) references companies(id);
103
+ #
104
+ # CREATE TABLE "employees_partitions"."p20110103" (CHECK (created_at >= '2011-01-03'
105
+ # AND created_at < '2011-01-10')) INHERITS (employees);
106
+ # CREATE INDEX "index_employees_partitions.p20110103_on_created_at"
107
+ # ON "employees_partitions"."p20110103" ("created_at");
108
+ # CREATE UNIQUE INDEX "index_employees_partitions.p20110103_on_id"
109
+ # ON "employees_partitions"."p20110103" ("id");
110
+ # ALTER TABLE employees_partitions.p20110103 add foreign key (company_id) references companies(id);
111
+ #
112
+ # CREATE TABLE "employees_partitions"."p20110110" (CHECK (created_at >= '2011-01-10'
113
+ # AND created_at < '2011-01-17')) INHERITS (employees);
114
+ # CREATE INDEX "index_employees_partitions.p20110110_on_created_at"
115
+ # ON "employees_partitions"."p20110110" ("created_at");
116
+ # CREATE UNIQUE INDEX "index_employees_partitions.p20110110_on_id"
117
+ # ON "employees_partitions"."p20110110" ("id");
118
+ # ALTER TABLE employees_partitions.p20110110 add foreign key (company_id) references companies(id);
119
+ #
120
+ # ...
121
+ # CREATE TABLE "employees_partitions"."p20111212" (CHECK (created_at >= '2011-12-12'
122
+ # AND created_at < '2011-12-19')) INHERITS (employees);
123
+ # CREATE INDEX "index_employees_partitions.p20111212_on_created_at"
124
+ # ON "employees_partitions"."p20111212" ("created_at");
125
+ # CREATE UNIQUE INDEX "index_employees_partitions.p20111212_on_id"
126
+ # ON "employees_partitions"."p20111212" ("id");
127
+ # ALTER TABLE employees_partitions.p20111212 add foreign key (company_id) references companies(id);
128
+ #
129
+ # CREATE TABLE "employees_partitions"."p20111219" (CHECK (created_at >= '2011-12-19'
130
+ # AND created_at < '2011-12-26')) INHERITS (employees);
131
+ # CREATE INDEX "index_employees_partitions.p20111219_on_created_at"
132
+ # ON "employees_partitions"."p20111219" ("created_at");
133
+ # CREATE UNIQUE INDEX "index_employees_partitions.p20111219_on_id"
134
+ # ON "employees_partitions"."p20111219" ("id");
135
+ # ALTER TABLE employees_partitions.p20111219 add foreign key (company_id) references companies(id);
136
+ #
137
+ # CREATE TABLE "employees_partitions"."p20111226" (CHECK (created_at >= '2011-12-26'
138
+ # AND created_at < '2012-01-02')) INHERITS (employees);
139
+ # CREATE INDEX "index_employees_partitions.p20111226_on_created_at"
140
+ # ON "employees_partitions"."p20111226" ("created_at");
141
+ # CREATE UNIQUE INDEX "index_employees_partitions.p20111226_on_id"
142
+ # ON "employees_partitions"."p20111226" ("id");
143
+ # ALTER TABLE employees_partitions.p20111226 add foreign key (company_id) references companies(id);
144
+ #
145
+ # You should have the following tables with increments of one week:
146
+ # employees_partitions.p20101227
147
+ # employees_partitions.p20110103
148
+ # employees_partitions.p20110110
149
+ # employees_partitions.p20110117
150
+ # employees_partitions.p20110124
151
+ # employees_partitions.p20110131
152
+ # employees_partitions.p20110207
153
+ # employees_partitions.p20110214
154
+ # employees_partitions.p20110221
155
+ # employees_partitions.p20110228
156
+ # employees_partitions.p20110307
157
+ # employees_partitions.p20110314
158
+ # employees_partitions.p20110321
159
+ # employees_partitions.p20110328
160
+ # employees_partitions.p20110404
161
+ # employees_partitions.p20110411
162
+ # employees_partitions.p20110418
163
+ # employees_partitions.p20110425
164
+ # employees_partitions.p20110502
165
+ # employees_partitions.p20110509
166
+ # employees_partitions.p20110516
167
+ # employees_partitions.p20110523
168
+ # employees_partitions.p20110530
169
+ # employees_partitions.p20110606
170
+ # employees_partitions.p20110613
171
+ # employees_partitions.p20110620
172
+ # employees_partitions.p20110627
173
+ # employees_partitions.p20110704
174
+ # employees_partitions.p20110711
175
+ # employees_partitions.p20110718
176
+ # employees_partitions.p20110725
177
+ # employees_partitions.p20110801
178
+ # employees_partitions.p20110808
179
+ # employees_partitions.p20110815
180
+ # employees_partitions.p20110822
181
+ # employees_partitions.p20110829
182
+ # employees_partitions.p20110905
183
+ # employees_partitions.p20110912
184
+ # employees_partitions.p20110919
185
+ # employees_partitions.p20110926
186
+ # employees_partitions.p20111003
187
+ # employees_partitions.p20111010
188
+ # employees_partitions.p20111017
189
+ # employees_partitions.p20111024
190
+ # employees_partitions.p20111031
191
+ # employees_partitions.p20111107
192
+ # employees_partitions.p20111114
193
+ # employees_partitions.p20111121
194
+ # employees_partitions.p20111128
195
+ # employees_partitions.p20111205
196
+ # employees_partitions.p20111212
197
+ # employees_partitions.p20111219
198
+ # employees_partitions.p20111226
199
+ #
200
+ # Each of partitions inherits from employees table,
201
+ # thus a new row will automatically be added to the employees table .
202
+ #
203
+ # To add data, we use the following constructions,
204
+ # in which employees and employee_data - a random data:
205
+ #
206
+ # create_many - allows you to add multiple records
207
+ # Employee.create_many(employees)
208
+ # create - allows you to add one record
209
+ # Employee.create(employee_data)
210
+ # new/save! - allows you to add one record without using "create" method
211
+ # employee = Employee.new(employee_data)
212
+ # employee.save!
213
+ #
214
+ # For update data, we use the following constructions,
215
+ # in which updates - a random data:
216
+ #
217
+ # update_many - allows you to update multiple records.
218
+ # :set_array - additional option, you may read the description
219
+ # of the method in the file update_many bulk_methods_mixin.rb about this option.
220
+ # Employee.update_many(updates, {:set_array => '"salary = #{table_name}.salary +
221
+ # datatable.salary, updated_at = now()"'})
222
+ #
223
+ # This construction using for update one record. You also may use update method.
224
+ # employee = Employee.from_partition(employee_record[:created_at]).find(employee_record[:id])
225
+ # employee.save
226
+ #
227
+ # The data get into the employees table ONLY through partition tables.
228
+ # You can not do an insert row into a table employees directly.
229
+ # For this purpose special restrictions are imposed on the table employees.
230
+ #
231
+ # Result:
232
+ #
233
+ # We have table companies:
234
+ #
235
+ # id | created_at | updated_at | name
236
+ # ---+----------------------------+------------+---------------------
237
+ # 1 | 2012-03-11 13:26:52.184347 | | Fluent Mobile, inc.
238
+ # 2 | 2012-03-11 13:26:52.184347 | | Fiksu, inc.
239
+ # 3 | 2012-03-11 13:26:52.184347 | | AppExchanger, inc.
240
+ # 4 | 2012-03-11 13:26:52.184347 | | FreeMyApps, inc.
241
+ #
242
+ # Table employees with random data from 1 to 5000:
243
+ #
244
+ # id | created_at | updated_at | name | salary | company_id
245
+ #------+---------------------+----------------------------+-----------------------------------+-------------+------------
246
+ # 1 | 2011-03-06 21:06:59 | 2012-03-26 12:41:40.32776 | Winston J. Sillypants, I | $125,499.00 | 3
247
+ # 2 | 2011-11-19 21:03:15 | | Winston J. Sillypants, II | $84,881.00 | 2
248
+ # 3 | 2011-10-04 10:06:14 | 2012-03-26 12:41:40.478717 | Winston J. Sillypants, III | $124,067.00 | 3
249
+ # ...
250
+ # 4998 | 2011-09-23 06:10:23 | 2012-03-26 11:41:30.218432 | Picholine Pimplenad, MMMMCMXCVIII | $121,474.00 | 3
251
+ # 4999 | 2011-08-26 18:24:12 | 2012-03-26 11:41:30.222835 | Picholine Pimplenad, MMMMCMXCIX | $134,549.00 | 4
252
+ # 5000 | 2011-10-01 18:29:33 | 2012-03-26 12:41:40.544125 | Picholine Pimplenad, _V | $135,786.00 | 1
253
+ #
254
+ # Partition employees_partitions.p20101227 - partition where
255
+ # created_at >= '2010-12-27 00:00:00' AND created_at < '2011-01-03 00:00:00':
256
+ #
257
+ # id | created_at | updated_at | name | salary | company_id
258
+ #------+---------------------+----------------------------+--------------------------------+-------------+------------
259
+ # 501 | 2011-01-01 07:19:27 | | Winston J. Sillypants, DI | $114,587.00 | 2
260
+ # 1019 | 2011-01-01 15:35:56 | 2012-03-26 13:06:30.045207 | Winston J. Sillypants, MXIX | $84,563.00 | 3
261
+ # 1093 | 2011-01-02 16:59:03 | | Winston J. Sillypants, MXCIII | $81,852.00 | 1
262
+ # ...
263
+ # 4461 | 2011-01-02 09:10:12 | 2012-03-26 14:06:37.462631 | Picholine Pimplenad, MMMMCDLXI | $115,618.00 | 4
264
+ # 4544 | 2011-01-01 09:56:06 | 2012-03-26 13:06:24.708909 | Picholine Pimplenad, MMMMDXLIV | $71,629.00 | 4
265
+ # 4596 | 2011-01-02 03:10:12 | 2012-03-26 13:06:25.027589 | Picholine Pimplenad, MMMMDXCVI | $88,167.00 | 3
266
+ #
267
+ # Partition employees_partitions.p20110103 - partition where
268
+ # created_at >= '2011-01-03 00:00:00' AND created_at < '2011-01-10 00:00:00':
269
+ #
270
+ # id | created_at | updated_at | name | salary | company_id
271
+ #------+---------------------+----------------------------+------------------------------------+-------------+------------
272
+ # 41 | 2011-01-09 04:19:34 | | Winston J. Sillypants, XLI | $125,885.00 | 2
273
+ # 68 | 2011-01-05 13:27:00 | 2012-03-26 13:06:31.066556 | Winston J. Sillypants, LXVIII | $117,202.00 | 2
274
+ # 77 | 2011-01-08 11:34:15 | | Winston J. Sillypants, LXXVII | $68,907.00 | 4
275
+ # ...
276
+ # 4858 | 2011-01-03 04:13:29 | 2012-03-26 13:06:26.497023 | Picholine Pimplenad, MMMMDCCCLVIII | $85,379.00 | 4
277
+ # 4865 | 2011-01-04 05:42:59 | 2012-03-26 13:06:26.531102 | Picholine Pimplenad, MMMMDCCCLXV | $78,517.00 | 4
278
+ # 4943 | 2011-01-05 04:15:05 | 2012-03-26 13:06:26.892893 | Picholine Pimplenad, MMMMCMXLIII | $137,396.00 | 1
279
+ #
280
+ # Partition employees_partitions.p20110110 - partition where
281
+ # created_at >= '2011-01-10 00:00:00' AND created_at < '2011-01-17 00:00:00':
282
+ #
283
+ # id | created_at | updated_at | name | salary | company_id
284
+ #------+---------------------+----------------------------+---------------------------------+-------------+------------
285
+ # 7 | 2011-01-13 04:29:44 | | Winston J. Sillypants, VII | $65,096.00 | 2
286
+ # 8 | 2011-01-14 16:34:09 | 2012-03-26 13:06:30.408574 | Winston J. Sillypants, VIII | $96,136.00 | 4
287
+ # 53 | 2011-01-14 15:02:05 | 2012-03-26 13:06:30.596073 | Winston J. Sillypants, LIII | $107,568.00 | 2
288
+ # ...
289
+ # 4909 | 2011-01-16 21:35:17 | 2012-03-26 13:06:26.734996 | Picholine Pimplenad, MMMMCMIX | $117,583.00 | 3
290
+ # 4945 | 2011-01-14 13:08:14 | 2012-03-26 13:06:26.902338 | Picholine Pimplenad, MMMMCMXLV | $138,966.00 | 1
291
+ # 4946 | 2011-01-15 13:01:35 | 2012-03-26 14:06:37.290964 | Picholine Pimplenad, MMMMCMXLVI | $131,803.00 | 3
292
+ #
293
+ # ...
294
+ #
295
+ # Partition employees_partitions.p20111212 - partition where
296
+ # created_at >= '2011-12-12 00:00:00' AND created_at < '2011-12-19 00:00:00':
297
+ #
298
+ # id | created_at | updated_at | name | salary | company_id
299
+ #------+---------------------+----------------------------+------------------------------------+-------------+------------
300
+ # 10 | 2011-12-17 11:21:01 | | Winston J. Sillypants, X | $66,153.00 | 4
301
+ # 137 | 2011-12-18 06:55:52 | | Winston J. Sillypants, CXXXVII | $67,900.00 | 1
302
+ # 195 | 2011-12-17 15:39:41 | | Winston J. Sillypants, CXCV | $121,419.00 | 1
303
+ # ...
304
+ # 4958 | 2011-12-14 07:16:08 | 2012-03-26 13:06:26.965279 | Picholine Pimplenad, MMMMCMLVIII | $114,922.00 | 1
305
+ # 4987 | 2011-12-12 07:11:57 | 2012-03-26 13:06:30.022127 | Picholine Pimplenad, MMMMCMLXXXVII | $86,493.00 | 2
306
+ # 5000 | 2011-12-18 04:23:49 | 2012-03-26 14:06:37.20847 | Picholine Pimplenad, _V | $84,113.00 | 4
307
+ #
308
+ # Partition employees_partitions.p20111219 - partition where
309
+ # created_at >= '2011-12-19 00:00:00' AND created_at < '2011-12-26 00:00:00':
310
+ #
311
+ # id | created_at | updated_at | name | salary | company_id
312
+ #------+---------------------+----------------------------+-------------------------------------+-------------+------------
313
+ # 2 | 2011-12-25 15:24:20 | 2012-03-26 13:06:28.669243 | Winston J. Sillypants, II | $67,221.00 | 3
314
+ # 73 | 2011-12-20 01:04:46 | | Winston J. Sillypants, LXXIII | $108,260.00 | 4
315
+ # 88 | 2011-12-24 17:58:28 | | Winston J. Sillypants, LXXXVIII | $66,455.00 | 2
316
+ # ...
317
+ # 4898 | 2011-12-25 23:23:17 | 2012-03-26 13:06:26.685775 | Picholine Pimplenad, MMMMDCCCXCVIII | $139,737.00 | 3
318
+ # 4919 | 2011-12-24 07:30:13 | 2012-03-26 13:06:26.777466 | Picholine Pimplenad, MMMMCMXIX | $78,781.00 | 4
319
+ # 4988 | 2011-12-20 12:03:47 | 2012-03-26 13:06:27.112457 | Picholine Pimplenad, MMMMCMLXXXVIII | $101,671.00 | 1
320
+ #
321
+ # Partition employees_partitions.p20111226 - partition where
322
+ # created_at >= '2011-12-26 00:00:00' AND created_at < '2012-01-02 00:00:00':
323
+ #
324
+ # id | created_at | updated_at | name | salary | company_id
325
+ #------+---------------------+----------------------------+-------------------------------------+-------------+------------
326
+ # 91 | 2011-12-28 09:57:36 | 2012-03-26 14:06:37.434407 | Winston J. Sillypants, XCI | $63,230.00 | 2
327
+ # 118 | 2011-12-29 21:05:05 | | Winston J. Sillypants, CXVIII | $131,837.00 | 3
328
+ # 146 | 2011-12-27 04:50:46 | | Winston J. Sillypants, CXLVI | $107,580.00 | 1
329
+ # ...
330
+ # 4488 | 2011-12-26 03:03:13 | 2012-03-26 13:06:24.43532 | Picholine Pimplenad, MMMMCDLXXXVIII | $91,115.00 | 3
331
+ # 4730 | 2011-12-26 11:07:25 | 2012-03-26 13:06:25.785818 | Picholine Pimplenad, MMMMDCCXXX | $95,658.00 | 2
332
+ # 4817 | 2011-12-27 12:00:07 | 2012-03-26 13:06:34.28227 | Picholine Pimplenad, MMMMDCCCXVII | $63,418.00 | 1
333
+
334
+ require File.expand_path(File.dirname(__FILE__) + "/lib/command_line_tool_mixin")
335
+ require File.expand_path(File.dirname(__FILE__) + "/lib/get_options")
336
+
337
+ include CommandLineToolMixin
338
+
339
+ $cleanup = false
340
+ $force = false
341
+ $create_many = 3000
342
+ $create_individual = 1000
343
+ $new_individual = 1000
344
+ $update_many = 1000
345
+ $update_individual = 1000
346
+
347
+ @options = {
348
+ "--cleanup" => {
349
+ :short => "-C",
350
+ :argument => GetoptLong::NO_ARGUMENT,
351
+ :note => "cleanup data in database and exit"
352
+ },
353
+ "--force" => {
354
+ :short => "-F",
355
+ :argument => GetoptLong::NO_ARGUMENT,
356
+ :note => "cleanup data in database before creating new data"
357
+ },
358
+ "--create-many" => {
359
+ :short => "-m",
360
+ :argument => GetoptLong::REQUIRED_ARGUMENT,
361
+ :note => "how many objects to create via create_many",
362
+ :argument_note => "NUMBER"
363
+ },
364
+ "--create-individual" => {
365
+ :short => "-i",
366
+ :argument => GetoptLong::REQUIRED_ARGUMENT,
367
+ :note => "how many objects to create via create",
368
+ :argument_note => "NUMBER"
369
+ },
370
+ "--new-individual" => {
371
+ :short => "-I",
372
+ :argument => GetoptLong::REQUIRED_ARGUMENT,
373
+ :note => "how many objects to create via new/save",
374
+ :argument_note => "NUMBER"
375
+ },
376
+ "--update-individual" => {
377
+ :short => "-u",
378
+ :argument => GetoptLong::REQUIRED_ARGUMENT,
379
+ :note => "how many objects to update indivudually",
380
+ :argument_note => "NUMBER"
381
+ },
382
+ "--update-many" => {
383
+ :short => "-U",
384
+ :argument => GetoptLong::REQUIRED_ARGUMENT,
385
+ :note => "how many objects to update via update_many",
386
+ :argument_note => "NUMBER"
387
+ },
388
+ }
389
+
390
+ command_line_options(@options) do |option,argument|
391
+ if option == '--cleanup'
392
+ $cleanup = true
393
+ elsif option == '--force'
394
+ $force = true
395
+ elsif option == '--create-many'
396
+ $create_many = argument.to_i
397
+ elsif option == '--create-individual'
398
+ $create_individual = argument.to_i
399
+ elsif option == '--new-individual'
400
+ $new_individual = argument.to_i
401
+ elsif option == '--update-individual'
402
+ $update_individual = argument.to_i
403
+ elsif option == '--update-many'
404
+ $update_many = argument.to_i
405
+ end
406
+ end
407
+
408
+ if $cleanup || $force
409
+ ActiveRecord::Base.connection.drop_schema("employees_partitions", :cascade => true) rescue nil
410
+ ActiveRecord::Base.connection.drop_table("employees") rescue nil
411
+ ActiveRecord::Base.connection.drop_table("companies") rescue nil
412
+ exit(0) if $cleanup
413
+ end
414
+
415
+ $total_records = $create_many + $create_individual + $new_individual
416
+
417
+ puts "total records: #{$total_records}"
418
+
419
+ START_DATE = Date.parse('2011-01-01')
420
+ END_DATE = Date.parse('2011-12-31')
421
+
422
+ # the ActiveRecord classes
423
+
424
+ require File.expand_path(File.dirname(__FILE__) + "/lib/company")
425
+
426
+ class Employee < Partitioned::ByCreatedAt
427
+ belongs_to :company, :class_name => 'Company'
428
+ attr_accessible :name, :company_id, :salary, :created_at
429
+
430
+ partitioned do |partition|
431
+ partition.index :id, :unique => true
432
+ partition.foreign_key :company_id
433
+ end
434
+
435
+ connection.execute <<-SQL
436
+ create table employees
437
+ (
438
+ id serial not null primary key,
439
+ created_at timestamp not null default now(),
440
+ updated_at timestamp,
441
+ name text not null,
442
+ salary money not null,
443
+ company_id integer not null
444
+ );
445
+ SQL
446
+ end
447
+
448
+ # You should have the following tables:
449
+ # public.companies
450
+ # public.employees
451
+
452
+ # create the infrastructure for EMPLOYEES table which includes the schema and partition tables
453
+
454
+ Employee.create_infrastructure
455
+
456
+ # You should have the following schema:
457
+ # employees_partitions
458
+
459
+ dates = Employee.partition_generate_range(START_DATE, END_DATE)
460
+ Employee.create_new_partition_tables(dates)
461
+
462
+ # You should have the following tables with increments of one week:
463
+ # employees_partitions.p20101227
464
+ # employees_partitions.p20110103
465
+ # employees_partitions.p20110110
466
+ # employees_partitions.p20110117
467
+ # employees_partitions.p20110124
468
+ # employees_partitions.p20110131
469
+ # employees_partitions.p20110207
470
+ # employees_partitions.p20110214
471
+ # employees_partitions.p20110221
472
+ # employees_partitions.p20110228
473
+ # employees_partitions.p20110307
474
+ # employees_partitions.p20110314
475
+ # employees_partitions.p20110321
476
+ # employees_partitions.p20110328
477
+ # employees_partitions.p20110404
478
+ # employees_partitions.p20110411
479
+ # employees_partitions.p20110418
480
+ # employees_partitions.p20110425
481
+ # employees_partitions.p20110502
482
+ # employees_partitions.p20110509
483
+ # employees_partitions.p20110516
484
+ # employees_partitions.p20110523
485
+ # employees_partitions.p20110530
486
+ # employees_partitions.p20110606
487
+ # employees_partitions.p20110613
488
+ # employees_partitions.p20110620
489
+ # employees_partitions.p20110627
490
+ # employees_partitions.p20110704
491
+ # employees_partitions.p20110711
492
+ # employees_partitions.p20110718
493
+ # employees_partitions.p20110725
494
+ # employees_partitions.p20110801
495
+ # employees_partitions.p20110808
496
+ # employees_partitions.p20110815
497
+ # employees_partitions.p20110822
498
+ # employees_partitions.p20110829
499
+ # employees_partitions.p20110905
500
+ # employees_partitions.p20110912
501
+ # employees_partitions.p20110919
502
+ # employees_partitions.p20110926
503
+ # employees_partitions.p20111003
504
+ # employees_partitions.p20111010
505
+ # employees_partitions.p20111017
506
+ # employees_partitions.p20111024
507
+ # employees_partitions.p20111031
508
+ # employees_partitions.p20111107
509
+ # employees_partitions.p20111114
510
+ # employees_partitions.p20111121
511
+ # employees_partitions.p20111128
512
+ # employees_partitions.p20111205
513
+ # employees_partitions.p20111212
514
+ # employees_partitions.p20111219
515
+ # employees_partitions.p20111226
516
+
517
+ # add some companies
518
+
519
+ Company.create_many(COMPANIES)
520
+ company_ids = Company.all.map(&:id)
521
+
522
+ employees = []
523
+
524
+ require File.expand_path(File.dirname(__FILE__) + "/lib/roman")
525
+
526
+ # generates data for employees_partitions and employees tables
527
+
528
+ base = 0
529
+ (1..$create_many).each do |i|
530
+ employees << {
531
+ :name => "Winston J. Sillypants, #{to_roman(base+i)}",
532
+ :created_at => START_DATE + rand(END_DATE - START_DATE) + rand(1.day.seconds).seconds,
533
+ :salary => rand(80000) + 60000,
534
+ :company_id => company_ids[rand company_ids.length]
535
+ }
536
+ end
537
+
538
+ puts "creating many #{$create_many}"
539
+ Employee.create_many(employees)
540
+ base += $create_many
541
+
542
+ puts "creating individual #{$create_individual}"
543
+ (1..$create_individual).each do |i|
544
+ employee_data = {
545
+ :name => "Jonathan Crabapple, #{to_roman(base+i)}",
546
+ :created_at => START_DATE + rand(END_DATE - START_DATE) + rand(1.day.seconds).seconds,
547
+ :salary => rand(80000) + 60000,
548
+ :company_id => company_ids[rand company_ids.length]
549
+ }
550
+ employees << Employee.create(employee_data)
551
+ end
552
+ base += $create_individual
553
+
554
+ puts "new individual #{$new_individual}"
555
+ (1..$new_individual).each do |i|
556
+ employee_data = {
557
+ :name => "Picholine Pimplenad, #{to_roman(base+i)}",
558
+ :created_at => START_DATE + rand(END_DATE - START_DATE) + rand(1.day.seconds).seconds,
559
+ :salary => rand(80000) + 60000,
560
+ :company_id => company_ids[rand company_ids.length]
561
+ }
562
+ employee = Employee.new(employee_data)
563
+ employee.save
564
+ employees << employee
565
+ end
566
+ base += $new_individual
567
+
568
+ updates = {}
569
+ puts "update many #{$update_many}"
570
+ (1..$update_many).each do |i|
571
+ index = rand(employees.length)
572
+ employee_record = employees[index]
573
+ updates[{
574
+ :id => employee_record[:id],
575
+ :created_at => employee_record[:created_at]
576
+ }] = {
577
+ :salary => 100
578
+ }
579
+ end
580
+
581
+ Employee.update_many(updates, {:set_array => '"salary = #{table_name}.salary + datatable.salary, updated_at = now()"'})
582
+
583
+ puts "update individual #{$update_individual}"
584
+ (1..$update_individual).each do |i|
585
+ index = rand(employees.length)
586
+ employee_record = employees[index]
587
+ employee = Employee.from_partition(employee_record[:created_at]).find(employee_record[:id])
588
+ employee.salary += 1000
589
+ employee.save
590
+ end