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,37 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../base_adapter'
4
- require_relative '../base_processor'
3
+ require_relative '../adapter_base'
4
+ require_relative '../processor_base'
5
5
 
6
6
  class ActiveSet
7
- class PaginateProcessor < BaseProcessor
8
- class ActiveRecordAdapter < BaseAdapter
7
+ class Processor::Paginate < Processor::Base
8
+ class ActiveRecordAdapter < Adapter::Base
9
9
  def process
10
- return return_set unless @set.respond_to? :to_sql
10
+ return false unless @set.respond_to? :to_sql
11
+ return @set.none if @set.length <= page_size && page_number > 1
11
12
 
12
- return_set(paginated_set)
13
+ @set.limit(page_size).offset(page_offset)
13
14
  end
14
15
 
15
16
  private
16
17
 
17
- def paginated_set
18
- return @set.none if @set.length <= page_size && page_number > 1
19
- @set.limit(page_size).offset(page_offset)
20
- end
21
-
22
18
  def page_offset
23
19
  return 0 if page_number == 1
20
+
24
21
  page_size * (page_number - 1)
25
22
  end
26
23
 
27
24
  def page_size
28
- @instruction.value
25
+ @instructions.get('size').to_i
29
26
  end
30
27
 
31
28
  def page_number
32
- num = @instruction.attribute.to_i
29
+ num = @instructions.get('page').to_i
33
30
  return 1 if (num - 1).negative?
34
31
  return 1 if (num - 1).zero?
32
+
35
33
  num
36
34
  end
37
35
  end
@@ -1,39 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../base_adapter'
4
- require_relative '../base_processor'
3
+ require_relative '../adapter_base'
4
+ require_relative '../processor_base'
5
5
 
6
6
  class ActiveSet
7
- class PaginateProcessor < BaseProcessor
8
- class EnumerableAdapter < BaseAdapter
7
+ class Processor::Paginate < Processor::Base
8
+ class EnumerableAdapter < Adapter::Base
9
9
  def process
10
- return_set(paginated_set)
11
- end
12
-
13
- private
14
-
15
- def paginated_set
16
10
  return [] if @set.count <= page_size && page_number > 1
17
11
 
18
12
  @set[page_start..page_end] || []
19
13
  end
20
14
 
15
+ private
16
+
21
17
  def page_start
22
18
  return 0 if page_number == 1
19
+
23
20
  page_size * (page_number - 1)
24
21
  end
25
22
 
26
23
  def page_end
27
24
  return page_start if page_size == 1
25
+
28
26
  page_start + page_size - 1
29
27
  end
30
28
 
31
29
  def page_size
32
- @instruction.value
30
+ @instructions.get('size').to_i
33
31
  end
34
32
 
35
33
  def page_number
36
- num = @instruction.attribute.to_i
34
+ num = @instructions.get('page').to_i
37
35
  (num.to_i - 1).negative? ? 0 : num
38
36
  end
39
37
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './processor_base'
4
+ require_relative './processor_sort/enumerable_adapter'
5
+ require_relative './processor_sort/active_record_adapter'
6
+
7
+ class ActiveSet
8
+ class Processor::Sort < Processor::Base
9
+ def process
10
+ adapters.each do |adapter|
11
+ result = adapter.new(@set, @instructions).process
12
+ break(result) if result
13
+ end
14
+ end
15
+
16
+ register_adapter(EnumerableAdapter)
17
+ register_adapter(ActiveRecordAdapter)
18
+ end
19
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../adapter_activerecord'
4
+ require_relative '../processor_base'
5
+ require_relative '../../helpers/throws'
6
+
7
+ class ActiveSet
8
+ class Processor::Sort < Processor::Base
9
+ class ActiveRecordAdapter < Adapter::ActiveRecord
10
+ def process
11
+ @instructions.reduce(@set) do |set, _instruction|
12
+ # set Adapter::Base#instruction, which many methods depend on
13
+ self.instruction = _instruction
14
+
15
+ return false unless @set.respond_to?(:to_sql)
16
+ return false unless can_query_with_active_record?
17
+
18
+ statement = arel_eager_load_associations
19
+ .merge(arel_operation)
20
+
21
+ return false if throws?(ActiveRecord::StatementInvalid) { statement.load }
22
+
23
+ statement
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def arel_operation
30
+ arel_direction = arel_direction(instruction.value)
31
+
32
+ attribute_model.order(arel_column.send(arel_direction))
33
+ end
34
+
35
+ def arel_column
36
+ case_insensitive? ? super.lower : super
37
+ end
38
+
39
+ def case_insensitive?
40
+ instruction.operator.to_s.downcase == 'i'
41
+ end
42
+
43
+ def arel_direction(direction)
44
+ return 'desc' if direction.to_s.downcase.start_with? 'desc'
45
+
46
+ 'asc'
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../adapter_base'
4
+ require_relative '../processor_base'
5
+
6
+ class ActiveSet
7
+ class Processor::Sort < Processor::Base
8
+ class EnumerableAdapter < Adapter::Base
9
+ def process
10
+ @set.sort do |left, right|
11
+ @instructions.reduce(0) do |diff, instruction|
12
+ # set Adapter::Base#instruction, which many methods depend on
13
+ self.instruction = instruction
14
+
15
+ # `left` and `right` differed at an earlier order entry
16
+ next diff if diff != 0
17
+
18
+ left_value = sortable_attribute_for(left)
19
+ right_value = sortable_attribute_for(right)
20
+
21
+ # handle `nil` values
22
+ next 0 if left_value.nil? && right_value.nil?
23
+ next 1 if left_value.nil?
24
+ next -1 if right_value.nil?
25
+
26
+ # do the actual comparison
27
+ comparison = left_value <=> right_value
28
+ next comparison * direction_multiplier(instruction.value)
29
+ end
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def sortable_attribute_for(item)
36
+ value = instruction.value_for(item: item)
37
+
38
+ return value.to_s.downcase if case_insensitive?(value)
39
+
40
+ value
41
+ end
42
+
43
+ def case_insensitive?(value)
44
+ # Cannot sort pure Booleans or Nils, so we _must_ cast to Strings
45
+ return true if value.is_a?(TrueClass) || value.is_a?(FalseClass)
46
+ return true if value.is_a?(NilClass)
47
+
48
+ instruction.operator.to_s.downcase == 'i'
49
+ end
50
+
51
+ def direction_multiplier(direction)
52
+ return -1 if direction.to_s.downcase.start_with? 'desc'
53
+
54
+ 1
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './base_processor'
4
- require_relative './transform/csv_adapter'
3
+ require_relative './processor_base'
4
+ require_relative './processor_transform/csv_adapter'
5
5
 
6
6
  class ActiveSet
7
- class TransformProcessor < BaseProcessor
7
+ class Processor::Transform < Processor::Base
8
8
  def process
9
9
  fail "Format #{format} is not currently supported as option for tranform" unless %w[csv].include?(format)
10
10
 
11
- adapter = adapter_for(format: format)
12
- output = adapter.new(@set, columns).process
13
- output[:set]
11
+ adapter_for(format: format)
12
+ .new(@set, columns)
13
+ .process
14
14
  end
15
15
 
16
16
  private
@@ -2,20 +2,15 @@
2
2
 
3
3
  require 'csv'
4
4
  require 'active_support/core_ext/hash/indifferent_access'
5
+ require 'active_support/core_ext/string/inflections'
5
6
 
6
- require_relative '../base_adapter'
7
- require_relative '../base_processor'
7
+ require_relative '../adapter_base'
8
+ require_relative '../processor_base'
8
9
 
9
10
  class ActiveSet
10
- class TransformProcessor < BaseProcessor
11
- class CSVAdapter < BaseAdapter
11
+ class Processor::Transform < Processor::Base
12
+ class CSVAdapter < Adapter::Base
12
13
  def process
13
- return_set(transformed_set)
14
- end
15
-
16
- private
17
-
18
- def transformed_set
19
14
  ::CSV.generate do |output|
20
15
  output << column_keys_for(item: @set.first)
21
16
  @set.each do |item|
@@ -24,6 +19,8 @@ class ActiveSet
24
19
  end
25
20
  end
26
21
 
22
+ private
23
+
27
24
  def column_keys_for(item:)
28
25
  columns.map do |column|
29
26
  ColumnInstruction.new(column, item).key
@@ -37,7 +34,7 @@ class ActiveSet
37
34
  end
38
35
 
39
36
  def columns
40
- @instruction.compact
37
+ @instructions.compact
41
38
  end
42
39
 
43
40
  class ColumnInstruction
@@ -48,8 +45,8 @@ class ActiveSet
48
45
 
49
46
  def key
50
47
  return @hash[:key] if @hash.key? :key
51
- return attribute_model.human_attribute_name(instruction_entry.attribute) if attribute_model.respond_to? :human_attribute_name
52
- instruction_entry.titleized
48
+ return attribute_model.human_attribute_name(instructions_entry.attribute) if attribute_model.respond_to? :human_attribute_name
49
+ instruction_entry.keypath.map(&:titleize).join(' ')
53
50
  end
54
51
 
55
52
  def value
@@ -61,7 +58,7 @@ class ActiveSet
61
58
  private
62
59
 
63
60
  def instruction_entry
64
- Instructions::Entry.new(@hash[:value], nil)
61
+ Instruction.new(@hash[:value], nil)
65
62
  end
66
63
 
67
64
  def attribute_model
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ActiveSet
4
- VERSION = '0.5.8'
4
+ VERSION = '0.6.0'
5
5
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Returns a Boolean for whether the block raises the Exception expected
4
+ #
5
+ # throws?(StandardError) { raise }
6
+ # => true
7
+ # throws?(NameError) { raise NameError }
8
+ # => true
9
+ # throws?(NoMethodError) { raise NameError }
10
+ # => false
11
+ # throws?(StandardError) { 'foo' }
12
+ # => false
13
+
14
+ def throws?(exception) # &block
15
+ yield
16
+ return false
17
+ rescue Exception => e
18
+ return e.is_a? exception
19
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeset
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.8
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Margheim
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-30 00:00:00.000000000 Z
11
+ date: 2018-08-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -171,25 +171,27 @@ files:
171
171
  - bin/console
172
172
  - bin/setup
173
173
  - config.ru
174
+ - lib/.DS_Store
174
175
  - lib/active_set.rb
175
- - lib/active_set/instructions/base.rb
176
- - lib/active_set/instructions/entry.rb
177
- - lib/active_set/instructions/entry/keypath.rb
178
- - lib/active_set/instructions/entry/value.rb
179
- - lib/active_set/processors/base_adapter.rb
180
- - lib/active_set/processors/base_processor.rb
181
- - lib/active_set/processors/filter/active_record_adapter.rb
182
- - lib/active_set/processors/filter/enumerable_adapter.rb
183
- - lib/active_set/processors/filter_processor.rb
184
- - lib/active_set/processors/paginate/active_record_adapter.rb
185
- - lib/active_set/processors/paginate/enumerable_adapter.rb
186
- - lib/active_set/processors/paginate_processor.rb
187
- - lib/active_set/processors/sort/active_record_adapter.rb
188
- - lib/active_set/processors/sort/enumerable_adapter.rb
189
- - lib/active_set/processors/sort_processor.rb
190
- - lib/active_set/processors/transform/csv_adapter.rb
191
- - lib/active_set/processors/transform_processor.rb
176
+ - lib/active_set/.DS_Store
177
+ - lib/active_set/adapter_activerecord.rb
178
+ - lib/active_set/adapter_base.rb
179
+ - lib/active_set/instruction.rb
180
+ - lib/active_set/instructions.rb
181
+ - lib/active_set/processor_base.rb
182
+ - lib/active_set/processor_filter.rb
183
+ - lib/active_set/processor_filter/active_record_adapter.rb
184
+ - lib/active_set/processor_filter/enumerable_adapter.rb
185
+ - lib/active_set/processor_paginate.rb
186
+ - lib/active_set/processor_paginate/active_record_adapter.rb
187
+ - lib/active_set/processor_paginate/enumerable_adapter.rb
188
+ - lib/active_set/processor_sort.rb
189
+ - lib/active_set/processor_sort/active_record_adapter.rb
190
+ - lib/active_set/processor_sort/enumerable_adapter.rb
191
+ - lib/active_set/processor_transform.rb
192
+ - lib/active_set/processor_transform/csv_adapter.rb
192
193
  - lib/active_set/version.rb
194
+ - lib/helpers/throws.rb
193
195
  - lib/patches/core_ext/hash/flatten_keys.rb
194
196
  homepage: https://github.com/fractaledmind/activeset
195
197
  licenses:
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/hash/keys'
4
- require 'active_support/core_ext/hash/indifferent_access'
5
-
6
- require_relative './entry'
7
-
8
- class ActiveSet
9
- class Instructions
10
- attr_reader :hash
11
-
12
- def initialize(hash)
13
- @hash = hash.with_indifferent_access
14
- @flattened_hash = hash.flatten_keys.transform_keys { |k| k.map(&:to_s) }
15
- end
16
-
17
- def process_adapter(set:, adapter:)
18
- @flattened_hash.reduce(set) do |inner_set, (keypath, value)|
19
- instruction = Entry.new(keypath, value)
20
- output = adapter.new(inner_set, instruction).process
21
- remove_from_instruction_set(key: instruction.path) if output[:processed]
22
-
23
- output[:set]
24
- end
25
- end
26
-
27
- def get(keypath)
28
- @hash.dig(*keypath)
29
- end
30
-
31
- private
32
-
33
- def remove_from_instruction_set(key:)
34
- @flattened_hash.delete(key)
35
- end
36
- end
37
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/module/delegation'
4
-
5
- require_relative 'entry/keypath'
6
- require_relative 'entry/value'
7
-
8
- class ActiveSet
9
- class Instructions
10
- class Entry
11
- attr_reader :keypath
12
-
13
- delegate :path, :attribute, :operator, :associations_array,
14
- :associations_hash, :value_for, :resource_for, :titleized,
15
- to: :keypath
16
-
17
- def initialize(keypath, value)
18
- @keypath = KeyPath.new(keypath)
19
- @value = Value.new(value)
20
- end
21
-
22
- def value
23
- @value.raw
24
- end
25
- end
26
- end
27
- end