searchkon 0.1.1
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 +7 -0
- data/.gitignore +3 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +1 -0
- data/lib/searchkon.rb +4 -0
- data/lib/searchkon/filterable.rb +60 -0
- data/lib/searchkon/query_builder.rb +83 -0
- data/lib/searchkon/regex_formatter.rb +40 -0
- data/lib/searchkon/searchables.rb +7 -0
- data/searchkon.gemspec +18 -0
- metadata +95 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 5c3a98b95fd101cdff626be2a58c06db08136f252913bea0951de36291efc6f2
|
|
4
|
+
data.tar.gz: 38a365ea4287172a83922d2cc44ba1a4cb4182be2376f0d0164ba09b7c27f936
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 973e2e6d10e9b0186487013ca5fa3ffc941875cd02f0a523703e2586cbf031394e8affb182405d4cd6456fb8e7a2d4f34387be5f97c1df3f4f413bb2e67914f8
|
|
7
|
+
data.tar.gz: 1d225347ce400fe97012cc29f91beb753d0c0b5a3e39147553faa152170b359a35df88466cf88499a082f5ae641f1e0a7f7b81baaba7f3c46998b738a83b3794
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 majid imanzade
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Hello
|
data/lib/searchkon.rb
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module Searchkon
|
|
2
|
+
module Filterable
|
|
3
|
+
|
|
4
|
+
def validate_params filters, model_filterables
|
|
5
|
+
valid_params = []
|
|
6
|
+
unless filters.blank?
|
|
7
|
+
valid_params.concat formatted_simple_params(model_filterables, filters)
|
|
8
|
+
valid_params.concat formatted_fulltext_params(model_filterables, filters)
|
|
9
|
+
end
|
|
10
|
+
valid_params
|
|
11
|
+
end
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def formatted_simple_params model_filterables, filters
|
|
15
|
+
valid_params = []
|
|
16
|
+
model_filterables.each do |scope, columns|
|
|
17
|
+
columns.each do |column|
|
|
18
|
+
value_of_column = filters[column.to_sym]
|
|
19
|
+
|
|
20
|
+
value_of_column.reject! { |c| c.blank? } if value_of_column.kind_of?(Array)
|
|
21
|
+
next if value_of_column.blank?
|
|
22
|
+
next unless valid_range? value_of_column
|
|
23
|
+
|
|
24
|
+
valid_params.push({value: value_of_column, key: column, scope: scope}) if filters.include?(column.to_sym)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
valid_params
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def valid_range? value
|
|
31
|
+
if range? value
|
|
32
|
+
return (date_range?(value) or digit_range?(value))
|
|
33
|
+
end
|
|
34
|
+
true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def formatted_fulltext_params model_filterables, filters
|
|
38
|
+
valid_params = []
|
|
39
|
+
filters.each do |key, value|
|
|
40
|
+
if key.to_s.include? ','
|
|
41
|
+
valid_keys = validate_fulltext_keys key, model_filterables
|
|
42
|
+
valid_params.push({value: value, key: valid_keys, scope: :fulltext}) unless valid_keys.blank?
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
valid_params
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def validate_fulltext_keys keys, model_filterables
|
|
49
|
+
valid_params = []
|
|
50
|
+
return if keys.blank?
|
|
51
|
+
|
|
52
|
+
keys.to_s.split(',')&.each do |key|
|
|
53
|
+
valid_params << key if model_filterables[:like].include?(key)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
return if valid_params.blank?
|
|
57
|
+
valid_params.join(',')
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
module Searchkon
|
|
2
|
+
class QueryBuilder
|
|
3
|
+
class << self
|
|
4
|
+
include Searchkon::Filterable
|
|
5
|
+
include Searchkon::RegexFormatter
|
|
6
|
+
|
|
7
|
+
def filter model, params = {}
|
|
8
|
+
@model = model.constantize
|
|
9
|
+
@res = @model.all
|
|
10
|
+
valid_params = validate_params(params, @model.searchable_columns)
|
|
11
|
+
create_filters valid_params
|
|
12
|
+
@res
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def create_filters valid_params
|
|
18
|
+
valid_params.each do |filter|
|
|
19
|
+
if(filter[:scope] == :fulltext)
|
|
20
|
+
fulltext_query filter[:key], filter[:value]
|
|
21
|
+
elsif(relational? filter[:key])
|
|
22
|
+
relation_query filter[:key]
|
|
23
|
+
where_query filter[:key], filter[:value], filter[:scope]
|
|
24
|
+
elsif(range? filter[:value])
|
|
25
|
+
range_query filter[:key], filter[:value]
|
|
26
|
+
else
|
|
27
|
+
where_query filter[:key], filter[:value], filter[:scope]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def fulltext_query key, value
|
|
33
|
+
query = ""
|
|
34
|
+
keys = key.to_s.split(',')
|
|
35
|
+
keys.each do |fulltext_key|
|
|
36
|
+
relation_query fulltext_key if(relational? fulltext_key)
|
|
37
|
+
query << " or " unless query.blank?
|
|
38
|
+
if relational? fulltext_key
|
|
39
|
+
relations = relation_values fulltext_key
|
|
40
|
+
table_name = get_relation_table_name relations.relation
|
|
41
|
+
query << "#{table_name}.#{relations.key} like :value"
|
|
42
|
+
else
|
|
43
|
+
query << "#{@model.table_name}.#{fulltext_key} like :value"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
@res = @res.where(query, {value: "%#{value}%"})
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def where_query key, value, scope
|
|
50
|
+
exact_query key, value if scope == :exact
|
|
51
|
+
like_query key, value if scope == :like
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def like_query key, value
|
|
55
|
+
if(relational? key)
|
|
56
|
+
relations = relation_values key
|
|
57
|
+
table_name = get_relation_table_name relations.relation
|
|
58
|
+
@res = @res.where("#{table_name}.#{relations.key} like ?", "%#{value}%")
|
|
59
|
+
else
|
|
60
|
+
@res = @res.where("#{@model.table_name}.#{key} like ?", "%#{value}%")
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def exact_query key, value
|
|
65
|
+
@res = @res.where(key => value)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def range_query key, value
|
|
69
|
+
range = range_values value
|
|
70
|
+
@res = @res.where("#{@model.table_name}.#{key} between ? and ?", range.from, range.to)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def relation_query key
|
|
74
|
+
relations = relation_values key
|
|
75
|
+
@res = @res.joins(relations.relation.to_sym)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def get_relation_table_name relation
|
|
79
|
+
@model.reflect_on_all_associations.detect { |association| association.name == relation.to_sym }.table_name
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Searchkon
|
|
2
|
+
module RegexFormatter
|
|
3
|
+
SIMPLE_RANGE_FORMAT_REGEX = /\((.*)\.\.(.*)\)/
|
|
4
|
+
RELATIONAL_FORMAT_REGEX = /(.*)\.(.*)/
|
|
5
|
+
DIGIT_RANGE_FORMAT_REGEX = /\((\d*)\.\.(\d*)\)/
|
|
6
|
+
DATE_RANGE_FORMAT_REGEX = /\((\d{4}-\d{1,2}-\d{1,2})\.\.(\d{4}-\d{1,2}-\d{1,2})\)/
|
|
7
|
+
|
|
8
|
+
def relational? value
|
|
9
|
+
value.to_s.match RELATIONAL_FORMAT_REGEX
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def range? value
|
|
13
|
+
value.to_s.match SIMPLE_RANGE_FORMAT_REGEX
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def date_range? value
|
|
17
|
+
value.to_s.match DATE_RANGE_FORMAT_REGEX
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def digit_range? value
|
|
21
|
+
value.to_s.match DIGIT_RANGE_FORMAT_REGEX
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def range_values value
|
|
25
|
+
struct = Struct.new :from, :to
|
|
26
|
+
regex_match value, SIMPLE_RANGE_FORMAT_REGEX, struct
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def relation_values value
|
|
30
|
+
struct = Struct.new :relation, :key
|
|
31
|
+
regex_match value, RELATIONAL_FORMAT_REGEX, struct
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def regex_match value, pattern, struct
|
|
37
|
+
value.to_s.match(pattern) { |m| struct.new(*m.captures) }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/searchkon.gemspec
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Gem::Specification.new do |s|
|
|
2
|
+
s.name = 'searchkon'
|
|
3
|
+
s.version = '0.1.1'
|
|
4
|
+
s.date = '2020-05-24'
|
|
5
|
+
s.summary = "Search Command"
|
|
6
|
+
s.description = "make search easy"
|
|
7
|
+
s.authors = ["Majid Imanzade"]
|
|
8
|
+
s.email = 'majidimanzade1@gmail.com'
|
|
9
|
+
s.homepage = 'https://rubygems.org/gems/Helliot'
|
|
10
|
+
s.homepage = "http://github.com/majidimanzade/Helliot"
|
|
11
|
+
s.license = 'MIT'
|
|
12
|
+
|
|
13
|
+
s.files = `git ls-files`.split("\n")
|
|
14
|
+
s.require_paths = ['lib']
|
|
15
|
+
s.add_development_dependency("bundler")
|
|
16
|
+
s.add_development_dependency("rake")
|
|
17
|
+
s.add_development_dependency("rspec")
|
|
18
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: searchkon
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Majid Imanzade
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2020-05-24 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bundler
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
description: make search easy
|
|
56
|
+
email: majidimanzade1@gmail.com
|
|
57
|
+
executables: []
|
|
58
|
+
extensions: []
|
|
59
|
+
extra_rdoc_files: []
|
|
60
|
+
files:
|
|
61
|
+
- ".gitignore"
|
|
62
|
+
- Gemfile
|
|
63
|
+
- LICENSE
|
|
64
|
+
- README.md
|
|
65
|
+
- elliot-0.0.1.gem
|
|
66
|
+
- lib/searchkon.rb
|
|
67
|
+
- lib/searchkon/filterable.rb
|
|
68
|
+
- lib/searchkon/query_builder.rb
|
|
69
|
+
- lib/searchkon/regex_formatter.rb
|
|
70
|
+
- lib/searchkon/searchables.rb
|
|
71
|
+
- searchkon.gemspec
|
|
72
|
+
homepage: http://github.com/majidimanzade/Helliot
|
|
73
|
+
licenses:
|
|
74
|
+
- MIT
|
|
75
|
+
metadata: {}
|
|
76
|
+
post_install_message:
|
|
77
|
+
rdoc_options: []
|
|
78
|
+
require_paths:
|
|
79
|
+
- lib
|
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
81
|
+
requirements:
|
|
82
|
+
- - ">="
|
|
83
|
+
- !ruby/object:Gem::Version
|
|
84
|
+
version: '0'
|
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
requirements: []
|
|
91
|
+
rubygems_version: 3.1.2
|
|
92
|
+
signing_key:
|
|
93
|
+
specification_version: 4
|
|
94
|
+
summary: Search Command
|
|
95
|
+
test_files: []
|