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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c3a98b95fd101cdff626be2a58c06db08136f252913bea0951de36291efc6f2
4
- data.tar.gz: 38a365ea4287172a83922d2cc44ba1a4cb4182be2376f0d0164ba09b7c27f936
3
+ metadata.gz: eb893a4d3dc86aa19c3da94c49e4fcb2746931308710ba6a165b5a39290a8cb4
4
+ data.tar.gz: 18eec74102de5b1ae4d5f07a965f682871f7bdfbff793f1ddf7ced1ea35a7c43
5
5
  SHA512:
6
- metadata.gz: 973e2e6d10e9b0186487013ca5fa3ffc941875cd02f0a523703e2586cbf031394e8affb182405d4cd6456fb8e7a2d4f34387be5f97c1df3f4f413bb2e67914f8
7
- data.tar.gz: 1d225347ce400fe97012cc29f91beb753d0c0b5a3e39147553faa152170b359a35df88466cf88499a082f5ae641f1e0a7f7b81baaba7f3c46998b738a83b3794
6
+ metadata.gz: d11d1b0d6c13e55e4239f641c8fa65fa2378a2d856ca43d8f2ea09321dac83876258206ca5ee5791ce147a7be8e87acfba768c003116705bc1248b43f941d044
7
+ data.tar.gz: f09f8209e58b8be30119cc4da86b0e9e9c785e4c2a03f4df3626d5847e341bef6a8aad772133a00337386f415838d04a3c23b1dedd51388252f7c3b59862e274
data/Gemfile CHANGED
@@ -2,3 +2,5 @@
2
2
  source "http://rubygems.org"
3
3
 
4
4
  gemspec
5
+ gem 'activerecord', '~> 5.0', '>= 5.0.0.1'
6
+ gem 'activesupport', '~> 5.0', '>= 5.0.0.1'
@@ -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
- SIMPLE_RANGE_FORMAT_REGEX = /\((.*)\.\.(.*)\)/
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})\)/
@@ -1,13 +1,13 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'searchkon'
3
- s.version = '0.1.1'
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/Helliot'
10
- s.homepage = "http://github.com/majidimanzade/Helliot"
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,3 @@
1
+ class Coupon < ActiveRecord::Base
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ class Payment < ActiveRecord::Base
2
+
3
+ end
@@ -0,0 +1,17 @@
1
+ class Product < ActiveRecord::Base
2
+
3
+ has_many :coupons
4
+ has_many :payments
5
+
6
+ def self.searchable_columns
7
+ {
8
+ like: ['title', 'coupons.code'],
9
+ exact: [
10
+ 'created_at',
11
+ 'coupons.id',
12
+ 'payments.id',
13
+ 'id'
14
+ ]
15
+ }
16
+ end
17
+ 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
@@ -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
@@ -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.1.1
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
- homepage: http://github.com/majidimanzade/Helliot
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: {}