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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +2 -0
  3. data/lib/.DS_Store +0 -0
  4. data/lib/active_set.rb +24 -26
  5. data/lib/active_set/.DS_Store +0 -0
  6. data/lib/active_set/adapter_activerecord.rb +58 -0
  7. data/lib/active_set/adapter_base.rb +14 -0
  8. data/lib/active_set/instruction.rb +66 -0
  9. data/lib/active_set/instructions.rb +34 -0
  10. data/lib/active_set/processor_base.rb +28 -0
  11. data/lib/active_set/processor_filter.rb +21 -0
  12. data/lib/active_set/processor_filter/active_record_adapter.rb +50 -0
  13. data/lib/active_set/processor_filter/enumerable_adapter.rb +21 -0
  14. data/lib/active_set/processor_paginate.rb +35 -0
  15. data/lib/active_set/{processors/paginate → processor_paginate}/active_record_adapter.rb +11 -13
  16. data/lib/active_set/{processors/paginate → processor_paginate}/enumerable_adapter.rb +10 -12
  17. data/lib/active_set/processor_sort.rb +19 -0
  18. data/lib/active_set/processor_sort/active_record_adapter.rb +50 -0
  19. data/lib/active_set/processor_sort/enumerable_adapter.rb +58 -0
  20. data/lib/active_set/{processors/transform_processor.rb → processor_transform.rb} +6 -6
  21. data/lib/active_set/{processors/transform → processor_transform}/csv_adapter.rb +11 -14
  22. data/lib/active_set/version.rb +1 -1
  23. data/lib/helpers/throws.rb +19 -0
  24. metadata +21 -19
  25. data/lib/active_set/instructions/base.rb +0 -37
  26. data/lib/active_set/instructions/entry.rb +0 -27
  27. data/lib/active_set/instructions/entry/keypath.rb +0 -65
  28. data/lib/active_set/instructions/entry/value.rb +0 -15
  29. data/lib/active_set/processors/base_adapter.rb +0 -17
  30. data/lib/active_set/processors/base_processor.rb +0 -22
  31. data/lib/active_set/processors/filter/active_record_adapter.rb +0 -78
  32. data/lib/active_set/processors/filter/enumerable_adapter.rb +0 -27
  33. data/lib/active_set/processors/filter_processor.rb +0 -18
  34. data/lib/active_set/processors/paginate_processor.rb +0 -36
  35. data/lib/active_set/processors/sort/active_record_adapter.rb +0 -55
  36. data/lib/active_set/processors/sort/enumerable_adapter.rb +0 -41
  37. 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,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class ActiveSet
4
- class Instructions
5
- class Entry
6
- class Value
7
- attr_reader :raw
8
-
9
- def initialize(value)
10
- @raw = value
11
- end
12
- end
13
- end
14
- end
15
- 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