active_record_simple_execute 0.9.1 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0eceac39c7160f6176c6951721ab2eea654c308e6de1a5feb4ca26fd21badb9
4
- data.tar.gz: 1c134afe71506b1dea030060b44f659cd351ff1ca28bdbd95736b8e53a896a22
3
+ metadata.gz: a2bdba6b0063a89fdb67b412435ac5f1216e9d91bae6409dbc6508e4800fc1a4
4
+ data.tar.gz: bc6be6a5ce0e62d0f16f3e02f8367de49729c79e9c68e7408ea2e384861bfeca
5
5
  SHA512:
6
- metadata.gz: 6671f5c3f4cc84226b19c9613384ece86803854b0e4c943e31146aa34b49901a3afcd81ea24ccbc3437362ef71e54cdc9d58ab75877560e1ab5059b6b2a9f6cc
7
- data.tar.gz: 2fb5d735c43a0f25a57f51bfb5db6e8d946ae8a5e109f3b3776879f2f8ffe7b4ae2e37ca72d02baf2c8def971a9a30728a0f94bed26d97475484052a82d093b7
6
+ metadata.gz: 385b6d4fbe5a37e64d6f701aa91020f94a283e8445dd40726ac9974d7089705e5f1d56ad7c87b871ab6d46ad5d3ea41815e8854223d90d2228ab0033fb96e049
7
+ data.tar.gz: 8a9967b9f13f356f529a8dd479abe16d06afc02d66c04ae7fec694ed93518fe1e58789504e5acf9685201742a3138cd7cdfeba34ffb21fadf5b53b81f3199e1c
data/CHANGELOG.md CHANGED
@@ -1,11 +1,19 @@
1
1
  CHANGELOG
2
2
  ---------
3
3
 
4
- - Unreleased - [View Diff](https://github.com/westonganger/active_record_simple_execute/compare/v0.9.1...master)
4
+ - Unreleased - [View Diff](https://github.com/westonganger/active_record_simple_execute/compare/v1.1.0...master)
5
5
  * Nothing yet
6
6
 
7
- - v0.9.1 - [View Diff](https://github.com/westonganger/active_record_simple_execute/compare/v0.9.0...v0.9.1)
8
- * [#1](https://github.com/westonganger/active_sort_order/pull/1) - Utilize active_record lazy loading
7
+ - v1.1.0 - Nov 27, 2024 - [View Diff](https://github.com/westonganger/active_record_simple_execute/compare/v1.0.0...v1.1.0)
8
+ * [#9](https://github.com/westonganger/active_record_simple_execute/pull/9) - Automatically switch between `select_all` and `exec_query` based on if query is read or write, update readme examples with new knowledge around `Arel.sql` vs `sanitize_sql_array`
9
+
10
+ - v1.0.0 - Oct 17, 2024 - [View Diff](https://github.com/westonganger/active_record_simple_execute/compare/v0.9.1...v1.0.0)
11
+ * [#8](https://github.com/westonganger/active_record_simple_execute/pull/8) - Allow usage with different Active Record database connections
12
+ * [#7](https://github.com/westonganger/active_record_simple_execute/pull/7) - Drop support for Rails 5.1 and below
13
+ * [#5](https://github.com/westonganger/active_record_simple_execute/pull/5) - Switch from using Active Record `execute` method to `exec_query` method for better memory management
14
+
15
+ - v0.9.1 - Feb 13, 2023 - [View Diff](https://github.com/westonganger/active_record_simple_execute/compare/v0.9.0...v0.9.1)
16
+ * [#1](https://github.com/westonganger/active_record_simple_execute/pull/1) - Utilize active_record lazy loading
9
17
 
10
18
  - v0.9.0 - May 20, 2021 - [View Diff](https://github.com/westonganger/active_record_simple_execute/compare/1546ce4...v0.9.0)
11
19
  * Initial Release
data/README.md CHANGED
@@ -1,72 +1,112 @@
1
1
  # ActiveRecord Simple Execute
2
2
 
3
3
  <a href="https://badge.fury.io/rb/active_record_simple_execute" target="_blank"><img height="21" style='border:0px;height:21px;' border='0' src="https://badge.fury.io/rb/active_record_simple_execute.svg" alt="Gem Version"></a>
4
- <a href='https://github.com/westonganger/active_record_simple_execute/actions' target='_blank'><img src="https://github.com/westonganger/active_record_simple_execute/workflows/Tests/badge.svg" style="max-width:100%;" height='21' style='border:0px;height:21px;' border='0' alt="CI Status"></a>
4
+ <a href='https://github.com/westonganger/active_record_simple_execute/actions' target='_blank'><img src="https://github.com/westonganger/active_record_simple_execute/actions/workflows/test.yml/badge.svg?branch=master" style="max-width:100%;" height='21' style='border:0px;height:21px;' border='0' alt="CI Status"></a>
5
5
  <a href='https://rubygems.org/gems/active_record_simple_execute' target='_blank'><img height='21' style='border:0px;height:21px;' src='https://img.shields.io/gem/dt/active_record_simple_execute?color=brightgreen&label=Rubygems%20Downloads' border='0' alt='RubyGems Downloads' /></a>
6
6
 
7
7
  Sanitize and Execute your raw SQL queries in ActiveRecord and Rails with a much more intuitive and shortened syntax.
8
8
 
9
+ This gem is in response to a lack of proper documentation of best practices within Rails - I've [created a documentation PR](https://github.com/rails/rails/pull/53719) to resolve this but until this this is merged this gem seems necessary for the eco-system.
10
+
9
11
  # Installation
10
12
 
11
13
  ```ruby
12
- gem 'active_record_simple_execute'
14
+ gem "active_record_simple_execute"
13
15
  ```
14
16
 
15
17
  ## Comparison with Plain ActiveRecord
16
18
 
17
19
  As seen here using `simple_execute` is much easier to remember than all the hoops plain ActiveRecord makes you jump through.
18
20
 
19
- ### Using Simple Execute
21
+ ### Using `simple_execute`
20
22
  ```ruby
21
23
  sql_str = <<~SQL.squish
22
24
  SELECT * FROM orders
23
- FROM orders
25
+ FROM orders
24
26
  WHERE orders.company_id = :company_id AND orders.updated_by_user_id = :user_id
25
27
  SQL
26
28
 
27
- records = ActiveRecord::Base.simple_execute(sql_str, company_id: @company.id, user_id: @user.id)
29
+ records = ActiveRecord::Base.connection.simple_execute(sql_str, company_id: @company.id, user_id: @user.id)
30
+ # OR use the convenience method excluding the connection portion
31
+ # ActiveRecord::Base.simple_execute(...)
32
+ ```
33
+
34
+ ### Using original ActiveRecord `select_all` or `exec_query` method
35
+ ```ruby
36
+ sql_str = <<~SQL.squish
37
+ SELECT *
38
+ FROM orders
39
+ WHERE orders.company_id = :company_id AND orders.updated_by_user_id = :user_id
40
+ SQL
41
+
42
+ ### FOR READ OPERATIONS
43
+ sanitized_sql = Arel.sql(sql_str, company_id: @company.id, user_id: @user.id)
44
+ result = ActiveRecord::Base.connection.select_all(sanitized_sql)
45
+
46
+ ### OR FOR WRITE OPERATIONS (you probably shouldnt be doing this anyways)
47
+ ### (while exec_query is capable of read & write operations, recommended only for write operations as it affects the query cache)
48
+ sanitized_sql = ActiveRecord::Base.sanitize_sql_array([sql_str, {company_id: @company.id, user_id: @user.id}]) # Must use sanitize_sql_array, since Arel.sql is not yet compatible with `exec_query`
49
+ result = ActiveRecord::Base.connection.exec_query(sanitized_sql) # recommended only for write operations as it affects the query cache
50
+
51
+ records = result.to_a # convert the ActiveRecord::Result object into an array of hashes
52
+
53
+ return records
28
54
  ```
29
55
 
30
- ### Using Plain ActiveRecord Syntax
56
+ ### Using original ActiveRecord `execute` method
57
+
58
+ It should be noted that it is recommended to avoid all usage of `execute` and to instead use `select_all` or `exec_query` which returns generic ActiveRecord::Result objects
59
+
31
60
  ```ruby
32
61
  sql_str = <<~SQL.squish
33
- SELECT *
34
- FROM orders
62
+ SELECT *
63
+ FROM orders
35
64
  WHERE orders.company_id = :company_id AND orders.updated_by_user_id = :user_id
36
65
  SQL
37
66
 
38
- ### must use send because this method is private is Rails 5.1 only, Public in 5.0 and 5.2
39
- sanitized_sql = ActiveRecord::Base.sanitize_sql_array([sql_str, company_id: @company.id, user_id: @user.id])
67
+ # Must use sanitize_sql_array, since Arel.sql is not yet compatible with `execute`
68
+ sanitized_sql = ActiveRecord::Base.sanitize_sql_array([sql_str, {company_id: @company.id, user_id: @user.id}])
40
69
 
41
- results = ActiveRecord::Base.connection.execute(sanitized_sql)
70
+ result = ActiveRecord::Base.connection.execute(sanitized_sql)
42
71
 
43
- if defined?(PG::Result) && results.is_a?(PG::Result)
44
- records = results.to_a
45
- elsif defined?(Mysql2::Result) && results.is_a?(Mysql2::Result)
72
+ if defined?(PG::Result) && result.is_a?(PG::Result)
73
+ records = result.to_a
74
+
75
+ result.clear # to prevent memory leak
76
+
77
+ elsif defined?(Mysql2::Result) && result.is_a?(Mysql2::Result)
46
78
  records = []
47
79
 
48
- results.each do |row|
80
+ result.each do |row|
49
81
  h = {}
50
82
 
51
- results.fields.each_with_index do |field,i|
83
+ result.fields.each_with_index do |field,i|
52
84
  h[field] = row[i]
53
85
  end
54
86
 
55
87
  records << h
56
88
  end
89
+
57
90
  else
58
- records = results
91
+ records = result
59
92
  end
60
93
 
61
94
  return records
62
95
  ```
63
96
 
64
- # Contributing
97
+ # Testing
65
98
 
66
- We test multiple versions of `Rails` using the `appraisal` gem. Please use the following steps to test using `appraisal`.
99
+ ```
100
+ bundle exec rake test
101
+ ```
102
+
103
+ We can locally test different versions of Rails using `ENV['RAILS_VERSION']`
67
104
 
68
- 1. `bundle exec appraisal install`
69
- 2. `bundle exec appraisal rake test`
105
+ ```
106
+ export RAILS_VERSION=7.0
107
+ bundle install
108
+ bundle exec rake test
109
+ ```
70
110
 
71
111
  For quicker feedback during gem development or debugging feel free to use the provided `rake console` task. It is defined within the [`Rakefile`](./Rakefile).
72
112
 
data/Rakefile CHANGED
@@ -10,12 +10,3 @@ Rake::TestTask.new(:test) do |t|
10
10
  end
11
11
 
12
12
  task default: [:test]
13
-
14
- task :console do
15
- require 'active_record_simple_execute'
16
-
17
- require 'test/dummy_app/app/models/post'
18
-
19
- require 'irb'
20
- binding.irb
21
- end
@@ -1,5 +1,3 @@
1
1
  module ActiveRecordSimpleExecute
2
-
3
- VERSION = "0.9.1".freeze
4
-
2
+ VERSION = "1.1.0".freeze
5
3
  end
@@ -4,33 +4,34 @@ require "active_support/lazy_load_hooks"
4
4
 
5
5
  ActiveSupport.on_load(:active_record) do
6
6
 
7
- ActiveRecord::Base.class_eval do
8
- def self.simple_execute(sql_str, **sql_vars)
9
- ### must use send because this method is private is Rails 5.1 only, Public in 5.0 and 5.2
10
- sanitized_sql = ActiveRecord::Base.send(:sanitize_sql_array, [sql_str, **sql_vars])
11
-
12
- results = ActiveRecord::Base.connection.execute(sanitized_sql)
13
-
14
- if defined?(PG::Result) && results.is_a?(PG::Result)
15
- records = results.to_a
16
- elsif defined?(Mysql2::Result) && results.is_a?(Mysql2::Result)
17
- records = []
18
-
19
- results.each do |row|
20
- h = {}
21
-
22
- results.fields.each_with_index do |field,i|
23
- h[field] = row[i]
24
- end
25
-
26
- records << h
7
+ ActiveRecord::ConnectionAdapters::DatabaseStatements.module_eval do
8
+ def simple_execute(sql_str, **sql_vars)
9
+ readonly = sql_str.strip.downcase.start_with?("select ")
10
+
11
+ if readonly
12
+ if Rails::VERSION::STRING.to_f >= 7.1
13
+ sanitized_sql = Arel.sql(sql_str, **sql_vars)
14
+ else
15
+ sanitized_sql = ActiveRecord::Base.sanitize_sql_array([sql_str, **sql_vars])
27
16
  end
17
+ query_result = select_all(sanitized_sql)
28
18
  else
29
- records = results
19
+ # Must use sanitize_sql_array, since Arel.sql is not yet compatible with `exec_query` or `execute`, https://github.com/rails/rails/pull/53740
20
+
21
+ sanitized_sql = ActiveRecord::Base.sanitize_sql_array([sql_str, **sql_vars])
22
+ query_result = exec_query(sanitized_sql)
30
23
  end
31
24
 
25
+ records = query_result.to_a
26
+
32
27
  return records
33
28
  end
34
29
  end
35
30
 
31
+ ActiveRecord::Base.class_eval do
32
+ def self.simple_execute(sql_str, **sql_vars)
33
+ self.connection.simple_execute(sql_str, **sql_vars)
34
+ end
35
+ end
36
+
36
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_simple_execute
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Weston Ganger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-14 00:00:00.000000000 Z
11
+ date: 2024-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3.2'
19
+ version: '5.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '3.2'
26
+ version: '5.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -66,48 +66,6 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: sqlite3
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rails
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: appraisal
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
69
  - !ruby/object:Gem::Dependency
112
70
  name: warning
113
71
  requirement: !ruby/object:Gem::Requirement
@@ -150,14 +108,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
150
108
  requirements:
151
109
  - - ">="
152
110
  - !ruby/object:Gem::Version
153
- version: 1.9.3
111
+ version: '0'
154
112
  required_rubygems_version: !ruby/object:Gem::Requirement
155
113
  requirements:
156
114
  - - ">="
157
115
  - !ruby/object:Gem::Version
158
116
  version: '0'
159
117
  requirements: []
160
- rubygems_version: 3.3.7
118
+ rubygems_version: 3.4.22
161
119
  signing_key:
162
120
  specification_version: 4
163
121
  summary: Sanitize and Execute your raw SQL queries in ActiveRecord and Rails with