mincer 0.1.2 → 0.2.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/.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
|