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,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