activerecord-simpledb-adapter 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -28,6 +28,7 @@ for creating domain:
28
28
  rake db:create
29
29
 
30
30
  model example:
31
+
31
32
  Person < ActiveRecord::Base
32
33
  columns_definition do |t|
33
34
  t.string :login
@@ -41,10 +42,20 @@ model example:
41
42
  end
42
43
  end
43
44
 
45
+ using batches:
46
+
47
+ #default batch type is update
48
+ Person.batch do
49
+ Person.create(some_valid_params)
50
+ end
51
+ #or for delete
52
+ Person.batch(:delete) do
53
+ person_item.destroy
54
+ end
55
+
44
56
  # TODO
45
57
 
46
58
  - Add some howtos to wiki
47
- - Rewrite rails model generator
48
59
 
49
60
  # LICENSE
50
61
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{activerecord-simpledb-adapter}
8
- s.version = "0.3.0"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ilia Ablamonov", "Alex Gorkunov", "Cloud Castle Inc."]
12
- s.date = %q{2011-04-21}
12
+ s.date = %q{2011-04-22}
13
13
  s.email = %q{ilia@flamefork.ru}
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE.txt",
@@ -47,6 +47,7 @@ Gem::Specification.new do |s|
47
47
  "spec/active_record/core_actions_spec.rb",
48
48
  "spec/active_record/defaults_spec.rb",
49
49
  "spec/active_record/locking_spec.rb",
50
+ "spec/active_record/offset_spec.rb",
50
51
  "spec/active_record/record_attributes_spec.rb",
51
52
  "spec/active_record/validates_spec.rb",
52
53
  "spec/active_record/where_spec.rb",
@@ -59,41 +59,45 @@ module ActiveRecord
59
59
  end
60
60
  #=======================================
61
61
  #======== BATCHES ==========
62
- def begin_batch type
62
+ def begin_batch
63
63
  raise ActiveRecord::ActiveRecordError.new("Batch already started. Finish it before start new batch") \
64
- if defined?(@batch_type) && !@batch_type.nil?
64
+ if batch_started
65
65
 
66
- @batch_type = type
66
+ @batch_started = true
67
67
  end
68
68
 
69
- def commit_batch
70
- log({:type => @batch_type, :count => batch_pool.count }.inspect, "SimpleDB Batch Operation") do
71
- case @batch_type
72
- when :update
73
- @connection.batch_put_attributes domain_name, batch_pool
74
- when :delete
75
- @connection.batch_delete_attributes domain_name, batch_pool
76
- end
77
- clear_batch
78
- end
79
- end
69
+ def commit_batch type = nil
70
+ count = batch_pool.inject(0) {|sum, (key, value)| sum += value.count }
71
+ log({:count => count }.inspect, "SimpleDB Batch Operation") do
72
+ pool = batch_pool[:update]
73
+ @connection.batch_put_attributes(domain_name, pool) \
74
+ if pool && (type.nil? || type == :update)
75
+
76
+ pool = batch_pool[:delete]
77
+ @connection.batch_delete_attributes(domain_name, pool) \
78
+ if pool && (type.nil? || type == :delete)
80
79
 
81
- def clear_batch
82
- batch_pool.clear
83
- @batch_type = nil
80
+ clear_batch type
81
+ end
84
82
  end
85
83
 
86
- def is_batch type
87
- type = :update if type == :insert
88
- defined?(@batch_type) && @batch_type == type
84
+ def clear_batch type = nil
85
+ if type.nil?
86
+ batch_pool.clear
87
+ @batch_started = false
88
+ else
89
+ batch_pool[type].clear
90
+ end
89
91
  end
90
92
 
91
93
  #===========================
92
94
  attr_reader :domain_name
95
+ attr_reader :batch_started
93
96
 
94
97
  def initialize(connection, logger, aws_key, aws_secret, domain_name, connection_parameters, config)
95
98
  super(connection, logger)
96
99
  @config = config
100
+ @batch_started = false
97
101
  @domain_name = domain_name
98
102
  @connection_parameters = [
99
103
  aws_key,
@@ -120,30 +124,30 @@ module ActiveRecord
120
124
  end
121
125
 
122
126
  def execute sql, name = nil, skip_logging = false
123
- log_title = "SimpleDB"
124
- log_title += "(batched)" if is_batch sql[:action]
127
+ log_title = "SimpleDB (#{sql[:action]})"
128
+ log_title += " *BATCHED*" if batch_started
125
129
  log sql.inspect, log_title do
126
130
  case sql[:action]
127
131
  when :insert
128
132
  item_name = get_id sql[:attrs]
129
133
  item_name = sql[:attrs][:id] = generate_id unless item_name
130
- if is_batch :update
131
- add_to_batch item_name, sql[:attrs], true
134
+ if batch_started
135
+ add_to_batch :update, item_name, sql[:attrs], true
132
136
  else
133
137
  @connection.put_attributes domain_name, item_name, sql[:attrs], true
134
138
  end
135
139
  @last_insert_id = item_name
136
140
  when :update
137
141
  item_name = get_id sql[:wheres], true
138
- if is_batch :update
139
- add_to_batch item_name, sql[:attrs], true
142
+ if batch_started
143
+ add_to_batch :update, item_name, sql[:attrs], true
140
144
  else
141
145
  @connection.put_attributes domain_name, item_name, sql[:attrs], true, sql[:wheres]
142
146
  end
143
147
  when :delete
144
148
  item_name = get_id sql[:wheres], true
145
- if is_batch :delete
146
- add_to_batch item_name
149
+ if batch_started
150
+ add_to_batch :delete, item_name
147
151
  else
148
152
  @connection.delete_attributes domain_name, item_name, nil, sql[:wheres]
149
153
  end
@@ -161,7 +165,18 @@ module ActiveRecord
161
165
  def select sql, name = nil
162
166
  log sql, "SimpleDB" do
163
167
  result = []
164
- response = @connection.select(sql, nil, true)
168
+ response = nil
169
+ if sql.offset
170
+ first_query = sql.gsub(/LIMIT\s+\d+/, "LIMIT #{sql.offset}")
171
+ first_query.gsub!(/SELECT(.+?)FROM/, "SELECT COUNT(*) FROM")
172
+ log first_query, "SimpleDB (offset partial)" do
173
+ response = @connection.select(first_query, nil, false) #without consistent read
174
+ end
175
+ puts response[:request_id]
176
+ response = @connection.select(sql, response[:request_id], true)
177
+ else
178
+ response = @connection.select(sql, nil, true)
179
+ end
165
180
  collection_name = get_collection_column_and_name(sql)
166
181
  columns = columns_definition(collection_name)
167
182
 
@@ -241,15 +256,14 @@ module ActiveRecord
241
256
 
242
257
  MAX_BATCH_ITEM_COUNT = 25
243
258
  def batch_pool
244
- @batch_pool ||=[]
259
+ @batch_pool ||= {}
245
260
  end
246
261
 
247
- def add_to_batch item_name, attributes = nil, replace = nil
248
- batch_pool << Aws::SdbInterface::Item.new(item_name, attributes, replace)
249
- if batch_pool.count == MAX_BATCH_ITEM_COUNT
250
- type = @batch_type
251
- commit_batch
252
- begin_batch type
262
+ def add_to_batch type, item_name, attributes = nil, replace = nil
263
+ type_batch_pool = (batch_pool[type] ||= [])
264
+ type_batch_pool << Aws::SdbInterface::Item.new(item_name, attributes, replace)
265
+ if type_batch_pool.count == MAX_BATCH_ITEM_COUNT
266
+ commit_batch type
253
267
  end
254
268
  end
255
269
  end
@@ -56,8 +56,8 @@ module ActiveRecord
56
56
  end
57
57
  end
58
58
 
59
- def self.batch type = :update, &block
60
- connection.begin_batch type
59
+ def self.batch &block
60
+ connection.begin_batch
61
61
  block.call
62
62
  connection.commit_batch
63
63
  end
@@ -42,7 +42,14 @@ module Arel
42
42
  collection = o.cores.first.froms.name
43
43
  o.cores.first.wheres << SqlLiteral.new("`#{@connection.collection_column_name(collection)}` = #{quote(collection)}")
44
44
  o.cores.first.froms = Table.new @connection.domain_name
45
- super
45
+ query = super
46
+ query.offset = o.offset.expr if o.offset
47
+ query.limit = o.limit.expr if o.limit
48
+ query
49
+ end
50
+
51
+ def visit_Arel_Nodes_Offset o
52
+ nil
46
53
  end
47
54
 
48
55
  def visit_Arel_Nodes_Values o
@@ -69,7 +76,11 @@ module Arel
69
76
 
70
77
  def visit_Arel_Nodes_Equality o
71
78
  right = o.right ? hash_value_quote(o.right, o.left.column) : nil
79
+ begin
72
80
  left = o.left.column.name
81
+ rescue
82
+ puts $!.backtrace
83
+ end
73
84
  {left => right}.tap { |m|
74
85
  m.override_to_s "#{visit o.left} = #{quote(o.right, o.left.column)}"
75
86
  }
@@ -112,7 +123,10 @@ module Arel
112
123
  VISITORS['simpledb'] = Arel::Visitors::SimpleDB
113
124
  end
114
125
  end
115
-
126
+ class String
127
+ attr_accessor :offset
128
+ attr_accessor :limit
129
+ end
116
130
  class Object
117
131
  def override_to_s s
118
132
  @override_to_s = s
@@ -38,17 +38,41 @@ describe "SimpleDBAdapter ActiveRecord batches operation" do
38
38
  items.each { |item| item.is_valid? }
39
39
  end
40
40
 
41
+ it "should work with usual update statments" do
42
+ count = 5
43
+ items = []
44
+ count.times { items << Person.create_valid }
45
+ Person.batch do
46
+ items.each {|item| item.update_attributes({:login => 'test'}); item.save! }
47
+ end
48
+ items = Person.all
49
+ items.count.should == count
50
+ items.each { |item| item.login.should == 'test' }
51
+ end
41
52
  #this test doesn't work with fakesdb
42
53
  it "should work with usual destroy statments" do
43
54
  count = 5
44
55
  items = []
45
56
  count.times { items << Person.create_valid }
46
- Person.batch(:delete) do
57
+ Person.batch do
47
58
  items.each {|item| item.destroy }
48
59
  end
49
60
  Person.count.should == 0
50
61
  end
51
62
 
63
+ it "should work with diferrent statments in one batch session" do
64
+ count = 5
65
+ items = []
66
+ count.times { items << Person.create_valid }
67
+ Person.batch do
68
+ items.each do |item|
69
+ item.destroy
70
+ Person.create_valid
71
+ end
72
+ end
73
+ Person.count.should == count
74
+ end
75
+
52
76
  it "should auto split to several batches when count of items more than BATCH_MAX_ITEM_COUNT" do
53
77
  count = 35
54
78
  Person.batch do
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+ #testes
3
+ describe "SimpleDBAdapter ActiveRecord offset operation" do
4
+
5
+ before :each do
6
+ ActiveRecord::Base.logger = Logger.new(STDOUT)
7
+ ActiveRecord::Base.establish_connection($config)
8
+ ActiveRecord::Base.connection.create_domain($config[:domain_name])
9
+ 50.times { |i| Person.create!({:login => "login#{i}"}) }
10
+ end
11
+
12
+ after :each do
13
+ ActiveRecord::Base.connection.delete_domain($config[:domain_name])
14
+ end
15
+
16
+ it "should work" do
17
+ Person.limit(10).offset(20).all.each_with_index do |person, i|
18
+ person.login.should == "login#{i + 20}"
19
+ end
20
+ end
21
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-simpledb-adapter
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
8
+ - 4
9
9
  - 0
10
- version: 0.3.0
10
+ version: 0.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ilia Ablamonov
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2011-04-21 00:00:00 +04:00
20
+ date: 2011-04-22 00:00:00 +04:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency
@@ -298,6 +298,7 @@ files:
298
298
  - spec/active_record/core_actions_spec.rb
299
299
  - spec/active_record/defaults_spec.rb
300
300
  - spec/active_record/locking_spec.rb
301
+ - spec/active_record/offset_spec.rb
301
302
  - spec/active_record/record_attributes_spec.rb
302
303
  - spec/active_record/validates_spec.rb
303
304
  - spec/active_record/where_spec.rb
@@ -345,6 +346,7 @@ test_files:
345
346
  - spec/active_record/core_actions_spec.rb
346
347
  - spec/active_record/defaults_spec.rb
347
348
  - spec/active_record/locking_spec.rb
349
+ - spec/active_record/offset_spec.rb
348
350
  - spec/active_record/record_attributes_spec.rb
349
351
  - spec/active_record/validates_spec.rb
350
352
  - spec/active_record/where_spec.rb