like_query 0.0.7 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +80 -51
- data/lib/like_query/collect.rb +34 -25
- data/lib/like_query/model_extensions.rb +8 -2
- data/lib/like_query/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '09331b69e73a5710ea602d9f20c26a11453589480b8be7130bb678a430c13f17'
|
4
|
+
data.tar.gz: 82eb9cb8c04f0c3d0d6fa7bccd22fde4cf9468a3aec31f533f2ce8d2fb9d0765
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '090626d9d0b0afe7879c6a7053e9ab3e87fd7e3faa797015ab47bbc258c41ee19bc2666fda4bb0bfacb8c563e871e9f75c2e959275836d0233955f3cd7fdbdad'
|
7
|
+
data.tar.gz: c1835c63c13d9b09d084b34b6b7ae24db6cf890317166e130e13daf56f8f8baabe6d4ae49bc9f36b94798276caa07853fbca6eee0f58978bca143dfecd7a76d1
|
data/README.md
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
# like_query
|
2
2
|
|
3
|
-
For my
|
3
|
+
For my clients' newly built applications with Turbo, search queries mostly serve two purposes:
|
4
4
|
|
5
5
|
- Index view callable by a url like `/customers?find=müller screw`
|
6
|
-
- javascript component / dropdown on the front, in our case
|
7
|
-
built with svelte, which receives a json and renders a table in a dropdown.
|
6
|
+
- javascript component / dropdown on the front, in our case built with svelte, which receives a json and renders a table in a dropdown.
|
8
7
|
|
9
|
-
This query generator is built for
|
8
|
+
This query generator is built for these two purposes
|
10
9
|
|
11
|
-
|
10
|
+
Modules like one of the svelte components mentioned above have a total response time (from pressing a key until the result is rendered) of about 60 msec, while with turbo the same time is mostly around 140-160 msec. The gem itself, from querying the database to producing a hash, has a time of about 3 msec. These results are for small data sets (e.g. 30 records found).
|
12
11
|
|
13
12
|
## Installation
|
14
13
|
|
@@ -20,13 +19,23 @@ to Gemfile
|
|
20
19
|
|
21
20
|
this adds the methods `#like` and `#generate_hash` to all models.
|
22
21
|
|
22
|
+
**Config**
|
23
|
+
|
24
|
+
You can set a default limit by
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
config.x.like_query.limit = 20
|
28
|
+
```
|
29
|
+
|
30
|
+
This can be overriden by calling the methods
|
31
|
+
|
23
32
|
## Usage
|
24
33
|
|
25
34
|
**#like**
|
26
35
|
|
27
36
|
```ruby
|
28
37
|
customer = Customer.create(name: 'Ambühl')
|
29
|
-
|
38
|
+
Article.create(name: 'first', number: '01', customer: customer)
|
30
39
|
|
31
40
|
Article.like('fir', :name, :number)
|
32
41
|
# => <Article:0x00000001067107a8 id: ...>
|
@@ -41,8 +50,7 @@ Article.like(['fir', 'ambühl'], :name, :number, customer: :name)
|
|
41
50
|
|
42
51
|
**#generate_hash**
|
43
52
|
|
44
|
-
can
|
45
|
-
returns a hash that can easily be transformed by `#to_json` for a javascript-frontend, by example
|
53
|
+
returns a hash that can easily be transformed by `#to_json` for a javascript frontend, for example
|
46
54
|
|
47
55
|
```ruby
|
48
56
|
customer = Customer.create(name: 'Ambühl')
|
@@ -51,14 +59,22 @@ art1 = Article.create(name: 'first', number: '01', customer: customer)
|
|
51
59
|
Article.like('fir', :name).generate_hash(limit: 10)
|
52
60
|
# returns:
|
53
61
|
{
|
54
|
-
:
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
+
data:
|
63
|
+
[
|
64
|
+
{
|
65
|
+
values: ["Müller"],
|
66
|
+
attributes: {"customer.name": "Müller"},
|
67
|
+
id: 1,
|
68
|
+
model: "Article"
|
69
|
+
},
|
70
|
+
...
|
71
|
+
],
|
72
|
+
length: 4,
|
73
|
+
overflow: true,
|
74
|
+
columns_count: 2,
|
75
|
+
sub_records_columns_count: 0,
|
76
|
+
image: false,
|
77
|
+
time: 18.282996
|
62
78
|
}
|
63
79
|
|
64
80
|
Article.like('fir', :name).generate_hash(:number, limit: 10)
|
@@ -71,42 +87,56 @@ Article.like('fir', :name).generate_hash(:number, limit: 10)
|
|
71
87
|
**Class LikeQuery::Collect**
|
72
88
|
|
73
89
|
```ruby
|
74
|
-
cust = Customer.create(name: '
|
75
|
-
|
90
|
+
cust = Customer.create(name: 'cust')
|
91
|
+
Article.create(name: 'screw', customer: cust)
|
76
92
|
|
77
93
|
c = LikeQuery::Collect.new(4)
|
78
94
|
# => 4 is the limit
|
79
95
|
|
80
|
-
c.
|
81
|
-
|
82
|
-
|
83
|
-
c.collect { Customer.like('any-art', :name, image: :image_column, articles: :name) }
|
84
|
-
# => limit is already exhausted: does nothing
|
85
|
-
# => otherwise it would add Customers to the result hash
|
86
|
-
|
96
|
+
c.set_schema(Customer, :name)
|
97
|
+
c.collect(parent: :customer) { Article.like('screw', :name) }
|
98
|
+
c.generate_json
|
87
99
|
c.result
|
88
|
-
|
100
|
+
|
101
|
+
# =>
|
89
102
|
{
|
90
|
-
:
|
91
|
-
{
|
92
|
-
:
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
}
|
103
|
+
"data": [
|
104
|
+
{
|
105
|
+
"values": [
|
106
|
+
"cust"
|
107
|
+
],
|
108
|
+
"attributes": {
|
109
|
+
"name": "cust"
|
110
|
+
},
|
111
|
+
"id": 1,
|
112
|
+
"model": "Customer",
|
113
|
+
"children": [
|
114
|
+
{
|
115
|
+
"values": [
|
116
|
+
"screw"
|
117
|
+
],
|
118
|
+
"attributes": {
|
119
|
+
"name": "screw"
|
120
|
+
},
|
121
|
+
"id": 1,
|
122
|
+
"model": "Customer.Article",
|
123
|
+
"parent_id": 1,
|
124
|
+
}
|
125
|
+
]
|
98
126
|
}
|
99
127
|
],
|
100
|
-
:
|
101
|
-
:
|
102
|
-
:
|
103
|
-
:
|
128
|
+
"length": 2,
|
129
|
+
"overflow": false,
|
130
|
+
"columns_count": 1,
|
131
|
+
"sub_records_columns_count": 0,
|
132
|
+
"image": false,
|
133
|
+
"time": 0.0075
|
104
134
|
}
|
105
135
|
```
|
106
136
|
|
107
137
|
**query schema and result_schema**
|
108
138
|
|
109
|
-
The resulting hash for
|
139
|
+
The resulting hash for a record looks like this:
|
110
140
|
|
111
141
|
```ruby
|
112
142
|
{
|
@@ -117,7 +147,7 @@ The resulting hash for one record looks like:
|
|
117
147
|
}
|
118
148
|
```
|
119
149
|
|
120
|
-
The resulting hash or json is built from the schema, which can look like:
|
150
|
+
The resulting hash or json is built from the schema, which can look like this:
|
121
151
|
|
122
152
|
```ruby
|
123
153
|
:number
|
@@ -138,22 +168,22 @@ or
|
|
138
168
|
}
|
139
169
|
```
|
140
170
|
|
141
|
-
There is a query schema and
|
142
|
-
If no output schema is defined, query schema is used for both
|
171
|
+
There is a query schema and an output schema.
|
172
|
+
If no output schema is defined, the query schema is used for both.
|
143
173
|
|
144
174
|
```ruby
|
145
175
|
Article.like('first', :name).generate_hash
|
146
176
|
# => :values => ["first"]
|
147
177
|
```
|
148
178
|
|
149
|
-
If output schema is
|
179
|
+
If an output schema is specified, the result may differ from the search scope:
|
150
180
|
|
151
181
|
```ruby
|
152
182
|
Article.like('first', :name).generate_hash(:number, :name)
|
153
183
|
# => :values => ["012", "first"]
|
154
184
|
```
|
155
185
|
|
156
|
-
The collect class
|
186
|
+
The collect class remembers the schema for a model:
|
157
187
|
|
158
188
|
```ruby
|
159
189
|
c = LikeQuery::Collect.new
|
@@ -164,8 +194,8 @@ c.collect { Article.like('x', :number) } # => schema [:number] is used
|
|
164
194
|
|
165
195
|
**#set_schema**
|
166
196
|
|
167
|
-
|
168
|
-
Otherwise `#generate_hash` would not know
|
197
|
+
When a child returns its parent, the schema for the parent must be given.
|
198
|
+
Otherwise `#generate_hash` would not know what values to return.
|
169
199
|
|
170
200
|
```ruby
|
171
201
|
c = LikeQuery::Collect.new
|
@@ -178,15 +208,14 @@ Otherwise `#generate_hash` would not know which values it should return
|
|
178
208
|
|
179
209
|
**Performance**
|
180
210
|
|
181
|
-
Values defined by schema are processed by `#send` method, but
|
182
|
-
This,
|
211
|
+
Values defined by the schema are processed by the `#send` method, but recursively.
|
212
|
+
This means, for example, that for an `article` with the given key `customer.employees.contact_details.email` in the schema would return the name of the associated customer.
|
183
213
|
|
184
|
-
ATTENTION: This can trigger
|
214
|
+
ATTENTION: This can trigger a lot of database queries, depending on your structure or if or which method is behind the called names.
|
185
215
|
|
186
216
|
## Tests
|
187
217
|
|
188
|
-
Tests for this gem, by rspec, are included
|
189
|
-
a [test project](https://gitlab.com/sedl/like_query_project)
|
218
|
+
Tests for this gem, by rspec, are not included in this gem, they can be found in [test project](https://gitlab.com/sedl/like_query_project)
|
190
219
|
|
191
220
|
- [ ] [Set up project integrations](https://gitlab.com/sedl/like_query/-/settings/integrations)
|
192
221
|
|
data/lib/like_query/collect.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
module LikeQuery
|
2
2
|
class Collect
|
3
|
-
def initialize(limit =
|
4
|
-
|
3
|
+
def initialize(limit = nil)
|
4
|
+
if limit
|
5
|
+
@limit = limit
|
6
|
+
elsif Rails.configuration.x.like_query.limit
|
7
|
+
@limit = Rails.configuration.x.like_query.limit
|
8
|
+
else
|
9
|
+
@limit = nil
|
10
|
+
end
|
5
11
|
@length = 0
|
6
12
|
@data = {}
|
7
13
|
@overflow = false
|
@@ -18,9 +24,7 @@ module LikeQuery
|
|
18
24
|
@schemes[model.to_s] = schema_to_hash(schema)
|
19
25
|
end
|
20
26
|
|
21
|
-
def collect(output_schema = nil, limit: nil, parent: nil, image: nil, &block)
|
22
|
-
|
23
|
-
Rails.logger.debug(' x x x x x x x x x START COLLECT x x x x x x x x x x x x x x x x x x')
|
27
|
+
def collect(output_schema = nil, limit: nil, parent: nil, image: nil, url: nil, &block)
|
24
28
|
|
25
29
|
_limit = (limit ? (@limit && @limit < limit ? @limit : limit) : @limit)
|
26
30
|
return false if @length >= _limit
|
@@ -45,15 +49,6 @@ module LikeQuery
|
|
45
49
|
if !parent_assoc
|
46
50
|
raise "parent «#{parent}» is not a valid association"
|
47
51
|
end
|
48
|
-
# parent_polymorphic = parent_assoc.options[:polymorphic]
|
49
|
-
# unless parent_polymorphic
|
50
|
-
# parent_class_name = parent_assoc.klass.to_s
|
51
|
-
# parent_schema = @schemes[parent_class_name]
|
52
|
-
# unless parent_schema
|
53
|
-
# Rails.logger.debug("WARNING: NO SCHEMA GIVEN FOR «#{parent_class_name}»")
|
54
|
-
# parent_schema = schema_to_hash(nil)
|
55
|
-
# end
|
56
|
-
# end
|
57
52
|
end
|
58
53
|
|
59
54
|
recs.each do |rec|
|
@@ -62,19 +57,17 @@ module LikeQuery
|
|
62
57
|
@overflow = true
|
63
58
|
break
|
64
59
|
else
|
65
|
-
|
66
|
-
c = (@image ? 1 : 0) + r[:values].to_a.length
|
67
|
-
@columns_count = c if c > @columns_count
|
60
|
+
|
68
61
|
if parent
|
69
62
|
parent_record = rec.send(parent)
|
70
|
-
|
63
|
+
r = record_to_hash(rec, schema, image, parent_record)
|
64
|
+
parent_class_name = parent_record.class.to_s
|
71
65
|
parent_key = "#{parent_class_name}#{parent_record.id}"
|
72
66
|
|
73
67
|
unless @data[parent_key]
|
74
|
-
|
75
|
-
parent_schema = @schemes[pk]
|
68
|
+
parent_schema = @schemes[parent_class_name]
|
76
69
|
unless parent_schema
|
77
|
-
Rails.logger.debug("WARNING: NO SCHEMA GIVEN FOR «#{
|
70
|
+
Rails.logger.debug("WARNING: NO SCHEMA GIVEN FOR «#{parent_class_name}»")
|
78
71
|
parent_schema = schema_to_hash(nil)
|
79
72
|
end
|
80
73
|
@data[parent_key] = record_to_hash(parent_record, parent_schema, @images[parent_class_name])
|
@@ -83,8 +76,11 @@ module LikeQuery
|
|
83
76
|
@data[parent_key][:children] ||= []
|
84
77
|
@data[parent_key][:children].push(r)
|
85
78
|
else
|
79
|
+
r = record_to_hash(rec, schema, image, url: url)
|
86
80
|
@data["#{rec.class}#{rec.id}"] = r
|
87
81
|
end
|
82
|
+
c = (@image ? 1 : 0) + r[:values].to_a.length
|
83
|
+
@columns_count = c if c > @columns_count
|
88
84
|
@length += 1
|
89
85
|
length += 1
|
90
86
|
end
|
@@ -107,17 +103,30 @@ module LikeQuery
|
|
107
103
|
}
|
108
104
|
end
|
109
105
|
|
106
|
+
def generate_json
|
107
|
+
generate_hash.to_json
|
108
|
+
end
|
109
|
+
|
110
110
|
private
|
111
111
|
|
112
|
-
def record_to_hash(record, schema, image)
|
112
|
+
def record_to_hash(record, schema, image, parent = nil, url: nil)
|
113
113
|
r = {}
|
114
|
-
schema[:values].each do |
|
114
|
+
schema[:values].each do |k|
|
115
|
+
v = get_column_value(record, k)
|
115
116
|
r[:values] ||= []
|
116
|
-
r[:values].push(
|
117
|
+
r[:values].push(v)
|
118
|
+
r[:attributes] ||= {}
|
119
|
+
r[:attributes][k] = v
|
117
120
|
end
|
118
121
|
r[:id] = record.id
|
119
|
-
|
122
|
+
if parent
|
123
|
+
r[:model] = "#{parent.class.to_s}.#{record.class}"
|
124
|
+
r[:parent_id] = parent.id
|
125
|
+
else
|
126
|
+
r[:model] = record.class.to_s
|
127
|
+
end
|
120
128
|
r[:image] = record.send(image) if image
|
129
|
+
r[:url] = url.yield(record) if url
|
121
130
|
r
|
122
131
|
end
|
123
132
|
|
@@ -53,12 +53,18 @@ module LikeQuery
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
def generate_hash(output_schema = nil, limit: 50, image: nil)
|
56
|
+
def generate_hash(output_schema = nil, limit: 50, image: nil, url: nil)
|
57
57
|
c = LikeQuery::Collect.new(limit)
|
58
|
-
c.collect(output_schema, limit: limit, image: image) { all }
|
58
|
+
c.collect(output_schema, limit: limit, image: image, url: url) { all }
|
59
59
|
c.generate_hash
|
60
60
|
end
|
61
61
|
|
62
|
+
def generate_json(output_schema = nil, limit: 50, image: nil, url: nil)
|
63
|
+
c = LikeQuery::Collect.new(limit)
|
64
|
+
c.collect(output_schema, limit: limit, image: image, url: url) { all }
|
65
|
+
c.generate_json
|
66
|
+
end
|
67
|
+
|
62
68
|
def like_query_schema
|
63
69
|
@like_query_schema
|
64
70
|
end
|
data/lib/like_query/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: like_query
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- christian
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|