simple_query 0.1.0 → 0.2.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/README.md +57 -2
- data/lib/simple_query/builder.rb +114 -73
- data/lib/simple_query/clauses/distinct_clause.rb +22 -0
- data/lib/simple_query/clauses/group_having_clause.rb +30 -0
- data/lib/simple_query/clauses/join_clause.rb +35 -0
- data/lib/simple_query/clauses/limit_offset_clause.rb +30 -0
- data/lib/simple_query/clauses/order_clause.rb +32 -0
- data/lib/simple_query/clauses/where_clause.rb +38 -0
- data/lib/simple_query/read_model.rb +25 -0
- data/lib/simple_query/version.rb +1 -1
- data/lib/simple_query.rb +32 -4
- metadata +15 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8295c4f43760f52dd7097852465c6d5ba007fb98789c233c25e88132113fccf
|
4
|
+
data.tar.gz: 45ced1eee79912b86eddaa4bf13ad7d56b4609ee8e68ce02390d027600d78509
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 745e1f6bd0b85d12a5cab8e21d4839950bd98948914a54fae2ac77c47e7fe5861625081396ff4437684a1e2ade5441514c597e9c4d61577d51e580b628751f69
|
7
|
+
data.tar.gz: 1b034d21747e3740e2e390d428856a67b112e7c179d7704457bddc4983723f752f6aef87b76b3b2dd8d0c1857a6d55a834055f6749e85e7def1b005574c38cb5
|
data/README.md
CHANGED
@@ -20,6 +20,30 @@ Or install it yourself as:
|
|
20
20
|
gem install simple_query
|
21
21
|
```
|
22
22
|
|
23
|
+
## Configuration
|
24
|
+
|
25
|
+
By default, `SimpleQuery` does **not** automatically patch `ActiveRecord::Base`. You can **manually** include the module in individual models or in a global initializer:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
# Manual include (per model)
|
29
|
+
class User < ActiveRecord::Base
|
30
|
+
include SimpleQuery
|
31
|
+
end
|
32
|
+
|
33
|
+
# or do it globally
|
34
|
+
ActiveRecord::Base.include(SimpleQuery)
|
35
|
+
```
|
36
|
+
If you prefer a “just works” approach (i.e., every model has `.simple_query`), you can opt in:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
# config/initializers/simple_query.rb
|
40
|
+
SimpleQuery.configure do |config|
|
41
|
+
config.auto_include_ar = true
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
This tells SimpleQuery to automatically do `ActiveRecord::Base.include(SimpleQuery)` for you.
|
46
|
+
|
23
47
|
## Usage
|
24
48
|
|
25
49
|
SimpleQuery offers an intuitive interface for building queries with joins, conditions, and aggregations. Here are some examples:
|
@@ -58,6 +82,32 @@ User.simple_query
|
|
58
82
|
.lazy_execute
|
59
83
|
```
|
60
84
|
|
85
|
+
## Custom Read Models
|
86
|
+
By default, SimpleQuery returns results as `Struct` objects for maximum speed. However, you can also define a lightweight model class for more explicit attribute handling or custom logic.
|
87
|
+
|
88
|
+
**Create a read model** inheriting from `SimpleQuery::ReadModel`:
|
89
|
+
```ruby
|
90
|
+
class MyUserReadModel < SimpleQuery::ReadModel
|
91
|
+
attribute :identifier, column: :id
|
92
|
+
attribute :full_name, column: :name
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
96
|
+
**Map query results** to your read model:
|
97
|
+
```ruby
|
98
|
+
results = User.simple_query
|
99
|
+
.select("users.id AS id", "users.name AS name")
|
100
|
+
.where(active: true)
|
101
|
+
.map_to(MyUserReadModel)
|
102
|
+
.execute
|
103
|
+
|
104
|
+
results.each do |user|
|
105
|
+
puts user.identifier # => user.id from the DB
|
106
|
+
puts user.full_name # => user.name from the DB
|
107
|
+
end
|
108
|
+
```
|
109
|
+
This custom read model approach provides more clarity or domain-specific logic while still being faster than typical ActiveRecord instantiation.
|
110
|
+
|
61
111
|
## Features
|
62
112
|
|
63
113
|
- Efficient query building
|
@@ -67,7 +117,9 @@ User.simple_query
|
|
67
117
|
- Aggregations
|
68
118
|
- LIMIT and OFFSET
|
69
119
|
- ORDER BY clause
|
120
|
+
- Having and Grouping
|
70
121
|
- Subqueries
|
122
|
+
- Custom Read models
|
71
123
|
|
72
124
|
## Performance
|
73
125
|
|
@@ -75,9 +127,12 @@ SimpleQuery is designed to potentially outperform standard ActiveRecord queries
|
|
75
127
|
|
76
128
|
```
|
77
129
|
🚀 Performance Results (100,000 records):
|
78
|
-
ActiveRecord Query:
|
79
|
-
SimpleQuery Execution: 0.
|
130
|
+
ActiveRecord Query: 0.47441 seconds
|
131
|
+
SimpleQuery Execution (Struct): 0.05346 seconds
|
132
|
+
SimpleQuery Execution (Read model): 0.14408 seconds
|
80
133
|
```
|
134
|
+
- The **Struct-based** approach is the fastest.
|
135
|
+
- The **Read model** approach is still significantly faster than ActiveRecord, while letting you define custom logic or domain-specific attributes.
|
81
136
|
|
82
137
|
## Development
|
83
138
|
|
data/lib/simple_query/builder.rb
CHANGED
@@ -2,21 +2,24 @@
|
|
2
2
|
|
3
3
|
module SimpleQuery
|
4
4
|
class Builder
|
5
|
-
attr_reader :model, :arel_table
|
5
|
+
attr_reader :model, :arel_table
|
6
6
|
|
7
7
|
def initialize(source)
|
8
8
|
@model = source
|
9
9
|
@arel_table = @model.arel_table
|
10
|
+
|
10
11
|
@selects = []
|
11
|
-
@wheres =
|
12
|
-
@joins =
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@
|
16
|
-
@distinct_flag =
|
12
|
+
@wheres = WhereClause.new(@arel_table)
|
13
|
+
@joins = JoinClause.new
|
14
|
+
@group_having = GroupHavingClause.new(@arel_table)
|
15
|
+
@orders = OrderClause.new(@arel_table)
|
16
|
+
@limits = LimitOffsetClause.new
|
17
|
+
@distinct_flag = DistinctClause.new
|
18
|
+
|
17
19
|
@query_cache = {}
|
18
|
-
@result_struct = nil
|
19
20
|
@query_built = false
|
21
|
+
@read_model_class = nil
|
22
|
+
@result_struct = nil
|
20
23
|
end
|
21
24
|
|
22
25
|
def select(*fields)
|
@@ -26,58 +29,75 @@ module SimpleQuery
|
|
26
29
|
end
|
27
30
|
|
28
31
|
def where(condition)
|
29
|
-
@wheres.
|
32
|
+
@wheres.add(condition)
|
30
33
|
reset_query
|
31
34
|
self
|
32
35
|
end
|
33
36
|
|
34
37
|
def join(table1, table2, foreign_key:, primary_key:)
|
35
|
-
@joins
|
36
|
-
table1: arel_table(table1),
|
37
|
-
table2: arel_table(table2),
|
38
|
-
foreign_key: foreign_key,
|
39
|
-
primary_key: primary_key
|
40
|
-
}
|
38
|
+
@joins.add(table1, table2, foreign_key: foreign_key, primary_key: primary_key)
|
41
39
|
reset_query
|
42
40
|
self
|
43
41
|
end
|
44
42
|
|
45
43
|
def order(order_conditions)
|
46
|
-
@orders.
|
44
|
+
@orders.add(order_conditions)
|
47
45
|
reset_query
|
48
46
|
self
|
49
47
|
end
|
50
48
|
|
51
49
|
def limit(number)
|
52
|
-
|
53
|
-
@limits = number
|
50
|
+
@limits.with_limit(number)
|
54
51
|
reset_query
|
55
52
|
self
|
56
53
|
end
|
57
54
|
|
58
55
|
def offset(number)
|
59
|
-
|
60
|
-
@offsets = number
|
56
|
+
@limits.with_offset(number)
|
61
57
|
reset_query
|
62
58
|
self
|
63
59
|
end
|
64
60
|
|
65
61
|
def distinct
|
66
|
-
@distinct_flag
|
62
|
+
@distinct_flag.set_distinct
|
63
|
+
reset_query
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
def group(*fields)
|
68
|
+
@group_having.add_group(*fields)
|
69
|
+
reset_query
|
70
|
+
self
|
71
|
+
end
|
72
|
+
|
73
|
+
def having(condition)
|
74
|
+
@group_having.add_having(condition)
|
75
|
+
reset_query
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
79
|
+
def map_to(klass)
|
80
|
+
@read_model_class = klass
|
67
81
|
reset_query
|
68
82
|
self
|
69
83
|
end
|
70
84
|
|
71
85
|
def execute
|
72
86
|
records = ActiveRecord::Base.connection.select_all(cached_sql)
|
73
|
-
|
87
|
+
build_result_objects_from_rows(records)
|
74
88
|
end
|
75
89
|
|
76
90
|
def lazy_execute
|
77
91
|
Enumerator.new do |yielder|
|
78
92
|
records = ActiveRecord::Base.connection.select_all(cached_sql)
|
79
|
-
|
80
|
-
|
93
|
+
if @read_model_class
|
94
|
+
build_read_models_enumerator(records, yielder)
|
95
|
+
else
|
96
|
+
struct = result_struct(records.columns)
|
97
|
+
records.rows.each do |row_array|
|
98
|
+
yielder << struct.new(*row_array)
|
99
|
+
end
|
100
|
+
end
|
81
101
|
end
|
82
102
|
end
|
83
103
|
|
@@ -87,10 +107,11 @@ module SimpleQuery
|
|
87
107
|
@query = Arel::SelectManager.new(Arel::Table.engine)
|
88
108
|
@query.from(@arel_table)
|
89
109
|
@query.project(*(@selects.empty? ? [@arel_table[Arel.star]] : @selects))
|
90
|
-
@query.distinct if @distinct_flag
|
91
110
|
|
111
|
+
apply_distinct
|
92
112
|
apply_where_conditions
|
93
113
|
apply_joins
|
114
|
+
apply_group_and_having
|
94
115
|
apply_order_conditions
|
95
116
|
apply_limit_and_offset
|
96
117
|
|
@@ -106,78 +127,98 @@ module SimpleQuery
|
|
106
127
|
end
|
107
128
|
|
108
129
|
def cached_sql
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
130
|
+
key = [
|
131
|
+
@selects,
|
132
|
+
@wheres.conditions,
|
133
|
+
@joins.joins,
|
134
|
+
@group_having.group_fields,
|
135
|
+
@group_having.having_conditions,
|
136
|
+
@orders.orders,
|
137
|
+
@limits.limit_value,
|
138
|
+
@limits.offset_value,
|
139
|
+
@distinct_flag.use_distinct?
|
140
|
+
]
|
141
|
+
|
142
|
+
@query_cache[key] ||= build_query.to_sql
|
143
|
+
end
|
144
|
+
|
145
|
+
def build_result_objects_from_rows(records)
|
146
|
+
if @read_model_class
|
147
|
+
build_read_models_from_arrays(records)
|
121
148
|
else
|
122
|
-
|
123
|
-
|
124
|
-
end
|
125
|
-
|
126
|
-
def parse_where_condition(condition)
|
127
|
-
case condition
|
128
|
-
when Hash then condition.map { |field, value| @arel_table[field].eq(value) }
|
129
|
-
when Arel::Nodes::Node then [condition]
|
130
|
-
else [Arel.sql(condition.to_s)]
|
149
|
+
struct = result_struct(records.columns)
|
150
|
+
records.rows.map { |row_array| struct.new(*row_array) }
|
131
151
|
end
|
132
152
|
end
|
133
153
|
|
134
|
-
def
|
135
|
-
|
136
|
-
|
154
|
+
def build_read_models_from_arrays(records)
|
155
|
+
columns = records.columns
|
156
|
+
column_map = columns.each_with_index.to_h
|
157
|
+
rows = records.rows
|
137
158
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
159
|
+
rows.map do |row_array|
|
160
|
+
obj = @read_model_class.allocate
|
161
|
+
@read_model_class.attributes.each do |attr_name, col_name|
|
162
|
+
idx = column_map[col_name]
|
163
|
+
obj.instance_variable_set(:"@#{attr_name}", row_array[idx]) if idx
|
164
|
+
end
|
165
|
+
obj
|
142
166
|
end
|
143
167
|
end
|
144
168
|
|
145
|
-
def
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
169
|
+
def build_read_models_enumerator(records, yielder)
|
170
|
+
columns = records.columns
|
171
|
+
column_map = columns.each_with_index.to_h
|
172
|
+
records.rows.each do |row_array|
|
173
|
+
obj = @read_model_class.allocate
|
174
|
+
@read_model_class.attributes.each do |attr_name, col_name|
|
175
|
+
idx = column_map[col_name]
|
176
|
+
obj.instance_variable_set(:"@#{attr_name}", row_array[idx]) if idx
|
177
|
+
end
|
178
|
+
yielder << obj
|
179
|
+
end
|
153
180
|
end
|
154
181
|
|
155
|
-
def
|
156
|
-
|
182
|
+
def result_struct(columns)
|
183
|
+
@result_struct ||= Struct.new(*columns.map(&:to_sym))
|
157
184
|
end
|
158
185
|
|
159
|
-
def
|
160
|
-
|
161
|
-
records.rows.map { |row| struct.new(*row) }
|
186
|
+
def apply_distinct
|
187
|
+
@distinct_flag.apply_to(@query)
|
162
188
|
end
|
163
189
|
|
164
190
|
def apply_where_conditions
|
165
|
-
|
191
|
+
condition = @wheres.to_arel
|
192
|
+
@query.where(condition) if condition
|
166
193
|
end
|
167
194
|
|
168
195
|
def apply_joins
|
169
|
-
@joins.
|
170
|
-
|
171
|
-
|
196
|
+
@joins.apply_to(@query)
|
197
|
+
end
|
198
|
+
|
199
|
+
def apply_group_and_having
|
200
|
+
@group_having.apply_to(@query)
|
172
201
|
end
|
173
202
|
|
174
203
|
def apply_order_conditions
|
175
|
-
@orders.
|
204
|
+
@orders.apply_to(@query)
|
176
205
|
end
|
177
206
|
|
178
207
|
def apply_limit_and_offset
|
179
|
-
@
|
180
|
-
|
208
|
+
@limits.apply_to(@query)
|
209
|
+
end
|
210
|
+
|
211
|
+
def parse_select_field(field)
|
212
|
+
case field
|
213
|
+
when Symbol
|
214
|
+
@arel_table[field]
|
215
|
+
when String
|
216
|
+
Arel.sql(field)
|
217
|
+
when Arel::Nodes::Node
|
218
|
+
field
|
219
|
+
else
|
220
|
+
raise ArgumentError, "Unsupported select field type: #{field.class}"
|
221
|
+
end
|
181
222
|
end
|
182
223
|
end
|
183
224
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SimpleQuery
|
4
|
+
class DistinctClause
|
5
|
+
def initialize
|
6
|
+
@use_distinct = false
|
7
|
+
end
|
8
|
+
|
9
|
+
def use_distinct?
|
10
|
+
@use_distinct
|
11
|
+
end
|
12
|
+
|
13
|
+
def set_distinct
|
14
|
+
@use_distinct = true
|
15
|
+
end
|
16
|
+
|
17
|
+
def apply_to(query)
|
18
|
+
query.distinct if @use_distinct
|
19
|
+
query
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SimpleQuery
|
4
|
+
class GroupHavingClause
|
5
|
+
attr_reader :group_fields, :having_conditions
|
6
|
+
|
7
|
+
def initialize(table)
|
8
|
+
@table = table
|
9
|
+
@group_fields = []
|
10
|
+
@having_conditions = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_group(*fields)
|
14
|
+
@group_fields.concat(fields.map { |f| @table[f] })
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_having(condition)
|
18
|
+
@having_conditions << condition
|
19
|
+
end
|
20
|
+
|
21
|
+
def apply_to(query)
|
22
|
+
@group_fields.each { |g| query.group(g) }
|
23
|
+
if @having_conditions.any?
|
24
|
+
combined = @having_conditions.inject { |c, a| c.and(a) }
|
25
|
+
query.having(combined)
|
26
|
+
end
|
27
|
+
query
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SimpleQuery
|
4
|
+
class JoinClause
|
5
|
+
attr_reader :joins
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@joins = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def add(table1, table2, foreign_key:, primary_key:)
|
12
|
+
@joins << {
|
13
|
+
table1: to_arel_table(table1),
|
14
|
+
table2: to_arel_table(table2),
|
15
|
+
foreign_key: foreign_key,
|
16
|
+
primary_key: primary_key
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def apply_to(query)
|
21
|
+
@joins.each do |join|
|
22
|
+
query.join(join[:table2])
|
23
|
+
.on(join[:table2][join[:foreign_key]]
|
24
|
+
.eq(join[:table1][join[:primary_key]]))
|
25
|
+
end
|
26
|
+
query
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def to_arel_table(obj)
|
32
|
+
obj.is_a?(Arel::Table) ? obj : Arel::Table.new(obj)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SimpleQuery
|
4
|
+
class LimitOffsetClause
|
5
|
+
attr_reader :limit_value, :offset_value
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@limit_value = nil
|
9
|
+
@offset_value = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def with_limit(limit)
|
13
|
+
raise ArgumentError, "LIMIT must be a positive integer" unless limit.is_a?(Integer) && limit.positive?
|
14
|
+
|
15
|
+
@limit_value = limit
|
16
|
+
end
|
17
|
+
|
18
|
+
def with_offset(offset)
|
19
|
+
raise ArgumentError, "OFFSET must be a non-negative integer" unless offset.is_a?(Integer) && offset >= 0
|
20
|
+
|
21
|
+
@offset_value = offset
|
22
|
+
end
|
23
|
+
|
24
|
+
def apply_to(query)
|
25
|
+
query.take(@limit_value) if @limit_value
|
26
|
+
query.skip(@offset_value) if @offset_value
|
27
|
+
query
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SimpleQuery
|
4
|
+
class OrderClause
|
5
|
+
attr_reader :orders
|
6
|
+
|
7
|
+
def initialize(table)
|
8
|
+
@table = table
|
9
|
+
@orders = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def add(order_conditions)
|
13
|
+
order_conditions.each do |field, direction|
|
14
|
+
validate_order_direction(direction)
|
15
|
+
@orders << @table[field].send(direction)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def apply_to(query)
|
20
|
+
@orders.each { |order_node| query.order(order_node) }
|
21
|
+
query
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def validate_order_direction(direction)
|
27
|
+
return if [:asc, :desc].include?(direction)
|
28
|
+
|
29
|
+
raise ArgumentError, "Invalid order direction: #{direction}. Use :asc or :desc."
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SimpleQuery
|
4
|
+
class WhereClause
|
5
|
+
attr_reader :conditions
|
6
|
+
|
7
|
+
def initialize(table)
|
8
|
+
@table = table
|
9
|
+
@conditions = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def add(condition)
|
13
|
+
parsed_conditions = parse_condition(condition)
|
14
|
+
@conditions.concat(parsed_conditions)
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_arel
|
18
|
+
return nil if @conditions.empty?
|
19
|
+
|
20
|
+
@conditions.inject do |combined, current|
|
21
|
+
combined.and(current)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def parse_condition(condition)
|
28
|
+
case condition
|
29
|
+
when Hash
|
30
|
+
condition.map { |field, value| @table[field].eq(value) }
|
31
|
+
when Arel::Nodes::Node
|
32
|
+
[condition]
|
33
|
+
else
|
34
|
+
[Arel.sql(condition.to_s)]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SimpleQuery
|
4
|
+
class ReadModel
|
5
|
+
def self.attribute(attr_name, column: attr_name)
|
6
|
+
@attributes ||= {}
|
7
|
+
@attributes[attr_name] = column.to_s
|
8
|
+
attr_reader attr_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.attributes
|
12
|
+
@attributes || {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.build_from_row(row_hash)
|
16
|
+
obj = allocate
|
17
|
+
attributes.each do |attr_name, column_name|
|
18
|
+
obj.instance_variable_set(:"@#{attr_name}", row_hash[column_name])
|
19
|
+
end
|
20
|
+
obj
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize; end
|
24
|
+
end
|
25
|
+
end
|
data/lib/simple_query/version.rb
CHANGED
data/lib/simple_query.rb
CHANGED
@@ -1,16 +1,44 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/concern"
|
3
4
|
require "active_record"
|
4
|
-
|
5
|
+
|
6
|
+
require_relative "simple_query/builder"
|
7
|
+
require_relative "simple_query/read_model"
|
8
|
+
require_relative "simple_query/clauses/where_clause"
|
9
|
+
require_relative "simple_query/clauses/join_clause"
|
10
|
+
require_relative "simple_query/clauses/order_clause"
|
11
|
+
require_relative "simple_query/clauses/distinct_clause"
|
12
|
+
require_relative "simple_query/clauses/limit_offset_clause"
|
13
|
+
require_relative "simple_query/clauses/group_having_clause"
|
5
14
|
|
6
15
|
module SimpleQuery
|
7
16
|
extend ActiveSupport::Concern
|
8
17
|
|
18
|
+
class Configuration
|
19
|
+
attr_accessor :auto_include_ar
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@auto_include_ar = false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.configure
|
27
|
+
yield config
|
28
|
+
auto_include! if config.auto_include_ar
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.config
|
32
|
+
@config ||= Configuration.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.auto_include!
|
36
|
+
ActiveRecord::Base.include(SimpleQuery)
|
37
|
+
end
|
38
|
+
|
9
39
|
included do
|
10
40
|
def self.simple_query
|
11
|
-
|
41
|
+
Builder.new(self)
|
12
42
|
end
|
13
43
|
end
|
14
44
|
end
|
15
|
-
|
16
|
-
ActiveRecord::Base.include SimpleQuery
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_query
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Kholodniak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-02-
|
11
|
+
date: 2025-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
- - "
|
19
|
+
version: '7.0'
|
20
|
+
- - "<="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '8.0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
30
|
-
- - "
|
29
|
+
version: '7.0'
|
30
|
+
- - "<="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '8.0'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rake
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,6 +100,13 @@ files:
|
|
100
100
|
- README.md
|
101
101
|
- lib/simple_query.rb
|
102
102
|
- lib/simple_query/builder.rb
|
103
|
+
- lib/simple_query/clauses/distinct_clause.rb
|
104
|
+
- lib/simple_query/clauses/group_having_clause.rb
|
105
|
+
- lib/simple_query/clauses/join_clause.rb
|
106
|
+
- lib/simple_query/clauses/limit_offset_clause.rb
|
107
|
+
- lib/simple_query/clauses/order_clause.rb
|
108
|
+
- lib/simple_query/clauses/where_clause.rb
|
109
|
+
- lib/simple_query/read_model.rb
|
103
110
|
- lib/simple_query/version.rb
|
104
111
|
homepage: https://oneruby.dev
|
105
112
|
licenses:
|