partitioned 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -105,7 +105,7 @@
105
105
  # partitioned do |partition|
106
106
  # partition.foreign_key lambda {|model, *partition_key_values|
107
107
  # return Configurator::Data::ForeignKey.
108
- # new(:employee_id, Employee.partition_name(*partition_key_values), :id)
108
+ # new(:employee_id, Employee.partition_table_name(*partition_key_values), :id)
109
109
  # }
110
110
  # end
111
111
  # end
@@ -702,7 +702,7 @@ class Award < ByEmployeeCreatedAt
702
702
 
703
703
  partitioned do |partition|
704
704
  partition.foreign_key lambda {|model, *partition_key_values|
705
- return Configurator::Data::ForeignKey.new(:employee_id, Employee.partition_name(*partition_key_values), :id)
705
+ return Configurator::Data::ForeignKey.new(:employee_id, Employee.partition_table_name(*partition_key_values), :id)
706
706
  }
707
707
  end
708
708
 
@@ -13,6 +13,40 @@ module ActiveRecord
13
13
  # Patches for Persistence to allow certain partitioning (that related to the primary key) to work.
14
14
  #
15
15
  module Persistence
16
+ # Deletes the record in the database and freezes this instance to reflect
17
+ # that no changes should be made (since they can't be persisted).
18
+ def destroy
19
+ destroy_associations
20
+
21
+ if persisted?
22
+ IdentityMap.remove(self) if IdentityMap.enabled?
23
+ pk = self.class.primary_key
24
+ column = self.class.columns_hash[pk]
25
+ substitute = connection.substitute_at(column, 0)
26
+
27
+ using_arel_table = self.respond_to?(:dynamic_arel_table) ? dynamic_arel_table() : self.class.arel_table
28
+ relation = self.class.unscoped.where(
29
+ using_arel_table[pk].eq(substitute))
30
+
31
+ relation.bind_values = [[column, id]]
32
+ relation.delete_all
33
+ end
34
+
35
+ @destroyed = true
36
+ freeze
37
+ end
38
+
39
+ # Updates the associated record with values matching those of the instance attributes.
40
+ # Returns the number of affected rows.
41
+ def update(attribute_names = @attributes.keys)
42
+ attributes_with_values = arel_attributes_values(false, false, attribute_names)
43
+ return 0 if attributes_with_values.empty?
44
+ klass = self.class
45
+ using_arel_table = self.respond_to?(:dynamic_arel_table) ? dynamic_arel_table() : klass.arel_table
46
+ stmt = klass.unscoped.where(using_arel_table[klass.primary_key].eq(id)).arel.compile_update(attributes_with_values)
47
+ klass.connection.update stmt
48
+ end
49
+
16
50
  #
17
51
  # patch the create method to prefetch the primary key if needed
18
52
  #
@@ -65,7 +99,7 @@ module ActiveRecord
65
99
  # that are used to determine the child table this insert should be
66
100
  # redirected to)
67
101
  #
68
- actual_arel_table = @klass.dynamic_arel_table(Hash[*values.map{|k,v| [k.name,v]}.flatten]) if @klass.respond_to? :dynamic_arel_table
102
+ actual_arel_table = @klass.dynamic_arel_table(Hash[*values.map{|k,v| [k.name,v]}.flatten]) if @klass.respond_to?(:dynamic_arel_table)
69
103
  actual_arel_table = @table unless actual_arel_table
70
104
  im.into actual_arel_table
71
105
 
@@ -1,6 +1,7 @@
1
1
  require 'active_record'
2
2
  require 'active_record/base'
3
3
  require 'active_record/connection_adapters/abstract_adapter'
4
+ require 'active_record/connection_adapters/postgresql_adapter'
4
5
 
5
6
  #
6
7
  # Patching {ActiveRecord::ConnectionAdapters::TableDefinition} and
@@ -28,6 +29,23 @@ module ActiveRecord::ConnectionAdapters
28
29
  # to take advantage of these SQL builders.
29
30
  #
30
31
  class PostgreSQLAdapter < AbstractAdapter
32
+
33
+ #
34
+ # Returns the sequence name for a table's primary key or some other specified key.
35
+ #
36
+ # the default version strips off the schema name on the table (if it exists), as:
37
+ # serial_sequence(table_name, pk || 'id').split('.').last
38
+ # i can't see any good reason for that -- in fact, it seems completely
39
+ # broken -- if you have a table public.foos and other.foos, you'll fail to
40
+ # get the correct schema if you fetch the default schema name from model
41
+ # associated with other.foos
42
+ #
43
+ def default_sequence_name(table_name, pk = nil) #:nodoc:
44
+ serial_sequence(table_name, pk || 'id')
45
+ rescue ActiveRecord::StatementInvalid => e
46
+ "#{table_name}_#{pk || 'id'}_seq"
47
+ end
48
+
31
49
  #
32
50
  # Get the next value in a sequence. Used on INSERT operation for
33
51
  # partitioning like by_id because the ID is required before the insert
@@ -36,7 +54,7 @@ module ActiveRecord::ConnectionAdapters
36
54
  # @param [String] sequence_name the name of the sequence to fetch the next value from
37
55
  # @return [Integer] the value from the sequence
38
56
  def next_sequence_value(sequence_name)
39
- return execute("select nextval('#{sequence_name}')").field_values("nextval").first
57
+ return execute("select nextval('#{sequence_name}')").field_values("nextval").first.to_i
40
58
  end
41
59
 
42
60
  #
@@ -23,7 +23,7 @@ module Partitioned
23
23
  # @return [Hash] hash of key value pairs associated with persistent attributes
24
24
  def arel_attributes_values(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys)
25
25
  attrs = super
26
- actual_arel_table = dynamic_arel_table(self.class.table_name)
26
+ actual_arel_table = dynamic_arel_table()
27
27
  return Hash[*attrs.map{|k,v| [actual_arel_table[k.name], v]}.flatten]
28
28
  end
29
29
 
@@ -81,7 +81,7 @@ module Partitioned
81
81
  # set :created_at if need be
82
82
  row[:created_at] ||= created_at_value
83
83
  end.group_by do |row|
84
- respond_to?(:partition_name) ? partition_name(*partition_key_values(row)) : table_name
84
+ respond_to?(:partition_table_name) ? partition_table_name(*partition_key_values(row)) : table_name
85
85
  end.each do |table_name, rows_for_table|
86
86
  column_names = rows_for_table[0].keys.sort{|a,b| a.to_s <=> b.to_s}
87
87
  sql_insert_string = "insert into #{table_name} (#{column_names.join(',')}) values "
@@ -189,7 +189,7 @@ module Partitioned
189
189
  returning = []
190
190
 
191
191
  rows.group_by do |row|
192
- respond_to?(:partition_name) ? partition_name(*partition_key_values(row)) : table_name
192
+ respond_to?(:partition_table_name) ? partition_table_name(*partition_key_values(row)) : table_name
193
193
  end.each do |table_name, rows_for_table|
194
194
  column_names = rows_for_table[0].keys.sort{|a,b| a.to_s <=> b.to_s}
195
195
  rows_for_table.each_slice(options[:slice_size]) do |update_slice|
@@ -23,6 +23,11 @@ module Partitioned
23
23
  return integer_field_value / partition_table_size * partition_table_size
24
24
  end
25
25
 
26
+ def self.partition_generate_range(start_value, end_value, step = :default)
27
+ step = partition_table_size if step == :default
28
+ return Range.new(start_value, end_value).step(step)
29
+ end
30
+
26
31
  partitioned do |partition|
27
32
  partition.on lambda {|model| return model.partition_integer_field }
28
33
 
@@ -40,8 +40,9 @@ module Partitioned
40
40
 
41
41
  attr_accessor :on_field, :indexes, :foreign_keys, :last_partitions_order_by_clause,
42
42
  :schema_name, :name_prefix, :base_name,
43
- :part_name, :table_name, :parent_table_schema_name,
44
- :parent_table_name, :check_constraint, :encoded_name
43
+ :part_name, :table_name, :table_alias_name, :parent_table_schema_name,
44
+ :parent_table_name, :check_constraint, :encoded_name,
45
+ :janitorial_creates_needed, :janitorial_archives_needed, :janitorial_drops_needed
45
46
 
46
47
  def initialize
47
48
  @on_field = nil
@@ -57,6 +58,7 @@ module Partitioned
57
58
  @part_name = nil
58
59
 
59
60
  @table_name = nil
61
+ @table_alias_name = nil
60
62
 
61
63
  @parent_table_schema_name = nil
62
64
  @parent_table_name = nil
@@ -64,6 +66,10 @@ module Partitioned
64
66
  @check_constraint = nil
65
67
 
66
68
  @encoded_name = nil
69
+
70
+ @janitorial_creates_needed = nil
71
+ @janitorial_archives_needed = nil
72
+ @janitorial_drops_needed = nil
67
73
  end
68
74
  end
69
75
  end
@@ -550,6 +550,11 @@ module Partitioned
550
550
  data.table_name = value
551
551
  end
552
552
 
553
+ # a reasonable alias for this table
554
+ def table_alias_name(value)
555
+ data.table_alias_name = value
556
+ end
557
+
553
558
  #
554
559
  # The table name of the table who is the direct ancestor of a child table.
555
560
  #
@@ -627,6 +632,20 @@ module Partitioned
627
632
  def parent_table_schema_name(value)
628
633
  data.parent_table_schema_name = value
629
634
  end
635
+
636
+ #
637
+
638
+ def janitorial_creates_needed(value)
639
+ data.janitorial_creates_needed = value
640
+ end
641
+
642
+ def janitorial_archives_needed(value)
643
+ data.janitorial_archives_needed = value
644
+ end
645
+
646
+ def janitorial_drops_needed(value)
647
+ data.janitorial_drops_needed = value
648
+ end
630
649
  end
631
650
  end
632
651
  end
@@ -26,6 +26,10 @@ module Partitioned
26
26
  @parent_table_name = nil
27
27
 
28
28
  @encoded_name = nil
29
+
30
+ @janitorial_creates_needed = nil
31
+ @janitorial_archives_needed = nil
32
+ @janitorial_drops_needed = nil
29
33
  end
30
34
 
31
35
  #
@@ -100,6 +104,13 @@ module Partitioned
100
104
  return collect_first(*partition_key_values, &:table_name)
101
105
  end
102
106
 
107
+ #
108
+ # A reasonable alias for this partition table
109
+ #
110
+ def table_alias_name(*partition_key_values)
111
+ return collect_first(*partition_key_values, &:table_alias_name)
112
+ end
113
+
103
114
  #
104
115
  # The name of the child table without the schema name or name prefix.
105
116
  #
@@ -135,6 +146,26 @@ module Partitioned
135
146
  return @last_partitions_order_by_clause
136
147
  end
137
148
 
149
+ def janitorial_creates_needed
150
+ unless @janitorial_creates_needed
151
+ @janitorial_creates_needed = collect_first(&:janitorial_creates_needed)
152
+ end
153
+ return @janitorial_creates_needed
154
+ end
155
+
156
+ def janitorial_archives_needed
157
+ unless @janitorial_archives_needed
158
+ @janitorial_archives_needed = collect_first(&:janitorial_archives_needed)
159
+ end
160
+ return @janitorial_archives_needed
161
+ end
162
+
163
+ def janitorial_drops_needed
164
+ unless @janitorial_drops_needed
165
+ @janitorial_drops_needed = collect_first(&:janitorial_drops_needed)
166
+ end
167
+ return @janitorial_drops_needed
168
+ end
138
169
 
139
170
  protected
140
171
 
@@ -14,6 +14,17 @@ module Partitioned
14
14
  @parent_table_class = parent_table_class
15
15
  end
16
16
 
17
+ #
18
+ # Archive partitions that need such.
19
+ # uses #archive_old_partition_key_values_set as the list of
20
+ # partitions to remove.
21
+ #
22
+ def archive_old_partitions
23
+ archive_old_partition_key_values_set.each do |*partition_key_values|
24
+ archive_old_partition(*partition_key_values)
25
+ end
26
+ end
27
+
17
28
  #
18
29
  # Drop partitions that are no longer necessary.
19
30
  # uses #old_partition_key_values_set as the list of
@@ -64,10 +75,20 @@ module Partitioned
64
75
  # Used by #create_new_partitions and generally called once a day to update
65
76
  # the database with new soon-to-be needed child tables.
66
77
  #
67
- # Typically overridden by the concrete class as this is pure business logic.
68
- #
69
78
  def new_partition_key_values_set
70
- []
79
+ return configurator.janitorial_creates_needed
80
+ end
81
+
82
+ #
83
+ # An array of key values (each key value is an array of keys) that represent
84
+ # the child partitions that should be archived probably because they are
85
+ # about to be dropped.
86
+ #
87
+ # Used by #archive_old_partitions and generally called once a day to clean up
88
+ # unneeded child tables.
89
+ #
90
+ def archive_old_partition_key_values_set
91
+ return configurator.janitorial_archives_needed
71
92
  end
72
93
 
73
94
  #
@@ -77,10 +98,16 @@ module Partitioned
77
98
  # Used by #drop_old_partitions and generally called once a day to clean up
78
99
  # unneeded child tables.
79
100
  #
80
- # Typically overridden by the concrete class as this is pure business logic.
81
- #
82
101
  def old_partition_key_values_set
83
- []
102
+ return configurator.janitorial_drops_needed
103
+ end
104
+
105
+ #
106
+ # Archive a specific partition from the database given
107
+ # the key value(s) of its check constraint columns.
108
+ #
109
+ def archive_old_partition(*partition_key_values)
110
+ archive_partition_table(*partition_key_values)
84
111
  end
85
112
 
86
113
  #
@@ -131,10 +158,24 @@ module Partitioned
131
158
  # :method: partition_table_name
132
159
  # delegated to Partitioned::PartitionedBase::PartitionManager::SqlAdapter#partition_table_name
133
160
 
161
+ ##
162
+ # :method: partition_table_alias_name
163
+ # delegated to Partitioned::PartitionedBase::PartitionManager::SqlAdapter#partition_table_alias_name
164
+
165
+ ##
166
+ # :method: sql_adapter
167
+ # delegated to Partitioned::PartitionedBase#sql_adapter
168
+
169
+ ##
170
+ # :method: configurator
171
+ # delegated to Partitioned::PartitionedBase#configurator
172
+
134
173
  extend Forwardable
135
- def_delegators :parent_table_class, :sql_adapter
174
+ def_delegators :parent_table_class, :sql_adapter, :configurator
136
175
  def_delegators :sql_adapter, :drop_partition_table, :create_partition_table, :add_partition_table_index,
137
- :add_references_to_partition_table, :create_partition_schema, :add_parent_table_rules, :partition_table_name
176
+ :add_references_to_partition_table, :create_partition_schema, :add_parent_table_rules,
177
+ :partition_table_name, :partition_table_alias_name
178
+
138
179
  end
139
180
  end
140
181
  end
@@ -126,6 +126,13 @@ module Partitioned
126
126
  return configurator.table_name(*partition_key_values)
127
127
  end
128
128
 
129
+ #
130
+ # A reasonable alias for the partition table
131
+ #
132
+ def partition_table_alias_name(*partition_key_values)
133
+ return configurator.table_alias_name(*partition_key_values)
134
+ end
135
+
129
136
  #
130
137
  # Create a single child table.
131
138
  #
@@ -61,7 +61,7 @@ module Partitioned
61
61
  # @return [String] the fully qualified name of the database table, ie: foos_partitions.p17
62
62
  def partition_table_name
63
63
  symbolized_attributes = attributes.symbolize_keys
64
- return self.class.partition_name(*self.class.partition_keys.map{|attribute_name| symbolized_attributes[attribute_name]})
64
+ return self.class.partition_table_name(*self.class.partition_keys.map{|attribute_name| symbolized_attributes[attribute_name]})
65
65
  end
66
66
 
67
67
  #
@@ -119,7 +119,7 @@ module Partitioned
119
119
  new_arel_table = @arel_tables[key_values]
120
120
  arel_engine_hash = {:engine => self.arel_engine}
121
121
  arel_engine_hash[:as] = as unless as.blank?
122
- new_arel_table = Arel::Table.new(self.partition_name(*key_values), arel_engine_hash)
122
+ new_arel_table = Arel::Table.new(self.partition_table_name(*key_values), arel_engine_hash)
123
123
  return new_arel_table
124
124
  end
125
125
 
@@ -135,19 +135,8 @@ module Partitioned
135
135
  return self.class.dynamic_arel_table(key_values, as)
136
136
  end
137
137
 
138
- # :from_partition_scope is generally not used directly,
139
- # use helper self.from_partition so that the derived class
140
- # can be passed into :from_partition_scope
141
138
  #
142
- # @return [Hash] the from scoping
143
- scope :from_partition_scope, lambda { |target_class, *partition_field|
144
- {
145
- :from => "#{target_class.partition_name(*partition_field)} AS #{target_class.table_name}"
146
- }
147
- }
148
-
149
- #
150
- # Real scope (uses #from_partition_scope). This scope is used to target the
139
+ # This scoping is used to target the
151
140
  # active record find() to a specific child table and alias it to the name of the
152
141
  # parent table (so activerecord can generally work with it)
153
142
  #
@@ -157,29 +146,16 @@ module Partitioned
157
146
  #
158
147
  # where KEY is the key value(s) used as the check constraint on Foo's table.
159
148
  #
160
- # Because the scope is specific to a class (a class method) but unlike
161
- # class methods is not inherited, one must use this form (#from_partition) instead
162
- # of #from_partition_scope to get the most derived classes specific active record scope.
163
- #
164
149
  # @param [*Array<Object>] partition_field the field values to partition on
165
150
  # @return [Hash] the scoping
166
151
  def self.from_partition(*partition_field)
167
- from_partition_scope(self, *partition_field)
152
+ table_alias_name = partition_table_alias_name(*partition_field)
153
+ from("#{partition_table_name(*partition_field)} AS #{table_alias_name}").
154
+ tap{|relation| relation.table.table_alias = table_alias_name}
168
155
  end
169
156
 
170
- # :from_partitioned_without_alias_scope is generally not used directly,
171
- # use helper self.from_partitioned_without_alias so that the derived class
172
- # can be passed into :from_partitioned_without_alias_scope
173
157
  #
174
- # @return [Hash] the from scoping
175
- scope :from_partitioned_without_alias_scope, lambda { |target_class, *partition_field|
176
- {
177
- :from => target_class.partition_name(*partition_field)
178
- }
179
- }
180
-
181
- #
182
- # Real scope (uses #from_partitioned_without_alias_scope). This scope is used to target the
158
+ # This scope is used to target the
183
159
  # active record find() to a specific child table. Is probably best used in advanced
184
160
  # activerecord queries when a number of tables are involved in the query.
185
161
  #
@@ -205,7 +181,9 @@ module Partitioned
205
181
  # @param [*Array<Object>] partition_field the field values to partition on
206
182
  # @return [Hash] the scoping
207
183
  def self.from_partitioned_without_alias(*partition_field)
208
- from_partitioned_without_alias_scope(self, *partition_field)
184
+ table_alias_name = partition_table_name(*partition_field)
185
+ from(table_alias_name).
186
+ tap{|relation| relation.table.table_alias = table_alias_name}
209
187
  end
210
188
 
211
189
  #
@@ -252,8 +230,24 @@ module Partitioned
252
230
  #
253
231
  # For a parent table name foos, that would be foos_partitions
254
232
  #
233
+ # N.B.: if the parent table is not in the default schema ("public") the name of the
234
+ # partition schema is prefixed by the schema name of the parent table and an
235
+ # underscore. That is, if a parent table schema/table name is "other.foos"
236
+ # the schema for its partitions will be "other_foos_partitions"
237
+ #
255
238
  partition.schema_name lambda {|model|
256
- return model.table_name + '_partitions'
239
+ schema_parts = []
240
+ table_parts = model.table_name.split('.')
241
+ # table_parts should be either ["table_name"] or ["schema_name", "table_name"]
242
+ if table_parts.length == 2
243
+ # XXX should we find the schema_path here and accept anything in the path as "public"
244
+ unless table_parts.first == "public"
245
+ schema_parts << table_parts.first
246
+ end
247
+ end
248
+ schema_parts << table_parts.last
249
+ schema_parts << 'partitions'
250
+ return schema_parts.join('_')
257
251
  }
258
252
 
259
253
  #
@@ -272,7 +266,9 @@ module Partitioned
272
266
  # The child table is defined by the partition key values passed in.
273
267
  #
274
268
  partition.parent_table_schema_name lambda {|model, *partition_key_values|
275
- # this should be a connection_adapter thing
269
+ table_parts = model.table_name.split('.')
270
+ # table_parts should be either ["table_name"] or ["schema_name", "table_name"]
271
+ return table_parts.first if table_parts.length == 2
276
272
  return "public"
277
273
  }
278
274
 
@@ -308,6 +304,13 @@ module Partitioned
308
304
  return "#{configurator.schema_name}.#{configurator.part_name(*partition_key_values)}"
309
305
  }
310
306
 
307
+ #
308
+ # A reasonable alias for this table
309
+ #
310
+ partition.table_alias_name lambda {|model, *partition_key_values|
311
+ return model.configurator.parent_table_name(*partition_key_values).gsub('.', '_')
312
+ }
313
+
311
314
  #
312
315
  # The name of the child table without a schema name or prefix. this is used to
313
316
  # build child table names for multi-level partitions.
@@ -366,6 +369,13 @@ module Partitioned
366
369
  partition_manager.add_parent_table_rules(*partition_key_values)
367
370
  end
368
371
 
372
+ ##
373
+ # :method: archive_old_partitions
374
+ # delegated to Partitioned::PartitionedBase::PartitionManager#archive_old_partitions
375
+ def self.archive_old_partitions
376
+ partition_manager.archive_old_partitions
377
+ end
378
+
369
379
  ##
370
380
  # :method: drop_old_partitions
371
381
  # delegated to Partitioned::PartitionedBase::PartitionManager#drop_old_partitions
@@ -380,6 +390,13 @@ module Partitioned
380
390
  partition_manager.create_new_partitions
381
391
  end
382
392
 
393
+ ##
394
+ # :method: archive_old_partition
395
+ # delegated to Partitioned::PartitionedBase::PartitionManager#archive_old_partition
396
+ def self.archive_old_partition(*partition_key_values)
397
+ partition_manager.archive_old_partition(*partition_key_values)
398
+ end
399
+
383
400
  ##
384
401
  # :method: drop_old_partition
385
402
  # delegated to Partitioned::PartitionedBase::PartitionManager#drop_old_partition
@@ -421,5 +438,12 @@ module Partitioned
421
438
  def self.partition_name(*partition_key_values)
422
439
  return partition_manager.partition_table_name(*partition_key_values)
423
440
  end
441
+
442
+ ##
443
+ # :method: partition_table_alias_name
444
+ # delegated to Partitioned::PartitionedBase::PartitionManager#partition_table_alias_name
445
+ def self.partition_table_alias_name(*partition_key_values)
446
+ return partition_manager.partition_table_alias_name(*partition_key_values)
447
+ end
424
448
  end
425
449
  end
@@ -1,4 +1,4 @@
1
1
  module Partitioned
2
2
  # the current version of this gem
3
- VERSION = "1.0.1"
3
+ VERSION = "1.1.0"
4
4
  end
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 = '2012-03-07'
10
+ s.date = '2012-09-11'
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"]
@@ -45,12 +45,12 @@ module ActiveRecord::ConnectionAdapters
45
45
  describe "next_sequence_value" do
46
46
 
47
47
  it "returns next_sequence_value" do
48
- ActiveRecord::Base.connection.next_sequence_value(Employee.sequence_name).should == "1"
48
+ ActiveRecord::Base.connection.next_sequence_value(Employee.sequence_name).should == 1
49
49
  ActiveRecord::Base.connection.execute <<-SQL
50
50
  insert into employees(name, company_id) values ('Nikita', 1);
51
51
  SQL
52
- ActiveRecord::Base.connection.next_sequence_value(Employee.sequence_name).should == "3"
53
- ActiveRecord::Base.connection.next_sequence_value(Employee.sequence_name).should == "4"
52
+ ActiveRecord::Base.connection.next_sequence_value(Employee.sequence_name).should == 3
53
+ ActiveRecord::Base.connection.next_sequence_value(Employee.sequence_name).should == 4
54
54
  end
55
55
 
56
56
  end # next_sequence_value
@@ -173,4 +173,4 @@ module ActiveRecord::ConnectionAdapters
173
173
 
174
174
  end # PostgreSQLAdapter
175
175
 
176
- end # ActiveRecord::ConnectionAdapters
176
+ end # ActiveRecord::ConnectionAdapters
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: partitioned
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-03-07 00:00:00.000000000 Z
13
+ date: 2012-09-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: pg
@@ -175,18 +175,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
175
175
  - - ! '>='
176
176
  - !ruby/object:Gem::Version
177
177
  version: '0'
178
- segments:
179
- - 0
180
- hash: -2034428678854769428
181
178
  required_rubygems_version: !ruby/object:Gem::Requirement
182
179
  none: false
183
180
  requirements:
184
181
  - - ! '>='
185
182
  - !ruby/object:Gem::Version
186
183
  version: '0'
187
- segments:
188
- - 0
189
- hash: -2034428678854769428
190
184
  requirements: []
191
185
  rubyforge_project:
192
186
  rubygems_version: 1.8.24