partitioned 1.1.1 → 1.1.3
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/.rspec +2 -0
- data/Gemfile.lock +116 -0
- data/examples/company_id.rb +1 -1
- data/examples/company_id_and_created_at.rb +1 -1
- data/examples/created_at.rb +1 -1
- data/examples/created_at_referencing_awards.rb +2 -2
- data/examples/id.rb +1 -1
- data/examples/lib/company.rb +1 -1
- data/examples/start_date.rb +1 -1
- data/lib/partitioned/by_yearly_time_field.rb +29 -0
- data/lib/partitioned/partitioned_base.rb +5 -8
- data/lib/partitioned/version.rb +1 -1
- data/lib/partitioned.rb +2 -2
- data/partitioned.gemspec +5 -4
- data/spec/monkey_patch_posgres_spec.rb +1 -1
- data/spec/partitioned/by_yearly_time_field_spec.rb +100 -0
- data/spec/partitioned/multi_level/configurator/dsl_spec.rb +4 -0
- data/spec/partitioned/partitioned_base/configurator/dsl_spec.rb +4 -0
- data/spec/support/shared_example_spec_helper_for_time_key.rb +3 -3
- data/spec/support/tables_spec_helper.rb +1 -1
- metadata +23 -5
- data/lib/partitioned/bulk_methods_mixin.rb +0 -233
- data/spec/partitioned/bulk_methods_mixin_spec.rb +0 -512
data/.rspec
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
partitioned (1.1.3)
|
5
|
+
bulk_data_methods (= 1.0.0)
|
6
|
+
pg
|
7
|
+
rails (>= 3.2.8)
|
8
|
+
rspec-rails
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: http://rubygems.org/
|
12
|
+
specs:
|
13
|
+
actionmailer (3.2.11)
|
14
|
+
actionpack (= 3.2.11)
|
15
|
+
mail (~> 2.4.4)
|
16
|
+
actionpack (3.2.11)
|
17
|
+
activemodel (= 3.2.11)
|
18
|
+
activesupport (= 3.2.11)
|
19
|
+
builder (~> 3.0.0)
|
20
|
+
erubis (~> 2.7.0)
|
21
|
+
journey (~> 1.0.4)
|
22
|
+
rack (~> 1.4.0)
|
23
|
+
rack-cache (~> 1.2)
|
24
|
+
rack-test (~> 0.6.1)
|
25
|
+
sprockets (~> 2.2.1)
|
26
|
+
activemodel (3.2.11)
|
27
|
+
activesupport (= 3.2.11)
|
28
|
+
builder (~> 3.0.0)
|
29
|
+
activerecord (3.2.11)
|
30
|
+
activemodel (= 3.2.11)
|
31
|
+
activesupport (= 3.2.11)
|
32
|
+
arel (~> 3.0.2)
|
33
|
+
tzinfo (~> 0.3.29)
|
34
|
+
activeresource (3.2.11)
|
35
|
+
activemodel (= 3.2.11)
|
36
|
+
activesupport (= 3.2.11)
|
37
|
+
activesupport (3.2.11)
|
38
|
+
i18n (~> 0.6)
|
39
|
+
multi_json (~> 1.0)
|
40
|
+
arel (3.0.2)
|
41
|
+
builder (3.0.4)
|
42
|
+
bulk_data_methods (1.0.0)
|
43
|
+
pg
|
44
|
+
rails (>= 3.0.0)
|
45
|
+
rspec-rails
|
46
|
+
diff-lcs (1.1.3)
|
47
|
+
erubis (2.7.0)
|
48
|
+
hike (1.2.1)
|
49
|
+
i18n (0.6.1)
|
50
|
+
journey (1.0.4)
|
51
|
+
jquery-rails (2.1.4)
|
52
|
+
railties (>= 3.0, < 5.0)
|
53
|
+
thor (>= 0.14, < 2.0)
|
54
|
+
json (1.7.6)
|
55
|
+
mail (2.4.4)
|
56
|
+
i18n (>= 0.4.0)
|
57
|
+
mime-types (~> 1.16)
|
58
|
+
treetop (~> 1.4.8)
|
59
|
+
mime-types (1.19)
|
60
|
+
multi_json (1.5.0)
|
61
|
+
pg (0.14.1)
|
62
|
+
polyglot (0.3.3)
|
63
|
+
rack (1.4.4)
|
64
|
+
rack-cache (1.2)
|
65
|
+
rack (>= 0.4)
|
66
|
+
rack-ssl (1.3.2)
|
67
|
+
rack
|
68
|
+
rack-test (0.6.2)
|
69
|
+
rack (>= 1.0)
|
70
|
+
rails (3.2.11)
|
71
|
+
actionmailer (= 3.2.11)
|
72
|
+
actionpack (= 3.2.11)
|
73
|
+
activerecord (= 3.2.11)
|
74
|
+
activeresource (= 3.2.11)
|
75
|
+
activesupport (= 3.2.11)
|
76
|
+
bundler (~> 1.0)
|
77
|
+
railties (= 3.2.11)
|
78
|
+
railties (3.2.11)
|
79
|
+
actionpack (= 3.2.11)
|
80
|
+
activesupport (= 3.2.11)
|
81
|
+
rack-ssl (~> 1.3.2)
|
82
|
+
rake (>= 0.8.7)
|
83
|
+
rdoc (~> 3.4)
|
84
|
+
thor (>= 0.14.6, < 2.0)
|
85
|
+
rake (10.0.3)
|
86
|
+
rdoc (3.12)
|
87
|
+
json (~> 1.4)
|
88
|
+
rspec-core (2.12.2)
|
89
|
+
rspec-expectations (2.12.1)
|
90
|
+
diff-lcs (~> 1.1.3)
|
91
|
+
rspec-mocks (2.12.1)
|
92
|
+
rspec-rails (2.12.2)
|
93
|
+
actionpack (>= 3.0)
|
94
|
+
activesupport (>= 3.0)
|
95
|
+
railties (>= 3.0)
|
96
|
+
rspec-core (~> 2.12.0)
|
97
|
+
rspec-expectations (~> 2.12.0)
|
98
|
+
rspec-mocks (~> 2.12.0)
|
99
|
+
sprockets (2.2.2)
|
100
|
+
hike (~> 1.2)
|
101
|
+
multi_json (~> 1.0)
|
102
|
+
rack (~> 1.0)
|
103
|
+
tilt (~> 1.1, != 1.3.0)
|
104
|
+
thor (0.16.0)
|
105
|
+
tilt (1.3.3)
|
106
|
+
treetop (1.4.12)
|
107
|
+
polyglot
|
108
|
+
polyglot (>= 0.3.1)
|
109
|
+
tzinfo (0.3.35)
|
110
|
+
|
111
|
+
PLATFORMS
|
112
|
+
ruby
|
113
|
+
|
114
|
+
DEPENDENCIES
|
115
|
+
jquery-rails
|
116
|
+
partitioned!
|
data/examples/company_id.rb
CHANGED
@@ -131,7 +131,7 @@
|
|
131
131
|
#
|
132
132
|
# update_many - allows you to update multiple records.
|
133
133
|
# :set_array - additional option, you may read the description
|
134
|
-
# of the method in the
|
134
|
+
# of the method update_many in the gem bulk_data_methods about this option.
|
135
135
|
# Employee.update_many(updates, { :set_array => '"salary = #{table_name}.salary +
|
136
136
|
# datatable.salary, updated_at = now()"' })
|
137
137
|
#
|
@@ -230,7 +230,7 @@
|
|
230
230
|
#
|
231
231
|
# update_many - allows you to update multiple records.
|
232
232
|
# :set_array - additional option, you may read the description
|
233
|
-
# of the method in the
|
233
|
+
# of the method update_many in the gem bulk_data_methods about this option.
|
234
234
|
# Employee.update_many(updates, { :set_array => '"salary = #{table_name}.salary +
|
235
235
|
# datatable.salary, updated_at = now()"' })
|
236
236
|
#
|
data/examples/created_at.rb
CHANGED
@@ -216,7 +216,7 @@
|
|
216
216
|
#
|
217
217
|
# update_many - allows you to update multiple records.
|
218
218
|
# :set_array - additional option, you may read the description
|
219
|
-
# of the method in the
|
219
|
+
# of the method update_many in the gem bulk_data_methods about this option.
|
220
220
|
# Employee.update_many(updates, {:set_array => '"salary = #{table_name}.salary +
|
221
221
|
# datatable.salary, updated_at = now()"'})
|
222
222
|
#
|
@@ -240,7 +240,7 @@
|
|
240
240
|
#
|
241
241
|
# update_many - allows you to update multiple records.
|
242
242
|
# :set_array - additional option, you may read the description
|
243
|
-
# of the method in the
|
243
|
+
# of the method update_many in the gem bulk_data_methods about this option.
|
244
244
|
# Employee.update_many(updates, { :set_array => '"salary = #{table_name}.salary +
|
245
245
|
# datatable.salary, updated_at = now()"' })
|
246
246
|
#
|
@@ -364,7 +364,7 @@
|
|
364
364
|
#
|
365
365
|
# update_many - allows you to update multiple records.
|
366
366
|
# :set_array - additional option, you may read the description
|
367
|
-
# of the method in the
|
367
|
+
# of the method update_many in the gem bulk_data_methods about this option.
|
368
368
|
# Award.update_many(updates, { :set_array => '"award_title = datatable.award_title,
|
369
369
|
# awarded_on = now()"' })
|
370
370
|
#
|
data/examples/id.rb
CHANGED
@@ -150,7 +150,7 @@
|
|
150
150
|
#
|
151
151
|
# update_many - allows you to update multiple records.
|
152
152
|
# :set_array - additional option, you may read the description
|
153
|
-
# of the method in the
|
153
|
+
# of the method update_many in the gem bulk_data_methods about this option.
|
154
154
|
# Employee.update_many(updates, {:set_array => '"salary = #{table_name}.salary +
|
155
155
|
# datatable.salary, updated_at = now()"'})
|
156
156
|
#
|
data/examples/lib/company.rb
CHANGED
data/examples/start_date.rb
CHANGED
@@ -200,7 +200,7 @@
|
|
200
200
|
#
|
201
201
|
# update_many - allows you to update multiple records.
|
202
202
|
# :set_array - additional option, you may read the description
|
203
|
-
# of the method in the
|
203
|
+
# of the method update_many in the gem bulk_data_methods about this option.
|
204
204
|
# Employee.update_many(updates, {:set_array => '"salary = #{table_name}.salary +
|
205
205
|
# datatable.salary, updated_at = now()"'})
|
206
206
|
#
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Partitioned
|
2
|
+
#
|
3
|
+
# Partition tables by a time field grouping them by year.
|
4
|
+
#
|
5
|
+
class ByYearlyTimeField < ByTimeField
|
6
|
+
self.abstract_class = true
|
7
|
+
|
8
|
+
# Normalize a partition key value by year.
|
9
|
+
#
|
10
|
+
# @param [Time] time_value the time value to normalize
|
11
|
+
# @return [Time] the value normalized
|
12
|
+
def self.partition_normalize_key_value(time_value)
|
13
|
+
return time_value.at_beginning_of_year
|
14
|
+
end
|
15
|
+
|
16
|
+
# The size of the partition table, a year
|
17
|
+
#
|
18
|
+
# @return [Integer] the size of this partition
|
19
|
+
def self.partition_table_size
|
20
|
+
return 1.year
|
21
|
+
end
|
22
|
+
|
23
|
+
partitioned do |partition|
|
24
|
+
partition.base_name lambda { |model, time_field|
|
25
|
+
return model.partition_normalize_key_value(time_field).strftime('%Y')
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# :include: ../../README
|
3
3
|
#
|
4
|
+
require "bulk_data_methods"
|
4
5
|
|
5
6
|
module Partitioned
|
6
7
|
#
|
@@ -19,7 +20,7 @@ module Partitioned
|
|
19
20
|
# Uses a domain specific language to configure, see Partitioned::PartitionedBase::Configurator
|
20
21
|
# for more information.
|
21
22
|
#
|
22
|
-
# Extends
|
23
|
+
# Extends BulkMethodsMixin to provide create_many and update_many.
|
23
24
|
#
|
24
25
|
# Uses PartitionManager to manage creation of child tables.
|
25
26
|
#
|
@@ -28,7 +29,7 @@ module Partitioned
|
|
28
29
|
#
|
29
30
|
class PartitionedBase < ActiveRecord::Base
|
30
31
|
include ActiveRecordOverrides
|
31
|
-
extend
|
32
|
+
extend ::BulkMethodsMixin
|
32
33
|
|
33
34
|
self.abstract_class = true
|
34
35
|
|
@@ -161,7 +162,7 @@ module Partitioned
|
|
161
162
|
#
|
162
163
|
# Use as:
|
163
164
|
#
|
164
|
-
# Foo.
|
165
|
+
# Foo.from_partition_without_alias(KEY).find(:all, :select => "*")
|
165
166
|
#
|
166
167
|
# where KEY is the key value(s) used as the check constraint on Foo's table.
|
167
168
|
#
|
@@ -174,13 +175,9 @@ module Partitioned
|
|
174
175
|
# which fails because table foos is not referenced. using the form #from_partition
|
175
176
|
# is almost always the correct thing when using activerecord.
|
176
177
|
#
|
177
|
-
# Because the scope is specific to a class (a class method) but unlike
|
178
|
-
# class methods is not inherited, one must use this form (#from_partitioned_without_alias) instead
|
179
|
-
# of #from_partitioned_without_alias_scope to get the most derived classes specific active record scope.
|
180
|
-
#
|
181
178
|
# @param [*Array<Object>] partition_field the field values to partition on
|
182
179
|
# @return [Hash] the scoping
|
183
|
-
def self.
|
180
|
+
def self.from_partition_without_alias(*partition_field)
|
184
181
|
table_alias_name = partition_table_name(*partition_field)
|
185
182
|
from(table_alias_name).
|
186
183
|
tap{|relation| relation.table.table_alias = table_alias_name}
|
data/lib/partitioned/version.rb
CHANGED
data/lib/partitioned.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'monkey_patch_activerecord'
|
2
2
|
require 'monkey_patch_postgres'
|
3
3
|
|
4
|
-
require 'partitioned/bulk_methods_mixin'
|
5
4
|
require 'partitioned/active_record_overrides'
|
6
5
|
require 'partitioned/partitioned_base/configurator.rb'
|
7
6
|
require 'partitioned/partitioned_base/configurator/data'
|
@@ -12,6 +11,7 @@ require 'partitioned/partitioned_base/partition_manager'
|
|
12
11
|
require 'partitioned/partitioned_base/sql_adapter'
|
13
12
|
|
14
13
|
require 'partitioned/by_time_field'
|
14
|
+
require 'partitioned/by_yearly_time_field'
|
15
15
|
require 'partitioned/by_monthly_time_field'
|
16
16
|
require 'partitioned/by_weekly_time_field'
|
17
17
|
require 'partitioned/by_created_at'
|
@@ -23,4 +23,4 @@ require 'partitioned/multi_level'
|
|
23
23
|
require 'partitioned/multi_level/configurator/data'
|
24
24
|
require 'partitioned/multi_level/configurator/dsl'
|
25
25
|
require 'partitioned/multi_level/configurator/reader'
|
26
|
-
require 'partitioned/multi_level/partition_manager'
|
26
|
+
require 'partitioned/multi_level/partition_manager'
|
data/partitioned.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.name = 'partitioned'
|
8
8
|
s.version = Partitioned::VERSION
|
9
9
|
s.license = 'New BSD License'
|
10
|
-
s.date = '
|
10
|
+
s.date = '2013-10-14'
|
11
11
|
s.summary = "Postgres table partitioning support for ActiveRecord."
|
12
12
|
s.description = "A gem providing support for table partitioning in ActiveRecord. Support is only available for postgres databases. Other features include child table management (creation and deletion) and bulk data creating and updating."
|
13
13
|
s.authors = ["Keith Gabryelski", "Aleksandr Dembskiy"]
|
@@ -16,7 +16,8 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
17
|
s.require_path = 'lib'
|
18
18
|
s.homepage = 'http://github.com/fiksu/partitioned'
|
19
|
-
s.add_dependency
|
20
|
-
s.add_dependency
|
21
|
-
s.add_dependency
|
19
|
+
s.add_dependency 'pg'
|
20
|
+
s.add_dependency 'rails', '>= 3.2.8'
|
21
|
+
s.add_dependency 'rspec-rails'
|
22
|
+
s.add_dependency 'bulk_data_methods', '1.0.0'
|
22
23
|
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require "#{File.dirname(__FILE__)}/../support/tables_spec_helper"
|
3
|
+
require "#{File.dirname(__FILE__)}/../support/shared_example_spec_helper_for_time_key"
|
4
|
+
|
5
|
+
module Partitioned
|
6
|
+
|
7
|
+
describe ByYearlyTimeField do
|
8
|
+
|
9
|
+
include TablesSpecHelper
|
10
|
+
|
11
|
+
module YearlyTimeField
|
12
|
+
class Employee < Partitioned::ByYearlyTimeField
|
13
|
+
belongs_to :company, :class_name => 'Company'
|
14
|
+
attr_accessible :company_id, :name, :created_at
|
15
|
+
|
16
|
+
def self.partition_time_field
|
17
|
+
return :created_at
|
18
|
+
end
|
19
|
+
|
20
|
+
partitioned do |partition|
|
21
|
+
partition.index :id, :unique => true
|
22
|
+
partition.foreign_key :company_id
|
23
|
+
end
|
24
|
+
end # Employee
|
25
|
+
end # YearlyTimeField
|
26
|
+
|
27
|
+
before(:all) do
|
28
|
+
@employee = YearlyTimeField::Employee
|
29
|
+
create_tables
|
30
|
+
dates = @employee.partition_generate_range(DATE_NOW,
|
31
|
+
DATE_NOW + 1.year)
|
32
|
+
@employee.create_new_partition_tables(dates)
|
33
|
+
ActiveRecord::Base.connection.execute <<-SQL
|
34
|
+
insert into employees_partitions.
|
35
|
+
p#{DATE_NOW.at_beginning_of_year.strftime('%Y')}
|
36
|
+
(company_id,name) values (1,'Keith');
|
37
|
+
SQL
|
38
|
+
end
|
39
|
+
|
40
|
+
after(:all) do
|
41
|
+
drop_tables
|
42
|
+
end
|
43
|
+
|
44
|
+
let(:class_by_yearly_time_field) { ::Partitioned::ByYearlyTimeField }
|
45
|
+
|
46
|
+
describe "model is abstract class" do
|
47
|
+
|
48
|
+
it "returns true" do
|
49
|
+
class_by_yearly_time_field.abstract_class.should be_true
|
50
|
+
end
|
51
|
+
|
52
|
+
end # model is abstract class
|
53
|
+
|
54
|
+
describe "#partition_normalize_key_value" do
|
55
|
+
|
56
|
+
it "returns date with day set to 1st January of the year" do
|
57
|
+
class_by_yearly_time_field.
|
58
|
+
partition_normalize_key_value(Date.parse('2011-02-05')).
|
59
|
+
should == Date.parse('2011-01-01')
|
60
|
+
end
|
61
|
+
|
62
|
+
end # #partition_normalize_key_value
|
63
|
+
|
64
|
+
describe "#partition_table_size" do
|
65
|
+
|
66
|
+
it "returns 1.year" do
|
67
|
+
class_by_yearly_time_field.partition_table_size.should == 1.year
|
68
|
+
end
|
69
|
+
|
70
|
+
end # #partition_table_size
|
71
|
+
|
72
|
+
describe "partitioned block" do
|
73
|
+
|
74
|
+
let(:data) do
|
75
|
+
class_by_yearly_time_field.configurator_dsl.data
|
76
|
+
end
|
77
|
+
|
78
|
+
context "checks data in the base_name is Proc" do
|
79
|
+
|
80
|
+
it "returns Proc" do
|
81
|
+
data.base_name.should be_is_a Proc
|
82
|
+
end
|
83
|
+
|
84
|
+
end # checks data in the on_field is Proc
|
85
|
+
|
86
|
+
context "checks data in the base_name" do
|
87
|
+
|
88
|
+
it "returns base_name" do
|
89
|
+
data.base_name.call(@employee, Date.parse('2011-02-05')).should == "2011"
|
90
|
+
end
|
91
|
+
|
92
|
+
end # checks data in the base_name
|
93
|
+
|
94
|
+
end # partitioned block
|
95
|
+
|
96
|
+
it_should_behave_like "check that basic operations with postgres works correctly for time key", YearlyTimeField::Employee
|
97
|
+
|
98
|
+
end # ByYearlyTimeField
|
99
|
+
|
100
|
+
end # Partitioned
|
@@ -20,9 +20,13 @@ describe Partitioned::MultiLevel::Configurator::Dsl do
|
|
20
20
|
{
|
21
21
|
"on_field" => nil,
|
22
22
|
"indexes" => [],
|
23
|
+
"janitorial_archives_needed" => nil,
|
24
|
+
"janitorial_creates_needed" => nil,
|
25
|
+
"janitorial_drops_needed" => nil,
|
23
26
|
"foreign_keys" => [],
|
24
27
|
"last_partitions_order_by_clause" => nil,
|
25
28
|
"schema_name" => nil,
|
29
|
+
"table_alias_name" => nil,
|
26
30
|
"name_prefix" => nil,
|
27
31
|
"base_name" => nil,
|
28
32
|
"part_name" => nil,
|