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,11 @@
1
+ class ByCompanyId < Partitioned::ByForeignKey
2
+ self.abstract_class = true
3
+
4
+ def self.partition_foreign_key
5
+ return :company_id
6
+ end
7
+
8
+ partitioned do |partition|
9
+ partition.index :id, :unique => true
10
+ end
11
+ end
@@ -0,0 +1,71 @@
1
+ module CommandLineToolMixin
2
+ def columnized_row(fields, sized)
3
+ r = []
4
+ fields.each_with_index do |f, i|
5
+ r << sprintf("%0-#{sized[i]}s", f.to_s.gsub(/\\n\\r/, '').slice(0, sized[i]))
6
+ end
7
+ r.join(' ')
8
+ end
9
+
10
+ def columnized(rows, options = {})
11
+ sized = {}
12
+ rows.each do |row|
13
+ row.each_index do |i|
14
+ value = row[i]
15
+ sized[i] = [sized[i].to_i, value.to_s.length].max
16
+ sized[i] = [options[:max_width], sized[i].to_i].min if options[:max_width]
17
+ end
18
+ end
19
+
20
+ table = []
21
+ rows.each { |row| table << " " + columnized_row(row, sized).rstrip }
22
+ table.join("\n")
23
+ end
24
+
25
+ def help(command_line_usage, command_line_options)
26
+ puts(command_line_usage)
27
+ rows = []
28
+ command_line_options.keys.sort.each do |long_switch|
29
+ parameters = command_line_options[long_switch]
30
+ columns = []
31
+ switches = "#{long_switch}"
32
+ if (parameters[:short])
33
+ switches += " | #{parameters[:short]}"
34
+ end
35
+ if (parameters[:argument_note])
36
+ switches += " #{parameters[:argument_note]}"
37
+ end
38
+ columns << switches
39
+ columns << parameters[:note]
40
+ columns << (parameters[:environment_variable] or "")
41
+ rows << columns
42
+ end
43
+ puts(columnized(rows))
44
+ end
45
+
46
+ def command_line_options(options, usage = "command [OPTIONS]")
47
+ options.merge!({
48
+ "--?" => {
49
+ :short => "-?",
50
+ :argument => GetoptLong::NO_ARGUMENT,
51
+ :note => "show this help"
52
+ },
53
+ })
54
+ get_options = GetOptions.new(options)
55
+ get_options.each do |option, argument|
56
+ if option == '--?'
57
+ help(usage, options)
58
+ exit 0
59
+ else
60
+ if (options[option] && options[option][:constraint])
61
+ error = options[option][:constraint].call(argument, self)
62
+ if error
63
+ puts(error)
64
+ exit 0
65
+ end
66
+ end
67
+ yield option, argument
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,29 @@
1
+ class Company < ActiveRecord::Base
2
+ extend Partitioned::BulkMethodsMixin
3
+ has_many :employees, :class_name => 'Company', :conditions => "companies.id = employees.companies_id"
4
+
5
+ connection.execute <<-SQL
6
+ create table companies
7
+ (
8
+ id serial not null primary key,
9
+ created_at timestamp not null default now(),
10
+ updated_at timestamp,
11
+ name text null
12
+ );
13
+ SQL
14
+ end
15
+
16
+ COMPANIES = [
17
+ {
18
+ :name => 'Fluent Mobile, inc.'
19
+ },
20
+ {
21
+ :name => 'Fiksu, inc.'
22
+ },
23
+ {
24
+ :name => 'AppExchanger, inc.'
25
+ },
26
+ {
27
+ :name => 'FreeMyApps, inc.'
28
+ },
29
+ ]
@@ -0,0 +1,44 @@
1
+ require 'getoptlong'
2
+
3
+ class GetOptions < GetoptLong
4
+ ARGUMENT_FLAGS = [
5
+ NO_ARGUMENT = GetoptLong::NO_ARGUMENT,
6
+ REQUIRED_ARGUMENT = GetoptLong::REQUIRED_ARGUMENT,
7
+ OPTIONAL_ARGUMENT = GetoptLong::OPTIONAL_ARGUMENT
8
+ ]
9
+
10
+ def initialize(switches = {})
11
+ @command_line_switches = switches
12
+ @environment_variables = {}
13
+ @getopt_options = []
14
+
15
+ @command_line_switches.each do |long_switch, parameters|
16
+ if parameters[:environment_variable].present?
17
+ @environment_variables[parameters[:environment_variable]] = long_switch
18
+ end
19
+
20
+ options = []
21
+ options << long_switch
22
+ if (parameters[:short])
23
+ options << parameters[:short]
24
+ end
25
+ options << parameters[:argument]
26
+ @getopt_options << options
27
+ end
28
+
29
+ argv_additions = []
30
+ for environment_variable_name, value in @environment_variables do
31
+ if ENV[environment_variable_name]
32
+ argv_additions << value
33
+ argv_additions << ENV[environment_variable_name] unless ENV[environment_variable_name].empty?
34
+ end
35
+ end
36
+ for arg in ARGV do
37
+ argv_additions << arg
38
+ end
39
+
40
+ argv_additions.each_with_index{ |v, i| ARGV[i] = v }
41
+
42
+ super(*@getopt_options)
43
+ end
44
+ end
@@ -0,0 +1,41 @@
1
+ Roman_array = [
2
+ [ 1000000, '_M' ],
3
+ [ 900000, '_C_M' ],
4
+ [ 500000, '_D' ],
5
+ [ 400000, '_C_D' ],
6
+ [ 100000, '_C' ],
7
+ [ 90000, '_X_C' ],
8
+ [ 50000, '_L' ],
9
+ [ 40000, '_X_L' ],
10
+ [ 10000, '_X' ],
11
+ [ 9000, '_I_X' ],
12
+ [ 5000, '_V' ],
13
+ [ 1000, 'M' ],
14
+ [ 900, 'CM' ],
15
+ [ 500, 'D' ],
16
+ [ 400, 'CD' ],
17
+ [ 100, 'C' ],
18
+ [ 90, 'XC' ],
19
+ [ 50, 'L' ],
20
+ [ 40, 'XL' ],
21
+ [ 10, 'X' ],
22
+ [ 9, 'IX' ],
23
+ [ 5, 'V' ],
24
+ [ 4, 'IV' ],
25
+ [ 1, 'I' ]
26
+ ]
27
+
28
+ def to_roman(val)
29
+ if val < 0 or val >= 5000000
30
+ raise "out of range '#{val}'"
31
+ else
32
+ s = ""
33
+ Roman_array.each { |pair|
34
+ while val >= pair[0]
35
+ s << pair[1]
36
+ val -= pair[0]
37
+ end
38
+ }
39
+ return s
40
+ end
41
+ end
@@ -0,0 +1,621 @@
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
+ # ./start_date.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
+ # (
41
+ # id serial not null primary key,
42
+ # created_at timestamp not null default now(),
43
+ # updated_at timestamp null,
44
+ # start_date date not null,
45
+ # name text not null,
46
+ # salary money not null,
47
+ # company_id integer not null
48
+ # );
49
+ #
50
+ # id | created_at | updated_at | start_date | name | salary | company_id
51
+ # ----+------------+------------+------------+------+--------+------------
52
+ #
53
+ # Task:
54
+ #
55
+ # To increase the speed of requests to the database and to reduce the time
56
+ # of the request, need to split the Employees table to the partition tables.
57
+ # Break criterion is a start date(start_date).
58
+ #
59
+ # Implementation:
60
+ #
61
+ # Class Employee inherits from the abstract class ByStartDate,
62
+ # which supports partitioning.
63
+ #
64
+ # class Employee < Partitioned::ByStartDate
65
+ #
66
+ # Indicates a relationship to the companies table.
67
+ # belongs_to :company, :class_name => 'Company'
68
+ #
69
+ # Create a rules for each partition.
70
+ # Id is a unique index. Foreign key is company_id.
71
+ # This imposes a restriction on each of partition, that
72
+ # the column company_id associated with the table of companies
73
+ # and can not have values ​​that are not in the table companies.
74
+ # In this example, set up only 4 records in the table companies,
75
+ # so company_id can not be equal to 5 in any partition
76
+ # until it is an established company with id = 5.
77
+ #
78
+ # partitioned do |partition|
79
+ # partition.index :id, :unique => true
80
+ # partition.foreign_key :company_id
81
+ # end
82
+ # end
83
+ #
84
+ # Create a schema employees_partitions, within which to store all of our partitions:
85
+ #
86
+ # Employee.create_infrastructure
87
+ #
88
+ # Create a partition tables with increments of one month:
89
+ #
90
+ # dates = Employee.partition_generate_range(START_DATE, END_DATE)
91
+ # Employee.create_new_partition_tables(dates)
92
+ #
93
+ # Each of partition has the same structure as that of the employees table:
94
+ #
95
+ # id | created_at | updated_at | start_date | name | salary | company_id
96
+ # ----+------------+------------+------------+------+--------+------------
97
+ #
98
+ # CREATE TABLE "employees_partitions"."p201101" (CHECK (start_date >= '2011-01-01'
99
+ # AND start_date < '2011-02-01')) INHERITS (employees);
100
+ # CREATE INDEX "p201101_start_date_idx" ON "employees_partitions"."p201101" ("start_date");
101
+ # CREATE UNIQUE INDEX "p201101_id_udx" ON "employees_partitions"."p201101" ("id");
102
+ # ALTER TABLE employees_partitions.p201101 add foreign key (company_id) references companies(id);
103
+ #
104
+ # CREATE TABLE "employees_partitions"."p201102" (CHECK (start_date >= '2011-02-01'
105
+ # AND start_date < '2011-03-01')) INHERITS (employees);
106
+ # CREATE INDEX "p201102_start_date_idx" ON "employees_partitions"."p201102" ("start_date");
107
+ # CREATE UNIQUE INDEX "p201102_id_udx" ON "employees_partitions"."p201102" ("id");
108
+ # ALTER TABLE employees_partitions.p201102 add foreign key (company_id) references companies(id);
109
+ #
110
+ # CREATE TABLE "employees_partitions"."p201103" (CHECK (start_date >= '2011-03-01'
111
+ # AND start_date < '2011-04-01')) INHERITS (employees);
112
+ # CREATE INDEX "p201103_start_date_idx" ON "employees_partitions"."p201103" ("start_date");
113
+ # CREATE UNIQUE INDEX "p201103_id_udx" ON "employees_partitions"."p201103" ("id");
114
+ # ALTER TABLE employees_partitions.p201103 add foreign key (company_id) references companies(id);
115
+ #
116
+ # CREATE TABLE "employees_partitions"."p201104" (CHECK (start_date >= '2011-04-01'
117
+ # AND start_date < '2011-05-01')) INHERITS (employees);
118
+ # CREATE INDEX "p201104_start_date_idx" ON "employees_partitions"."p201104" ("start_date");
119
+ # CREATE UNIQUE INDEX "p201104_id_udx" ON "employees_partitions"."p201104" ("id");
120
+ # ALTER TABLE employees_partitions.p201104 add foreign key (company_id) references companies(id);
121
+ #
122
+ # CREATE TABLE "employees_partitions"."p201105" (CHECK (start_date >= '2011-05-01'
123
+ # AND start_date < '2011-06-01')) INHERITS (employees);
124
+ # CREATE INDEX "p201105_start_date_idx" ON "employees_partitions"."p201105" ("start_date");
125
+ # CREATE UNIQUE INDEX "p201105_id_udx" ON "employees_partitions"."p201105" ("id");
126
+ # ALTER TABLE employees_partitions.p201105 add foreign key (company_id) references companies(id);
127
+ #
128
+ # CREATE TABLE "employees_partitions"."p201106" (CHECK (start_date >= '2011-06-01'
129
+ # AND start_date < '2011-07-01')) INHERITS (employees);
130
+ # CREATE INDEX "p201106_start_date_idx" ON "employees_partitions"."p201106" ("start_date");
131
+ # CREATE UNIQUE INDEX "p201106_id_udx" ON "employees_partitions"."p201106" ("id");
132
+ # ALTER TABLE employees_partitions.p201106 add foreign key (company_id) references companies(id);
133
+ #
134
+ # CREATE TABLE "employees_partitions"."p201107" (CHECK (start_date >= '2011-07-01'
135
+ # AND start_date < '2011-08-01')) INHERITS (employees);
136
+ # CREATE INDEX "p201107_start_date_idx" ON "employees_partitions"."p201107" ("start_date");
137
+ # CREATE UNIQUE INDEX "p201107_id_udx" ON "employees_partitions"."p201107" ("id");
138
+ # ALTER TABLE employees_partitions.p201107 add foreign key (company_id) references companies(id);
139
+ #
140
+ # CREATE TABLE "employees_partitions"."p201108" (CHECK (start_date >= '2011-08-01'
141
+ # AND start_date < '2011-09-01')) INHERITS (employees);
142
+ # CREATE INDEX "p201108_start_date_idx" ON "employees_partitions"."p201108" ("start_date");
143
+ # CREATE UNIQUE INDEX "p201108_id_udx" ON "employees_partitions"."p201108" ("id");
144
+ # ALTER TABLE employees_partitions.p201108 add foreign key (company_id) references companies(id);
145
+ #
146
+ # CREATE TABLE "employees_partitions"."p201109" (CHECK (start_date >= '2011-09-01'
147
+ # AND start_date < '2011-10-01')) INHERITS (employees);
148
+ # CREATE INDEX "p201109_start_date_idx" ON "employees_partitions"."p201109" ("start_date");
149
+ # CREATE UNIQUE INDEX "p201109_id_udx" ON "employees_partitions"."p201109" ("id");
150
+ # ALTER TABLE employees_partitions.p201109 add foreign key (company_id) references companies(id);
151
+ #
152
+ # CREATE TABLE "employees_partitions"."p201110" (CHECK (start_date >= '2011-10-01'
153
+ # AND start_date < '2011-11-01')) INHERITS (employees);
154
+ # CREATE INDEX "p201110_start_date_idx" ON "employees_partitions"."p201110" ("start_date");
155
+ # CREATE UNIQUE INDEX "p201110_id_udx" ON "employees_partitions"."p201110" ("id");
156
+ # ALTER TABLE employees_partitions.p201110 add foreign key (company_id) references companies(id);
157
+ #
158
+ # CREATE TABLE "employees_partitions"."p201111" (CHECK (start_date >= '2011-11-01'
159
+ # AND start_date < '2011-12-01')) INHERITS (employees);
160
+ # CREATE INDEX "p201111_start_date_idx" ON "employees_partitions"."p201111" ("start_date");
161
+ # CREATE UNIQUE INDEX "p201111_id_udx" ON "employees_partitions"."p201111" ("id");
162
+ # ALTER TABLE employees_partitions.p201111 add foreign key (company_id) references companies(id);
163
+ #
164
+ # CREATE TABLE "employees_partitions"."p201112" (CHECK (start_date >= '2011-12-01'
165
+ # AND start_date < '2012-01-01')) INHERITS (employees);
166
+ # CREATE INDEX "p201112_start_date_idx" ON "employees_partitions"."p201112" ("start_date");
167
+ # CREATE UNIQUE INDEX "p201112_id_udx" ON "employees_partitions"."p201112" ("id");
168
+ # ALTER TABLE employees_partitions.p201112 add foreign key (company_id) references companies(id);
169
+ #
170
+ # You should have the following tables with increments of one month:
171
+ # employees_partitions.p201101
172
+ # employees_partitions.p201102
173
+ # employees_partitions.p201103
174
+ # employees_partitions.p201104
175
+ # employees_partitions.p201105
176
+ # employees_partitions.p201106
177
+ # employees_partitions.p201107
178
+ # employees_partitions.p201108
179
+ # employees_partitions.p201109
180
+ # employees_partitions.p201110
181
+ # employees_partitions.p201111
182
+ # employees_partitions.p201112
183
+ #
184
+ # Each of partitions inherits from employees table,
185
+ # thus a new row will automatically be added to the employees table .
186
+ #
187
+ # To add data, we use the following constructions,
188
+ # in which employees and employee_data - a random data:
189
+ #
190
+ # create_many - allows you to add multiple records
191
+ # Employee.create_many(employees)
192
+ # create - allows you to add one record
193
+ # Employee.create(employee_data)
194
+ # new/save! - allows you to add one record without using "create" method
195
+ # employee = Employee.new(employee_data)
196
+ # employee.save!
197
+ #
198
+ # For update data, we use the following constructions,
199
+ # in which updates - a random data:
200
+ #
201
+ # update_many - allows you to update multiple records.
202
+ # :set_array - additional option, you may read the description
203
+ # of the method in the file update_many bulk_methods_mixin.rb about this option.
204
+ # Employee.update_many(updates, {:set_array => '"salary = #{table_name}.salary +
205
+ # datatable.salary, updated_at = now()"'})
206
+ #
207
+ # This construction using for update one record. You also may use update method.
208
+ # employee = Employee.from_partition(employee_record[:start_date]).find(employee_record[:id])
209
+ # employee.save
210
+ #
211
+ # The data get into the employees table ONLY through partition tables.
212
+ # You can not do an insert row into a table employees directly.
213
+ # For this purpose special restrictions are imposed on the table employees.
214
+ #
215
+ # Result:
216
+ #
217
+ # We have table companies:
218
+ #
219
+ # id | created_at | updated_at | name
220
+ # ---+----------------------------+------------+---------------------
221
+ # 1 | 2012-03-11 13:26:52.184347 | | Fluent Mobile, inc.
222
+ # 2 | 2012-03-11 13:26:52.184347 | | Fiksu, inc.
223
+ # 3 | 2012-03-11 13:26:52.184347 | | AppExchanger, inc.
224
+ # 4 | 2012-03-11 13:26:52.184347 | | FreeMyApps, inc.
225
+ #
226
+ # Table employees with random data from 1 to 5000:
227
+ #
228
+ # id | created_at | updated_at | start_date | name | salary | company_id
229
+ #------+----------------------------+----------------------------+------------+-----------------------------------+-------------+------------
230
+ # 1 | 2012-03-27 08:00:17.328727 | | 2011-11-12 | Winston J. Sillypants, I | $61,403.00 | 4
231
+ # 2 | 2012-03-27 08:00:17.328727 | | 2011-11-24 | Winston J. Sillypants, II | $94,140.00 | 3
232
+ # 3 | 2012-03-27 08:00:17.328727 | 2012-03-27 08:00:35.840263 | 2011-07-21 | Winston J. Sillypants, III | $101,512.00 | 3
233
+ # ...
234
+ # 4998 | 2012-03-27 08:00:29.175598 | 2012-03-27 08:00:29.175598 | 2011-08-31 | Picholine Pimplenad, MMMMCMXCVIII | $70,642.00 | 1
235
+ # 4999 | 2012-03-27 08:00:29.180265 | 2012-03-27 08:00:29.180265 | 2011-05-19 | Picholine Pimplenad, MMMMCMXCIX | $92,530.00 | 1
236
+ # 5000 | 2012-03-27 08:00:29.184878 | 2012-03-27 09:00:43.18046 | 2011-03-16 | Picholine Pimplenad, _V | $123,110.00 | 1
237
+ #
238
+ # Partition employees_partitions.p201101 - partition where
239
+ # start_date >= '2011-01-01' AND start_date < '2011-02-01':
240
+ #
241
+ # id | created_at | updated_at | start_date | name | salary | company_id
242
+ #------+----------------------------+----------------------------+------------+-----------------------------------+-------------+------------
243
+ # 5 | 2012-03-27 08:00:17.328727 | | 2011-01-06 | Winston J. Sillypants, V | $101,809.00 | 4
244
+ # 16 | 2012-03-27 08:00:17.328727 | 2012-03-27 09:00:43.198146 | 2011-01-11 | Winston J. Sillypants, XVI | $108,194.00 | 3
245
+ # 18 | 2012-03-27 08:00:17.328727 | | 2011-01-29 | Winston J. Sillypants, XVIII | $131,523.00 | 2
246
+ # ...
247
+ # 4982 | 2012-03-27 08:00:29.099722 | 2012-03-27 08:00:29.099722 | 2011-01-12 | Picholine Pimplenad, MMMMCMLXXXII | $138,806.00 | 1
248
+ # 4990 | 2012-03-27 08:00:29.138021 | 2012-03-27 08:00:33.090801 | 2011-01-17 | Picholine Pimplenad, MMMMCMXC | $73,884.00 | 1
249
+ # 4997 | 2012-03-27 08:00:29.170905 | 2012-03-27 08:00:29.170905 | 2011-01-07 | Picholine Pimplenad, MMMMCMXCVII | $71,352.00 | 3
250
+ #
251
+ # Partition employees_partitions.p201102 - partition where
252
+ # start_date >= '2011-02-01' AND start_date < '2011-03-01':
253
+ #
254
+ # id | created_at | updated_at | start_date | name | salary | company_id
255
+ #------+----------------------------+----------------------------+------------+-----------------------------------+-------------+------------
256
+ # 39 | 2012-03-27 08:00:17.328727 | 2012-03-27 09:00:43.124392 | 2011-02-16 | Winston J. Sillypants, XXXIX | $61,801.00 | 3
257
+ # 118 | 2012-03-27 08:00:17.328727 | | 2011-02-15 | Winston J. Sillypants, CXVIII | $77,866.00 | 2
258
+ # 147 | 2012-03-27 08:00:17.328727 | 2012-03-27 09:00:43.124392 | 2011-02-24 | Winston J. Sillypants, CXLVII | $119,707.00 | 4
259
+ # ...
260
+ # 4981 | 2012-03-27 08:00:29.094862 | 2012-03-27 08:00:29.094862 | 2011-02-28 | Picholine Pimplenad, MMMMCMLXXXI | $123,537.00 | 3
261
+ # 4993 | 2012-03-27 08:00:29.152405 | 2012-03-27 09:00:43.124392 | 2011-02-02 | Picholine Pimplenad, MMMMCMXCIII | $139,969.00 | 3
262
+ # 4995 | 2012-03-27 08:00:29.161747 | 2012-03-27 08:00:29.161747 | 2011-02-24 | Picholine Pimplenad, MMMMCMXCV | $114,288.00 | 3
263
+ #
264
+ # Partition employees_partitions.p201103 - partition where
265
+ # start_date >= '2011-03-01' AND start_date < '2011-04-01':
266
+ #
267
+ # id | created_at | updated_at | start_date | name | salary | company_id
268
+ #------+----------------------------+----------------------------+------------+-----------------------------------+-------------+------------
269
+ # 13 | 2012-03-27 08:00:17.328727 | 2012-03-27 08:00:30.051678 | 2011-03-17 | Winston J. Sillypants, XIII | $127,027.00 | 2
270
+ # 20 | 2012-03-27 08:00:17.328727 | | 2011-03-23 | Winston J. Sillypants, XX | $67,804.00 | 4
271
+ # 50 | 2012-03-27 08:00:17.328727 | | 2011-03-12 | Winston J. Sillypants, L | $75,709.00 | 1
272
+ # ...
273
+ # 4991 | 2012-03-27 08:00:29.142771 | 2012-03-27 08:00:33.477371 | 2011-03-15 | Picholine Pimplenad, MMMMCMXCI | $81,774.00 | 4
274
+ # 4996 | 2012-03-27 08:00:29.166363 | 2012-03-27 08:00:34.219636 | 2011-03-17 | Picholine Pimplenad, MMMMCMXCVI | $62,954.00 | 2
275
+ # 5000 | 2012-03-27 08:00:29.184878 | 2012-03-27 09:00:43.18046 | 2011-03-16 | Picholine Pimplenad, _V | $123,110.00 | 1
276
+ #
277
+ # Partition employees_partitions.p201104 - partition where
278
+ # start_date >= '2011-04-01' AND start_date < '2011-05-01':
279
+ #
280
+ # id | created_at | updated_at | start_date | name | salary | company_id
281
+ #------+----------------------------+----------------------------+------------+-----------------------------------+-------------+------------
282
+ # 14 | 2012-03-27 08:00:17.328727 | | 2011-04-26 | Winston J. Sillypants, XIV | $79,735.00 | 3
283
+ # 30 | 2012-03-27 08:00:17.328727 | | 2011-04-05 | Winston J. Sillypants, XXX | $111,415.00 | 2
284
+ # 44 | 2012-03-27 08:00:17.328727 | | 2011-04-26 | Winston J. Sillypants, XLIV | $119,897.00 | 2
285
+ # ...
286
+ # 4953 | 2012-03-27 08:00:28.901328 | 2012-03-27 08:00:28.901328 | 2011-04-02 | Picholine Pimplenad, MMMMCMLIII | $79,695.00 | 4
287
+ # 4979 | 2012-03-27 08:00:29.085946 | 2012-03-27 08:00:29.085946 | 2011-04-12 | Picholine Pimplenad, MMMMCMLXXIX | $127,600.00 | 1
288
+ # 4983 | 2012-03-27 08:00:29.105705 | 2012-03-27 08:00:30.791092 | 2011-04-04 | Picholine Pimplenad, MMMMCMLXXXIII| $136,207.00 | 1
289
+ #
290
+ # Partition employees_partitions.p201105 - partition where
291
+ # start_date >= '2011-05-01' AND start_date < '2011-06-01':
292
+ #
293
+ # id | created_at | updated_at | start_date | name | salary | company_id
294
+ #------+----------------------------+----------------------------+------------+-----------------------------------+-------------+------------
295
+ # 7 | 2012-03-27 08:00:17.328727 | | 2011-05-06 | Winston J. Sillypants, VII | $92,576.00 | 3
296
+ # 41 | 2012-03-27 08:00:17.328727 | 2012-03-27 09:00:43.3198 | 2011-05-21 | Winston J. Sillypants, XLI | $101,404.00 | 2
297
+ # 76 | 2012-03-27 08:00:17.328727 | | 2011-05-13 | Winston J. Sillypants, LXXVI | $90,599.00 | 3
298
+ # ...
299
+ # 4987 | 2012-03-27 08:00:29.123474 | 2012-03-27 08:00:29.123474 | 2011-05-14 | Picholine Pimplenad, MMMMCMLXXXVII| $125,956.00 | 4
300
+ # 4994 | 2012-03-27 08:00:29.157211 | 2012-03-27 08:00:29.157211 | 2011-05-30 | Picholine Pimplenad, MMMMCMXCIV | $70,812.00 | 4
301
+ # 4999 | 2012-03-27 08:00:29.180265 | 2012-03-27 08:00:29.180265 | 2011-05-19 | Picholine Pimplenad, MMMMCMXCIX | $92,530.00 | 1
302
+ #
303
+ # Partition employees_partitions.p201106 - partition where
304
+ # start_date >= '2011-06-01' AND start_date < '2011-07-01':
305
+ #
306
+ # id | created_at | updated_at | start_date | name | salary | company_id
307
+ #------+----------------------------+----------------------------+------------+-----------------------------------+-------------+------------
308
+ # 9 | 2012-03-27 08:00:17.328727 | | 2011-06-11 | Winston J. Sillypants, IX | $76,361.00 | 1
309
+ # 23 | 2012-03-27 08:00:17.328727 | | 2011-06-07 | Winston J. Sillypants, XXIII | $99,101.00 | 2
310
+ # 42 | 2012-03-27 08:00:17.328727 | 2012-03-27 08:00:36.081006 | 2011-06-02 | Winston J. Sillypants, XLII | $98,706.00 | 1
311
+ # ...
312
+ # 4948 | 2012-03-27 08:00:28.878517 | 2012-03-27 09:00:43.3421 | 2011-06-17 | Picholine Pimplenad, MMMMCMXLVIII | $92,524.00 | 4
313
+ # 4969 | 2012-03-27 08:00:28.973943 | 2012-03-27 08:00:28.973943 | 2011-06-28 | Picholine Pimplenad, MMMMCMLXIX | $91,862.00 | 3
314
+ # 4973 | 2012-03-27 08:00:28.991697 | 2012-03-27 08:00:28.991697 | 2011-06-26 | Picholine Pimplenad, MMMMCMLXXIII | $102,840.00 | 2
315
+ #
316
+ # Partition employees_partitions.p201107 - partition where
317
+ # start_date >= '2011-07-01' AND start_date < '2011-08-01':
318
+ #
319
+ # id | created_at | updated_at | start_date | name | salary | company_id
320
+ #------+----------------------------+----------------------------+------------+-----------------------------------+-------------+------------
321
+ # 3 | 2012-03-27 08:00:17.328727 | 2012-03-27 08:00:35.840263 | 2011-07-21 | Winston J. Sillypants, III | $101,512.00 | 3
322
+ # 4 | 2012-03-27 08:00:17.328727 | | 2011-07-26 | Winston J. Sillypants, IV | $75,210.00 | 4
323
+ # 10 | 2012-03-27 08:00:17.328727 | | 2011-07-16 | Winston J. Sillypants, X | $84,192.00 | 3
324
+ # ...
325
+ # 4951 | 2012-03-27 08:00:28.892169 | 2012-03-27 08:00:28.892169 | 2011-07-13 | Picholine Pimplenad, MMMMCMLI | $74,385.00 | 1
326
+ # 4958 | 2012-03-27 08:00:28.924581 | 2012-03-27 08:00:29.740671 | 2011-07-30 | Picholine Pimplenad, MMMMCMLVIII | $134,710.00 | 3
327
+ # 4964 | 2012-03-27 08:00:28.951394 | 2012-03-27 08:00:35.574577 | 2011-07-02 | Picholine Pimplenad, MMMMCMLXIV | $111,258.00 | 4
328
+ #
329
+ # Partition employees_partitions.p201108 - partition where
330
+ # start_date >= '2011-08-01' AND start_date < '2011-09-01':
331
+ #
332
+ # id | created_at | updated_at | start_date | name | salary | company_id
333
+ #------+----------------------------+----------------------------+------------+-----------------------------------+-------------+------------
334
+ # 11 | 2012-03-27 08:00:17.328727 | | 2011-08-08 | Winston J. Sillypants, XI | $124,558.00 | 2
335
+ # 28 | 2012-03-27 08:00:17.328727 | 2012-03-27 09:00:43.087144 | 2011-08-12 | Winston J. Sillypants, XXVIII | $103,416.00 | 2
336
+ # 37 | 2012-03-27 08:00:17.328727 | | 2011-08-30 | Winston J. Sillypants, XXXVII | $119,090.00 | 2
337
+ # ...
338
+ # 4985 | 2012-03-27 08:00:29.114785 | 2012-03-27 08:00:29.114785 | 2011-08-12 | Picholine Pimplenad, MMMMCMLXXXV | $79,474.00 | 3
339
+ # 4989 | 2012-03-27 08:00:29.133224 | 2012-03-27 08:00:35.107938 | 2011-08-29 | Picholine Pimplenad, MMMMCMLXXXIX | $118,545.00 | 2
340
+ # 4998 | 2012-03-27 08:00:29.175598 | 2012-03-27 08:00:29.175598 | 2011-08-31 | Picholine Pimplenad, MMMMCMXCVIII | $70,642.00 | 1
341
+ #
342
+ # Partition employees_partitions.p201109 - partition where
343
+ # start_date >= '2011-09-01' AND start_date < '2011-10-01':
344
+ #
345
+ # id | created_at | updated_at | start_date | name | salary | company_id
346
+ #------+----------------------------+----------------------------+------------+------------------------------------+-------------+------------
347
+ # 17 | 2012-03-27 08:00:17.328727 | | 2011-09-03 | Winston J. Sillypants, XVII | $137,286.00 | 4
348
+ # 22 | 2012-03-27 08:00:17.328727 | | 2011-09-19 | Winston J. Sillypants, XXII | $108,640.00 | 1
349
+ # 24 | 2012-03-27 08:00:17.328727 | | 2011-09-09 | Winston J. Sillypants, XXIV | $71,643.00 | 2
350
+ # ...
351
+ # 4967 | 2012-03-27 08:00:28.965141 | 2012-03-27 08:00:28.965141 | 2011-09-15 | Picholine Pimplenad, MMMMCMLXVII | $103,039.00 | 1
352
+ # 4978 | 2012-03-27 08:00:29.015989 | 2012-03-27 09:00:43.299117 | 2011-09-26 | Picholine Pimplenad, MMMMCMLXXVIII | $110,453.00 | 3
353
+ # 4988 | 2012-03-27 08:00:29.12854 | 2012-03-27 08:00:34.414851 | 2011-09-15 | Picholine Pimplenad, MMMMCMLXXXVIII| $140,014.00 | 4
354
+ #
355
+ # Partition employees_partitions.p201110 - partition where
356
+ # start_date >= '2011-10-01' AND start_date < '2011-11-01':
357
+ #
358
+ # id | created_at | updated_at | start_date | name | salary | company_id
359
+ #------+----------------------------+----------------------------+------------+-----------------------------------+-------------+------------
360
+ # 15 | 2012-03-27 08:00:17.328727 | | 2011-10-29 | Winston J. Sillypants, XV | $122,755.00 | 4
361
+ # 27 | 2012-03-27 08:00:17.328727 | | 2011-10-18 | Winston J. Sillypants, XXVII | $62,954.00 | 3
362
+ # 38 | 2012-03-27 08:00:17.328727 | | 2011-10-14 | Winston J. Sillypants, XXXVIII | $85,840.00 | 1
363
+ # ...
364
+ # 4976 | 2012-03-27 08:00:29.005547 | 2012-03-27 08:00:29.005547 | 2011-10-10 | Picholine Pimplenad, MMMMCMLXXVI | $125,095.00 | 3
365
+ # 4984 | 2012-03-27 08:00:29.11038 | 2012-03-27 08:00:33.269888 | 2011-10-11 | Picholine Pimplenad, MMMMCMLXXXIV | $105,346.00 | 3
366
+ # 4992 | 2012-03-27 08:00:29.147872 | 2012-03-27 08:00:29.147872 | 2011-10-08 | Picholine Pimplenad, MMMMCMXCII | $65,541.00 | 4
367
+ #
368
+ # Partition employees_partitions.p201111 - partition where
369
+ # start_date >= '2011-11-01' AND start_date < '2011-12-01':
370
+ #
371
+ # id | created_at | updated_at | start_date | name | salary | company_id
372
+ #------+----------------------------+----------------------------+------------+-----------------------------------+-------------+------------
373
+ # 1 | 2012-03-27 08:00:17.328727 | | 2011-11-12 | Winston J. Sillypants, I | $61,403.00 | 4
374
+ # 2 | 2012-03-27 08:00:17.328727 | | 2011-11-24 | Winston J. Sillypants, II | $94,140.00 | 3
375
+ # 8 | 2012-03-27 08:00:17.328727 | | 2011-11-22 | Winston J. Sillypants, VIII | $139,234.00 | 1
376
+ # ...
377
+ # 4950 | 2012-03-27 08:00:28.887451 | 2012-03-27 08:00:28.887451 | 2011-11-18 | Picholine Pimplenad, MMMMCML | $78,791.00 | 2
378
+ # 4962 | 2012-03-27 08:00:28.942506 | 2012-03-27 09:00:43.14307 | 2011-11-15 | Picholine Pimplenad, MMMMCMLXII | $121,325.00 | 3
379
+ # 4974 | 2012-03-27 08:00:28.996189 | 2012-03-27 08:00:28.996189 | 2011-11-21 | Picholine Pimplenad, MMMMCMLXXIV | $60,607.00 | 2
380
+ #
381
+ # Partition employees_partitions.p201112 - partition where
382
+ # start_date >= '2011-12-01' AND start_date < '2012-01-01':
383
+ #
384
+ # id | created_at | updated_at | start_date | name | salary | company_id
385
+ #------+----------------------------+----------------------------+------------+-----------------------------------+-------------+------------
386
+ # 6 | 2012-03-27 08:00:17.328727 | | 2011-12-22 | Winston J. Sillypants, VI | $114,347.00 | 2
387
+ # 12 | 2012-03-27 08:00:17.328727 | | 2011-12-22 | Winston J. Sillypants, XII | $83,008.00 | 4
388
+ # 19 | 2012-03-27 08:00:17.328727 | 2012-03-27 08:00:35.479746 | 2011-12-16 | Winston J. Sillypants, XIX | $101,796.00 | 4
389
+ # ...
390
+ # 4939 | 2012-03-27 08:00:28.837839 | 2012-03-27 09:00:43.1619 | 2011-12-16 | Picholine Pimplenad, MMMMCMXXXIX | $114,202.00 | 1
391
+ # 4968 | 2012-03-27 08:00:28.969687 | 2012-03-27 08:00:33.652371 | 2011-12-13 | Picholine Pimplenad, MMMMCMLXVIII | $116,727.00 | 3
392
+ # 4975 | 2012-03-27 08:00:29.000734 | 2012-03-27 08:00:29.000734 | 2011-12-25 | Picholine Pimplenad, MMMMCMLXXV | $125,930.00 | 2
393
+ #
394
+
395
+ require File.expand_path(File.dirname(__FILE__) + "/lib/command_line_tool_mixin")
396
+ require File.expand_path(File.dirname(__FILE__) + "/lib/get_options")
397
+
398
+ include CommandLineToolMixin
399
+
400
+ $cleanup = false
401
+ $force = false
402
+ $create_many = 3000
403
+ $create_individual = 1000
404
+ $new_individual = 1000
405
+ $update_many = 1000
406
+ $update_individual = 1000
407
+
408
+ @options = {
409
+ "--cleanup" => {
410
+ :short => "-C",
411
+ :argument => GetoptLong::NO_ARGUMENT,
412
+ :note => "cleanup data in database and exit"
413
+ },
414
+ "--force" => {
415
+ :short => "-F",
416
+ :argument => GetoptLong::NO_ARGUMENT,
417
+ :note => "cleanup data in database before creating new data"
418
+ },
419
+ "--create-many" => {
420
+ :short => "-m",
421
+ :argument => GetoptLong::REQUIRED_ARGUMENT,
422
+ :note => "how many objects to create via create_many",
423
+ :argument_note => "NUMBER"
424
+ },
425
+ "--create-individual" => {
426
+ :short => "-i",
427
+ :argument => GetoptLong::REQUIRED_ARGUMENT,
428
+ :note => "how many objects to create via create",
429
+ :argument_note => "NUMBER"
430
+ },
431
+ "--new-individual" => {
432
+ :short => "-I",
433
+ :argument => GetoptLong::REQUIRED_ARGUMENT,
434
+ :note => "how many objects to create via new/save",
435
+ :argument_note => "NUMBER"
436
+ },
437
+ "--update-individual" => {
438
+ :short => "-u",
439
+ :argument => GetoptLong::REQUIRED_ARGUMENT,
440
+ :note => "how many objects to update indivudually",
441
+ :argument_note => "NUMBER"
442
+ },
443
+ "--update-many" => {
444
+ :short => "-U",
445
+ :argument => GetoptLong::REQUIRED_ARGUMENT,
446
+ :note => "how many objects to update via update_many",
447
+ :argument_note => "NUMBER"
448
+ },
449
+ }
450
+
451
+ command_line_options(@options) do |option,argument|
452
+ if option == '--cleanup'
453
+ $cleanup = true
454
+ elsif option == '--force'
455
+ $force = true
456
+ elsif option == '--create-many'
457
+ $create_many = argument.to_i
458
+ elsif option == '--create-individual'
459
+ $create_individual = argument.to_i
460
+ elsif option == '--new-individual'
461
+ $new_individual = argument.to_i
462
+ elsif option == '--update-individual'
463
+ $update_individual = argument.to_i
464
+ elsif option == '--update-many'
465
+ $update_many = argument.to_i
466
+ end
467
+ end
468
+
469
+ if $cleanup || $force
470
+ ActiveRecord::Base.connection.drop_schema("employees_partitions", :cascade => true) rescue nil
471
+ ActiveRecord::Base.connection.drop_table("employees") rescue nil
472
+ ActiveRecord::Base.connection.drop_table("companies") rescue nil
473
+ exit(0) if $cleanup
474
+ end
475
+
476
+ $total_records = $create_many + $create_individual + $new_individual
477
+
478
+ puts "total records: #{$total_records}"
479
+
480
+ START_DATE = Date.parse('2011-01-01')
481
+ END_DATE = Date.parse('2011-12-31')
482
+
483
+ # the ActiveRecord classes
484
+
485
+ require File.expand_path(File.dirname(__FILE__) + "/lib/company")
486
+
487
+ class Partitioned::ByStartDate < Partitioned::ByMonthlyTimeField
488
+ self.abstract_class = true
489
+
490
+ def self.partition_time_field
491
+ return :start_date
492
+ end
493
+ end
494
+
495
+ class Employee < Partitioned::ByStartDate
496
+ belongs_to :company, :class_name => 'Company'
497
+ attr_accessible :company_id, :start_date, :salary, :name
498
+
499
+ partitioned do |partition|
500
+ partition.index :id, :unique => true
501
+ partition.foreign_key :company_id
502
+ end
503
+
504
+ connection.execute <<-SQL
505
+ create table employees
506
+ (
507
+ id serial not null primary key,
508
+ created_at timestamp not null default now(),
509
+ updated_at timestamp null,
510
+ start_date date not null,
511
+ name text not null,
512
+ salary money not null,
513
+ company_id integer not null
514
+ );
515
+ SQL
516
+ end
517
+
518
+ # You should have the following tables:
519
+ # public.companies
520
+ # public.employees
521
+
522
+ # create the infrastructure for EMPLOYEES table which includes the schema and partition tables
523
+
524
+ Employee.create_infrastructure
525
+
526
+ # You should have the following schema:
527
+ # employees_partitions
528
+
529
+ dates = Employee.partition_generate_range(START_DATE, END_DATE)
530
+ Employee.create_new_partition_tables(dates)
531
+
532
+ # You should have the following tables with increments of one month:
533
+ # employees_partitions.p201101
534
+ # employees_partitions.p201102
535
+ # employees_partitions.p201103
536
+ # employees_partitions.p201104
537
+ # employees_partitions.p201105
538
+ # employees_partitions.p201106
539
+ # employees_partitions.p201107
540
+ # employees_partitions.p201108
541
+ # employees_partitions.p201109
542
+ # employees_partitions.p201110
543
+ # employees_partitions.p201111
544
+ # employees_partitions.p201112
545
+
546
+ # add some companies
547
+
548
+ Company.create_many(COMPANIES)
549
+ company_ids = Company.all.map(&:id)
550
+
551
+ # now add some employees across the year.
552
+
553
+ employees = []
554
+
555
+ require File.expand_path(File.dirname(__FILE__) + "/lib/roman")
556
+
557
+ # generates data for employees_partitions and employees tables
558
+
559
+ base = 0
560
+ (1..$create_many).each do |i|
561
+ employees << {
562
+ :name => "Winston J. Sillypants, #{to_roman(base+i)}",
563
+ :start_date => START_DATE + rand(END_DATE - START_DATE) + rand(1.day.seconds).seconds,
564
+ :salary => rand(80000) + 60000,
565
+ :company_id => company_ids[rand company_ids.length]
566
+ }
567
+ end
568
+
569
+ puts "creating many #{$create_many}"
570
+ Employee.create_many(employees)
571
+ base += $create_many
572
+
573
+ puts "creating individual #{$create_individual}"
574
+ (1..$create_individual).each do |i|
575
+ employee_data = {
576
+ :name => "Jonathan Crabapple, #{to_roman(base+i)}",
577
+ :start_date => START_DATE + rand(END_DATE - START_DATE) + rand(1.day.seconds).seconds,
578
+ :salary => rand(80000) + 60000,
579
+ :company_id => company_ids[rand company_ids.length]
580
+ }
581
+ employees << Employee.create(employee_data)
582
+ end
583
+ base += $create_individual
584
+
585
+ puts "new individual #{$new_individual}"
586
+ (1..$new_individual).each do |i|
587
+ employee_data = {
588
+ :name => "Picholine Pimplenad, #{to_roman(base+i)}",
589
+ :start_date => START_DATE + rand(END_DATE - START_DATE) + rand(1.day.seconds).seconds,
590
+ :salary => rand(80000) + 60000,
591
+ :company_id => company_ids[rand company_ids.length]
592
+ }
593
+ employee = Employee.new(employee_data)
594
+ employee.save
595
+ employees << employee
596
+ end
597
+ base += $new_individual
598
+
599
+ updates = {}
600
+ puts "update many #{$update_many}"
601
+ (1..$update_many).each do |i|
602
+ index = rand(employees.length)
603
+ employee_record = employees[index]
604
+ updates[{
605
+ :id => employee_record[:id],
606
+ :start_date => employee_record[:start_date]
607
+ }] = {
608
+ :salary => 100
609
+ }
610
+ end
611
+
612
+ Employee.update_many(updates, {:set_array => '"salary = #{table_name}.salary + datatable.salary, updated_at = now()"'})
613
+
614
+ puts "update individual #{$update_individual}"
615
+ (1..$update_individual).each do |i|
616
+ index = rand(employees.length)
617
+ employee_record = employees[index]
618
+ employee = Employee.from_partition(employee_record[:start_date]).find(employee_record[:id])
619
+ employee.salary += 1000
620
+ employee.save
621
+ end