partitioned 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +17 -0
- data/LICENSE +30 -0
- data/PARTITIONING_EXPLAINED.txt +351 -0
- data/README +111 -0
- data/Rakefile +27 -0
- data/examples/README +23 -0
- data/examples/company_id.rb +417 -0
- data/examples/company_id_and_created_at.rb +689 -0
- data/examples/created_at.rb +590 -0
- data/examples/created_at_referencing_awards.rb +1000 -0
- data/examples/id.rb +475 -0
- data/examples/lib/by_company_id.rb +11 -0
- data/examples/lib/command_line_tool_mixin.rb +71 -0
- data/examples/lib/company.rb +29 -0
- data/examples/lib/get_options.rb +44 -0
- data/examples/lib/roman.rb +41 -0
- data/examples/start_date.rb +621 -0
- data/init.rb +1 -0
- data/lib/monkey_patch_activerecord.rb +92 -0
- data/lib/monkey_patch_postgres.rb +73 -0
- data/lib/partitioned.rb +26 -0
- data/lib/partitioned/active_record_overrides.rb +34 -0
- data/lib/partitioned/bulk_methods_mixin.rb +288 -0
- data/lib/partitioned/by_created_at.rb +13 -0
- data/lib/partitioned/by_foreign_key.rb +21 -0
- data/lib/partitioned/by_id.rb +35 -0
- data/lib/partitioned/by_integer_field.rb +32 -0
- data/lib/partitioned/by_monthly_time_field.rb +23 -0
- data/lib/partitioned/by_time_field.rb +65 -0
- data/lib/partitioned/by_weekly_time_field.rb +30 -0
- data/lib/partitioned/multi_level.rb +20 -0
- data/lib/partitioned/multi_level/configurator/data.rb +14 -0
- data/lib/partitioned/multi_level/configurator/dsl.rb +32 -0
- data/lib/partitioned/multi_level/configurator/reader.rb +162 -0
- data/lib/partitioned/multi_level/partition_manager.rb +47 -0
- data/lib/partitioned/partitioned_base.rb +354 -0
- data/lib/partitioned/partitioned_base/configurator.rb +6 -0
- data/lib/partitioned/partitioned_base/configurator/data.rb +62 -0
- data/lib/partitioned/partitioned_base/configurator/dsl.rb +628 -0
- data/lib/partitioned/partitioned_base/configurator/reader.rb +209 -0
- data/lib/partitioned/partitioned_base/partition_manager.rb +138 -0
- data/lib/partitioned/partitioned_base/sql_adapter.rb +286 -0
- data/lib/partitioned/version.rb +3 -0
- data/lib/tasks/desirable_tasks.rake +4 -0
- data/partitioned.gemspec +21 -0
- data/spec/dummy/.rspec +1 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +9 -0
- data/spec/dummy/app/assets/stylesheets/application.css +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +51 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +32 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +30 -0
- data/spec/dummy/config/environments/production.rb +60 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/spec/spec_helper.rb +27 -0
- data/spec/monkey_patch_posgres_spec.rb +176 -0
- data/spec/partitioned/bulk_methods_mixin_spec.rb +512 -0
- data/spec/partitioned/by_created_at_spec.rb +62 -0
- data/spec/partitioned/by_foreign_key_spec.rb +95 -0
- data/spec/partitioned/by_id_spec.rb +97 -0
- data/spec/partitioned/by_integer_field_spec.rb +143 -0
- data/spec/partitioned/by_monthly_time_field_spec.rb +100 -0
- data/spec/partitioned/by_time_field_spec.rb +182 -0
- data/spec/partitioned/by_weekly_time_field_spec.rb +100 -0
- data/spec/partitioned/multi_level/configurator/dsl_spec.rb +88 -0
- data/spec/partitioned/multi_level/configurator/reader_spec.rb +147 -0
- data/spec/partitioned/partitioned_base/configurator/dsl_spec.rb +459 -0
- data/spec/partitioned/partitioned_base/configurator/reader_spec.rb +513 -0
- data/spec/partitioned/partitioned_base/sql_adapter_spec.rb +204 -0
- data/spec/partitioned/partitioned_base_spec.rb +173 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/support/shared_example_spec_helper_for_integer_key.rb +137 -0
- data/spec/support/shared_example_spec_helper_for_time_key.rb +147 -0
- data/spec/support/tables_spec_helper.rb +47 -0
- metadata +250 -0
|
@@ -0,0 +1,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
|