activeset 0.5.8 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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