activerecord-tablefree 3.0.1 → 3.1.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.
@@ -1,9 +1,9 @@
1
- #require 'bundler'
1
+ # require 'bundler'
2
2
  begin
3
3
  Bundler.setup(:default, :development)
4
4
  rescue Bundler::BundlerError => e
5
- $stderr.puts e.message
6
- $stderr.puts "Run `bundle install` to install missing gems"
5
+ warn e.message
6
+ warn 'Run `bundle install` to install missing gems'
7
7
  exit e.status_code
8
8
  end
9
9
 
@@ -15,11 +15,11 @@ module NavigationHelpers
15
15
  else
16
16
  begin
17
17
  page_name =~ /the (.*) page/
18
- path_components = $1.split(/\s+/)
19
- self.send(path_components.push('path').join('_').to_sym)
18
+ path_components = Regexp.last_match(1).split(/\s+/)
19
+ send(path_components.push('path').join('_').to_sym)
20
20
  rescue Object => e
21
- raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
22
- "Now, go and add a mapping in #{__FILE__}"
21
+ raise "Can't find mapping from \"#{page_name}\" to a path.\n" \
22
+ "Now, go and add a mapping in #{__FILE__}"
23
23
  end
24
24
  end
25
25
  end
@@ -1,7 +1,7 @@
1
1
  PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..')).freeze
2
2
  APP_NAME = 'testapp'.freeze
3
- BUNDLE_ENV_VARS = %w(RUBYOPT BUNDLE_PATH BUNDLE_BIN_PATH BUNDLE_GEMFILE)
4
- ORIGINAL_BUNDLE_VARS = Hash[ENV.select{ |key,value| BUNDLE_ENV_VARS.include?(key) }]
3
+ BUNDLE_ENV_VARS = %w[RUBYOPT BUNDLE_PATH BUNDLE_BIN_PATH BUNDLE_GEMFILE].freeze
4
+ ORIGINAL_BUNDLE_VARS = Hash[ENV.select { |key, _value| BUNDLE_ENV_VARS.include?(key) }]
5
5
 
6
6
  ENV['RAILS_ENV'] = 'test'
7
7
 
@@ -32,7 +32,7 @@ module RailsCommandHelpers
32
32
  end
33
33
 
34
34
  def framework_major_version
35
- framework_version.split(".").first.to_i
35
+ framework_version.split('.').first.to_i
36
36
  end
37
37
 
38
38
  def new_application_command(app_name)
@@ -40,13 +40,12 @@ module RailsCommandHelpers
40
40
  end
41
41
 
42
42
  def generator_command
43
- framework_major_version >= 3 ? "rails generate" : "script/generate"
43
+ framework_major_version >= 3 ? 'rails generate' : 'script/generate'
44
44
  end
45
45
 
46
46
  def runner_command
47
- framework_major_version >= 3 ? "rails runner" : "script/runner"
47
+ framework_major_version >= 3 ? 'rails runner' : 'script/runner'
48
48
  end
49
-
50
49
  end
51
50
 
52
51
  World(RailsCommandHelpers)
@@ -7,11 +7,11 @@ module HtmlSelectorsHelpers
7
7
  #
8
8
  def selector_for(locator)
9
9
  case locator
10
- when "the page"
11
- "html > body"
10
+ when 'the page'
11
+ 'html > body'
12
12
  else
13
- raise "Can't find mapping from \"#{locator}\" to a selector.\n" +
14
- "Now, go and add a mapping in #{__FILE__}"
13
+ raise "Can't find mapping from \"#{locator}\" to a selector.\n" \
14
+ "Now, go and add a mapping in #{__FILE__}"
15
15
  end
16
16
  end
17
17
  end
@@ -1,8 +1,13 @@
1
- # See #ActiveRecord::Tablefree
1
+ require 'cgi'
2
+ require 'active_record'
3
+
2
4
  require 'activerecord-tablefree/version'
5
+ require 'activerecord-tablefree/cast_type'
6
+ require 'activerecord-tablefree/schema_cache'
7
+ require 'activerecord-tablefree/connection'
8
+ require 'activerecord-tablefree/transaction'
3
9
 
4
10
  module ActiveRecord
5
-
6
11
  # = ActiveRecord::Tablefree
7
12
  #
8
13
  # Allow classes to behave like ActiveRecord models, but without an associated
@@ -29,26 +34,24 @@ module ActiveRecord
29
34
  # end
30
35
  #
31
36
  module Tablefree
32
- require 'active_record'
33
37
 
34
38
  class NoDatabase < StandardError; end
35
39
  class Unsupported < StandardError; end
36
40
 
37
- def self.included( base ) #:nodoc:
41
+ def self.included(base) #:nodoc:
38
42
  base.send :extend, ActsMethods
39
43
  end
40
44
 
41
45
  module ActsMethods #:nodoc:
42
-
43
46
  # A model that needs to be tablefree will call this method to indicate
44
47
  # it.
45
- def has_no_table(options = {:database => :fail_fast})
46
- raise ArgumentError.new("Invalid database option '#{options[:database]}'") unless [:fail_fast, :pretend_success].member? options[:database]
48
+ def has_no_table(options = { database: :fail_fast })
49
+ raise ArgumentError, "Invalid database option '#{options[:database]}'" unless %i[fail_fast pretend_success].member? options[:database]
47
50
  # keep our options handy
48
51
  class_attribute :tablefree_options
49
52
  self.tablefree_options = {
50
- :database => options[:database],
51
- :columns_hash => {}
53
+ database: options[:database],
54
+ columns_hash: {}
52
55
  }
53
56
 
54
57
  # extend
@@ -66,20 +69,18 @@ module ActiveRecord
66
69
  def tablefree?
67
70
  false
68
71
  end
69
-
70
72
  end
71
73
 
72
74
  module SingletonMethods
73
-
74
75
  # Used internally by ActiveRecord 5. This is the special hook that makes everything else work.
75
76
  def load_schema!
76
77
  @columns_hash = tablefree_options[:columns_hash].except(*ignored_columns)
77
78
  @columns_hash.each do |name, column|
78
79
  define_attribute(
79
- name,
80
- connection.lookup_cast_type_from_column(column),
81
- default: column.default,
82
- user_provided_default: false
80
+ name,
81
+ connection.lookup_cast_type_from_column(column),
82
+ default: column.default,
83
+ user_provided_default: false
83
84
  )
84
85
  end
85
86
  end
@@ -97,12 +98,12 @@ module ActiveRecord
97
98
  end
98
99
  end
99
100
 
100
- def destroy(*args)
101
+ def destroy(*_args)
101
102
  case tablefree_options[:database]
102
103
  when :pretend_success
103
- self.new()
104
+ new
104
105
  when :fail_fast
105
- raise NoDatabase.new("Can't #destroy on Tablefree class")
106
+ raise NoDatabase, "Can't #destroy on Tablefree class"
106
107
  end
107
108
  end
108
109
 
@@ -111,33 +112,32 @@ module ActiveRecord
111
112
  when :pretend_success
112
113
  []
113
114
  when :fail_fast
114
- raise NoDatabase.new("Can't #destroy_all on Tablefree class")
115
+ raise NoDatabase, "Can't #destroy_all on Tablefree class"
115
116
  end
116
117
  end
117
118
 
118
119
  case ActiveRecord::VERSION::MAJOR
119
120
  when 5
120
- def find_by_sql(*args)
121
+ def find_by_sql(*_args)
121
122
  case tablefree_options[:database]
122
123
  when :pretend_success
123
124
  []
124
125
  when :fail_fast
125
- raise NoDatabase.new("Can't #find_by_sql on Tablefree class")
126
+ raise NoDatabase, "Can't #find_by_sql on Tablefree class"
126
127
  end
127
-
128
128
  end
129
129
  else
130
- raise Unsupported.new("Unsupported ActiveRecord version")
130
+ raise Unsupported, 'Unsupported ActiveRecord version'
131
131
  end
132
132
 
133
- def transaction(&block)
134
- # case tablefree_options[:database]
135
- # when :pretend_success
136
- @_current_transaction_records ||= []
137
- yield
138
- # when :fail_fast
139
- # raise NoDatabase.new("Can't #transaction on Tablefree class")
140
- # end
133
+ def transaction
134
+ # case tablefree_options[:database]
135
+ # when :pretend_success
136
+ @_current_transaction_records ||= []
137
+ yield
138
+ # when :fail_fast
139
+ # raise NoDatabase.new("Can't #transaction on Tablefree class")
140
+ # end
141
141
  end
142
142
 
143
143
  def tablefree?
@@ -150,123 +150,43 @@ module ActiveRecord
150
150
  end
151
151
 
152
152
  module ClassMethods
153
-
154
153
  def from_query_string(query_string)
155
- unless query_string.blank?
154
+ if query_string.blank?
155
+ new
156
+ else
156
157
  params = query_string.split('&').collect do |chunk|
157
158
  next if chunk.empty?
158
159
  key, value = chunk.split('=', 2)
159
160
  next if key.empty?
160
161
  value = value.nil? ? nil : CGI.unescape(value)
161
- [ CGI.unescape(key), value ]
162
+ [CGI.unescape(key), value]
162
163
  end.compact.to_h
163
164
 
164
165
  new(params)
165
- else
166
- new
167
166
  end
168
167
  end
169
168
 
170
169
  def connection
171
- conn = Object.new()
172
- def conn.quote_table_name(*_args)
173
- ""
174
- end
175
- def conn.quote_column_name(*_args)
176
- ""
177
- end
178
- def conn.substitute_at(*_args)
179
- nil
180
- end
181
- def conn.schema_cache(*_args)
182
- schema_cache = Object.new()
183
- def schema_cache.columns_hash(*_args)
184
- Hash.new()
185
- end
186
- schema_cache
187
- end
188
- # Fixes Issue #17. https://github.com/softace/activerecord-tablefree/issues/17
189
- # The following method is from the ActiveRecord gem: /lib/active_record/connection_adapters/abstract/database_statements.rb .
190
- # Sanitizes the given LIMIT parameter in order to prevent SQL injection.
191
- #
192
- # The +limit+ may be anything that can evaluate to a string via #to_s. It
193
- # should look like an integer, or a comma-delimited list of integers, or
194
- # an Arel SQL literal.
195
- #
196
- # Returns Integer and Arel::Nodes::SqlLiteral limits as is.
197
- # Returns the sanitized limit parameter, either as an integer, or as a
198
- # string which contains a comma-delimited list of integers.
199
- def conn.sanitize_limit(limit)
200
- if limit.is_a?(Integer) || limit.is_a?(Arel::Nodes::SqlLiteral)
201
- limit
202
- elsif limit.to_s.include?(',')
203
- Arel.sql limit.to_s.split(',').map{ |i| Integer(i) }.join(',')
204
- else
205
- Integer(limit)
206
- end
207
- end
208
-
209
- # Called by bound_attributes in /lib/active_record/relation/query_methods.rb
210
- # Returns a SQL string with the from, join, where, and having clauses, in addition to the limit and offset.
211
- def conn.combine_bind_parameters(**_args)
212
- ""
213
- end
214
-
215
- def conn.lookup_cast_type_from_column(*_args)
216
- lct = Object.new
217
- def lct.assert_valid_value(*_args)
218
- true
219
- end
220
- # Needed for Rails 5.0
221
- def lct.serialize(args)
222
- args
223
- end
224
- def lct.deserialize(args)
225
- args
226
- end
227
- def lct.cast(args)
228
- args
229
- end
230
- def lct.changed?(*_args)
231
- false
232
- end
233
- def lct.changed_in_place?(*_args)
234
- false
235
- end
236
- lct
237
- end
238
-
239
- # This is used in the StatementCache object. It returns an object that
240
- # can be used to query the database repeatedly.
241
- def conn.cacheable_query(arel) # :nodoc:
242
- if prepared_statements
243
- ActiveRecord::StatementCache.query visitor, arel.ast
244
- else
245
- ActiveRecord::StatementCache.partial_query visitor, arel.ast, collector
246
- end
247
- end
248
- conn
170
+ @_connection ||= ActiveRecord::Tablefree::Connection.new
249
171
  end
250
-
251
172
  end
252
173
 
253
174
  module InstanceMethods
254
-
255
175
  def to_query_string(prefix = nil)
256
- attributes.to_a.collect{|(name,value)| escaped_var_name(name, prefix) + "=" + escape_for_url(value) if value }.compact.join("&")
176
+ attributes.to_a.collect { |(name, value)| escaped_var_name(name, prefix) + '=' + escape_for_url(value) if value }.compact.join('&')
257
177
  end
258
178
 
259
179
  def quote_value(_value, _column = nil)
260
- ""
180
+ ''
261
181
  end
262
182
 
263
- %w(create create_record _create_record update update_record _update_record).each do |method_name|
264
- define_method(method_name) do |*args|
183
+ %w[create create_record _create_record update update_record _update_record].each do |method_name|
184
+ define_method(method_name) do |*_args|
265
185
  case self.class.tablefree_options[:database]
266
186
  when :pretend_success
267
187
  true
268
188
  when :fail_fast
269
- raise NoDatabase.new("Can't ##{method_name} a Tablefree object")
189
+ raise NoDatabase, "Can't ##{method_name} a Tablefree object"
270
190
  end
271
191
  end
272
192
  end
@@ -277,42 +197,39 @@ module ActiveRecord
277
197
  @destroyed = true
278
198
  freeze
279
199
  when :fail_fast
280
- raise NoDatabase.new("Can't #destroy a Tablefree object")
200
+ raise NoDatabase, "Can't #destroy a Tablefree object"
281
201
  end
282
202
  end
283
203
 
284
- def reload(*args)
204
+ def reload(*_args)
285
205
  case self.class.tablefree_options[:database]
286
206
  when :pretend_success
287
207
  self
288
208
  when :fail_fast
289
- raise NoDatabase.new("Can't #reload a Tablefree object")
209
+ raise NoDatabase, "Can't #reload a Tablefree object"
290
210
  end
291
211
  end
292
212
 
293
- def add_to_transaction
294
- end
213
+ def add_to_transaction; end
295
214
 
296
215
  private
297
216
 
298
- def escaped_var_name(name, prefix = nil)
299
- prefix ? "#{URI.escape(prefix)}[#{URI.escape(name)}]" : URI.escape(name)
300
- end
217
+ def escaped_var_name(name, prefix = nil)
218
+ prefix ? "#{CGI.escape(prefix)}[#{CGI.escape(name)}]" : CGI.escape(name)
219
+ end
301
220
 
302
- def escape_for_url(value)
303
- case value
304
- when true then "1"
305
- when false then "0"
306
- when nil then ""
307
- else URI.escape(value.to_s)
308
- end
309
- rescue
310
- ""
221
+ def escape_for_url(value)
222
+ case value
223
+ when true then '1'
224
+ when false then '0'
225
+ when nil then ''
226
+ else CGI.escape(value.to_s)
311
227
  end
312
-
228
+ rescue
229
+ ''
230
+ end
313
231
  end
314
-
315
232
  end
316
233
  end
317
234
 
318
- ActiveRecord::Base.send( :include, ActiveRecord::Tablefree )
235
+ ActiveRecord::Base.send(:include, ActiveRecord::Tablefree)
@@ -0,0 +1,28 @@
1
+ module ActiveRecord::Tablefree
2
+ class CastType
3
+ def assert_valid_value(*_args)
4
+ true
5
+ end
6
+
7
+ # Needed for Rails 5.0
8
+ def serialize(args)
9
+ args
10
+ end
11
+
12
+ def deserialize(args)
13
+ args
14
+ end
15
+
16
+ def cast(args)
17
+ args
18
+ end
19
+
20
+ def changed?(*_args)
21
+ false
22
+ end
23
+
24
+ def changed_in_place?(*_args)
25
+ false
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,70 @@
1
+ module ActiveRecord::Tablefree
2
+ class Connection
3
+ def quote_table_name(*_args)
4
+ ''
5
+ end
6
+
7
+ def quote_column_name(*_args)
8
+ ''
9
+ end
10
+
11
+ def substitute_at(*_args)
12
+ nil
13
+ end
14
+
15
+ def schema_cache(*_args)
16
+ @_schema_cache ||= ActiveRecord::Tablefree::SchemaCache.new
17
+ end
18
+
19
+ # Fixes Issue #17. https://github.com/softace/activerecord-tablefree/issues/17
20
+ # The following method is from the ActiveRecord gem:
21
+ # /lib/active_record/connection_adapters/abstract/database_statements.rb .
22
+ # Sanitizes the given LIMIT parameter in order to prevent SQL injection.
23
+ #
24
+ # The +limit+ may be anything that can evaluate to a string via #to_s. It
25
+ # should look like an integer, or a comma-delimited list of integers, or
26
+ # an Arel SQL literal.
27
+ #
28
+ # Returns Integer and Arel::Nodes::SqlLiteral limits as is.
29
+ # Returns the sanitized limit parameter, either as an integer, or as a
30
+ # string which contains a comma-delimited list of integers.
31
+ def sanitize_limit(limit)
32
+ if limit.is_a?(Integer) || limit.is_a?(Arel::Nodes::SqlLiteral)
33
+ limit
34
+ elsif limit.to_s.include?(',')
35
+ Arel.sql limit.to_s.split(',').map { |i| Integer(i) }.join(',')
36
+ else
37
+ Integer(limit)
38
+ end
39
+ end
40
+
41
+ # Called by bound_attributes in /lib/active_record/relation/query_methods.rb
42
+ # Returns a SQL string with the from, join, where, and having clauses,
43
+ # in addition to the limit and offset.
44
+ def combine_bind_parameters(**_args)
45
+ ''
46
+ end
47
+
48
+ def lookup_cast_type_from_column(*_args)
49
+ @_cast_type ||= ActiveRecord::Tablefree::CastType.new
50
+ end
51
+
52
+ def current_transaction
53
+ @_current_transaction ||= ActiveRecord::Tablefree::Transaction.new
54
+ end
55
+
56
+ def execute(*_args)
57
+ {}
58
+ end
59
+
60
+ # This is used in the StatementCache object. It returns an object that
61
+ # can be used to query the database repeatedly.
62
+ def cacheable_query(arel) # :nodoc:
63
+ if prepared_statements
64
+ ActiveRecord::StatementCache.query visitor, arel.ast
65
+ else
66
+ ActiveRecord::StatementCache.partial_query visitor, arel.ast, collector
67
+ end
68
+ end
69
+ end
70
+ end