arel_toolkit 0.4.1 → 0.4.2

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: 1e58b08598fbaed4b77466a70f23818f8f41c6a82657c3a7bed28541b06f3c01
4
- data.tar.gz: a16bfdb439a31fece794eaa6d54092ad0edb52e3e463957abf96db8259e6e0c9
3
+ metadata.gz: ff1c5420d091c5e2df0fb1bbc6350fb9a7454893855c6091eb25b3d7ae5ba46c
4
+ data.tar.gz: 1b98b3c7b2bc7488af08cc9b58d6f1b2d92dfe0a3cda7f7bdb01a61e2fa1a193
5
5
  SHA512:
6
- metadata.gz: ee280959b83a74d0f633442d488218aa36ea88bba7f1d2783ae9848bcb1904055e28db1d71a66bd187360e0bf4cebce1da0c248284a6bf28c3476c6a206d4d98
7
- data.tar.gz: 7b571f3ed5301b57053039fd1088a698d4e3f7bb355bda276477254a33a5b49dcee64abf0381268df1408ebf7d35a593ec14757b5ea4998c898c71e978f41b5b
6
+ metadata.gz: 772871812878e1ac7c4989a4d14c2414675b327ed5b1b5a140841bb699a0f590fc7f04f3ea1de6dfefb0166541b5260c7a01360d41869948e8a1a7b7d77cd6b6
7
+ data.tar.gz: b996389ef2016ba70449d44491496882ff246e01e43801e086b1db4831901acfe7e4a10c5df5a323e5167b74f9333dc5ff8d62e6d66b61bf3da84a650c978a06
@@ -47,6 +47,8 @@ jobs:
47
47
  - name: Rebase
48
48
  if: matrix.rebase
49
49
  run: |
50
+ git config --global user.email "ci@github.com"
51
+ git config --global user.name "GitHub CI"
50
52
  git fetch origin $GITHUB_REF
51
53
  git rebase $GITHUB_SHA
52
54
 
data/.gitignore CHANGED
@@ -20,4 +20,5 @@
20
20
  *.temp
21
21
  # emacs
22
22
  TAGS
23
- .#*
23
+ .#*
24
+ stackprof.json
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.4.2](https://github.com/mvgijssel/arel_toolkit/tree/v0.4.2) (2020-01-08)
4
+
5
+ [Full Changelog](https://github.com/mvgijssel/arel_toolkit/compare/v0.4.1...v0.4.2)
6
+
7
+ **Breaking changes:**
8
+
9
+ - Remove path, inline visit and improve recursion for improved performance [\#152](https://github.com/mvgijssel/arel_toolkit/pull/152) ([Willianvdv](https://github.com/Willianvdv))
10
+
11
+ **Implemented enhancements:**
12
+
13
+ - Validate whether setting a session variable transformation does the right thing [\#155](https://github.com/mvgijssel/arel_toolkit/issues/155)
14
+ - Add ability to mutate nodes with precomputed Arel::Nodes::Enhance [\#158](https://github.com/mvgijssel/arel_toolkit/pull/158) ([mvgijssel](https://github.com/mvgijssel))
15
+
3
16
  ## [v0.4.1](https://github.com/mvgijssel/arel_toolkit/tree/v0.4.1) (2019-11-13)
4
17
 
5
18
  [Full Changelog](https://github.com/mvgijssel/arel_toolkit/compare/v0.4.0...v0.4.1)
@@ -18,6 +31,7 @@
18
31
 
19
32
  **Fixed bugs:**
20
33
 
34
+ - Bundle install fails with missing arel\_toolkit/pg\_result\_init [\#148](https://github.com/mvgijssel/arel_toolkit/issues/148)
21
35
  - Handle column reference with 3 \(or more\) fields [\#145](https://github.com/mvgijssel/arel_toolkit/issues/145)
22
36
  - Error when aliasing a range select [\#144](https://github.com/mvgijssel/arel_toolkit/issues/144)
23
37
  - Make sure the method signatures of PostgreSQLAdapter match [\#122](https://github.com/mvgijssel/arel_toolkit/issues/122)
@@ -30,15 +44,15 @@
30
44
 
31
45
  **Implemented enhancements:**
32
46
 
47
+ - Replace Arel::Nodes::UnboundColumnReference with Arel::Nodes::UnqualifiedColumn [\#91](https://github.com/mvgijssel/arel_toolkit/issues/91)
48
+ - Add brakeman to check for security vulnerabilities [\#10](https://github.com/mvgijssel/arel_toolkit/issues/10)
33
49
  - Rename Arel.transformer to Arel.enhance [\#111](https://github.com/mvgijssel/arel_toolkit/issues/111)
34
50
  - Ability to query an Arel transformer tree [\#103](https://github.com/mvgijssel/arel_toolkit/issues/103)
35
51
  - Implement PREPARE and DEALLOCATE statement [\#101](https://github.com/mvgijssel/arel_toolkit/issues/101)
36
- - Replace Arel::Nodes::UnboundColumnReference with Arel::Nodes::UnqualifiedColumn [\#91](https://github.com/mvgijssel/arel_toolkit/issues/91)
37
52
  - Create Arel transformer class to safely and easily mutate an Arel AST [\#89](https://github.com/mvgijssel/arel_toolkit/issues/89)
38
53
  - Test and verify compatibility with Arel extension gems [\#81](https://github.com/mvgijssel/arel_toolkit/issues/81)
39
54
  - Automatically load Railtie when gem is included in Rails [\#66](https://github.com/mvgijssel/arel_toolkit/issues/66)
40
55
  - Create remove ActiveRecord specifics transformer [\#63](https://github.com/mvgijssel/arel_toolkit/issues/63)
41
- - Add brakeman to check for security vulnerabilities [\#10](https://github.com/mvgijssel/arel_toolkit/issues/10)
42
56
 
43
57
  **Fixed bugs:**
44
58
 
@@ -79,6 +93,7 @@
79
93
  **Implemented enhancements:**
80
94
 
81
95
  - Handle op in pg\_query\_visitor\#visit\_SelectStmt [\#38](https://github.com/mvgijssel/arel_toolkit/issues/38)
96
+ - Introduce Guard [\#5](https://github.com/mvgijssel/arel_toolkit/issues/5)
82
97
  - Add WITH, OVERRIDING and RETURNING to INSERT [\#28](https://github.com/mvgijssel/arel_toolkit/issues/28)
83
98
  - Return \(Select|Update|Insert|Delete\)Manager instead of \(Select|Update|Insert|Delete\)Statement [\#25](https://github.com/mvgijssel/arel_toolkit/issues/25)
84
99
  - Implement UNION in sql\_to\_arel [\#24](https://github.com/mvgijssel/arel_toolkit/issues/24)
@@ -87,10 +102,8 @@
87
102
  - Implement pg\_query\_visitor method for INSERT [\#21](https://github.com/mvgijssel/arel_toolkit/issues/21)
88
103
  - Implement pg\_query\_visitor method for UPDATE [\#20](https://github.com/mvgijssel/arel_toolkit/issues/20)
89
104
  - Implement all the visitor methods in PgQueryVisitor for SELECT statements [\#11](https://github.com/mvgijssel/arel_toolkit/issues/11)
90
- - Introduce Guard [\#5](https://github.com/mvgijssel/arel_toolkit/issues/5)
91
105
  - 22/implement delete [\#30](https://github.com/mvgijssel/arel_toolkit/pull/30) ([mvgijssel](https://github.com/mvgijssel))
92
106
  - Added WITH, OVERRIDING and RETURINING to INSERT [\#29](https://github.com/mvgijssel/arel_toolkit/pull/29) ([mvgijssel](https://github.com/mvgijssel))
93
- - Initial UPDATE\_STMT [\#27](https://github.com/mvgijssel/arel_toolkit/pull/27) ([mvgijssel](https://github.com/mvgijssel))
94
107
  - Added badges to README \(and fix setup\) [\#3](https://github.com/mvgijssel/arel_toolkit/pull/3) ([mvgijssel](https://github.com/mvgijssel))
95
108
  - Configure codeclimate [\#2](https://github.com/mvgijssel/arel_toolkit/pull/2) ([mvgijssel](https://github.com/mvgijssel))
96
109
  - Updated travis file [\#1](https://github.com/mvgijssel/arel_toolkit/pull/1) ([mvgijssel](https://github.com/mvgijssel))
@@ -101,9 +114,9 @@
101
114
 
102
115
  **Closed issues:**
103
116
 
104
- - Create issues for unknown branches in pg\_query\_visitor [\#19](https://github.com/mvgijssel/arel_toolkit/issues/19)
105
117
  - Remove unnecessary to\_arel remains [\#15](https://github.com/mvgijssel/arel_toolkit/issues/15)
106
118
  - Merge to\_arel gem [\#4](https://github.com/mvgijssel/arel_toolkit/issues/4)
119
+ - Create issues for unknown branches in pg\_query\_visitor [\#19](https://github.com/mvgijssel/arel_toolkit/issues/19)
107
120
 
108
121
 
109
122
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- arel_toolkit (0.4.1)
4
+ arel_toolkit (0.4.2)
5
5
  activerecord (~> 5.2.0)
6
6
  arel (~> 9.0.0)
7
7
  pg (~> 1.1.4)
@@ -87,6 +87,7 @@ GEM
87
87
  rb-inotify (~> 0.9, >= 0.9.7)
88
88
  ruby_dep (~> 1.2)
89
89
  lumberjack (1.0.13)
90
+ memory_profiler (0.9.14)
90
91
  method_source (0.9.2)
91
92
  mini_portile2 (2.4.0)
92
93
  minitest (5.13.0)
@@ -166,6 +167,7 @@ GEM
166
167
  hirb
167
168
  simplecov
168
169
  simplecov-html (0.10.2)
170
+ stackprof (0.2.13)
169
171
  thor (0.20.3)
170
172
  thread_safe (0.3.6)
171
173
  tzinfo (1.2.5)
@@ -188,6 +190,7 @@ DEPENDENCIES
188
190
  guard-rake (~> 1.0.0)
189
191
  guard-rspec (~> 4.7)
190
192
  guard-rubocop (~> 1.3.0)
193
+ memory_profiler (~> 0.9)
191
194
  pry
192
195
  pry-alias
193
196
  pry-doc
@@ -200,6 +203,7 @@ DEPENDENCIES
200
203
  rubocop (= 0.71.0)
201
204
  simplecov (~> 0.16.1)
202
205
  simplecov-console (~> 0.4.2)
206
+ stackprof (~> 0.2)
203
207
 
204
208
  BUNDLED WITH
205
- 2.0.1
209
+ 2.0.2
data/README.md CHANGED
@@ -65,7 +65,7 @@ enhanced_arel.child_at_path(['ast', 'cores', 0, 'projections', 1]).object
65
65
  ```
66
66
 
67
67
  ##### Replace or remove nodes without modifying the original arel
68
- `remove` and `replace` allow for modifications to the Arel AST. The changes are aplied to a new copy of the AST, making sure the original AST is not touched.
68
+ `remove` and `replace` allow for modifications to the Arel AST. The changes are aplied to a new copy of the AST, making sure the original AST is not touched. The `replace` method accepts any Arel node or a precomputed enhanced node for improved performance.
69
69
 
70
70
  ```ruby
71
71
  enhanced_arel.child_at_path(['ast', 'cores', 0, 'projections', 1]).replace(Post.arel_table[:content])
@@ -49,6 +49,9 @@ Gem::Specification.new do |spec|
49
49
  spec.add_development_dependency 'guard-rubocop', '~> 1.3.0'
50
50
  spec.add_development_dependency 'guard-rake', '~> 1.0.0'
51
51
 
52
+ spec.add_development_dependency 'stackprof', '~> 0.2'
53
+ spec.add_development_dependency 'memory_profiler', '~> 0.9'
54
+
52
55
  spec.add_development_dependency 'pry'
53
56
  spec.add_development_dependency 'pry-nav'
54
57
  spec.add_development_dependency 'pry-doc'
@@ -0,0 +1,54 @@
1
+ GC.disable
2
+
3
+ require 'arel'
4
+ require 'active_record'
5
+ require 'memory_profiler'
6
+ require 'json'
7
+ require 'stackprof'
8
+
9
+ require './lib/arel/enhance'
10
+ require './lib/arel/extensions'
11
+ require './lib/arel/sql_to_arel'
12
+
13
+ ActiveRecord::Base.establish_connection(
14
+ adapter: 'postgresql',
15
+ host: 'localhost',
16
+ databse: 'arel_toolkit_test',
17
+ username: 'postgres',
18
+ )
19
+
20
+ # rubocop:disable Metrics/LineLength
21
+ SQL = %{
22
+ SELECT COUNT("hacktivity_items"."id") FROM (SELECT "hacktivity_items".* FROM (SELECT "hacktivity_items".* FROM (SELECT "hacktivity_items".*, (NULLIF(current_setting('secure.requester_id'), ''))::integer AS "_requester_id" FROM (SELECT "outer_hacktivity_items".*, EXISTS (SELECT 1 FROM "public"."reports" INNER JOIN "public"."teams" ON "teams"."id" = "reports"."team_id" WHERE "teams"."state" = 5 AND "reports"."disclosed_at" IS NOT NULL AND "reports"."public_view" = 'full' AND "reports"."id" = "outer_hacktivity_items"."report_id") AS "is_someone_visiting_a_public_report", EXISTS (SELECT 1 FROM "public"."reports" INNER JOIN "public"."teams" ON "teams"."id" = "reports"."team_id" INNER JOIN "public"."whitelisted_reporters" ON "whitelisted_reporters"."team_id" = "teams"."id" WHERE "teams" ."state" = 4 AND "teams"."allows_private_disclosure" = 't'::bool AND (("whitelisted_reporters"."user_id" IS NULL AND NULLIF(current_setting('secure.requester_id'), '') IS NULL) OR "whitelisted_reporters"."user_id" = (NULLIF(current_setting('secure.requester_id'), ''))::integer) AND "reports"."disclosed_at" IS NOT NULL AND "reports"."public_view" = 'full' AND "reports"."id" = "outer_hacktivity_items"."report_id") AS "is_someone_visiting_a_report_privately_disclosed_to_them", EXISTS (SELECT 1 FROM "public"."reports" WHERE "reports"."hacker_published" = 't'::bool AND "reports"."disclosed_at" IS NOT NULL AND "reports"."id" = "outer_hacktivity_items"."report_id") AS "is_hacker_published", EXISTS (SELECT 1 FROM "public"."teams" INNER JOIN "public"."team_members" ON "team_members"."team_id" = "teams"."id" WHERE (("team_members"."user_id" IS NULL AND NULLIF(current_setting('secure.requester_id'), '') IS NULL) OR "team_members"."user_id" = (NULLIF(current_setting('secure.requester_id'), ''))::integer) AND "team_members"."user_id" IS NOT NULL AND "teams"."id" = "outer_hacktivity_items"."team_id") AS "is_team_team_member", EXISTS (SELECT 1 FROM "public"."teams" WHERE "teams"."state" = 5 AND "teams"."id" = "outer_hacktivity_items"."team_id") AS "is_team_public", EXISTS (SELECT 1 FROM "public"."teams" INNER JOIN "public"."whitelisted_reporters" ON "whitelisted_reporters"."team_id" = "teams"."id" INNER JOIN "public"."users" ON "users"."id" = "whitelisted_reporters"."user_id" WHERE (("users"."id" IS NULL AND NULLIF(current_setting('secure.requester_id'), '') IS NULL) OR "users"."id" = (NULLIF(current_setting('secure.requester_id'), ''))::integer) AND "users"."id" IS NOT NULL AND "teams"."id" = "outer_hacktivity_items"."team_id") AS "is_team_whitelisted_reporter", EXISTS (SELECT 1 FROM "public"."teams" WHERE "teams"."state" = 4 AND "teams"."id" = "outer_hacktivity_items"."team_id") AS "is_team_private", EXISTS (SELECT 1 FROM "public"."teams" WHERE "teams"."offers_bounties" = 't'::bool AND "teams"."hide_bounty_amounts" = 'f'::bool AND "teams"."id" = "outer_hacktivity_items"."team_id") AS "is_team_shows_bounty_amounts" FROM "public"."hacktivity_items" "outer_hacktivity_items") AS "hacktivity_items" WHERE "hacktivity_items"."is_team_public" = 't'::bool OR ("hacktivity_items"."is_team_private" = 't'::bool AND ("hacktivity_items"."is_team_team_member" = 't'::bool OR "hacktivity_items"."is_team_whitelisted_reporter" = 't'::bool)) OR "hacktivity_items"."is_hacker_published" = 't'::bool) hacktivity_items) AS "hacktivity_items" LEFT OUTER JOIN (SELECT "reports".*, "new_j0"."disclosed_at" AS "__new_filterable_disclosed_at" FROM (SELECT "reports".*, (NULLIF(current_setting('secure.requester_id'), ''))::integer AS "_requester_id" FROM (SELECT "outer_reports".*, EXISTS (SELECT 1 FROM "public"."teams" INNER JOIN "public"."team_members" ON "team_members"."team_id" = "teams"."id" INNER JOIN "public"."users" ON "users"."id" = "team_members"."user_id" WHERE (("users"."id" IS NULL AND NULLIF(current_setting('secure.requester_id'), '') IS NULL) OR "users"."id" = (NULLIF(current_setting('secure.requester_id'), ''))::integer) AND "users"."id" IS NOT NULL AND "teams"."id" = "outer_reports"."team_id") AS "is_team_member", (("outer_reports"."reporter_id" IS NULL AND NULLIF(current_setting('secure.requester_id'), '') IS NULL) OR "outer_reports"."reporter_id" = (NULLIF(current_setting('secure.requester_id'), ''))::integer) AND "outer_reports"."reporter_id" IS NOT NULL AS "is_reporter", EXISTS (SELECT 1 FROM "public"."reports_users" INNER JOIN "public"."users" ON "users"."id" = "reports_users"."user_id" WHERE (("reports_users"."user_id" IS NULL AND NULLIF(current_setting('secure.requester_id'), '') IS NULL) OR "reports_users"."user_id" = (NULLIF(current_setting('secure.requester_id'), ''))::integer) AND "reports_users"."user_id" IS NOT NULL AND "reports_users"."report_id" = "outer_reports"."id") AS "is_external_user", EXISTS (SELECT 1 FROM "public"."report_retests" INNER JOIN "public"."report_retest_users" ON "report_retest_users"."report_retest_id" = "report_retests"."id" WHERE (EXISTS (SELECT "invitations".* FROM "public"."invitations" WHERE ("accepted_at" IS NOT NULL OR "expires_at" >= now() OR "expires_at" IS NULL) AND "invitations"."cancelled_at" IS NULL AND "invitations"."rejected_at" IS NULL AND "invitations"."id" = "report_retest_users"."invitation_id") OR (NOT (EXISTS (SELECT "invitations".* FROM "public"."invitations" WHERE "invitations"."id" = "report_retest_users"."invitation_id")))) AND (("report_retest_users"."user_id" IS NULL AND NULLIF(current_setting('secure.requester_id'), '') IS NULL) OR "report_retest_users"."user_id" = (NULLIF(current_setting('secure.requester_id'), ''))::integer) AND "report_retest_users"."user_id" IS NOT NULL AND "report_retests"."report_id" = "outer_reports"."id") AS "is_retester", EXISTS (SELECT 1 FROM "public"."teams" LEFT OUTER JOIN "public"."users" ON "users"."anc_triager" WHERE "outer_reports"."pre_submission_review_state" IS NOT NULL AND "teams"."state" IN (4, 5) AND "teams"."anc_enabled" = 't'::bool AND (("users"."id" IS NULL AND NULLIF(current_setting('secure.requester_id'), '') IS NULL) OR "users"."id" = (NULLIF(current_setting('secure.requester_id'), ''))::integer) AND "users"."id" IS NOT NULL AND "teams"."id" = "outer_reports"."team_id") AS "is_anc_triager", EXISTS (SELECT 1 FROM "public"."teams" INNER JOIN "public"."team_members" ON "team_members"."team_id" = "teams"."id" INNER JOIN "public"."users" ON "users"."id" = "team_members"."user_id" WHERE (("users"."id" IS NULL AND NULLIF(current_setting('secure.requester_id'), '') IS NULL) OR "users"."id" = (NULLIF(current_setting('secure.requester_id'), ''))::integer) AND "users"."hackerone_triager" = 't'::bool AND "users"."id" IS NOT NULL AND "teams"."id" = "outer_reports"."team_id") AS "is_hackerone_triager", EXISTS (SELECT 1 FROM "public"."report_collaborators" WHERE (("report_collaborators"."user_id" IS NULL AND NULLIF(current_setting('secure.requester_id'), '') IS NULL) OR "report_collaborators"."user_id" = (NULLIF(current_setting('secure.requester_id'), ''))::integer) AND "report_collaborators"."user_id" IS NOT NULL AND "report_collaborators"."report_id" = "outer_reports"."id") AS "is_report_collaborator", EXISTS (SELECT 1 FROM "public"."teams" WHERE "teams"."state" = 5 AND "outer_reports"."disclosed_at" IS NOT NULL AND "outer_reports"."public_view" = 'full' AND "teams"."id" = "outer_reports"."team_id") AS "is_someone_visiting_a_public_report", EXISTS (SELECT 1 FROM "public"."teams" WHERE "teams"."state" = 5 AND "outer_reports"."disclosed_at" IS NOT NULL AND "outer_reports"."public_view" = 'no-content' AND "teams"."id" = "outer_reports"."team_id") AS "is_someone_visiting_a_public_limited_report", EXISTS (SELECT 1 FROM "public"."teams" INNER JOIN "public"."whitelisted_reporters" ON "whitelisted_reporters"."team_id" = "teams"."id" WHERE "teams"."state" = 4 AND "teams"."allows_private_disclosure" = 't'::bool AND (("whitelisted_reporters"."user_id" IS NULL AND NULLIF(current_setting('secure.requester_id'), '') IS NULL) OR "whitelisted_reporters"."user_id" = (NULLIF(current_setting('secure.requester_id'), ''))::integer) AND "outer_reports"."disclosed_at" IS NOT NULL AND "outer_reports"."public_view" = 'full' AND "teams"."id" = "outer_reports"."team_id") AS "is_someone_visiting_a_report_privately_disclosed_to_them", "outer_reports"."hacker_published" = 't'::bool AND "outer_reports"."disclosed_at" IS NOT NULL AS "is_hacker_published" FROM "public"."reports" "outer_reports") AS "reports" WHERE "reports"."is_reporter" = 't'::bool OR "reports"."is_team_member" = 't'::bool OR "reports"."is_external_user" = 't'::bool OR "reports"."is_anc_triager" = 't'::bool OR "reports"."is_report_collaborator" = 't'::bool OR "reports"."is_someone_visiting_a_public_report" = 't'::bool OR "reports"."is_someone_visiting_a_public_limited_report" = 't'::bool OR "reports"."is_someone_visiting_a_report_privately_disclosed_to_them" = 't'::bool OR "reports"."is_hacker_published" = 't'::bool OR "reports"."is_retester" = 't'::bool) reports LEFT OUTER JOIN "public"."reports" "new_j0" ON "reports"."id" = "new_j0"."id" AND ("reports"."is_reporter" = 't'::bool OR "reports"."is_team_member" = 't'::bool OR "reports"."is_external_user" = 't'::bool OR "reports"."is_anc_triager" = 't'::bool OR "reports"."is_report_collaborator" = 't'::bool OR "reports"."is_someone_visiting_a_public_report" = 't'::bool OR "reports"."is_someone_visiting_a_public_limited_report" = 't'::bool OR "reports"."is_someone_visiting_a_report_privately_disclosed_to_them" = 't'::bool OR "reports"."is_hacker_published" = 't'::bool)) AS "reports" ON "reports"."id" = "hacktivity_items"."report_id" WHERE "reports"."__new_filterable_disclosed_at" IS NOT NULL) AS "hacktivity_items" LEFT OUTER JOIN "hacktivity_scores" ON "hacktivity_scores"."hacktivity_item_id" = "hacktivity_items"."id"
23
+ }.freeze
24
+ # rubocop:enable Metrics/LineLength
25
+
26
+ def do_it
27
+ arel = Arel.sql_to_arel SQL
28
+ enhanced_arel = Arel.enhance(arel)
29
+
30
+ enhanced_arel.query(class: Arel::Attributes::Attribute).each do |node|
31
+ node.replace node
32
+ end
33
+
34
+ enhanced_arel
35
+ end
36
+
37
+ # Warm up
38
+ do_it
39
+
40
+ profile = StackProf.run(mode: :wall, raw: true) { do_it }
41
+ File.write('stackprof.json', JSON.generate(profile))
42
+
43
+ report = MemoryProfiler.report { do_it }
44
+ puts report.pretty_print
45
+
46
+ n = 100
47
+
48
+ Benchmark.bm do |benchmark|
49
+ benchmark.report do
50
+ n.times do
51
+ do_it
52
+ end
53
+ end
54
+ end
@@ -31,7 +31,7 @@ GIT
31
31
  PATH
32
32
  remote: ..
33
33
  specs:
34
- arel_toolkit (0.4.0)
34
+ arel_toolkit (0.4.2)
35
35
  activerecord (~> 5.2.0)
36
36
  arel (~> 9.0.0)
37
37
  pg (~> 1.1.4)
@@ -64,8 +64,8 @@ GEM
64
64
  i18n (>= 0.7, < 2)
65
65
  minitest (~> 5.1)
66
66
  tzinfo (~> 1.1)
67
- addressable (2.6.0)
68
- public_suffix (>= 2.0.2, < 4.0)
67
+ addressable (2.7.0)
68
+ public_suffix (>= 2.0.2, < 5.0)
69
69
  ansi (1.5.0)
70
70
  appraisal (2.2.0)
71
71
  bundler
@@ -88,20 +88,20 @@ GEM
88
88
  docile (1.3.2)
89
89
  dpl (1.10.12)
90
90
  erubi (1.8.0)
91
- faraday (0.15.4)
91
+ faraday (0.17.0)
92
92
  multipart-post (>= 1.2, < 3)
93
93
  faraday-http-cache (2.0.0)
94
94
  faraday (~> 0.8)
95
95
  ffi (1.11.1)
96
96
  formatador (0.2.5)
97
- github_changelog_generator (1.14.3)
97
+ github_changelog_generator (1.15.0)
98
98
  activesupport
99
99
  faraday-http-cache
100
100
  multi_json
101
101
  octokit (~> 4.6)
102
- rainbow (>= 2.1)
102
+ rainbow (>= 2.2.1)
103
103
  rake (>= 10.0)
104
- retriable (~> 2.1)
104
+ retriable (~> 3.0)
105
105
  guard (2.15.0)
106
106
  formatador (>= 0.2.4)
107
107
  listen (>= 2.7, < 4.0)
@@ -136,10 +136,11 @@ GEM
136
136
  crass (~> 1.0.2)
137
137
  nokogiri (>= 1.5.9)
138
138
  lumberjack (1.0.13)
139
+ memory_profiler (0.9.14)
139
140
  method_source (0.9.2)
140
141
  mini_portile2 (2.4.0)
141
142
  minitest (5.11.3)
142
- multi_json (1.13.1)
143
+ multi_json (1.14.1)
143
144
  multipart-post (2.1.1)
144
145
  nenv (0.3.0)
145
146
  nokogiri (1.10.3)
@@ -154,7 +155,7 @@ GEM
154
155
  ast (~> 2.4.0)
155
156
  pg (1.1.4)
156
157
  pg_array_parser (0.0.9)
157
- pg_query (1.1.0)
158
+ pg_query (1.1.1)
158
159
  pry (0.12.2)
159
160
  coderay (~> 1.1.0)
160
161
  method_source (~> 0.9.0)
@@ -172,7 +173,7 @@ GEM
172
173
  pry-stack_explorer (0.4.9.3)
173
174
  binding_of_caller (>= 0.7)
174
175
  pry (>= 0.9.11)
175
- public_suffix (3.1.1)
176
+ public_suffix (4.0.1)
176
177
  rack (2.0.7)
177
178
  rack-test (1.1.0)
178
179
  rack (>= 1.0, < 3)
@@ -194,7 +195,7 @@ GEM
194
195
  rb-fsevent (0.10.3)
195
196
  rb-inotify (0.10.0)
196
197
  ffi (~> 1.0)
197
- retriable (2.1.0)
198
+ retriable (3.1.2)
198
199
  rspec (3.8.0)
199
200
  rspec-core (~> 3.8.0)
200
201
  rspec-expectations (~> 3.8.0)
@@ -238,6 +239,7 @@ GEM
238
239
  hirb
239
240
  simplecov
240
241
  simplecov-html (0.10.2)
242
+ stackprof (0.2.13)
241
243
  thor (0.20.3)
242
244
  thread_safe (0.3.6)
243
245
  tzinfo (1.2.5)
@@ -256,11 +258,12 @@ DEPENDENCIES
256
258
  bundler (~> 2.0)
257
259
  database_cleaner (~> 1.7.0)
258
260
  dpl (~> 1.10.11)
259
- github_changelog_generator (~> 1.14.3)
261
+ github_changelog_generator (~> 1.15)
260
262
  guard (~> 2.15)
261
263
  guard-rake (~> 1.0.0)
262
264
  guard-rspec (~> 4.7)
263
265
  guard-rubocop (~> 1.3.0)
266
+ memory_profiler (~> 0.9)
264
267
  pg_search!
265
268
  postgres_ext!
266
269
  pry
@@ -276,6 +279,7 @@ DEPENDENCIES
276
279
  rubocop (= 0.71.0)
277
280
  simplecov (~> 0.16.1)
278
281
  simplecov-console (~> 0.4.2)
282
+ stackprof (~> 0.2)
279
283
 
280
284
  BUNDLED WITH
281
- 2.0.1
285
+ 2.0.2
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- arel_toolkit (0.4.0)
4
+ arel_toolkit (0.4.2)
5
5
  activerecord (~> 5.2.0)
6
6
  arel (~> 9.0.0)
7
7
  pg (~> 1.1.4)
@@ -21,8 +21,8 @@ GEM
21
21
  i18n (>= 0.7, < 2)
22
22
  minitest (~> 5.1)
23
23
  tzinfo (~> 1.1)
24
- addressable (2.6.0)
25
- public_suffix (>= 2.0.2, < 4.0)
24
+ addressable (2.7.0)
25
+ public_suffix (>= 2.0.2, < 5.0)
26
26
  ansi (1.5.0)
27
27
  appraisal (2.2.0)
28
28
  bundler
@@ -42,20 +42,20 @@ GEM
42
42
  diff-lcs (1.3)
43
43
  docile (1.3.2)
44
44
  dpl (1.10.12)
45
- faraday (0.15.4)
45
+ faraday (0.17.0)
46
46
  multipart-post (>= 1.2, < 3)
47
47
  faraday-http-cache (2.0.0)
48
48
  faraday (~> 0.8)
49
49
  ffi (1.11.1)
50
50
  formatador (0.2.5)
51
- github_changelog_generator (1.14.3)
51
+ github_changelog_generator (1.15.0)
52
52
  activesupport
53
53
  faraday-http-cache
54
54
  multi_json
55
55
  octokit (~> 4.6)
56
- rainbow (>= 2.1)
56
+ rainbow (>= 2.2.1)
57
57
  rake (>= 10.0)
58
- retriable (~> 2.1)
58
+ retriable (~> 3.0)
59
59
  guard (2.15.0)
60
60
  formatador (>= 0.2.4)
61
61
  listen (>= 2.7, < 4.0)
@@ -77,7 +77,7 @@ GEM
77
77
  guard (~> 2.0)
78
78
  rubocop (~> 0.20)
79
79
  hirb (0.7.3)
80
- i18n (1.6.0)
80
+ i18n (1.7.0)
81
81
  concurrent-ruby (~> 1.0)
82
82
  interception (0.5)
83
83
  jaro_winkler (1.5.3)
@@ -87,10 +87,11 @@ GEM
87
87
  rb-inotify (~> 0.9, >= 0.9.7)
88
88
  ruby_dep (~> 1.2)
89
89
  lumberjack (1.0.13)
90
+ memory_profiler (0.9.14)
90
91
  method_source (0.9.2)
91
92
  mini_portile2 (2.4.0)
92
- minitest (5.11.3)
93
- multi_json (1.13.1)
93
+ minitest (5.13.0)
94
+ multi_json (1.14.1)
94
95
  multipart-post (2.1.1)
95
96
  nenv (0.3.0)
96
97
  nokogiri (1.10.3)
@@ -104,7 +105,7 @@ GEM
104
105
  parser (2.6.3.0)
105
106
  ast (~> 2.4.0)
106
107
  pg (1.1.4)
107
- pg_query (1.1.0)
108
+ pg_query (1.1.1)
108
109
  pry (0.12.2)
109
110
  coderay (~> 1.1.0)
110
111
  method_source (~> 0.9.0)
@@ -122,7 +123,7 @@ GEM
122
123
  pry-stack_explorer (0.4.9.3)
123
124
  binding_of_caller (>= 0.7)
124
125
  pry (>= 0.9.11)
125
- public_suffix (3.1.1)
126
+ public_suffix (4.0.1)
126
127
  rainbow (3.0.0)
127
128
  rake (10.5.0)
128
129
  rake-compiler (1.0.7)
@@ -130,7 +131,7 @@ GEM
130
131
  rb-fsevent (0.10.3)
131
132
  rb-inotify (0.10.0)
132
133
  ffi (~> 1.0)
133
- retriable (2.1.0)
134
+ retriable (3.1.2)
134
135
  rspec (3.8.0)
135
136
  rspec-core (~> 3.8.0)
136
137
  rspec-expectations (~> 3.8.0)
@@ -166,6 +167,7 @@ GEM
166
167
  hirb
167
168
  simplecov
168
169
  simplecov-html (0.10.2)
170
+ stackprof (0.2.13)
169
171
  thor (0.20.3)
170
172
  thread_safe (0.3.6)
171
173
  tzinfo (1.2.5)
@@ -183,11 +185,12 @@ DEPENDENCIES
183
185
  bundler (~> 2.0)
184
186
  database_cleaner (~> 1.7.0)
185
187
  dpl (~> 1.10.11)
186
- github_changelog_generator (~> 1.14.3)
188
+ github_changelog_generator (~> 1.15)
187
189
  guard (~> 2.15)
188
190
  guard-rake (~> 1.0.0)
189
191
  guard-rspec (~> 4.7)
190
192
  guard-rubocop (~> 1.3.0)
193
+ memory_profiler (~> 0.9)
191
194
  pry
192
195
  pry-alias
193
196
  pry-doc
@@ -200,6 +203,7 @@ DEPENDENCIES
200
203
  rubocop (= 0.71.0)
201
204
  simplecov (~> 0.16.1)
202
205
  simplecov-console (~> 0.4.2)
206
+ stackprof (~> 0.2)
203
207
 
204
208
  BUNDLED WITH
205
- 2.0.1
209
+ 2.0.2
@@ -3,7 +3,7 @@ module Arel
3
3
  class Node
4
4
  attr_reader :object
5
5
  attr_reader :parent
6
- attr_reader :path
6
+ attr_reader :local_path
7
7
  attr_reader :fields
8
8
  attr_reader :children
9
9
  attr_reader :root_node
@@ -11,7 +11,6 @@ module Arel
11
11
 
12
12
  def initialize(object)
13
13
  @object = object
14
- @path = Path.new
15
14
  @root_node = self
16
15
  @fields = []
17
16
  @children = {}
@@ -51,12 +50,12 @@ module Arel
51
50
  mutate(nil, remove: true)
52
51
  end
53
52
 
54
- def replace(new_node)
55
- mutate(new_node)
53
+ def replace(new_arel_node)
54
+ mutate(new_arel_node)
56
55
  end
57
56
 
58
57
  def add(path_node, node)
59
- node.path = path.append(path_node)
58
+ node.local_path = path_node
60
59
  node.parent = self
61
60
  node.root_node = root_node
62
61
  @children[path_node.value.to_s] = node
@@ -107,9 +106,21 @@ module Arel
107
106
  Arel::Enhance::Query.call(self, kwargs)
108
107
  end
109
108
 
109
+ def full_path
110
+ the_path = [local_path]
111
+ current_parent = parent
112
+
113
+ while current_parent
114
+ the_path.unshift current_parent.local_path
115
+ current_parent = current_parent.parent
116
+ end
117
+
118
+ the_path.compact
119
+ end
120
+
110
121
  protected
111
122
 
112
- attr_writer :path
123
+ attr_writer :local_path
113
124
  attr_writer :parent
114
125
  attr_writer :root_node
115
126
 
@@ -117,7 +128,7 @@ module Arel
117
128
  # rubocop:disable Metrics/CyclomaticComplexity
118
129
  # rubocop:disable Metrics/PerceivedComplexity
119
130
  def recursive_inspect(string, indent = 1)
120
- string << "<#{inspect_name} #{path.inspect}\n"
131
+ string << "<#{inspect_name} #{full_path.inspect}\n"
121
132
  string << "#{spacing(indent)}sql = #{to_sql}\n" unless to_sql.nil?
122
133
  string << "#{spacing(indent)}parent = #{parent.nil? ? nil.inspect : parent.inspect_name}"
123
134
  string << "\n" unless children.length.zero?
@@ -135,6 +146,7 @@ module Arel
135
146
  "#{spacing(indent - 1)}>\n"
136
147
  end
137
148
  end
149
+
138
150
  # rubocop:enable Metrics/AbcSize
139
151
  # rubocop:enable Metrics/CyclomaticComplexity
140
152
  # rubocop:enable Metrics/PerceivedComplexity
@@ -154,10 +166,16 @@ module Arel
154
166
  def deep_copy_object
155
167
  # https://github.com/mvgijssel/arel_toolkit/issues/97
156
168
  new_object = Marshal.load(Marshal.dump(object))
169
+ self.object = new_object
157
170
 
158
- each do |node|
159
- selected_object = node.path.dig_send(new_object)
160
- node.object = selected_object
171
+ recursive_update_object(new_object)
172
+ end
173
+
174
+ def recursive_update_object(arel_tree)
175
+ children.each_value do |child|
176
+ tree_child = arel_tree.send(*child.local_path.method)
177
+ child.object = tree_child
178
+ child.recursive_update_object(tree_child)
161
179
  end
162
180
  end
163
181
 
@@ -177,28 +195,34 @@ module Arel
177
195
  root_node.mark_as_dirty
178
196
 
179
197
  parent_object = parent.object
180
- new_node = [] if remove && object.is_a?(Array)
198
+ new_arel_node = new_node.is_a?(Arel::Enhance::Node) ? new_node.object : new_node
199
+ new_arel_node = [] if remove && object.is_a?(Array)
181
200
 
182
- if parent_object.respond_to?("#{path.current.value}=")
183
- parent_object.send("#{path.current.value}=", new_node)
201
+ if parent_object.respond_to?("#{local_path.value}=")
202
+ parent_object.send("#{local_path.value}=", new_arel_node)
184
203
 
185
- elsif parent_object.instance_values.key?(path.current.value)
186
- parent_object.instance_variable_set("@#{path.current.value}", new_node)
204
+ elsif parent_object.instance_values.key?(local_path.value)
205
+ parent_object.instance_variable_set("@#{local_path.value}", new_arel_node)
187
206
 
188
- elsif path.current.arguments? && parent_object.respond_to?(path.current.method[0])
207
+ elsif local_path.arguments? && parent_object.respond_to?(local_path.method[0])
189
208
  if remove
190
- parent_object.delete_at(path.current.value)
209
+ parent_object.delete_at(local_path.value)
191
210
 
192
211
  else
193
- parent_object[path.current.value] = new_node
212
+ parent_object[local_path.value] = new_arel_node
194
213
  end
195
214
  else
196
- raise "Don't know how to replace `#{path.current.value}` in #{parent_object.inspect}"
215
+ raise "Don't know how to replace `#{local_path.value}` in #{parent_object.inspect}"
197
216
  end
198
217
 
199
- new_parent_tree = Visitor.new.accept_with_root(parent_object, parent)
200
- parent.parent.add(parent.path.current, new_parent_tree)
201
- new_parent_tree[path.current.value]
218
+ if new_node.is_a?(Arel::Enhance::Node)
219
+ parent.add(local_path, new_node)
220
+ parent[local_path.value]
221
+ else
222
+ new_parent_tree = Visitor.new.accept_with_root(parent_object, parent)
223
+ parent.parent.add(parent.local_path, new_parent_tree)
224
+ new_parent_tree[local_path.value]
225
+ end
202
226
  end
203
227
  # rubocop:enable Metrics/PerceivedComplexity
204
228
  # rubocop:enable Metrics/CyclomaticComplexity
@@ -63,9 +63,23 @@ module Arel
63
63
  end
64
64
  end
65
65
 
66
+ # rubocop:disable Metrics/AbcSize
67
+ # arel/lib/arel/visitors/visitor.rb:29
66
68
  def visit(object)
67
- Arel::Visitors::Visitor.instance_method(:visit).bind(self).call(object)
69
+ dispatch_method = dispatch[object.class]
70
+ send dispatch_method, object
71
+ rescue NoMethodError => e
72
+ raise e if respond_to?(dispatch_method, true)
73
+
74
+ superklass = object.class.ancestors.find do |klass|
75
+ respond_to?(dispatch[klass], true)
76
+ end
77
+ raise(TypeError, "Cannot visit #{object.class}") unless superklass
78
+
79
+ dispatch[object.class] = dispatch[superklass]
80
+ retry
68
81
  end
82
+ # rubocop:enable Metrics/AbcSize
69
83
 
70
84
  def current_node
71
85
  @node_stack.last
@@ -1,3 +1,3 @@
1
1
  module ArelToolkit
2
- VERSION = '0.4.1'.freeze
2
+ VERSION = '0.4.2'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arel_toolkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - maarten
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-11-13 00:00:00.000000000 Z
11
+ date: 2020-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: arel
@@ -290,6 +290,34 @@ dependencies:
290
290
  - - "~>"
291
291
  - !ruby/object:Gem::Version
292
292
  version: 1.0.0
293
+ - !ruby/object:Gem::Dependency
294
+ name: stackprof
295
+ requirement: !ruby/object:Gem::Requirement
296
+ requirements:
297
+ - - "~>"
298
+ - !ruby/object:Gem::Version
299
+ version: '0.2'
300
+ type: :development
301
+ prerelease: false
302
+ version_requirements: !ruby/object:Gem::Requirement
303
+ requirements:
304
+ - - "~>"
305
+ - !ruby/object:Gem::Version
306
+ version: '0.2'
307
+ - !ruby/object:Gem::Dependency
308
+ name: memory_profiler
309
+ requirement: !ruby/object:Gem::Requirement
310
+ requirements:
311
+ - - "~>"
312
+ - !ruby/object:Gem::Version
313
+ version: '0.9'
314
+ type: :development
315
+ prerelease: false
316
+ version_requirements: !ruby/object:Gem::Requirement
317
+ requirements:
318
+ - - "~>"
319
+ - !ruby/object:Gem::Version
320
+ version: '0.9'
293
321
  - !ruby/object:Gem::Dependency
294
322
  name: pry
295
323
  requirement: !ruby/object:Gem::Requirement
@@ -402,6 +430,7 @@ files:
402
430
  - README.md
403
431
  - Rakefile
404
432
  - arel_toolkit.gemspec
433
+ - benchmark.rb
405
434
  - bin/console
406
435
  - bin/setup
407
436
  - ext/pg_result_init/extconf.rb
@@ -573,8 +602,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
573
602
  - !ruby/object:Gem::Version
574
603
  version: '0'
575
604
  requirements: []
576
- rubyforge_project:
577
- rubygems_version: 2.7.6
605
+ rubygems_version: 3.0.3
578
606
  signing_key:
579
607
  specification_version: 4
580
608
  summary: Collection of tools for Arel