ncore 1.0.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.
@@ -0,0 +1,26 @@
1
+ module NCore
2
+ module Identity
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def class_name
7
+ self.name.split('::')[-1]
8
+ end
9
+
10
+ def module_name
11
+ self.name.split('::')[0..-2].join('::')
12
+ end
13
+
14
+ def attrib_name
15
+ class_name.underscore
16
+ end
17
+ alias :json_root :attrib_name
18
+ end
19
+
20
+
21
+ def json_root
22
+ self.class.json_root
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,36 @@
1
+ module NCore
2
+ module Lifecycle
3
+
4
+ def errors?
5
+ @errors.any?
6
+ end
7
+
8
+ def valid?
9
+ @errors.none?
10
+ end
11
+
12
+
13
+ def save(update_params={})
14
+ if id.present?
15
+ if respond_to? :update, true
16
+ update(update_params)
17
+ else
18
+ raise self.class.parent::Error, "Updating #{self.class.name} objects is not supported."
19
+ end
20
+ else
21
+ if respond_to? :create, true
22
+ create(update_params)
23
+ else
24
+ raise self.class.parent::Error, "Creating #{self.class.name} objects is not supported."
25
+ end
26
+ end
27
+ end
28
+ alias :update_attributes :save
29
+
30
+ def save!(update_params={})
31
+ save(update_params) || raise(self.class.parent::RecordInvalid, self)
32
+ end
33
+ alias :update_attributes! :save!
34
+
35
+ end
36
+ end
@@ -0,0 +1,30 @@
1
+ module NCore
2
+ module All
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def all(params={}, api_creds=nil)
7
+ parsed, creds = request(:get, url, api_creds, params)
8
+ if parsed[:errors].any?
9
+ raise parent::QueryError, parsed[:errors]
10
+ end
11
+ Collection.new.tap do |coll|
12
+ coll.metadata = parsed[:metadata]
13
+ parsed[:data].each do |hash|
14
+ if key = hash[:object]
15
+ coll << discover_class(key, self).new(hash.merge(metadata: parsed[:metadata]), creds)
16
+ else
17
+ coll << new(hash.merge(metadata: parsed[:metadata]), creds)
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ def first(params={}, api_creds=nil)
24
+ params = params.with_indifferent_access.merge(max_results: 1)
25
+ all(params, api_creds).first
26
+ end
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ module NCore
2
+ module Build
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def build(params={}, api_creds=nil)
7
+ parsed, creds = request(:get, url+'/new', api_creds, params)
8
+ if parsed[:errors].any?
9
+ raise parent::QueryError, parsed[:errors]
10
+ end
11
+ new(parsed, creds)
12
+ end
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ module NCore
2
+ module Count
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def count(params={}, api_creds=nil)
7
+ parsed, _ = request(:get, "#{url}/count", api_creds, params)
8
+ parsed[:data][:count]
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,33 @@
1
+ module NCore
2
+ module Create
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def create!(attribs={}, api_creds=nil)
7
+ obj = create(attribs, api_creds)
8
+ if obj.errors.any?
9
+ raise parent::RecordInvalid, obj
10
+ end
11
+ obj
12
+ end
13
+
14
+ # always returns a new object; check .errors? or .valid? to see how it went
15
+ def create(attribs={}, api_creds=nil)
16
+ params = {json_root => attribs}
17
+ parsed, creds = request(:post, url, api_creds, params)
18
+ new(attribs, creds).send(:load, parsed)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def create(attribs={})
25
+ params = {json_root => attribs}
26
+ parsed, @api_creds = request(:post, self.class.url, api_creds, params)
27
+ load(data: attribs) if parsed[:errors].any?
28
+ load(parsed)
29
+ errors.empty? ? self : false
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ module NCore
2
+ module Delete
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def delete(id, params={}, api_creds=nil)
7
+ obj = new({id: id}, api_creds)
8
+ obj.delete(params) || raise(parent::RecordInvalid, obj)
9
+ end
10
+ end
11
+
12
+ def delete(params={})
13
+ parsed, @api_creds = request(:delete, url, api_creds, params)
14
+ load(parsed)
15
+ errors.empty? ? self : false
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module NCore
2
+ module DeleteSingle
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def delete(params={}, api_creds=nil)
7
+ obj = new({}, api_creds)
8
+ obj.delete(params) || raise(parent::RecordInvalid, obj)
9
+ end
10
+ end
11
+
12
+ def delete(params={})
13
+ parsed, @api_creds = request(:delete, url, api_creds, params)
14
+ load(parsed)
15
+ errors.empty? ? self : false
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ module NCore
2
+ module Find
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def find(id, params={}, api_creds=nil)
7
+ o = new({id: id}, api_creds)
8
+ o.reload(params)
9
+ end
10
+
11
+ def retrieve(id, params={}, api_creds=nil)
12
+ find id, params, api_creds
13
+ rescue parent::RecordNotFound
14
+ false
15
+ end
16
+ end
17
+
18
+ def reload(find_params={})
19
+ return if id.blank?
20
+ parsed, @api_creds = request(:get, url, api_creds, find_params)
21
+ @attribs = {}.with_indifferent_access
22
+ load(parsed)
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,34 @@
1
+ module NCore
2
+ module FindSingle
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def find(params={}, api_creds=nil)
7
+ parsed, creds = request(:get, url, api_creds, params)
8
+ if parsed[:errors].any?
9
+ raise parent::QueryError, parsed[:errors]
10
+ end
11
+ new(parsed, creds)
12
+ end
13
+
14
+ def retrieve(params={}, api_creds=nil)
15
+ find params, api_creds
16
+ rescue parent::RecordNotFound
17
+ false
18
+ end
19
+ end
20
+
21
+ def id
22
+ 'singleton'
23
+ end
24
+
25
+ private
26
+
27
+ def reload(find_params={})
28
+ parsed, @api_creds = request(:get, url, api_creds, find_params)
29
+ @attribs = {}.with_indifferent_access
30
+ load(parsed)
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,29 @@
1
+ module NCore
2
+ module Update
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def update!(id, attribs, api_creds=nil)
7
+ obj = new({id: id}, api_creds)
8
+ obj.save!(attribs)
9
+ end
10
+
11
+ def update(id, attribs, api_creds=nil)
12
+ obj = new({id: id}, api_creds)
13
+ obj.save(attribs)
14
+ end
15
+ end
16
+
17
+
18
+ private
19
+
20
+ def update(attribs={})
21
+ params = {json_root => attribs}
22
+ parsed, @api_creds = request(:put, url, api_creds, params)
23
+ load(data: attribs) if parsed[:errors].any?
24
+ load(parsed)
25
+ errors.empty? ? self : false
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,44 @@
1
+ require 'active_model'
2
+
3
+ module NCore
4
+ module ActiveModel
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ include ::ActiveModel::Conversion
9
+ extend ::ActiveModel::Translation
10
+ alias :errors :errors_for_actionpack
11
+ end
12
+
13
+ if defined?(Rails)
14
+ def logger
15
+ Rails.logger
16
+ end
17
+ end
18
+
19
+ def new_record?
20
+ !id
21
+ end
22
+
23
+ def persisted?
24
+ !new_record?
25
+ end
26
+
27
+ def destroy(*args)
28
+ delete(*args)
29
+ end
30
+
31
+ # actionpack 4 requires a more robust Errors object
32
+ def errors_for_actionpack
33
+ e0 = ::ActiveModel::Errors.new(self)
34
+ @errors.each do |e|
35
+ e0.add :base, e
36
+ end
37
+ e0
38
+ end
39
+
40
+ end
41
+
42
+ Base.send :include, ActiveModel
43
+ SingletonBase.send :include, ActiveModel
44
+ end
@@ -0,0 +1,116 @@
1
+ module NCore
2
+ module LogSubscriber
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ class_attribute :runtime_variable, instance_accessor: false
7
+
8
+ # make :request show up in parent::LogSubscriber.new.public_methods(false)
9
+ define_method :request do |event|
10
+ log_request event
11
+ end
12
+ end
13
+
14
+ module ClassMethods
15
+ def runtime=(value)
16
+ Thread.current[runtime_variable] = value
17
+ end
18
+
19
+ def runtime
20
+ Thread.current[runtime_variable] ||= 0
21
+ end
22
+
23
+ def reset_runtime
24
+ rt, self.runtime = runtime, 0
25
+ rt
26
+ end
27
+ end
28
+
29
+ def log_request(event)
30
+ self.class.runtime += event.duration
31
+
32
+ env = event.payload
33
+ url = env[:url].to_s
34
+ http_method = env[:method].to_s.upcase
35
+ http_status = env[:status] || -1
36
+
37
+ msg = "%s %s" % [http_method, url]
38
+ res = " -> %d (%.1f ms)" % [http_status, event.duration]
39
+
40
+ msg = color(msg, ActiveSupport::LogSubscriber::YELLOW, false)
41
+ if (200..299).include? http_status
42
+ res = color(res, ActiveSupport::LogSubscriber::GREEN, true)
43
+ else
44
+ res = color(res, ActiveSupport::LogSubscriber::RED, true)
45
+ end
46
+
47
+ if (200..299).include? http_status
48
+ debug " #{msg}"
49
+ debug " #{res}"
50
+ else
51
+ error " #{msg}"
52
+ error " #{res}"
53
+ end
54
+ end
55
+
56
+ end
57
+
58
+ # Extends ActionController's logging system so as to include Api
59
+ # cumulative runtime at the end of each action's log entry.
60
+ # See ActiveRecord::Railties::ControllerRuntime for reference
61
+ module ControllerRuntime
62
+ extend ActiveSupport::Concern
63
+
64
+ protected
65
+
66
+ mattr_accessor :api_runtime_list
67
+ self.api_runtime_list = []
68
+
69
+ def process_action(action, *args)
70
+ api_runtime_list.each do |arl|
71
+ arl[:log_sub].reset_runtime
72
+ arl[:rt] = 0
73
+ end
74
+ super
75
+ end
76
+
77
+ def cleanup_view_runtime
78
+ rt_before_render = {}
79
+ rt_after_render = {}
80
+ api_runtime_list.each do |arl|
81
+ rt_before_render[arl[:title]] = arl[:log_sub].reset_runtime
82
+ end
83
+ runtime = super
84
+ api_runtime_list.each do |arl|
85
+ rt_after_render[arl[:title]] = arl[:log_sub].reset_runtime
86
+ arl[:rt] = rt_before_render[arl[:title]] + rt_after_render[arl[:title]]
87
+ end
88
+ runtime - rt_after_render.values.sum
89
+ end
90
+
91
+ def append_info_to_payload(payload)
92
+ super
93
+ payload[:api_runtime] = {}
94
+ api_runtime_list.each do |arl|
95
+ payload[:api_runtime][arl[:title]] = arl[:rt] + arl[:log_sub].reset_runtime
96
+ end
97
+ end
98
+
99
+
100
+ module ClassMethods
101
+
102
+ def log_process_action(payload)
103
+ messages, rt_set = super, payload[:api_runtime]
104
+ rt_set.each do |title, rt|
105
+ messages << ("#{title}: %.1fms" % rt.to_f) if rt && rt > 0
106
+ end if rt_set
107
+ messages
108
+ end
109
+
110
+ def register_api_runtime(log_sub, title)
111
+ ControllerRuntime.api_runtime_list += [{log_sub: log_sub, title: title, rt: 0}]
112
+ end
113
+ end
114
+
115
+ end
116
+ end