searchkon 0.1.1 → 1.0.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/Gemfile +2 -0
- data/lib/searchkon/query_builder.rb +1 -1
- data/lib/searchkon/regex_formatter.rb +1 -1
- data/searchkon.gemspec +8 -4
- data/spec/filterable_spec.rb +24 -0
- data/spec/models/coupon.rb +3 -0
- data/spec/models/payment.rb +3 -0
- data/spec/models/product.rb +17 -0
- data/spec/query_builder_spec.rb +114 -0
- data/spec/schema.rb +20 -0
- data/spec/spec_helper.rb +15 -0
- metadata +52 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: eb893a4d3dc86aa19c3da94c49e4fcb2746931308710ba6a165b5a39290a8cb4
|
|
4
|
+
data.tar.gz: 18eec74102de5b1ae4d5f07a965f682871f7bdfbff793f1ddf7ced1ea35a7c43
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d11d1b0d6c13e55e4239f641c8fa65fa2378a2d856ca43d8f2ea09321dac83876258206ca5ee5791ce147a7be8e87acfba768c003116705bc1248b43f941d044
|
|
7
|
+
data.tar.gz: f09f8209e58b8be30119cc4da86b0e9e9c785e4c2a03f4df3626d5847e341bef6a8aad772133a00337386f415838d04a3c23b1dedd51388252f7c3b59862e274
|
data/Gemfile
CHANGED
|
@@ -7,7 +7,7 @@ module Searchkon
|
|
|
7
7
|
def filter model, params = {}
|
|
8
8
|
@model = model.constantize
|
|
9
9
|
@res = @model.all
|
|
10
|
-
valid_params = validate_params(params, @model.searchable_columns)
|
|
10
|
+
valid_params = validate_params(params[:filters], @model.searchable_columns)
|
|
11
11
|
create_filters valid_params
|
|
12
12
|
@res
|
|
13
13
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module Searchkon
|
|
2
2
|
module RegexFormatter
|
|
3
|
-
|
|
3
|
+
SIMPLE_RANGE_FORMAT_REGEX = /\((.*)\.\.(.*)\)/
|
|
4
4
|
RELATIONAL_FORMAT_REGEX = /(.*)\.(.*)/
|
|
5
5
|
DIGIT_RANGE_FORMAT_REGEX = /\((\d*)\.\.(\d*)\)/
|
|
6
6
|
DATE_RANGE_FORMAT_REGEX = /\((\d{4}-\d{1,2}-\d{1,2})\.\.(\d{4}-\d{1,2}-\d{1,2})\)/
|
data/searchkon.gemspec
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = 'searchkon'
|
|
3
|
-
s.version = '0.
|
|
3
|
+
s.version = '1.0.0'
|
|
4
4
|
s.date = '2020-05-24'
|
|
5
5
|
s.summary = "Search Command"
|
|
6
6
|
s.description = "make search easy"
|
|
7
|
-
s.authors = ["Majid Imanzade"]
|
|
7
|
+
s.authors = ["Majid Imanzade", 'Amin Samadzade']
|
|
8
8
|
s.email = 'majidimanzade1@gmail.com'
|
|
9
|
-
s.homepage = 'https://rubygems.org/gems/
|
|
10
|
-
s.homepage = "http://github.com/majidimanzade/
|
|
9
|
+
s.homepage = 'https://rubygems.org/gems/searchkon'
|
|
10
|
+
s.homepage = "http://github.com/majidimanzade/searchkon"
|
|
11
11
|
s.license = 'MIT'
|
|
12
12
|
|
|
13
13
|
s.files = `git ls-files`.split("\n")
|
|
@@ -15,4 +15,8 @@ Gem::Specification.new do |s|
|
|
|
15
15
|
s.add_development_dependency("bundler")
|
|
16
16
|
s.add_development_dependency("rake")
|
|
17
17
|
s.add_development_dependency("rspec")
|
|
18
|
+
s.add_development_dependency "sqlite3"
|
|
19
|
+
|
|
20
|
+
s.add_dependency "activesupport"
|
|
21
|
+
s.add_dependency "activerecord"
|
|
18
22
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
|
+
|
|
3
|
+
class DummyClass
|
|
4
|
+
include Searchkon::RegexFormatter
|
|
5
|
+
include Searchkon::Filterable
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
RSpec.describe Searchkon::Filterable do
|
|
9
|
+
describe 'filterable test' do
|
|
10
|
+
it 'should return correct filter with scope' do
|
|
11
|
+
filrtetables = {
|
|
12
|
+
like: ['name', 'cities.name'],
|
|
13
|
+
exact: ['cities.id']
|
|
14
|
+
}
|
|
15
|
+
filters = {'cities.name,name': 'Don', 'cities.id': 1}
|
|
16
|
+
result = [{:value=>1, :key => "cities.id", :scope=>:exact},
|
|
17
|
+
{:value=>"Don", :key=> "cities.name,name", :scope=>:fulltext}]
|
|
18
|
+
|
|
19
|
+
dc = DummyClass.new
|
|
20
|
+
|
|
21
|
+
expect(dc.validate_params(filters, filrtetables)).to eq result
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
|
+
|
|
3
|
+
RSpec.describe Searchkon::QueryBuilder do
|
|
4
|
+
describe 'query builder for filter' do
|
|
5
|
+
let (:simple_where_params) do
|
|
6
|
+
{
|
|
7
|
+
filters: {
|
|
8
|
+
id: 1,
|
|
9
|
+
title: 'foobar'
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
let (:simple_range_params) do
|
|
15
|
+
{
|
|
16
|
+
filters: {
|
|
17
|
+
id: '(1..10)',
|
|
18
|
+
created_at: '(2012-12-21..2019-12-21)'
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
let (:range_and_array_where_params) do
|
|
24
|
+
{
|
|
25
|
+
filters: {
|
|
26
|
+
id: [1,2,3,4,5],
|
|
27
|
+
created_at: '(2012-12-21..2019-12-21)'
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'should return simple where query' do
|
|
33
|
+
query = "SELECT \"products\".* FROM \"products\" WHERE (products.title like '%foobar%') AND \"products\".\"id\" = 1"
|
|
34
|
+
expect(Searchkon::QueryBuilder.filter('Product', simple_where_params).to_sql).to eq query
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'should return simple range query' do
|
|
38
|
+
query = "SELECT \"products\".* FROM \"products\" WHERE (products.created_at between '2012-12-21' and '2019-12-21') AND (products.id between '1' and '10')"
|
|
39
|
+
|
|
40
|
+
expect(Searchkon::QueryBuilder.filter('Product', simple_range_params).to_sql).to eq query
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'should return simple where relational query' do
|
|
44
|
+
relational_params = { filters: { 'coupons.id': 1 } }
|
|
45
|
+
query = "SELECT \"products\".* FROM \"products\" INNER JOIN \"coupons\" ON \"coupons\".\"product_id\" = \"products\".\"id\" WHERE \"coupons\".\"id\" = 1"
|
|
46
|
+
|
|
47
|
+
expect(Searchkon::QueryBuilder.filter('Product', relational_params).to_sql).to eq query
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'should return range relational query' do
|
|
51
|
+
relational_params = { filters: { 'coupons.id': [1,2,3] } }
|
|
52
|
+
query = "SELECT \"products\".* FROM \"products\" INNER JOIN \"coupons\" ON \"coupons\".\"product_id\" = \"products\".\"id\" WHERE \"coupons\".\"id\" IN (1, 2, 3)"
|
|
53
|
+
|
|
54
|
+
expect(Searchkon::QueryBuilder.filter('Product', relational_params).to_sql).to eq query
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'should return simple where relational query with two relations' do
|
|
58
|
+
relational_params = { filters: { 'coupons.id': 1, 'payments.id': 1 } }
|
|
59
|
+
query = "SELECT \"products\".* FROM \"products\" INNER JOIN \"coupons\" ON \"coupons\".\"product_id\" = \"products\".\"id\" INNER JOIN \"payments\" ON \"payments\".\"product_id\" = \"products\".\"id\" WHERE \"coupons\".\"id\" = 1 AND \"payments\".\"id\" = 1"
|
|
60
|
+
expect(Searchkon::QueryBuilder.filter('Product', relational_params).to_sql).to eq query
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'should return range query and array where' do
|
|
64
|
+
query = "SELECT \"products\".* FROM \"products\" WHERE (products.created_at between '2012-12-21' and '2019-12-21') AND \"products\".\"id\" IN (1, 2, 3, 4, 5)"
|
|
65
|
+
|
|
66
|
+
expect(Searchkon::QueryBuilder.filter('Product', range_and_array_where_params).to_sql).to eq query
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'should return all if params empty' do
|
|
70
|
+
query = "SELECT \"products\".* FROM \"products\""
|
|
71
|
+
|
|
72
|
+
expect(Searchkon::QueryBuilder.filter('Product', {}).to_sql).to eq query
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'should raise error if model not exist' do
|
|
76
|
+
expect { Searchkon::QueryBuilder.filter('foobar', simple_where_params) }.to raise_error NameError
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it 'should return all if all filter column not exist' do
|
|
80
|
+
query = "SELECT \"products\".* FROM \"products\""
|
|
81
|
+
invalid_mock_params = {
|
|
82
|
+
filters: {
|
|
83
|
+
blah: 1,
|
|
84
|
+
foo: 'foobar'
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
expect(Searchkon::QueryBuilder.filter('Product', invalid_mock_params).to_sql).to eq query
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it 'should return query if one filter column not exist' do
|
|
92
|
+
query = "SELECT \"products\".* FROM \"products\" WHERE \"products\".\"id\" = 1"
|
|
93
|
+
some_invalid_mock_params = {
|
|
94
|
+
filters: {
|
|
95
|
+
id: 1,
|
|
96
|
+
foo: 'foobar'
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
expect(Searchkon::QueryBuilder.filter('Product', some_invalid_mock_params).to_sql).to eq query
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it 'should return fulltext query if params has fulltext key' do
|
|
104
|
+
query = "SELECT \"products\".* FROM \"products\" INNER JOIN \"coupons\" ON \"coupons\".\"product_id\" = \"products\".\"id\" WHERE (products.title like '%foobar%' or coupons.code like '%foobar%')"
|
|
105
|
+
params = {
|
|
106
|
+
filters: {
|
|
107
|
+
'title,coupons.code': 'foobar'
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
expect(Searchkon::QueryBuilder.filter('Product', params).to_sql).to eq query
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
data/spec/schema.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
ActiveRecord::Schema.define do
|
|
2
|
+
self.verbose = false
|
|
3
|
+
|
|
4
|
+
create_table :products, :force => true do |t|
|
|
5
|
+
t.string :key
|
|
6
|
+
t.string :title
|
|
7
|
+
t.timestamps
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
create_table :coupons, :force => true do |t|
|
|
11
|
+
t.string :title
|
|
12
|
+
t.timestamps
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
create_table :payments, :force => true do |t|
|
|
16
|
+
t.string :title
|
|
17
|
+
t.timestamps
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
3
|
+
|
|
4
|
+
require 'searchkon'
|
|
5
|
+
require 'active_record'
|
|
6
|
+
require 'active_support'
|
|
7
|
+
require 'active_support/core_ext'
|
|
8
|
+
require 'rspec'
|
|
9
|
+
|
|
10
|
+
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
|
|
11
|
+
|
|
12
|
+
load File.dirname(__FILE__) + '/schema.rb'
|
|
13
|
+
require File.dirname(__FILE__) + '/models/coupon.rb'
|
|
14
|
+
require File.dirname(__FILE__) + '/models/payment.rb'
|
|
15
|
+
require File.dirname(__FILE__) + '/models/product.rb'
|
metadata
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: searchkon
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Majid Imanzade
|
|
8
|
+
- Amin Samadzade
|
|
8
9
|
autorequire:
|
|
9
10
|
bindir: bin
|
|
10
11
|
cert_chain: []
|
|
@@ -52,6 +53,48 @@ dependencies:
|
|
|
52
53
|
- - ">="
|
|
53
54
|
- !ruby/object:Gem::Version
|
|
54
55
|
version: '0'
|
|
56
|
+
- !ruby/object:Gem::Dependency
|
|
57
|
+
name: sqlite3
|
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - ">="
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '0'
|
|
63
|
+
type: :development
|
|
64
|
+
prerelease: false
|
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - ">="
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '0'
|
|
70
|
+
- !ruby/object:Gem::Dependency
|
|
71
|
+
name: activesupport
|
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - ">="
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '0'
|
|
77
|
+
type: :runtime
|
|
78
|
+
prerelease: false
|
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
80
|
+
requirements:
|
|
81
|
+
- - ">="
|
|
82
|
+
- !ruby/object:Gem::Version
|
|
83
|
+
version: '0'
|
|
84
|
+
- !ruby/object:Gem::Dependency
|
|
85
|
+
name: activerecord
|
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
|
87
|
+
requirements:
|
|
88
|
+
- - ">="
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
version: '0'
|
|
91
|
+
type: :runtime
|
|
92
|
+
prerelease: false
|
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
94
|
+
requirements:
|
|
95
|
+
- - ">="
|
|
96
|
+
- !ruby/object:Gem::Version
|
|
97
|
+
version: '0'
|
|
55
98
|
description: make search easy
|
|
56
99
|
email: majidimanzade1@gmail.com
|
|
57
100
|
executables: []
|
|
@@ -62,14 +105,20 @@ files:
|
|
|
62
105
|
- Gemfile
|
|
63
106
|
- LICENSE
|
|
64
107
|
- README.md
|
|
65
|
-
- elliot-0.0.1.gem
|
|
66
108
|
- lib/searchkon.rb
|
|
67
109
|
- lib/searchkon/filterable.rb
|
|
68
110
|
- lib/searchkon/query_builder.rb
|
|
69
111
|
- lib/searchkon/regex_formatter.rb
|
|
70
112
|
- lib/searchkon/searchables.rb
|
|
71
113
|
- searchkon.gemspec
|
|
72
|
-
|
|
114
|
+
- spec/filterable_spec.rb
|
|
115
|
+
- spec/models/coupon.rb
|
|
116
|
+
- spec/models/payment.rb
|
|
117
|
+
- spec/models/product.rb
|
|
118
|
+
- spec/query_builder_spec.rb
|
|
119
|
+
- spec/schema.rb
|
|
120
|
+
- spec/spec_helper.rb
|
|
121
|
+
homepage: http://github.com/majidimanzade/searchkon
|
|
73
122
|
licenses:
|
|
74
123
|
- MIT
|
|
75
124
|
metadata: {}
|