inquery 1.0.11 → 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 +4 -4
- data/.github/workflows/rubocop.yml +1 -1
- data/.github/workflows/ruby.yml +24 -8
- data/.gitignore +2 -2
- data/.rubocop.yml +4 -0
- data/Appraisals +24 -4
- data/CHANGELOG.md +38 -0
- data/Gemfile +17 -1
- data/Gemfile.lock +125 -0
- data/LICENSE +1 -1
- data/MIGRATION.md +260 -0
- data/README.md +14 -8
- data/RUBY_VERSION +1 -1
- data/Rakefile +4 -11
- data/VERSION +1 -1
- data/doc/Inquery/Exceptions/Base.html +4 -4
- data/doc/Inquery/Exceptions/InvalidRelation.html +4 -4
- data/doc/Inquery/Exceptions/UnknownCallSignature.html +4 -4
- data/doc/Inquery/Exceptions.html +4 -4
- data/doc/Inquery/MethodAccessibleHash.html +431 -0
- data/doc/Inquery/Mixins/RawSqlUtils.html +17 -4
- data/doc/Inquery/Mixins/RelationValidation/ClassMethods.html +8 -7
- data/doc/Inquery/Mixins/RelationValidation.html +9 -8
- data/doc/Inquery/Mixins/SchemaValidation/ClassMethods.html +4 -4
- data/doc/Inquery/Mixins/SchemaValidation.html +4 -4
- data/doc/Inquery/Mixins.html +4 -4
- data/doc/Inquery/Query/Chainable.html +207 -90
- data/doc/Inquery/Query.html +401 -73
- data/doc/Inquery.html +12 -9
- data/doc/_index.html +12 -5
- data/doc/class_list.html +6 -3
- data/doc/css/full_list.css +3 -3
- data/doc/css/style.css +6 -0
- data/doc/file.README.html +102 -16
- data/doc/file_list.html +5 -2
- data/doc/frames.html +10 -5
- data/doc/index.html +102 -16
- data/doc/js/app.js +294 -264
- data/doc/js/full_list.js +30 -4
- data/doc/method_list.html +48 -21
- data/doc/top-level-namespace.html +4 -4
- data/gemfiles/rails_5.2.gemfile +1 -0
- data/gemfiles/rails_6.0.gemfile +1 -0
- data/gemfiles/rails_6.1.gemfile +1 -0
- data/gemfiles/rails_7.0.gemfile +1 -0
- data/gemfiles/{rails_5.1.gemfile → rails_7.1.gemfile} +2 -1
- data/gemfiles/rails_7.2.gemfile +8 -0
- data/gemfiles/rails_8.0.gemfile +8 -0
- data/gemfiles/rails_8.1.gemfile +8 -0
- data/inquery.gemspec +11 -34
- data/lib/inquery/method_accessible_hash.rb +45 -0
- data/lib/inquery/mixins/raw_sql_utils.rb +32 -6
- data/lib/inquery/mixins/relation_validation.rb +1 -1
- data/lib/inquery/query/chainable.rb +69 -27
- data/lib/inquery/query.rb +67 -14
- data/lib/inquery.rb +2 -0
- data/test/inquery/error_handling_test.rb +117 -0
- data/test/inquery/method_accessible_hash_test.rb +85 -0
- data/test/inquery/mixins/raw_sql_utils_test.rb +67 -0
- data/test/inquery/query/chainable_test.rb +78 -0
- data/test/inquery/query_test.rb +86 -0
- data/test/test_helper.rb +11 -0
- metadata +30 -129
- data/.yardopts +0 -1
data/doc/js/full_list.js
CHANGED
|
@@ -62,8 +62,25 @@ function enableToggles() {
|
|
|
62
62
|
evt.stopPropagation();
|
|
63
63
|
evt.preventDefault();
|
|
64
64
|
$(this).parent().parent().toggleClass('collapsed');
|
|
65
|
+
$(this).attr('aria-expanded', function (i, attr) {
|
|
66
|
+
return attr == 'true' ? 'false' : 'true'
|
|
67
|
+
});
|
|
65
68
|
highlight();
|
|
66
69
|
});
|
|
70
|
+
|
|
71
|
+
// navigation of nested classes using keyboard
|
|
72
|
+
$('#full_list a.toggle').on('keypress',function(evt) {
|
|
73
|
+
// enter key is pressed
|
|
74
|
+
if (evt.which == 13) {
|
|
75
|
+
evt.stopPropagation();
|
|
76
|
+
evt.preventDefault();
|
|
77
|
+
$(this).parent().parent().toggleClass('collapsed');
|
|
78
|
+
$(this).attr('aria-expanded', function (i, attr) {
|
|
79
|
+
return attr == 'true' ? 'false' : 'true'
|
|
80
|
+
});
|
|
81
|
+
highlight();
|
|
82
|
+
}
|
|
83
|
+
});
|
|
67
84
|
}
|
|
68
85
|
|
|
69
86
|
function populateSearchCache() {
|
|
@@ -91,7 +108,7 @@ function enableSearch() {
|
|
|
91
108
|
}
|
|
92
109
|
});
|
|
93
110
|
|
|
94
|
-
$('#full_list').after("<div id='noresults' style='display:none'></div>");
|
|
111
|
+
$('#full_list').after("<div id='noresults' role='status' style='display: none'></div>");
|
|
95
112
|
}
|
|
96
113
|
|
|
97
114
|
function ignoredKeyPress(event) {
|
|
@@ -154,11 +171,14 @@ function partialSearch(searchString, offset) {
|
|
|
154
171
|
function searchDone() {
|
|
155
172
|
searchTimeout = null;
|
|
156
173
|
highlight();
|
|
157
|
-
|
|
158
|
-
|
|
174
|
+
var found = $('#full_list li:visible').size();
|
|
175
|
+
if (found === 0) {
|
|
176
|
+
$('#noresults').text('No results were found.');
|
|
159
177
|
} else {
|
|
160
|
-
|
|
178
|
+
// This is read out to screen readers
|
|
179
|
+
$('#noresults').text('There are ' + found + ' results.');
|
|
161
180
|
}
|
|
181
|
+
$('#noresults').show();
|
|
162
182
|
$('#content').removeClass('insearch');
|
|
163
183
|
}
|
|
164
184
|
|
|
@@ -188,6 +208,12 @@ function expandTo(path) {
|
|
|
188
208
|
$target.addClass('clicked');
|
|
189
209
|
$target.removeClass('collapsed');
|
|
190
210
|
$target.parentsUntil('#full_list', 'li').removeClass('collapsed');
|
|
211
|
+
|
|
212
|
+
$target.find('a.toggle').attr('aria-expanded', 'true')
|
|
213
|
+
$target.parentsUntil('#full_list', 'li').each(function(i, el) {
|
|
214
|
+
$(el).find('> div > a.toggle').attr('aria-expanded', 'true');
|
|
215
|
+
});
|
|
216
|
+
|
|
191
217
|
if($target[0]) {
|
|
192
218
|
window.scrollTo(window.scrollX, $target.offset().top - 250);
|
|
193
219
|
highlight();
|
data/doc/method_list.html
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
2
|
+
<html >
|
|
3
3
|
<head>
|
|
4
4
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
5
5
|
<meta charset="utf-8" />
|
|
@@ -38,7 +38,10 @@
|
|
|
38
38
|
|
|
39
39
|
</div>
|
|
40
40
|
|
|
41
|
-
<div id="search">
|
|
41
|
+
<div id="search">
|
|
42
|
+
<label for="search-class">Search:</label>
|
|
43
|
+
<input id="search-class" type="text" />
|
|
44
|
+
</div>
|
|
42
45
|
</div>
|
|
43
46
|
|
|
44
47
|
<ul id="full_list" class="method">
|
|
@@ -46,7 +49,7 @@
|
|
|
46
49
|
|
|
47
50
|
<li class="odd ">
|
|
48
51
|
<div class="item">
|
|
49
|
-
<span class='object_link'><a href="Inquery/Query.html#call-
|
|
52
|
+
<span class='object_link'><a href="Inquery/Query.html#call-class_method" title="Inquery::Query.call (method)">call</a></span>
|
|
50
53
|
<small>Inquery::Query</small>
|
|
51
54
|
</div>
|
|
52
55
|
</li>
|
|
@@ -54,8 +57,8 @@
|
|
|
54
57
|
|
|
55
58
|
<li class="even ">
|
|
56
59
|
<div class="item">
|
|
57
|
-
<span class='object_link'><a href="Inquery/Query
|
|
58
|
-
<small>Inquery::Query
|
|
60
|
+
<span class='object_link'><a href="Inquery/Query.html#call-instance_method" title="Inquery::Query#call (method)">#call</a></span>
|
|
61
|
+
<small>Inquery::Query</small>
|
|
59
62
|
</div>
|
|
60
63
|
</li>
|
|
61
64
|
|
|
@@ -70,7 +73,7 @@
|
|
|
70
73
|
|
|
71
74
|
<li class="even ">
|
|
72
75
|
<div class="item">
|
|
73
|
-
<span class='object_link'><a href="Inquery/Query.html#
|
|
76
|
+
<span class='object_link'><a href="Inquery/Query.html#connection-instance_method" title="Inquery::Query#connection (method)">#connection</a></span>
|
|
74
77
|
<small>Inquery::Query</small>
|
|
75
78
|
</div>
|
|
76
79
|
</li>
|
|
@@ -78,15 +81,15 @@
|
|
|
78
81
|
|
|
79
82
|
<li class="odd ">
|
|
80
83
|
<div class="item">
|
|
81
|
-
<span class='object_link'><a href="Inquery/Query.html#connection-instance_method" title="Inquery::Query#connection (method)">#connection</a></span>
|
|
82
|
-
<small>Inquery::Query</small>
|
|
84
|
+
<span class='object_link'><a href="Inquery/Query/Chainable.html#connection-instance_method" title="Inquery::Query::Chainable#connection (method)">#connection</a></span>
|
|
85
|
+
<small>Inquery::Query::Chainable</small>
|
|
83
86
|
</div>
|
|
84
87
|
</li>
|
|
85
88
|
|
|
86
89
|
|
|
87
90
|
<li class="even ">
|
|
88
91
|
<div class="item">
|
|
89
|
-
<span class='object_link'><a href="Inquery/Query/Chainable.html#
|
|
92
|
+
<span class='object_link'><a href="Inquery/Query/Chainable.html#initialize-instance_method" title="Inquery::Query::Chainable#initialize (method)">#initialize</a></span>
|
|
90
93
|
<small>Inquery::Query::Chainable</small>
|
|
91
94
|
</div>
|
|
92
95
|
</li>
|
|
@@ -94,8 +97,8 @@
|
|
|
94
97
|
|
|
95
98
|
<li class="odd ">
|
|
96
99
|
<div class="item">
|
|
97
|
-
<span class='object_link'><a href="Inquery/
|
|
98
|
-
<small>Inquery::
|
|
100
|
+
<span class='object_link'><a href="Inquery/MethodAccessibleHash.html#initialize-instance_method" title="Inquery::MethodAccessibleHash#initialize (method)">#initialize</a></span>
|
|
101
|
+
<small>Inquery::MethodAccessibleHash</small>
|
|
99
102
|
</div>
|
|
100
103
|
</li>
|
|
101
104
|
|
|
@@ -108,6 +111,22 @@
|
|
|
108
111
|
</li>
|
|
109
112
|
|
|
110
113
|
|
|
114
|
+
<li class="odd ">
|
|
115
|
+
<div class="item">
|
|
116
|
+
<span class='object_link'><a href="Inquery/MethodAccessibleHash.html#merge-instance_method" title="Inquery::MethodAccessibleHash#merge (method)">#merge</a></span>
|
|
117
|
+
<small>Inquery::MethodAccessibleHash</small>
|
|
118
|
+
</div>
|
|
119
|
+
</li>
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
<li class="even ">
|
|
123
|
+
<div class="item">
|
|
124
|
+
<span class='object_link'><a href="Inquery/MethodAccessibleHash.html#method_missing-instance_method" title="Inquery::MethodAccessibleHash#method_missing (method)">#method_missing</a></span>
|
|
125
|
+
<small>Inquery::MethodAccessibleHash</small>
|
|
126
|
+
</div>
|
|
127
|
+
</li>
|
|
128
|
+
|
|
129
|
+
|
|
111
130
|
<li class="odd ">
|
|
112
131
|
<div class="item">
|
|
113
132
|
<span class='object_link'><a href="Inquery/Query.html#osparams-instance_method" title="Inquery::Query#osparams (method)">#osparams</a></span>
|
|
@@ -134,21 +153,29 @@
|
|
|
134
153
|
|
|
135
154
|
<li class="even ">
|
|
136
155
|
<div class="item">
|
|
137
|
-
<span class='object_link'><a href="Inquery/
|
|
138
|
-
<small>Inquery::
|
|
156
|
+
<span class='object_link'><a href="Inquery/Query/Chainable.html#relation-instance_method" title="Inquery::Query::Chainable#relation (method)">#relation</a></span>
|
|
157
|
+
<small>Inquery::Query::Chainable</small>
|
|
139
158
|
</div>
|
|
140
159
|
</li>
|
|
141
160
|
|
|
142
161
|
|
|
143
162
|
<li class="odd ">
|
|
144
163
|
<div class="item">
|
|
145
|
-
<span class='object_link'><a href="Inquery/
|
|
146
|
-
<small>Inquery::
|
|
164
|
+
<span class='object_link'><a href="Inquery/Mixins/RelationValidation/ClassMethods.html#relation-instance_method" title="Inquery::Mixins::RelationValidation::ClassMethods#relation (method)">#relation</a></span>
|
|
165
|
+
<small>Inquery::Mixins::RelationValidation::ClassMethods</small>
|
|
147
166
|
</div>
|
|
148
167
|
</li>
|
|
149
168
|
|
|
150
169
|
|
|
151
170
|
<li class="even ">
|
|
171
|
+
<div class="item">
|
|
172
|
+
<span class='object_link'><a href="Inquery/MethodAccessibleHash.html#respond_to_missing%3F-instance_method" title="Inquery::MethodAccessibleHash#respond_to_missing? (method)">#respond_to_missing?</a></span>
|
|
173
|
+
<small>Inquery::MethodAccessibleHash</small>
|
|
174
|
+
</div>
|
|
175
|
+
</li>
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
<li class="odd ">
|
|
152
179
|
<div class="item">
|
|
153
180
|
<span class='object_link'><a href="Inquery/Query.html#run-instance_method" title="Inquery::Query#run (method)">#run</a></span>
|
|
154
181
|
<small>Inquery::Query</small>
|
|
@@ -156,7 +183,7 @@
|
|
|
156
183
|
</li>
|
|
157
184
|
|
|
158
185
|
|
|
159
|
-
<li class="
|
|
186
|
+
<li class="even ">
|
|
160
187
|
<div class="item">
|
|
161
188
|
<span class='object_link'><a href="Inquery/Query.html#run-class_method" title="Inquery::Query.run (method)">run</a></span>
|
|
162
189
|
<small>Inquery::Query</small>
|
|
@@ -164,7 +191,7 @@
|
|
|
164
191
|
</li>
|
|
165
192
|
|
|
166
193
|
|
|
167
|
-
<li class="
|
|
194
|
+
<li class="odd ">
|
|
168
195
|
<div class="item">
|
|
169
196
|
<span class='object_link'><a href="Inquery/Mixins/SchemaValidation/ClassMethods.html#schema-instance_method" title="Inquery::Mixins::SchemaValidation::ClassMethods#schema (method)">#schema</a></span>
|
|
170
197
|
<small>Inquery::Mixins::SchemaValidation::ClassMethods</small>
|
|
@@ -172,7 +199,7 @@
|
|
|
172
199
|
</li>
|
|
173
200
|
|
|
174
201
|
|
|
175
|
-
<li class="
|
|
202
|
+
<li class="even ">
|
|
176
203
|
<div class="item">
|
|
177
204
|
<span class='object_link'><a href="Inquery/Mixins/SchemaValidation/ClassMethods.html#schema2-instance_method" title="Inquery::Mixins::SchemaValidation::ClassMethods#schema2 (method)">#schema2</a></span>
|
|
178
205
|
<small>Inquery::Mixins::SchemaValidation::ClassMethods</small>
|
|
@@ -180,7 +207,7 @@
|
|
|
180
207
|
</li>
|
|
181
208
|
|
|
182
209
|
|
|
183
|
-
<li class="
|
|
210
|
+
<li class="odd ">
|
|
184
211
|
<div class="item">
|
|
185
212
|
<span class='object_link'><a href="Inquery/Mixins/SchemaValidation/ClassMethods.html#schema3-instance_method" title="Inquery::Mixins::SchemaValidation::ClassMethods#schema3 (method)">#schema3</a></span>
|
|
186
213
|
<small>Inquery::Mixins::SchemaValidation::ClassMethods</small>
|
|
@@ -188,7 +215,7 @@
|
|
|
188
215
|
</li>
|
|
189
216
|
|
|
190
217
|
|
|
191
|
-
<li class="
|
|
218
|
+
<li class="even ">
|
|
192
219
|
<div class="item">
|
|
193
220
|
<span class='object_link'><a href="Inquery.html#setup-class_method" title="Inquery.setup (method)">setup</a></span>
|
|
194
221
|
<small>Inquery</small>
|
|
@@ -196,7 +223,7 @@
|
|
|
196
223
|
</li>
|
|
197
224
|
|
|
198
225
|
|
|
199
|
-
<li class="
|
|
226
|
+
<li class="odd ">
|
|
200
227
|
<div class="item">
|
|
201
228
|
<span class='object_link'><a href="Inquery/Mixins/RelationValidation.html#validate_relation!-instance_method" title="Inquery::Mixins::RelationValidation#validate_relation! (method)">#validate_relation!</a></span>
|
|
202
229
|
<small>Inquery::Mixins::RelationValidation</small>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title>
|
|
7
7
|
Top Level Namespace
|
|
8
8
|
|
|
9
|
-
— Documentation by YARD 0.9.
|
|
9
|
+
— Documentation by YARD 0.9.37
|
|
10
10
|
|
|
11
11
|
</title>
|
|
12
12
|
|
|
@@ -100,9 +100,9 @@
|
|
|
100
100
|
</div>
|
|
101
101
|
|
|
102
102
|
<div id="footer">
|
|
103
|
-
Generated on
|
|
104
|
-
<a href="
|
|
105
|
-
0.9.
|
|
103
|
+
Generated on Mon Jan 5 14:06:48 2026 by
|
|
104
|
+
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
105
|
+
0.9.37 (ruby-3.3.5).
|
|
106
106
|
</div>
|
|
107
107
|
|
|
108
108
|
</div>
|
data/gemfiles/rails_5.2.gemfile
CHANGED
data/gemfiles/rails_6.0.gemfile
CHANGED
data/gemfiles/rails_6.1.gemfile
CHANGED
data/gemfiles/rails_7.0.gemfile
CHANGED
data/inquery.gemspec
CHANGED
|
@@ -1,46 +1,23 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
-
# stub: inquery 1.0
|
|
2
|
+
# stub: inquery 1.1.0 ruby lib
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |s|
|
|
5
5
|
s.name = "inquery".freeze
|
|
6
|
-
s.version = "1.0.
|
|
6
|
+
s.version = "1.1.0".freeze
|
|
7
7
|
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
|
9
9
|
s.require_paths = ["lib".freeze]
|
|
10
10
|
s.authors = ["Sitrox".freeze]
|
|
11
|
-
s.date = "
|
|
12
|
-
s.files = [".github/workflows/rubocop.yml".freeze, ".github/workflows/ruby.yml".freeze, ".gitignore".freeze, ".releaser_config".freeze, ".rubocop.yml".freeze, "
|
|
13
|
-
s.
|
|
11
|
+
s.date = "2026-01-05"
|
|
12
|
+
s.files = [".github/workflows/rubocop.yml".freeze, ".github/workflows/ruby.yml".freeze, ".gitignore".freeze, ".releaser_config".freeze, ".rubocop.yml".freeze, "Appraisals".freeze, "CHANGELOG.md".freeze, "Gemfile".freeze, "Gemfile.lock".freeze, "LICENSE".freeze, "MIGRATION.md".freeze, "README.md".freeze, "RUBY_VERSION".freeze, "Rakefile".freeze, "VERSION".freeze, "doc/Inquery.html".freeze, "doc/Inquery/Exceptions.html".freeze, "doc/Inquery/Exceptions/Base.html".freeze, "doc/Inquery/Exceptions/InvalidRelation.html".freeze, "doc/Inquery/Exceptions/UnknownCallSignature.html".freeze, "doc/Inquery/MethodAccessibleHash.html".freeze, "doc/Inquery/Mixins.html".freeze, "doc/Inquery/Mixins/RawSqlUtils.html".freeze, "doc/Inquery/Mixins/RelationValidation.html".freeze, "doc/Inquery/Mixins/RelationValidation/ClassMethods.html".freeze, "doc/Inquery/Mixins/SchemaValidation.html".freeze, "doc/Inquery/Mixins/SchemaValidation/ClassMethods.html".freeze, "doc/Inquery/Query.html".freeze, "doc/Inquery/Query/Chainable.html".freeze, "doc/_index.html".freeze, "doc/class_list.html".freeze, "doc/css/common.css".freeze, "doc/css/full_list.css".freeze, "doc/css/style.css".freeze, "doc/file.README.html".freeze, "doc/file_list.html".freeze, "doc/frames.html".freeze, "doc/index.html".freeze, "doc/js/app.js".freeze, "doc/js/full_list.js".freeze, "doc/js/jquery.js".freeze, "doc/method_list.html".freeze, "doc/top-level-namespace.html".freeze, "gemfiles/rails_5.2.gemfile".freeze, "gemfiles/rails_6.0.gemfile".freeze, "gemfiles/rails_6.1.gemfile".freeze, "gemfiles/rails_7.0.gemfile".freeze, "gemfiles/rails_7.1.gemfile".freeze, "gemfiles/rails_7.2.gemfile".freeze, "gemfiles/rails_8.0.gemfile".freeze, "gemfiles/rails_8.1.gemfile".freeze, "inquery.gemspec".freeze, "lib/inquery.rb".freeze, "lib/inquery/exceptions.rb".freeze, "lib/inquery/method_accessible_hash.rb".freeze, "lib/inquery/mixins/raw_sql_utils.rb".freeze, "lib/inquery/mixins/relation_validation.rb".freeze, "lib/inquery/mixins/schema_validation.rb".freeze, "lib/inquery/query.rb".freeze, "lib/inquery/query/chainable.rb".freeze, "test/db/models.rb".freeze, "test/db/schema.rb".freeze, "test/inquery/error_handling_test.rb".freeze, "test/inquery/method_accessible_hash_test.rb".freeze, "test/inquery/mixins/raw_sql_utils_test.rb".freeze, "test/inquery/query/chainable_test.rb".freeze, "test/inquery/query_test.rb".freeze, "test/queries/group/fetch_as_json.rb".freeze, "test/queries/group/fetch_green.rb".freeze, "test/queries/group/fetch_red.rb".freeze, "test/queries/group/filter_with_color.rb".freeze, "test/queries/user/fetch_all.rb".freeze, "test/queries/user/fetch_in_group.rb".freeze, "test/queries/user/fetch_in_group_rel.rb".freeze, "test/test_helper.rb".freeze]
|
|
13
|
+
s.homepage = "https://github.com/sitrox/inquery".freeze
|
|
14
|
+
s.rubygems_version = "3.5.18".freeze
|
|
14
15
|
s.summary = "A skeleton that allows extracting queries into atomic, reusable classes.".freeze
|
|
15
|
-
s.test_files = ["test/db/models.rb".freeze, "test/db/schema.rb".freeze, "test/inquery/query/chainable_test.rb".freeze, "test/inquery/query_test.rb".freeze, "test/queries/group/fetch_as_json.rb".freeze, "test/queries/group/fetch_green.rb".freeze, "test/queries/group/fetch_red.rb".freeze, "test/queries/group/filter_with_color.rb".freeze, "test/queries/user/fetch_all.rb".freeze, "test/queries/user/fetch_in_group.rb".freeze, "test/queries/user/fetch_in_group_rel.rb".freeze, "test/test_helper.rb".freeze]
|
|
16
|
+
s.test_files = ["test/db/models.rb".freeze, "test/db/schema.rb".freeze, "test/inquery/error_handling_test.rb".freeze, "test/inquery/method_accessible_hash_test.rb".freeze, "test/inquery/mixins/raw_sql_utils_test.rb".freeze, "test/inquery/query/chainable_test.rb".freeze, "test/inquery/query_test.rb".freeze, "test/queries/group/fetch_as_json.rb".freeze, "test/queries/group/fetch_green.rb".freeze, "test/queries/group/fetch_red.rb".freeze, "test/queries/group/filter_with_color.rb".freeze, "test/queries/user/fetch_all.rb".freeze, "test/queries/user/fetch_in_group.rb".freeze, "test/queries/user/fetch_in_group_rel.rb".freeze, "test/test_helper.rb".freeze]
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
s.specification_version = 4
|
|
19
|
-
end
|
|
18
|
+
s.specification_version = 4
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
s.add_development_dependency(%q<sqlite3>.freeze, [">= 0"])
|
|
25
|
-
s.add_development_dependency(%q<haml>.freeze, [">= 0"])
|
|
26
|
-
s.add_development_dependency(%q<yard>.freeze, [">= 0"])
|
|
27
|
-
s.add_development_dependency(%q<rubocop>.freeze, ["= 1.25"])
|
|
28
|
-
s.add_development_dependency(%q<redcarpet>.freeze, [">= 0"])
|
|
29
|
-
s.add_runtime_dependency(%q<minitest>.freeze, [">= 0"])
|
|
30
|
-
s.add_runtime_dependency(%q<activesupport>.freeze, [">= 0"])
|
|
31
|
-
s.add_runtime_dependency(%q<activerecord>.freeze, [">= 0"])
|
|
32
|
-
s.add_runtime_dependency(%q<schemacop>.freeze, ["~> 3.0.8"])
|
|
33
|
-
else
|
|
34
|
-
s.add_dependency(%q<appraisal>.freeze, [">= 0"])
|
|
35
|
-
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
|
36
|
-
s.add_dependency(%q<sqlite3>.freeze, [">= 0"])
|
|
37
|
-
s.add_dependency(%q<haml>.freeze, [">= 0"])
|
|
38
|
-
s.add_dependency(%q<yard>.freeze, [">= 0"])
|
|
39
|
-
s.add_dependency(%q<rubocop>.freeze, ["= 1.25"])
|
|
40
|
-
s.add_dependency(%q<redcarpet>.freeze, [">= 0"])
|
|
41
|
-
s.add_dependency(%q<minitest>.freeze, [">= 0"])
|
|
42
|
-
s.add_dependency(%q<activesupport>.freeze, [">= 0"])
|
|
43
|
-
s.add_dependency(%q<activerecord>.freeze, [">= 0"])
|
|
44
|
-
s.add_dependency(%q<schemacop>.freeze, ["~> 3.0.8"])
|
|
45
|
-
end
|
|
20
|
+
s.add_runtime_dependency(%q<activesupport>.freeze, [">= 5.1".freeze])
|
|
21
|
+
s.add_runtime_dependency(%q<activerecord>.freeze, [">= 5.1".freeze])
|
|
22
|
+
s.add_runtime_dependency(%q<schemacop>.freeze, [">= 3.0.8".freeze, "< 4.0".freeze])
|
|
46
23
|
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Inquery
|
|
2
|
+
# A safe alternative for OpenStruct in Ruby. It behaves exactly the same, but
|
|
3
|
+
# does not define methods on-the-fly but uses `method_missing` instead.
|
|
4
|
+
#
|
|
5
|
+
# Usage example:
|
|
6
|
+
#
|
|
7
|
+
# ```ruby
|
|
8
|
+
# default_options = { foo: :bar }
|
|
9
|
+
# options = MethodAccessibleHash.new(default_options)
|
|
10
|
+
# options[:color] = :green
|
|
11
|
+
# options.foo # => :bar
|
|
12
|
+
# options.color # => green
|
|
13
|
+
# ```
|
|
14
|
+
class MethodAccessibleHash < ::Hash
|
|
15
|
+
# Takes an optional hash as argument and constructs a new
|
|
16
|
+
# MethodAccessibleHash.
|
|
17
|
+
def initialize(hash = {})
|
|
18
|
+
super()
|
|
19
|
+
|
|
20
|
+
hash.each do |key, value|
|
|
21
|
+
self[key.to_sym] = value
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @private
|
|
26
|
+
def merge(**hash)
|
|
27
|
+
super(hash.symbolize_keys)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @private
|
|
31
|
+
def method_missing(method, *args, &_block)
|
|
32
|
+
if method.to_s.end_with?('=')
|
|
33
|
+
name = method.to_s.gsub(/=$/, '')
|
|
34
|
+
self[name.to_sym] = args.first
|
|
35
|
+
else
|
|
36
|
+
self[method.to_sym]
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @private
|
|
41
|
+
def respond_to_missing?(_method, _include_private = false)
|
|
42
|
+
true
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -1,19 +1,45 @@
|
|
|
1
1
|
module Inquery
|
|
2
2
|
module Mixins
|
|
3
|
+
# Provides utilities for working with raw SQL queries in a safe way.
|
|
4
|
+
#
|
|
5
|
+
# This mixin adds two helper methods for executing raw SQL queries:
|
|
6
|
+
# 'san' for sanitizing SQL with parameter substitution, and 'exec_query'
|
|
7
|
+
# for executing sanitized SQL and returning results.
|
|
3
8
|
module RawSqlUtils
|
|
4
9
|
extend ActiveSupport::Concern
|
|
5
10
|
|
|
6
11
|
included do
|
|
7
|
-
# Sanitizes
|
|
8
|
-
#
|
|
12
|
+
# Sanitizes SQL and substitutes variables using ActiveRecord's
|
|
13
|
+
# parameterized query mechanism.
|
|
14
|
+
#
|
|
15
|
+
# This method uses ActiveRecord's 'sanitize_sql_array' to safely
|
|
16
|
+
# escape values and prevent SQL injection. Always use this instead of
|
|
17
|
+
# string interpolation when building SQL queries.
|
|
18
|
+
#
|
|
19
|
+
# Example:
|
|
20
|
+
# sql = san("SELECT * FROM users WHERE age > ? AND city = ?", 18, 'NYC')
|
|
21
|
+
# # => "SELECT * FROM users WHERE age > 18 AND city = 'NYC'"
|
|
22
|
+
#
|
|
23
|
+
# @param sql [String] SQL query with '?' placeholders
|
|
24
|
+
# @param variables [Array] Values to substitute for placeholders
|
|
25
|
+
# @return [String] Sanitized SQL with values substituted
|
|
9
26
|
def san(sql, *variables)
|
|
10
27
|
ActiveRecord::Base.send(:sanitize_sql_array, [sql, *variables])
|
|
11
28
|
end
|
|
12
29
|
|
|
13
|
-
# Executes
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
30
|
+
# Executes sanitized SQL and returns the results.
|
|
31
|
+
#
|
|
32
|
+
# The SQL should already be sanitized using the 'san' method or
|
|
33
|
+
# ActiveRecord's query methods. Uses the connection from the 'connection'
|
|
34
|
+
# method, which must be defined in the including class.
|
|
35
|
+
#
|
|
36
|
+
# Example:
|
|
37
|
+
# sql = san("SELECT COUNT(*) as total FROM users WHERE active = ?", true)
|
|
38
|
+
# result = exec_query(sql)
|
|
39
|
+
# result.first['total'] # => 42
|
|
40
|
+
#
|
|
41
|
+
# @param sql [String] Sanitized SQL query to execute
|
|
42
|
+
# @return [ActiveRecord::Result] Query results
|
|
17
43
|
def exec_query(sql)
|
|
18
44
|
connection.exec_query(sql, self.class.to_s)
|
|
19
45
|
end
|
|
@@ -91,7 +91,7 @@ module Inquery
|
|
|
91
91
|
# ---------------------------------------------------------------
|
|
92
92
|
fields_count = relation.select_values.size
|
|
93
93
|
|
|
94
|
-
if fields_count.zero? && options[:default_select] && options[:fields]
|
|
94
|
+
if fields_count.zero? && options[:default_select] && options[:fields]&.positive?
|
|
95
95
|
relation = relation.select(options[:default_select])
|
|
96
96
|
fields_count = 1
|
|
97
97
|
end
|