horza 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ad75669d3af7d16418b004a3c6ddea50258d8ae7
4
- data.tar.gz: dc77c4becdffc82ff00016ad6a7f84c49be6965a
3
+ metadata.gz: 75fcb74059583a6a1d2db95b90c205df028f4ca4
4
+ data.tar.gz: f3580ea7b8820ddf78398e0eb241b73f6c66f160
5
5
  SHA512:
6
- metadata.gz: fb4f6e4a305f50191357ff2fa7aed0e962961d12f020210833d45ca0b85ecd401835fb41576d37167ee285462a7355013dfd1309cf0eeeda0c821f9384cc7857
7
- data.tar.gz: f434ceacd8d0c426c2ab251ed547c675602599de999e10f9d2666c907742b3989b1d63ec4fbb5d6148831216df2c8339883506ac03818abcc6d55fd91ee7f1f5
6
+ metadata.gz: 2d8c3d3399690a7214c944a67a6960826d429367326266bac3561f0a5095db8a9285aab13cf348bf9665e80c201ae2c5a459cc6b7c9ab2b6e0a71fea82b6cb6e
7
+ data.tar.gz: e206eb74ba5391dfd7ee5ffad4994cdf7e44e12bbb19fb901f132c7792d2543052244b00eb7100f3219749a411efdf880c4390b16f15ea5640e27796752e0139
@@ -1,3 +1,5 @@
1
+ require 'horza/adapters/class_methods'
2
+ require 'horza/adapters/instance_methods'
1
3
  require 'horza/adapters/abstract_adapter'
2
4
  require 'horza/adapters/active_record'
3
5
  require 'horza/core_extensions/string'
@@ -6,7 +8,7 @@ require 'horza/entities/collection'
6
8
  require 'horza/entities'
7
9
  require 'horza/configuration'
8
10
  require 'horza/errors'
9
- require 'active_support/inflector'
11
+ require 'active_support'
10
12
 
11
13
  module Horza
12
14
  extend Configuration
@@ -1,44 +1,25 @@
1
1
  module Horza
2
2
  module Adapters
3
3
  class AbstractAdapter
4
+ extend ::Horza::Adapters::ClassMethods
5
+ include ::Horza::Adapters::InstanceMethods
6
+
4
7
  attr_reader :context
5
8
 
6
9
  class << self
7
- def expected_errors
8
- [::Horza::Errors::RecordNotFound, ::Horza::Errors::RecordInvalid]
9
- end
10
-
11
- def context_for_entity(entity)
10
+ def expected_errors_map
12
11
  not_implemented_error
13
12
  end
14
13
 
15
14
  def entity_context_map
16
15
  not_implemented_error
17
16
  end
18
-
19
- def not_implemented_error
20
- raise ::Horza::Errors::MethodNotImplemented, 'You must implement this method in your adapter.'
21
- end
22
- end
23
-
24
- def initialize(context)
25
- @context = context
26
17
  end
27
18
 
28
- def get(options = {})
29
- get!(options)
30
- rescue *self.class.expected_errors
31
- end
32
-
33
- def get!(options = {})
19
+ def get!(id)
34
20
  not_implemented_error
35
21
  end
36
22
 
37
- def find_first(options = {})
38
- find_first!(options)
39
- rescue *self.class.expected_errors
40
- end
41
-
42
23
  def find_first!(options = {})
43
24
  not_implemented_error
44
25
  end
@@ -47,29 +28,14 @@ module Horza
47
28
  not_implemented_error
48
29
  end
49
30
 
50
- def create(options = {})
51
- create!(options)
52
- rescue *self.class.expected_errors
53
- end
54
-
55
31
  def create!(options = {})
56
32
  not_implemented_error
57
33
  end
58
34
 
59
- def delete(id)
60
- delete!(id)
61
- rescue *self.class.expected_errors
62
- end
63
-
64
35
  def delete!(id)
65
36
  not_implemented_error
66
37
  end
67
38
 
68
- def update(id, options = {})
69
- update!(id, options)
70
- rescue *self.class.expected_errors
71
- end
72
-
73
39
  def update!(id, options = {})
74
40
  not_implemented_error
75
41
  end
@@ -78,27 +44,14 @@ module Horza
78
44
  not_implemented_error
79
45
  end
80
46
 
81
- def eager_load(options = {})
82
- not_implemented_error
83
- end
84
-
85
47
  def to_hash
86
48
  not_implemented_error
87
49
  end
88
50
 
89
- def entity_class(res = @context)
90
- collection?(res) ? ::Horza::Entities.collection_entity_for(entity_symbol).new(res) : ::Horza::Entities.single_entity_for(entity_symbol).new(res)
91
- end
92
-
93
51
  private
94
52
 
95
- def not_implemented_error
96
- self.class.not_implemented_error
97
- end
98
-
99
- def entity_symbol
100
- klass = @context.name.split('::').last
101
- collection? ? klass.pluralize.symbolize : klass.symbolize
53
+ def collection?
54
+ not_implemented_error
102
55
  end
103
56
  end
104
57
  end
@@ -4,64 +4,65 @@ module Horza
4
4
  INVALID_ANCESTRY_MSG = 'Invalid relation. Ensure that the plurality of your associations is correct.'
5
5
 
6
6
  class << self
7
- def context_for_entity(entity)
8
- entity_context_map[entity]
9
- end
10
-
11
7
  def entity_context_map
8
+ # Rails doesn't preload classes in development mode, caching doesn't make sense
9
+ return ::Horza.descendants_map(::ActiveRecord::Base) if ::Horza.configuration.development_mode
12
10
  @map ||= ::Horza.descendants_map(::ActiveRecord::Base)
13
11
  end
12
+
13
+ def expected_errors_map
14
+ {
15
+ ::ActiveRecord::RecordNotFound => Horza::Errors::RecordNotFound,
16
+ ::ActiveRecord::RecordInvalid => Horza::Errors::RecordInvalid
17
+ }
18
+ end
14
19
  end
15
20
 
16
21
  def get!(id)
17
- entity_class(@context.find(id).attributes)
18
- rescue ::ActiveRecord::RecordNotFound => e
19
- raise Horza::Errors::RecordNotFound.new(e)
22
+ run_and_convert_exceptions { entity_class(@context.find(id).attributes) }
20
23
  end
21
24
 
22
25
  def find_first!(options = {})
23
- entity_class(base_query(options).first!.attributes)
24
- rescue ::ActiveRecord::RecordNotFound => e
25
- raise Horza::Errors::RecordNotFound.new(e)
26
+ run_and_convert_exceptions { entity_class(base_query(options).first!.attributes) }
26
27
  end
27
28
 
28
29
  def find_all(options = {})
29
- entity_class(base_query(options))
30
+ run_and_convert_exceptions { entity_class(base_query(options)) }
30
31
  end
31
32
 
32
33
  def create!(options = {})
33
- record = @context.new(options)
34
- record.save!
35
- entity_class(record.attributes)
36
- rescue ::ActiveRecord::RecordInvalid => e
37
- raise Horza::Errors::RecordInvalid.new(e)
34
+ run_and_convert_exceptions do
35
+ record = @context.new(options)
36
+ record.save!
37
+ entity_class(record.attributes)
38
+ end
38
39
  end
39
40
 
40
41
  def update!(id, options = {})
41
- record = @context.find(id)
42
- record.assign_attributes(options)
43
- record.save!
44
- record
45
- rescue ::ActiveRecord::RecordNotFound => e
46
- raise Horza::Errors::RecordNotFound.new(e)
47
- rescue ::ActiveRecord::RecordInvalid => e
48
- raise Horza::Errors::RecordInvalid.new(e)
42
+ run_and_convert_exceptions do
43
+ record = @context.find(id)
44
+ record.assign_attributes(options)
45
+ record.save!
46
+ entity_class(record.attributes)
47
+ end
49
48
  end
50
49
 
51
50
  def delete!(id)
52
- record = @context.find(id)
53
- record.destroy!
54
- true
55
- rescue ::ActiveRecord::RecordNotFound => e
56
- raise Horza::Errors::RecordNotFound.new(e)
51
+ run_and_convert_exceptions do
52
+ record = @context.find(id)
53
+ record.destroy!
54
+ true
55
+ end
57
56
  end
58
57
 
59
58
  def ancestors(options = {})
60
- result = walk_family_tree(@context.find(options[:id]), options)
59
+ run_and_convert_exceptions do
60
+ result = walk_family_tree(@context.find(options[:id]), options)
61
61
 
62
- return nil unless result
62
+ return nil unless result
63
63
 
64
- collection?(result) ? entity_class(result) : entity_class(result.attributes)
64
+ collection?(result) ? entity_class(result) : entity_class(result.attributes)
65
+ end
65
66
  end
66
67
 
67
68
  def to_hash
@@ -0,0 +1,25 @@
1
+ module Horza
2
+ module Adapters
3
+ module ClassMethods
4
+ def expected_horza_errors
5
+ [Horza::Errors::RecordNotFound, Horza::Errors::RecordInvalid]
6
+ end
7
+
8
+ def expected_errors
9
+ expected_errors_map.keys
10
+ end
11
+
12
+ def horza_error_from_orm_error(orm_error)
13
+ expected_errors_map[orm_error]
14
+ end
15
+
16
+ def context_for_entity(entity)
17
+ entity_context_map[entity]
18
+ end
19
+
20
+ def not_implemented_error
21
+ raise ::Horza::Errors::MethodNotImplemented, 'You must implement this method in your adapter.'
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,87 @@
1
+ module Horza
2
+ module Adapters
3
+ module InstanceMethods
4
+
5
+ def initialize(context)
6
+ @context = context
7
+ end
8
+
9
+ def get(id)
10
+ run_quietly { get!(id) }
11
+ end
12
+
13
+ def find_first(options = {})
14
+ run_quietly { find_first!(options) }
15
+ end
16
+
17
+ def create(options = {})
18
+ run_quietly { create!(options) }
19
+ end
20
+
21
+ def delete(id)
22
+ run_quietly { delete!(id) }
23
+ end
24
+
25
+ def update(id, options = {})
26
+ run_quietly { update!(id, options) }
27
+ end
28
+
29
+ protected
30
+
31
+ def run_quietly(&block)
32
+ block.call
33
+ rescue *self.class.expected_horza_errors
34
+ end
35
+
36
+ # Execute the code block and convert ORM exceptions into Horza exceptions
37
+ def run_and_convert_exceptions(&block)
38
+ block.call
39
+ rescue *self.class.expected_errors => e
40
+ raise self.class.horza_error_from_orm_error(e.class)
41
+ end
42
+
43
+ def entity_class(res = @context)
44
+ collection?(res) ? ::Horza::Entities.collection_entity_for(entity_symbol).new(res) : ::Horza::Entities.single_entity_for(entity_symbol).new(res)
45
+ end
46
+
47
+ def entity_symbol
48
+ klass = @context.name.split('::').last
49
+ collection? ? klass.pluralize.symbolize : klass.symbolize
50
+ end
51
+
52
+ # given an options hash,
53
+ # with optional :conditions, :order, :limit and :offset keys,
54
+ # returns conditions, normalized order, limit and offset
55
+ def extract_conditions!(options = {})
56
+ order = normalize_order(options.delete(:order))
57
+ limit = options.delete(:limit)
58
+ offset = options.delete(:offset)
59
+ conditions = options.delete(:conditions) || options
60
+
61
+ [conditions, order, limit, offset]
62
+ end
63
+
64
+ # given an order argument, returns an array of pairs, with each pair containing the attribute, and :asc or :desc
65
+ def normalize_order(order)
66
+ order = Array(order)
67
+
68
+ if order.length == 2 && !order[0].is_a?(Array) && [:asc, :desc].include?(order[1])
69
+ order = [order]
70
+ else
71
+ order = order.map {|pair| pair.is_a?(Array) ? pair : [pair, :asc] }
72
+ end
73
+
74
+ order.each do |pair|
75
+ pair.length == 2 or raise ArgumentError, "each order clause must be a pair (unknown clause #{pair.inspect})"
76
+ [:asc, :desc].include?(pair[1]) or raise ArgumentError, "order must be specified with :asc or :desc (unknown key #{pair[1].inspect})"
77
+ end
78
+
79
+ order
80
+ end
81
+
82
+ def not_implemented_error
83
+ self.class.not_implemented_error
84
+ end
85
+ end
86
+ end
87
+ end
@@ -35,6 +35,6 @@ module Horza
35
35
  end
36
36
 
37
37
  class Config
38
- attr_accessor :adapter
38
+ attr_accessor :adapter, :development_mode
39
39
  end
40
40
  end
@@ -59,6 +59,28 @@ describe Horza do
59
59
  HorzaSpec::Employer.delete_all
60
60
  end
61
61
 
62
+ context '#context_for_entity' do
63
+ it 'Returns correct class' do
64
+ expect(Horza.adapter.context_for_entity(:user)).to eq HorzaSpec::User
65
+ end
66
+
67
+ context 'in development mode' do
68
+ before do
69
+ Horza.reset
70
+ Horza.configure do |config|
71
+ config.adapter = adapter
72
+ config.development_mode = true
73
+ end
74
+ end
75
+ after do
76
+ Horza.reset
77
+ end
78
+ it 'Returns correct class' do
79
+ expect(Horza.adapter.context_for_entity(:user)).to eq HorzaSpec::User
80
+ end
81
+ end
82
+ end
83
+
62
84
  describe '#adapter' do
63
85
  let(:user) { HorzaSpec::User.create }
64
86
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: horza
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Blake Turner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-03 00:00:00.000000000 Z
11
+ date: 2015-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -106,6 +106,8 @@ files:
106
106
  - lib/horza.rb
107
107
  - lib/horza/adapters/abstract_adapter.rb
108
108
  - lib/horza/adapters/active_record.rb
109
+ - lib/horza/adapters/class_methods.rb
110
+ - lib/horza/adapters/instance_methods.rb
109
111
  - lib/horza/configuration.rb
110
112
  - lib/horza/core_extensions/string.rb
111
113
  - lib/horza/entities.rb