activeset 0.5.8 → 0.6.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/CHANGELOG +2 -0
- data/lib/.DS_Store +0 -0
- data/lib/active_set.rb +24 -26
- data/lib/active_set/.DS_Store +0 -0
- data/lib/active_set/adapter_activerecord.rb +58 -0
- data/lib/active_set/adapter_base.rb +14 -0
- data/lib/active_set/instruction.rb +66 -0
- data/lib/active_set/instructions.rb +34 -0
- data/lib/active_set/processor_base.rb +28 -0
- data/lib/active_set/processor_filter.rb +21 -0
- data/lib/active_set/processor_filter/active_record_adapter.rb +50 -0
- data/lib/active_set/processor_filter/enumerable_adapter.rb +21 -0
- data/lib/active_set/processor_paginate.rb +35 -0
- data/lib/active_set/{processors/paginate → processor_paginate}/active_record_adapter.rb +11 -13
- data/lib/active_set/{processors/paginate → processor_paginate}/enumerable_adapter.rb +10 -12
- data/lib/active_set/processor_sort.rb +19 -0
- data/lib/active_set/processor_sort/active_record_adapter.rb +50 -0
- data/lib/active_set/processor_sort/enumerable_adapter.rb +58 -0
- data/lib/active_set/{processors/transform_processor.rb → processor_transform.rb} +6 -6
- data/lib/active_set/{processors/transform → processor_transform}/csv_adapter.rb +11 -14
- data/lib/active_set/version.rb +1 -1
- data/lib/helpers/throws.rb +19 -0
- metadata +21 -19
- data/lib/active_set/instructions/base.rb +0 -37
- data/lib/active_set/instructions/entry.rb +0 -27
- data/lib/active_set/instructions/entry/keypath.rb +0 -65
- data/lib/active_set/instructions/entry/value.rb +0 -15
- data/lib/active_set/processors/base_adapter.rb +0 -17
- data/lib/active_set/processors/base_processor.rb +0 -22
- data/lib/active_set/processors/filter/active_record_adapter.rb +0 -78
- data/lib/active_set/processors/filter/enumerable_adapter.rb +0 -27
- data/lib/active_set/processors/filter_processor.rb +0 -18
- data/lib/active_set/processors/paginate_processor.rb +0 -36
- data/lib/active_set/processors/sort/active_record_adapter.rb +0 -55
- data/lib/active_set/processors/sort/enumerable_adapter.rb +0 -41
- data/lib/active_set/processors/sort_processor.rb +0 -18
@@ -1,65 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support/core_ext/array/wrap'
|
4
|
-
require 'active_support/core_ext/object/try'
|
5
|
-
require 'active_support/core_ext/string/inflections'
|
6
|
-
|
7
|
-
class ActiveSet
|
8
|
-
class Instructions
|
9
|
-
class Entry
|
10
|
-
class KeyPath
|
11
|
-
attr_reader :path
|
12
|
-
|
13
|
-
def initialize(path)
|
14
|
-
# `path` can be an Array (e.g. [:parent, :child, :grandchild])
|
15
|
-
# or a String (e.g. 'parent.child.grandchild')
|
16
|
-
@path = Array.wrap(path).map(&:to_s).flat_map { |x| x.split('.') }
|
17
|
-
end
|
18
|
-
|
19
|
-
def attribute
|
20
|
-
attribute = @path.last
|
21
|
-
return attribute.sub(operator_regex, '') if attribute&.match operator_regex
|
22
|
-
attribute
|
23
|
-
end
|
24
|
-
|
25
|
-
def operator(default: '==')
|
26
|
-
attribute = @path.last
|
27
|
-
return attribute[operator_regex, 1] if attribute&.match operator_regex
|
28
|
-
default
|
29
|
-
end
|
30
|
-
|
31
|
-
def associations_array
|
32
|
-
return [] unless @path.any?
|
33
|
-
@path.slice(0, @path.length - 1)
|
34
|
-
end
|
35
|
-
|
36
|
-
def associations_hash
|
37
|
-
return {} unless @path.any?
|
38
|
-
associations_array.reverse.reduce({}) { |a, e| { e => a } }
|
39
|
-
end
|
40
|
-
|
41
|
-
def value_for(item:)
|
42
|
-
resource_for(item: item).send(attribute)
|
43
|
-
rescue
|
44
|
-
nil
|
45
|
-
end
|
46
|
-
|
47
|
-
def resource_for(item:)
|
48
|
-
associations_array.reduce(item, :try)
|
49
|
-
rescue
|
50
|
-
nil
|
51
|
-
end
|
52
|
-
|
53
|
-
def titleized
|
54
|
-
@path.map(&:titleize).join(' ')
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
def operator_regex
|
60
|
-
/\((.*?)\)/
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class ActiveSet
|
4
|
-
class BaseAdapter
|
5
|
-
def initialize(set, instruction)
|
6
|
-
@set = set
|
7
|
-
@instruction = instruction
|
8
|
-
end
|
9
|
-
|
10
|
-
def return_set(set = nil)
|
11
|
-
{}.tap do |h|
|
12
|
-
h[:set] = set || @set
|
13
|
-
h[:processed] = set ? true : false
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'patches/core_ext/hash/flatten_keys'
|
4
|
-
require_relative '../instructions/base'
|
5
|
-
|
6
|
-
class ActiveSet
|
7
|
-
class BaseProcessor
|
8
|
-
def self.queue_adapter(adapter)
|
9
|
-
@adapters ||= []
|
10
|
-
@adapters |= [adapter]
|
11
|
-
end
|
12
|
-
|
13
|
-
def initialize(set, instructions)
|
14
|
-
@set = set
|
15
|
-
@instructions = Instructions.new(instructions)
|
16
|
-
end
|
17
|
-
|
18
|
-
def adapters
|
19
|
-
self.class.instance_variable_get(:@adapters)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../base_adapter'
|
4
|
-
require_relative '../base_processor'
|
5
|
-
|
6
|
-
class ActiveSet
|
7
|
-
class FilterProcessor < BaseProcessor
|
8
|
-
class ActiveRecordAdapter < BaseAdapter
|
9
|
-
def process
|
10
|
-
return return_set unless @set.respond_to? :to_sql
|
11
|
-
return return_set(processed_query_set) if attribute_is_field?
|
12
|
-
return return_set(processed_scope_set) if attribute_is_class_method? && attribute_is_method_with_params?
|
13
|
-
|
14
|
-
return_set
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def processed_query_set
|
20
|
-
arel_eager_load_associations.where(arel_operation)
|
21
|
-
end
|
22
|
-
|
23
|
-
def processed_scope_set
|
24
|
-
tmp_results = attribute_model.public_send(@instruction.attribute, @instruction.value)
|
25
|
-
return @set unless tmp_results.is_a?(ActiveRecord::Relation)
|
26
|
-
arel_eager_load_associations.merge(tmp_results)
|
27
|
-
end
|
28
|
-
|
29
|
-
def attribute_is_field?
|
30
|
-
return false unless attribute_model
|
31
|
-
attribute_model.attribute_names
|
32
|
-
.include?(@instruction.attribute)
|
33
|
-
end
|
34
|
-
|
35
|
-
def attribute_is_class_method?
|
36
|
-
return false unless attribute_model
|
37
|
-
attribute_model.respond_to?(@instruction.attribute)
|
38
|
-
end
|
39
|
-
|
40
|
-
def attribute_is_method_with_params?
|
41
|
-
return false unless attribute_model
|
42
|
-
attribute_model.method(@instruction.attribute).arity != 0
|
43
|
-
end
|
44
|
-
|
45
|
-
def arel_operation
|
46
|
-
Arel::Nodes::InfixOperation.new(@instruction.operator(default: '='),
|
47
|
-
arel_column,
|
48
|
-
arel_value)
|
49
|
-
end
|
50
|
-
|
51
|
-
def attribute_model
|
52
|
-
tmp_model = @instruction.associations_array
|
53
|
-
.reduce(@set) do |obj, assoc|
|
54
|
-
obj.reflections[assoc.to_s]&.klass
|
55
|
-
end
|
56
|
-
return tmp_model.klass if tmp_model.is_a?(ActiveRecord::Relation)
|
57
|
-
tmp_model
|
58
|
-
end
|
59
|
-
|
60
|
-
def arel_eager_load_associations
|
61
|
-
@set.includes(@instruction.associations_hash)
|
62
|
-
.references(@instruction.associations_hash)
|
63
|
-
end
|
64
|
-
|
65
|
-
def arel_column
|
66
|
-
arel_table[@instruction.attribute]
|
67
|
-
end
|
68
|
-
|
69
|
-
def arel_value
|
70
|
-
Arel.sql(ActiveRecord::Base.connection.quote(@instruction.value))
|
71
|
-
end
|
72
|
-
|
73
|
-
def arel_table
|
74
|
-
Arel::Table.new(attribute_model.table_name)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../base_adapter'
|
4
|
-
|
5
|
-
class ActiveSet
|
6
|
-
class FilterProcessor < BaseProcessor
|
7
|
-
class EnumerableAdapter < BaseAdapter
|
8
|
-
def process
|
9
|
-
return_set(filtered_set)
|
10
|
-
end
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
def filtered_set
|
15
|
-
@set.select do |item|
|
16
|
-
select_comparison_for(item: item)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def select_comparison_for(item:)
|
21
|
-
@instruction.value_for(item: item)
|
22
|
-
.send(@instruction.operator,
|
23
|
-
@instruction.value)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative './base_processor'
|
4
|
-
require_relative './filter/enumerable_adapter'
|
5
|
-
require_relative './filter/active_record_adapter'
|
6
|
-
|
7
|
-
class ActiveSet
|
8
|
-
class FilterProcessor < BaseProcessor
|
9
|
-
queue_adapter ActiveRecordAdapter
|
10
|
-
queue_adapter EnumerableAdapter
|
11
|
-
|
12
|
-
def process
|
13
|
-
adapters.reduce(@set) do |outer_set, adapter|
|
14
|
-
@instructions.process_adapter(set: outer_set, adapter: adapter)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative './base_processor'
|
4
|
-
require_relative './paginate/enumerable_adapter'
|
5
|
-
require_relative './paginate/active_record_adapter'
|
6
|
-
|
7
|
-
class ActiveSet
|
8
|
-
class PaginateProcessor < BaseProcessor
|
9
|
-
queue_adapter ActiveRecordAdapter
|
10
|
-
queue_adapter EnumerableAdapter
|
11
|
-
|
12
|
-
def process
|
13
|
-
adapters.each do |adapter|
|
14
|
-
output = adapter.new(@set, instruction).process
|
15
|
-
|
16
|
-
return output[:set] if output[:processed]
|
17
|
-
end
|
18
|
-
|
19
|
-
@set
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def instruction
|
25
|
-
Instructions::Entry.new(page_number, page_size)
|
26
|
-
end
|
27
|
-
|
28
|
-
def page_number
|
29
|
-
@instructions.get(:page) || 1
|
30
|
-
end
|
31
|
-
|
32
|
-
def page_size
|
33
|
-
@instructions.get(:size) || 25
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../base_adapter'
|
4
|
-
require_relative '../base_processor'
|
5
|
-
|
6
|
-
class ActiveSet
|
7
|
-
class SortProcessor < BaseProcessor
|
8
|
-
class ActiveRecordAdapter < BaseAdapter
|
9
|
-
def process
|
10
|
-
return return_set unless @set.respond_to? :to_sql
|
11
|
-
return return_set unless attribute_is_field?
|
12
|
-
|
13
|
-
return_set(processed_set)
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def attribute_is_field?
|
19
|
-
return false unless attribute_model
|
20
|
-
attribute_model.attribute_names
|
21
|
-
.include?(@instruction.attribute)
|
22
|
-
end
|
23
|
-
|
24
|
-
def processed_set
|
25
|
-
@set.includes(@instruction.associations_hash)
|
26
|
-
.references(@instruction.associations_hash)
|
27
|
-
.merge(arel_operation)
|
28
|
-
end
|
29
|
-
|
30
|
-
def arel_operation
|
31
|
-
column = case_insensitive? ? arel_column.lower : arel_column
|
32
|
-
attribute_model.order(column.send(@instruction.value))
|
33
|
-
end
|
34
|
-
|
35
|
-
def attribute_model
|
36
|
-
@instruction.associations_array
|
37
|
-
.reduce(@set.klass) do |obj, assoc|
|
38
|
-
obj.reflections[assoc.to_s]&.klass
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def arel_column
|
43
|
-
arel_table[@instruction.attribute]
|
44
|
-
end
|
45
|
-
|
46
|
-
def arel_table
|
47
|
-
Arel::Table.new(attribute_model.table_name)
|
48
|
-
end
|
49
|
-
|
50
|
-
def case_insensitive?
|
51
|
-
@instruction.operator.to_s == 'i'
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../base_adapter'
|
4
|
-
require_relative '../base_processor'
|
5
|
-
|
6
|
-
class ActiveSet
|
7
|
-
class SortProcessor < BaseProcessor
|
8
|
-
class EnumerableAdapter < BaseAdapter
|
9
|
-
def process
|
10
|
-
return_set(sorted_set)
|
11
|
-
end
|
12
|
-
|
13
|
-
private
|
14
|
-
|
15
|
-
def sorted_set
|
16
|
-
@set.sort_by { |item| sortable_attribute_for(item: item) }
|
17
|
-
.tap { |c| c.reverse! if descending? }
|
18
|
-
end
|
19
|
-
|
20
|
-
def sortable_attribute_for(item:)
|
21
|
-
attribute_value = @instruction.value_for(item: item)
|
22
|
-
case_insensitive?(attribute_value) ? insensify(attribute_value) : attribute_value
|
23
|
-
end
|
24
|
-
|
25
|
-
def case_insensitive?(value)
|
26
|
-
# Cannot sort pure Booleans or Nils, so we _must_ cast to Strings
|
27
|
-
return true if value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
28
|
-
return true if value.is_a?(NilClass)
|
29
|
-
@instruction.operator.to_s == 'i'
|
30
|
-
end
|
31
|
-
|
32
|
-
def insensify(value)
|
33
|
-
value.to_s.downcase
|
34
|
-
end
|
35
|
-
|
36
|
-
def descending?
|
37
|
-
@instruction.value.to_s == 'desc'
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative './base_processor'
|
4
|
-
require_relative './sort/enumerable_adapter'
|
5
|
-
require_relative './sort/active_record_adapter'
|
6
|
-
|
7
|
-
class ActiveSet
|
8
|
-
class SortProcessor < BaseProcessor
|
9
|
-
queue_adapter ActiveRecordAdapter
|
10
|
-
queue_adapter EnumerableAdapter
|
11
|
-
|
12
|
-
def process
|
13
|
-
adapters.reduce(@set) do |outer_set, adapter|
|
14
|
-
@instructions.process_adapter(set: outer_set, adapter: adapter)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|