sunstone 5.0.1.4 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5ff6dca76dfaa5922dd16a451f32f8ab27d8a4ce
4
- data.tar.gz: 82dcd2022fb893e8f764e0ef032eedac6d1b8762
3
+ metadata.gz: 76178cd8049c5ecd168c637aa48c27118df5d9c4
4
+ data.tar.gz: 5e5f760949bb9cb27ccea262c5b4c7123ff9fd13
5
5
  SHA512:
6
- metadata.gz: 56c8135fad00fc2739483afdaa76eab3cf1b2fc494ffe9ee6ec83654021d8e1dd83fc51aaca35df5a505c8204c7c6bfc5aad259741034f25f66b2290616ff8d7
7
- data.tar.gz: 6d9549f7854ef738858b49ee53650920a1dc2c49b86ca9a69967b53edc5505e3c240babcb41f0dbc06574e55b8acfc63d4a6875a671e490dd9c204d0bfdd863e
6
+ metadata.gz: 185c9b5258d7c28a6f6224eb733483bab0e3a1ceeb92a61779c5923a1495a9a45b2fb27fb5fbce9733d5ce7a101d1ac753830c1e8fc59a738db54adc4e2b3248
7
+ data.tar.gz: e2e93bd51ba9a0d32d5f5e8acc6ed766a1f0ed1d9ef1b3d7df1fe5cd1ff37dc8772302c8e2d0823adcf0bd100911990583be25ad260efbeb5373dfa37b1af7c5
@@ -1,43 +1,55 @@
1
1
  language: ruby
2
-
3
- rvm:
4
- - 2.3.1
5
- - 2.4.0
6
-
7
- env:
8
- - RAILS_VERSION=v5.0.0
9
- - RAILS_VERSION=v5.0.0.1
10
- - RAILS_VERSION=v5.0.1
2
+ sudo: false
11
3
 
12
4
  cache:
13
5
  bundler: true
14
6
  directories:
15
7
  - /home/travis/.rvm/gems
16
8
 
9
+ rvm:
10
+ - 2.4.1
11
+
12
+ env:
13
+ matrix:
14
+ - RAILS_VERSION=v5.1.0 GEM=ar:mysql2
15
+ - RAILS_VERSION=v5.1.0 GEM=ar:sqlite3
16
+ - RAILS_VERSION=v5.1.0 GEM=ar:postgresql
17
+ - RAILS_VERSION=v5.1.1 GEM=ar:mysql2
18
+ - RAILS_VERSION=v5.1.1 GEM=ar:sqlite3
19
+ - RAILS_VERSION=v5.1.1 GEM=ar:postgresql
20
+ - RAILS_VERSION=v5.1.2 GEM=ar:mysql2
21
+ - RAILS_VERSION=v5.1.2 GEM=ar:sqlite3
22
+ - RAILS_VERSION=v5.1.2 GEM=ar:postgresql
23
+ - RAILS_VERSION=v5.1.3 GEM=ar:mysql2
24
+ - RAILS_VERSION=v5.1.3 GEM=ar:sqlite3
25
+ - RAILS_VERSION=v5.1.3 GEM=ar:postgresql
26
+
17
27
  addons:
18
28
  postgresql: "9.4"
19
29
 
20
30
  before_install:
21
31
  - unset BUNDLE_GEMFILE
32
+ - gem update --system
33
+ - gem update bundler
22
34
 
23
35
  install:
24
- - git clone https://github.com/rails/rails.git ~/build/rails
36
+ - git clone --branch $RAILS_VERSION https://github.com/rails/rails.git ~/build/rails
25
37
 
26
38
  before_script:
39
+ - sed -i "s/t.warning = true/t.warning = false/g" Rakefile
27
40
  - pushd ~/build/rails
28
- - git checkout $RAILS_VERSION
41
+ - git status
42
+ - sed -i "s/Gem.ruby, '-w'/Gem.ruby, '-w0'/" ~/build/rails/activerecord/Rakefile
43
+ - sed -i "s/t.warning = true/t.warning = false/g" ~/build/rails/activerecord/Rakefile
29
44
  - sed -i "/require 'support\/connection'/a \$LOAD_PATH.unshift\(File.expand_path\('~\/build\/malomalo\/sunstone\/lib'\)\)\nrequire 'sunstone'" ~/build/rails/activerecord/test/cases/helper.rb
30
45
  - cat ~/build/rails/Gemfile
31
- - "sed -i \"/group :db do/a gem 'sunstone', path: File.expand_path\\('~\\/build\\/malomalo\\/sunstone'\\)\" ~/build/rails/Gemfile"
46
+ - rm ~/build/rails/Gemfile.lock
47
+ - "sed -i \"/# Active Record./a gem 'sunstone', path: File.expand_path\\('~\\/build\\/malomalo\\/sunstone'\\)\" ~/build/rails/Gemfile"
32
48
  - cat ~/build/rails/Gemfile
33
- - bundle install --jobs=3 --retry=3
34
- - createdb activerecord_unittest
35
- - createdb activerecord_unittest2
36
- - mysql -e "create database IF NOT EXISTS activerecord_unittest DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci;"
37
- - mysql -e "create database IF NOT EXISTS activerecord_unittest2 DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci;"
38
- - gem environment gempath
49
+ - bundle update --jobs=3 --retry=3
39
50
  - popd
40
51
  - bundle install --jobs=3 --retry=3
41
- - gem environment gempath
42
52
 
43
- script: bundle exec rake test && cd ~/build/rails/activerecord && bundle exec rake test --verbose
53
+ script:
54
+ - bundle exec rake test
55
+ - cd ~/build/rails && ci/travis.rb
File without changes
@@ -28,7 +28,7 @@ module ActiveRecord
28
28
  end
29
29
  ka
30
30
  else
31
- expand(key, value)
31
+ build(table.arel_attribute(key), value)
32
32
  end
33
33
  end
34
34
  end
@@ -75,6 +75,21 @@ module ActiveRecord
75
75
  end
76
76
  end
77
77
 
78
+ def _update_record(attribute_names = self.attribute_names)
79
+ attributes_values = arel_attributes_with_values_for_update(attribute_names)
80
+ if attributes_values.empty?
81
+ rows_affected = 0
82
+ @_trigger_update_callback = true
83
+ else
84
+ rows_affected = self.class.unscoped._update_record(attributes_values, id, id_in_database)
85
+ @_trigger_update_callback = (rows_affected.is_a?(ActiveRecord::Result) ? rows_affected.rows.size : rows_affected) > 0
86
+ end
87
+
88
+ yield(self) if block_given?
89
+
90
+ rows_affected
91
+ end
92
+
78
93
  #!!!! TODO: I am duplicated from finder_methods.....
79
94
  def construct(parent, relations, seen, model_cache)
80
95
  relations.each do |key, attributes|
@@ -4,49 +4,36 @@ module ActiveRecord
4
4
  def to_sql
5
5
  @to_sql ||= begin
6
6
  relation = self
7
- connection = klass.connection
8
- visitor = if connection.visitor.is_a?(Arel::Visitors::Sunstone)
9
- Arel::Visitors::ToSql.new(connection)
10
- else
11
- connection.visitor
12
- end
13
-
7
+
14
8
  if eager_loading?
15
9
  find_with_associations { |rel| relation = rel }
16
10
  end
17
11
 
18
- binds = relation.bound_attributes
19
- binds = connection.prepare_binds_for_database(binds)
20
- binds.map! { |value| connection.quote(value) }
21
- collect = visitor.accept(relation.arel.ast, Arel::Collectors::Bind.new)
22
- collect.substitute_binds(binds).join
12
+ conn = klass.connection
13
+ conn.unprepared_statement {
14
+ conn.to_sql(relation.arel, relation.bound_attributes)
15
+ }
23
16
  end
24
17
  end
25
18
 
26
19
  def to_sar
27
20
  @to_sar ||= begin
28
21
  relation = self
29
- connection = klass.connection
30
- visitor = if connection.visitor.is_a?(Arel::Visitors::ToSql)
31
- Arel::Visitors::Sunstone.new(connection)
32
- else
33
- connection.visitor
34
- end
35
-
22
+
36
23
  if eager_loading?
37
24
  find_with_associations { |rel| relation = rel }
38
25
  end
39
26
 
40
- binds = relation.bound_attributes
41
- binds = connection.prepare_binds_for_database(binds)
42
- binds.map! { |value| connection.quote(value) }
43
- collect = visitor.accept(relation.arel.ast, Arel::Collectors::Sunstone.new)
44
- collect.compile binds
27
+ conn = klass.connection
28
+ conn.unprepared_statement {
29
+ conn.to_sar(relation.arel, relation.bound_attributes)
30
+ }
45
31
  end
46
32
  end
47
33
 
48
34
  def _update_record(values, id, id_was) # :nodoc:
49
35
  substitutes, binds = substitute_values values
36
+
50
37
  scope = @klass.unscoped
51
38
 
52
39
  if @klass.finder_needs_type_condition?
@@ -4,34 +4,29 @@ module ActiveRecord
4
4
 
5
5
  def initialize(values, sunstone=false)
6
6
  @values = values
7
- if sunstone
8
- @indexes = values.value.find_all { |thing|
7
+ @indexes = if sunstone
8
+ values.value.find_all { |thing|
9
9
  Arel::Nodes::BindParam === thing
10
10
  }
11
11
  else
12
- @indexes = values.each_with_index.find_all { |thing,i|
12
+ values.each_with_index.find_all { |thing,i|
13
13
  Arel::Nodes::BindParam === thing
14
14
  }.map(&:last)
15
15
  end
16
16
  end
17
17
 
18
18
  def sql_for(binds, connection)
19
- binds = connection.prepare_binds_for_database(binds)
19
+ casted_binds = binds.map(&:value_for_database)
20
20
 
21
21
  if connection.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter)
22
22
  @values.compile(binds)
23
23
  else
24
24
  val = @values.dup
25
- @indexes.each { |i| val[i] = connection.quote(binds.shift) }
25
+ @indexes.each { |i| val[i] = connection.quote(casted_binds.shift) }
26
26
  val.join
27
27
  end
28
28
  end
29
- end
30
29
 
31
- def self.partial_query(visitor, ast, collector)
32
- collected = visitor.accept(ast, collector)
33
- collected = collected.value if !visitor.is_a?(Arel::Visitors::Sunstone)
34
- PartialQuery.new(collected, visitor.is_a?(Arel::Visitors::Sunstone))
35
30
  end
36
31
 
37
32
  end
@@ -1,8 +1,19 @@
1
+ require "arel/collectors/sql_string"
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module Sunstone
4
6
  module DatabaseStatements
5
7
 
8
+ def to_sql(arel, binds = [])
9
+ if arel.respond_to?(:ast)
10
+ collected = Arel::Visitors::ToSql.new(self).accept(arel.ast, prepared_statements ? AbstractAdapter::SQLString.new : AbstractAdapter::BindCollector.new)
11
+ collected.compile(binds, self).freeze
12
+ else
13
+ arel.dup.freeze
14
+ end
15
+ end
16
+
6
17
  # Converts an arel AST to a Sunstone API Request
7
18
  def to_sar(arel, bvs = [])
8
19
  if arel.respond_to?(:ast)
@@ -12,10 +23,22 @@ module ActiveRecord
12
23
  arel
13
24
  end
14
25
  end
26
+
27
+ def cacheable_query(klass, arel) # :nodoc:
28
+ collected = visitor.accept(arel.ast, collector)
29
+ if prepared_statements
30
+ klass.query(collected.value)
31
+ else
32
+ if self.is_a?(ActiveRecord::ConnectionAdapters::SunstoneAPIAdapter)
33
+ StatementCache::PartialQuery.new(collected, true)
34
+ else
35
+ StatementCache::PartialQuery.new(collected.value, false)
36
+ end
37
+ end
38
+ end
15
39
 
16
40
  # Returns an ActiveRecord::Result instance.
17
41
  def select_all(arel, name = nil, binds = [], preparable: nil)
18
-
19
42
  arel, binds = binds_from_relation arel, binds
20
43
  select(arel, name, binds)
21
44
  end
@@ -69,7 +92,7 @@ module ActiveRecord
69
92
  else
70
93
  send_request.call(arel)
71
94
  end
72
-
95
+
73
96
  if sars[0].instance_variable_defined?(:@sunstone_calculation) && sars[0].instance_variable_get(:@sunstone_calculation)
74
97
  # this is a count, min, max.... yea i know..
75
98
  ActiveRecord::Result.new(['all'], [result], {:all => type_map.lookup('integer')})
@@ -79,6 +102,19 @@ module ActiveRecord
79
102
  ActiveRecord::Result.new(result.keys, [result])
80
103
  end
81
104
  end
105
+
106
+ def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
107
+ value = exec_insert(arel, name, binds, pk, sequence_name)
108
+ id_value || last_inserted_id(value)
109
+ end
110
+
111
+ def update(arel, name = nil, binds = [])
112
+ exec_update(arel, name, binds)
113
+ end
114
+
115
+ def delete(arel, name = nil, binds = [])
116
+ exec_delete(arel, name, binds)
117
+ end
82
118
 
83
119
  def last_inserted_id(result)
84
120
  row = result.rows.first
@@ -103,7 +103,7 @@ module ActiveRecord
103
103
 
104
104
  # Executes the delete statement and returns the number of rows affected.
105
105
  def delete(arel, name = nil, binds = [])
106
- r = exec_delete(to_sql(arel, binds), name, binds)
106
+ r = exec_delete(arel, name, binds)
107
107
  r.rows.first.to_i
108
108
  end
109
109
 
@@ -173,8 +173,8 @@ module ActiveRecord
173
173
  # If the next id was calculated in advance (as in Oracle), it should be
174
174
  # passed in as +id_value+.
175
175
  def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
176
- sql, binds, pk, sequence_name = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds)
177
- value = exec_insert(sql, name, binds, pk, sequence_name)
176
+ sql, binds, pk, sequence_name = sql_for_insert(arel, pk, id_value, sequence_name, binds)
177
+ exec_insert(sql, name, binds, pk, sequence_name)
178
178
  end
179
179
  alias create insert
180
180
 
@@ -1004,7 +1004,7 @@ module Arel
1004
1004
  # end
1005
1005
 
1006
1006
  def inject_join list, collector, join_str
1007
- list.each_with_index.inject([]) { |c, (x,i)|
1007
+ list.each_with_index.inject([]) { |c, (x,_)|
1008
1008
  c + [visit(x, collector)]
1009
1009
  }
1010
1010
  end
@@ -128,7 +128,7 @@ module Sunstone
128
128
  elsif Thread.current[:sunstone_request_sent]
129
129
  log_mess = request.path.split('?', 2)
130
130
  log_mess += Thread.current[:sunstone_request_sent].path.split('?', 2)
131
- raise <<~MSG
131
+ raise ActiveRecord::StatementInvalid, <<~MSG
132
132
  Cannot send multiple request in a transaction.
133
133
 
134
134
  Trying to send:
@@ -139,7 +139,7 @@ module Sunstone
139
139
  MSG
140
140
  else
141
141
  log_mess = request.path.split('?', 2)
142
- raise <<~MSG
142
+ raise ActiveRecord::StatementInvalid, <<~MSG
143
143
  Cannot send multiple request in a transaction.
144
144
 
145
145
  Trying to send:
@@ -1,3 +1,3 @@
1
1
  module Sunstone
2
- VERSION = '5.0.1.4'
2
+ VERSION = '5.1.0'
3
3
  end
@@ -29,11 +29,10 @@ Gem::Specification.new do |s|
29
29
  s.add_development_dependency 'rgeo'
30
30
  s.add_development_dependency 'simplecov'
31
31
  s.add_development_dependency 'byebug'
32
- s.add_development_dependency 'activesupport', '~> 5.0.1'
32
+ s.add_development_dependency 'activesupport', '~> 5.1.0'
33
33
 
34
34
  # Runtime
35
35
  s.add_runtime_dependency 'msgpack'
36
36
  s.add_runtime_dependency 'cookie_store'
37
- s.add_runtime_dependency 'arel', '~> 7.0'
38
- s.add_runtime_dependency 'activerecord', '~> 5.0.1'
37
+ s.add_runtime_dependency 'activerecord', '~> 5.1.0'
39
38
  end
@@ -28,6 +28,16 @@ class ActiveRecord::QueryTest < ActiveSupport::TestCase
28
28
 
29
29
  assert_nil Ship.first
30
30
  end
31
+
32
+ test '::first!' do
33
+ webmock(:get, "/ships", { limit: 1, order: [{id: :asc}] }).to_return({
34
+ body: [].to_json
35
+ })
36
+
37
+ assert_raises ActiveRecord::RecordNotFound do
38
+ Ship.first!
39
+ end
40
+ end
31
41
 
32
42
  test '::last' do
33
43
  webmock(:get, "/ships", { limit: 1, order: [{id: :desc}] }).to_return({
@@ -94,13 +104,13 @@ class ActiveRecord::QueryTest < ActiveSupport::TestCase
94
104
  end
95
105
 
96
106
  test '#to_sar' do
97
- assert_equal "/ships?%81%A5where%81%A2id%A210", Ship.where(:id => 10).to_sar.path
107
+ assert_equal "/ships?%81%A5where%81%A2id%0A", Ship.where(:id => 10).to_sar.path
98
108
  end
99
109
 
100
110
  test 'bind params get eaten when joining' do
101
111
  uri = URI(Ship.joins(:ownerships).where({ ownerships: { id: 1 } }).to_sar.path)
102
112
  query = MessagePack.unpack(CGI.unescape(uri.query))
103
- assert_equal({"where"=>{"ownerships"=>{"id"=>{"eq"=>"1"}}}}, query)
113
+ assert_equal({"where"=>{"ownerships"=>{"id"=>{"eq"=>1}}}}, query)
104
114
  end
105
115
 
106
116
  end
@@ -68,7 +68,6 @@ class ActiveSupport::TestCase
68
68
  query = deep_transform_query(query) if query
69
69
 
70
70
  stub_request(method, /^#{ActiveRecord::Base.connection.instance_variable_get(:@connection).url}/).with do |req|
71
- # puts "REQ\t#{unpack(req.uri.query.sub(/=true$/, ''))}" if req&.uri&.path == path && req.uri.query
72
71
  if query
73
72
  req&.uri&.path == path && req.uri.query && unpack(req.uri.query.sub(/=true$/, '')) == query
74
73
  else
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sunstone
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.1.4
4
+ version: 5.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Bracy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-20 00:00:00.000000000 Z
11
+ date: 2017-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -184,14 +184,14 @@ dependencies:
184
184
  requirements:
185
185
  - - "~>"
186
186
  - !ruby/object:Gem::Version
187
- version: 5.0.1
187
+ version: 5.1.0
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - "~>"
193
193
  - !ruby/object:Gem::Version
194
- version: 5.0.1
194
+ version: 5.1.0
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: msgpack
197
197
  requirement: !ruby/object:Gem::Requirement
@@ -220,34 +220,20 @@ dependencies:
220
220
  - - ">="
221
221
  - !ruby/object:Gem::Version
222
222
  version: '0'
223
- - !ruby/object:Gem::Dependency
224
- name: arel
225
- requirement: !ruby/object:Gem::Requirement
226
- requirements:
227
- - - "~>"
228
- - !ruby/object:Gem::Version
229
- version: '7.0'
230
- type: :runtime
231
- prerelease: false
232
- version_requirements: !ruby/object:Gem::Requirement
233
- requirements:
234
- - - "~>"
235
- - !ruby/object:Gem::Version
236
- version: '7.0'
237
223
  - !ruby/object:Gem::Dependency
238
224
  name: activerecord
239
225
  requirement: !ruby/object:Gem::Requirement
240
226
  requirements:
241
227
  - - "~>"
242
228
  - !ruby/object:Gem::Version
243
- version: 5.0.1
229
+ version: 5.1.0
244
230
  type: :runtime
245
231
  prerelease: false
246
232
  version_requirements: !ruby/object:Gem::Requirement
247
233
  requirements:
248
234
  - - "~>"
249
235
  - !ruby/object:Gem::Version
250
- version: 5.0.1
236
+ version: 5.1.0
251
237
  description: A library for interacting with REST APIs. Similar to ActiveResource
252
238
  email:
253
239
  - jonbracy@gmail.com
@@ -261,7 +247,7 @@ files:
261
247
  - Gemfile
262
248
  - LICENSE
263
249
  - README.md
264
- - Rakefile.rb
250
+ - Rakefile
265
251
  - TODO.md
266
252
  - ext/active_record/associations.rb
267
253
  - ext/active_record/associations/association.rb
@@ -337,7 +323,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
337
323
  version: '0'
338
324
  requirements: []
339
325
  rubyforge_project:
340
- rubygems_version: 2.6.8
326
+ rubygems_version: 2.6.11
341
327
  signing_key:
342
328
  specification_version: 4
343
329
  summary: A library for interacting with REST APIs