mincer 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/Gemfile +2 -1
- data/README.md +111 -64
- data/lib/mincer/action_view/sort_helper.rb +7 -7
- data/lib/mincer/base.rb +1 -1
- data/lib/mincer/config.rb +29 -0
- data/lib/mincer/core_ext/string.rb +5 -0
- data/lib/mincer/processors/cache_digest/processor.rb +54 -0
- data/lib/mincer/processors/helpers.rb +15 -0
- data/lib/mincer/processors/pagination/processor.rb +63 -0
- data/lib/mincer/processors/pg_json_dumper/processor.rb +69 -0
- data/lib/mincer/processors/pg_search/processor.rb +148 -0
- data/lib/mincer/processors/pg_search/sanitizer.rb +61 -0
- data/lib/mincer/processors/pg_search/search_engines/array.rb +41 -0
- data/lib/mincer/processors/pg_search/search_engines/base.rb +56 -0
- data/lib/mincer/processors/pg_search/search_engines/fulltext.rb +58 -0
- data/lib/mincer/processors/pg_search/search_engines/trigram.rb +41 -0
- data/lib/mincer/processors/pg_search/search_statement.rb +31 -0
- data/lib/mincer/processors/sorting/processor.rb +113 -0
- data/lib/mincer/version.rb +1 -1
- data/lib/mincer.rb +31 -31
- data/mincer.gemspec +0 -2
- data/spec/lib/mincer/action_view/sort_helper_spec.rb +11 -0
- data/spec/lib/mincer/base_spec.rb +15 -0
- data/spec/lib/mincer/config_spec.rb +7 -0
- data/spec/lib/{processors/cache_digest_spec.rb → mincer/processors/cache_digest/processor_spec.rb} +2 -9
- data/spec/lib/{processors/paginate_spec.rb → mincer/processors/pagination/processor_spec.rb} +43 -17
- data/spec/lib/{processors/pg_json_dumper_spec.rb → mincer/processors/pg_json_dumper/processor_spec.rb} +2 -6
- data/spec/lib/mincer/processors/pg_search/processor_spec.rb +268 -0
- data/spec/lib/mincer/processors/pg_search/sanitizer_spec.rb +38 -0
- data/spec/lib/mincer/processors/pg_search/search_engines/array_spec.rb +83 -0
- data/spec/lib/mincer/processors/pg_search/search_engines/fulltext_spec.rb +101 -0
- data/spec/lib/mincer/processors/pg_search/search_engines/trigram_spec.rb +91 -0
- data/spec/lib/mincer/processors/sorting/processor_spec.rb +181 -0
- data/spec/mincer_config.rb +38 -0
- data/spec/spec_helper.rb +40 -4
- data/spec/support/postgres_adapter.rb +12 -3
- data/spec/support/sqlite3_adapter.rb +3 -0
- metadata +42 -45
- data/lib/mincer/processors/cache_digest.rb +0 -50
- data/lib/mincer/processors/paginate.rb +0 -41
- data/lib/mincer/processors/pg_json_dumper.rb +0 -51
- data/lib/mincer/processors/search.rb +0 -34
- data/lib/mincer/processors/sort.rb +0 -59
- data/spec/lib/processors/search_spec.rb +0 -77
- data/spec/lib/processors/sort_spec.rb +0 -77
@@ -1,51 +0,0 @@
|
|
1
|
-
module Mincer
|
2
|
-
module Processors
|
3
|
-
class PgJsonDumper
|
4
|
-
|
5
|
-
def initialize(mincer, options = {})
|
6
|
-
@mincer, @args, @relation, @options = mincer, mincer.args, mincer.relation, options
|
7
|
-
end
|
8
|
-
|
9
|
-
def apply
|
10
|
-
@relation
|
11
|
-
end
|
12
|
-
|
13
|
-
def to_json
|
14
|
-
if dump_supported?
|
15
|
-
Mincer.connection.execute(@options[:root] ? query_with_root(@options[:root]) : query).first['json']
|
16
|
-
else
|
17
|
-
warn 'To dump data to json with postgres you need to use postgres server version >= 9.2'
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def dump_supported?
|
24
|
-
Mincer.postgres? && (Mincer.connection.send(:postgresql_version) >= 90200)
|
25
|
-
end
|
26
|
-
|
27
|
-
def query(root = 'json')
|
28
|
-
<<-SQL
|
29
|
-
SELECT COALESCE(array_to_json(array_agg(row_to_json(subq))), '[]') AS #{root}
|
30
|
-
FROM (#{@mincer.sql}) as subq
|
31
|
-
SQL
|
32
|
-
end
|
33
|
-
|
34
|
-
def query_with_root(root)
|
35
|
-
<<-SQL
|
36
|
-
SELECT row_to_json(t) as json FROM ( #{query(root)} ) as t
|
37
|
-
SQL
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
module PgJsonDumperOptions
|
43
|
-
extend ActiveSupport::Concern
|
44
|
-
|
45
|
-
def to_json(options = {})
|
46
|
-
PgJsonDumper.new(self, options).to_json
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module Mincer
|
2
|
-
module Processors
|
3
|
-
class Search
|
4
|
-
def initialize(mincer)
|
5
|
-
@mincer, @args, @relation = mincer, mincer.args, mincer.relation
|
6
|
-
end
|
7
|
-
|
8
|
-
def apply
|
9
|
-
if Mincer.postgres? && !textacular?
|
10
|
-
warn 'You must include "textacular" to your Gemfile to use search'
|
11
|
-
@relation
|
12
|
-
elsif Mincer.postgres? && @args['pattern'].present?
|
13
|
-
@relation.basic_search(@args['pattern']).presence || @relation.fuzzy_search(@args['pattern'])
|
14
|
-
else
|
15
|
-
@relation
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def textacular?
|
20
|
-
defined?(::Textacular)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
module SearchOptions
|
25
|
-
extend ActiveSupport::Concern
|
26
|
-
|
27
|
-
module ClassMethods
|
28
|
-
def skip_search!
|
29
|
-
active_processors.delete(Mincer::Processors::Search)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
module Mincer
|
2
|
-
module Processors
|
3
|
-
|
4
|
-
class Sort
|
5
|
-
def initialize(mincer)
|
6
|
-
@mincer, @args, @relation = mincer, mincer.args, mincer.relation
|
7
|
-
end
|
8
|
-
|
9
|
-
def apply
|
10
|
-
relation = @relation.order(sort_string)
|
11
|
-
@mincer.sort_attribute, @mincer.sort_order = sort_attr, order_attr
|
12
|
-
relation
|
13
|
-
end
|
14
|
-
|
15
|
-
def sort_string
|
16
|
-
sort_attr ? "#{sort_attr} #{order_attr}, #{@mincer.send(:default_sort_attribute)}" : "#{@mincer.send(:default_sort_attribute)} #{order_attr}"
|
17
|
-
end
|
18
|
-
|
19
|
-
def sort_attr
|
20
|
-
@mincer.send(:allowed_sort_attributes).include?(@args['sort']) && @args['sort']
|
21
|
-
end
|
22
|
-
|
23
|
-
def order_attr
|
24
|
-
(%w{ASC DESC}.include?(@args['order']) && @args['order']) || @mincer.send(:default_sort_order)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
|
29
|
-
module SortOptions
|
30
|
-
extend ActiveSupport::Concern
|
31
|
-
|
32
|
-
included do
|
33
|
-
attr_accessor :sort_attribute, :sort_order
|
34
|
-
end
|
35
|
-
|
36
|
-
module ClassMethods
|
37
|
-
def skip_sorting!
|
38
|
-
active_processors.delete(Mincer::Processors::Sort)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# Default sort attribute. You must override this method if you want something else
|
43
|
-
def default_sort_attribute
|
44
|
-
'id'
|
45
|
-
end
|
46
|
-
|
47
|
-
# Default order attribute. You must override this method if you want something else
|
48
|
-
def default_sort_order
|
49
|
-
'ASC'
|
50
|
-
end
|
51
|
-
|
52
|
-
# Allowed sort attributes, should return array of strings
|
53
|
-
def allowed_sort_attributes
|
54
|
-
@scope.attribute_names
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ::Mincer::Processors::Search do
|
4
|
-
context 'when postgres used' do
|
5
|
-
before do
|
6
|
-
setup_basic_postgres_table
|
7
|
-
class ActiveRecordModel < ActiveRecord::Base
|
8
|
-
end
|
9
|
-
ActiveRecordModel.create!(text: 'Test')
|
10
|
-
ActiveRecordModel.create!(text: 'Bingo')
|
11
|
-
ActiveRecordModel.create!(text: 'Bongo')
|
12
|
-
end
|
13
|
-
|
14
|
-
describe 'search without "textacular"' do
|
15
|
-
subject(:model) do
|
16
|
-
Class.new(Mincer::Base)
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'searches by pattern in args' do
|
20
|
-
::Mincer::Processors::Search.any_instance.stub(:textacular?).and_return(false)
|
21
|
-
query = subject.new(ActiveRecordModel, { 'pattern' => 'Bingo' })
|
22
|
-
query.to_a.count.should eq(3)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe 'search with "textacular"' do
|
27
|
-
describe 'searches with basic model without any Mincer::Base configuration' do
|
28
|
-
subject(:model) do
|
29
|
-
Class.new(Mincer::Base)
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'searches by pattern in args' do
|
33
|
-
query = subject.new(ActiveRecordModel, { 'pattern' => 'Bingo' })
|
34
|
-
query.to_a.count.should eq(1)
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'avoids search when pattern is an empty string or spaces' do
|
38
|
-
query = subject.new(ActiveRecordModel, { 'pattern' => ' ' })
|
39
|
-
query.to_a.count.should eq(3)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
describe 'paginating when basic model has disabled pagination' do
|
45
|
-
it 'does not modifies relation' do
|
46
|
-
subject = Class.new(Mincer::Base) do
|
47
|
-
skip_search!
|
48
|
-
end
|
49
|
-
query = subject.new(ActiveRecordModel, { 'pattern' => 'Bingo' })
|
50
|
-
query.to_a.count.should eq(3)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
context 'when postgres is NOT used' do
|
57
|
-
before do
|
58
|
-
setup_basic_sqlite3_table
|
59
|
-
class ActiveRecordModel < ActiveRecord::Base
|
60
|
-
end
|
61
|
-
ActiveRecordModel.create!(text: 'Test')
|
62
|
-
ActiveRecordModel.create!(text: 'Bingo')
|
63
|
-
ActiveRecordModel.create!(text: 'Bongo')
|
64
|
-
end
|
65
|
-
|
66
|
-
subject(:model) do
|
67
|
-
Class.new(Mincer::Base)
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'returns all records' do
|
71
|
-
query = subject.new(ActiveRecordModel, { 'pattern' => 'Bingo' })
|
72
|
-
query.to_a.count.should eq(3)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
|
77
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ::Mincer::Processors::Sort do
|
4
|
-
before do
|
5
|
-
setup_basic_sqlite3_table
|
6
|
-
class ActiveRecordModel < ActiveRecord::Base
|
7
|
-
end
|
8
|
-
%w{a c b}.each { |i| ActiveRecordModel.create(text: i) }
|
9
|
-
end
|
10
|
-
|
11
|
-
describe 'sorting with basic model without any Mincer::Base configuration' do
|
12
|
-
subject(:model) do
|
13
|
-
Class.new(Mincer::Base)
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'sorts by valid attribute and order when they are passed in args' do
|
17
|
-
query = subject.new(ActiveRecordModel, { 'sort' => 'text', 'order' => 'DESC' })
|
18
|
-
query.to_a.map(&:text).should == %w{c b a}
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'sorts by default attributes(id) abd order(ASC) when nothing passed to args' do
|
22
|
-
query = subject.new(ActiveRecordModel)
|
23
|
-
query.to_a.map(&:text).should == %w{a c b}
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'ignores sort attribute that is not allowed and use default(id)' do
|
27
|
-
query = subject.new(ActiveRecordModel, { 'sort' => 'text2', 'order' => 'DESC' })
|
28
|
-
query.to_a.map(&:text).should == %w{b c a}
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'ignores order that is not allowed and use default(ASC)' do
|
32
|
-
query = subject.new(ActiveRecordModel, { 'sort' => 'text', 'order' => 'DESCA' })
|
33
|
-
query.to_a.map(&:text).should == %w{a b c}
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
|
38
|
-
describe 'sorting with basic model with defaults changed' do
|
39
|
-
it 'sorts by default attributes(id) abd order(ASC) when nothing passed to args' do
|
40
|
-
subject = Class.new(Mincer::Base) do
|
41
|
-
def default_sort_attribute
|
42
|
-
'text'
|
43
|
-
end
|
44
|
-
def default_sort_order
|
45
|
-
'DESC'
|
46
|
-
end
|
47
|
-
end
|
48
|
-
query = subject.new(ActiveRecordModel)
|
49
|
-
query.to_a.map(&:text).should == %w{c b a}
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe 'sorting with basic model with defaults changed' do
|
54
|
-
it 'sorts by default attributes(id) abd order(ASC) when nothing passed to args' do
|
55
|
-
subject = Class.new(Mincer::Base) do
|
56
|
-
def allowed_sort_attributes
|
57
|
-
['id']
|
58
|
-
end
|
59
|
-
end
|
60
|
-
query = subject.new(ActiveRecordModel, { 'sort' => 'text' })
|
61
|
-
query.to_a.map(&:text).should == %w{a c b}
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
describe 'sorting when basic model has disabled sorting' do
|
67
|
-
it 'sorts by default attributes(id) abd order(ASC) when nothing passed to args' do
|
68
|
-
subject = Class.new(Mincer::Base) do
|
69
|
-
skip_sorting!
|
70
|
-
end
|
71
|
-
query = subject.new(ActiveRecordModel, { 'sort' => 'text' })
|
72
|
-
query.to_a.map(&:text).should == %w{a c b}
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
|
77
|
-
end
|