sp-duh 2.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +661 -0
- data/README.md +2 -0
- data/Rakefile +32 -0
- data/config/i18n/i18n.xlsx +0 -0
- data/config/initializers/active_record/connection_adapters_postgre_sql_adapter.rb +165 -0
- data/config/initializers/active_record/migration_without_transaction.rb +4 -0
- data/config/initializers/active_record/migrator.rb +34 -0
- data/config/initializers/rails/generators.rb +13 -0
- data/config/jsonapi/settings.yml +14 -0
- data/config/locales/pt.yml +15 -0
- data/lib/generators/accounting_migration/accounting_migration_generator.rb +10 -0
- data/lib/generators/accounting_migration/templates/migration.rb +42 -0
- data/lib/generators/accounting_payroll_migration/accounting_payroll_migration_generator.rb +10 -0
- data/lib/generators/accounting_payroll_migration/templates/migration.rb +73 -0
- data/lib/generators/sharded_migration/sharded_migration_generator.rb +10 -0
- data/lib/generators/sharded_migration/templates/migration.rb +45 -0
- data/lib/sp-duh.rb +32 -0
- data/lib/sp/duh.rb +180 -0
- data/lib/sp/duh/adapters/pg/text_decoder/json.rb +15 -0
- data/lib/sp/duh/adapters/pg/text_encoder/json.rb +15 -0
- data/lib/sp/duh/db/transfer/backup.rb +71 -0
- data/lib/sp/duh/db/transfer/restore.rb +89 -0
- data/lib/sp/duh/engine.rb +35 -0
- data/lib/sp/duh/exceptions.rb +70 -0
- data/lib/sp/duh/i18n/excel_loader.rb +26 -0
- data/lib/sp/duh/jsonapi/adapters/base.rb +168 -0
- data/lib/sp/duh/jsonapi/adapters/db.rb +36 -0
- data/lib/sp/duh/jsonapi/adapters/raw_db.rb +77 -0
- data/lib/sp/duh/jsonapi/configuration.rb +167 -0
- data/lib/sp/duh/jsonapi/doc/apidoc_documentation_format_generator.rb +286 -0
- data/lib/sp/duh/jsonapi/doc/generator.rb +32 -0
- data/lib/sp/duh/jsonapi/doc/schema_catalog_helper.rb +97 -0
- data/lib/sp/duh/jsonapi/doc/victor_pinus_metadata_format_parser.rb +374 -0
- data/lib/sp/duh/jsonapi/exceptions.rb +56 -0
- data/lib/sp/duh/jsonapi/model/base.rb +25 -0
- data/lib/sp/duh/jsonapi/model/concerns/attributes.rb +94 -0
- data/lib/sp/duh/jsonapi/model/concerns/model.rb +42 -0
- data/lib/sp/duh/jsonapi/model/concerns/persistence.rb +221 -0
- data/lib/sp/duh/jsonapi/model/concerns/serialization.rb +59 -0
- data/lib/sp/duh/jsonapi/parameters.rb +44 -0
- data/lib/sp/duh/jsonapi/resource_publisher.rb +28 -0
- data/lib/sp/duh/jsonapi/service.rb +110 -0
- data/lib/sp/duh/migrations.rb +47 -0
- data/lib/sp/duh/migrations/migrator.rb +41 -0
- data/lib/sp/duh/repl.rb +193 -0
- data/lib/sp/duh/version.rb +25 -0
- data/lib/tasks/db_utils.rake +98 -0
- data/lib/tasks/doc.rake +27 -0
- data/lib/tasks/i18n.rake +23 -0
- data/lib/tasks/oauth.rake +29 -0
- data/lib/tasks/transfer.rake +48 -0
- data/lib/tasks/xls2jrxml.rake +15 -0
- data/test/jsonapi/server.rb +67 -0
- data/test/tasks/test.rake +10 -0
- metadata +170 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'sp-excel-loader'
|
2
|
+
|
3
|
+
module SP
|
4
|
+
module Duh
|
5
|
+
module I18n
|
6
|
+
|
7
|
+
class ExcelLoader < ::Sp::Excel::Loader::WorkbookLoader
|
8
|
+
|
9
|
+
def initialize(filename, pg_connection)
|
10
|
+
super(filename)
|
11
|
+
@connection = pg_connection
|
12
|
+
end
|
13
|
+
|
14
|
+
def clear
|
15
|
+
@connection.exec "DELETE FROM public.i18n"
|
16
|
+
end
|
17
|
+
|
18
|
+
def reload
|
19
|
+
export_table_to_pg(@connection, 'public', '', 'i18n')
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
module SP
|
2
|
+
module Duh
|
3
|
+
module JSONAPI
|
4
|
+
module Adapters
|
5
|
+
|
6
|
+
class Base
|
7
|
+
|
8
|
+
def service ; @service ; end
|
9
|
+
|
10
|
+
def initialize(service)
|
11
|
+
@service = service
|
12
|
+
end
|
13
|
+
|
14
|
+
def get(path, params = {})
|
15
|
+
request('GET', path, params)
|
16
|
+
end
|
17
|
+
def post(path, params = {})
|
18
|
+
request('POST', path, params)
|
19
|
+
end
|
20
|
+
def patch(path, params = {})
|
21
|
+
request('PATCH', path, params)
|
22
|
+
end
|
23
|
+
def delete(path)
|
24
|
+
request('DELETE', path, nil)
|
25
|
+
end
|
26
|
+
|
27
|
+
def get!(path, params = {})
|
28
|
+
request!('GET', path, params)
|
29
|
+
end
|
30
|
+
def post!(path, params = {})
|
31
|
+
request!('POST', path, params)
|
32
|
+
end
|
33
|
+
def patch!(path, params = {})
|
34
|
+
request!('PATCH', path, params)
|
35
|
+
end
|
36
|
+
def delete!(path)
|
37
|
+
request!('DELETE', path, nil)
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_explicit!(exp_accounting_schema, exp_accounting_prefix, path, params = {})
|
41
|
+
explicit_request!(exp_accounting_schema, exp_accounting_prefix, 'GET', path, params)
|
42
|
+
end
|
43
|
+
def post_explicit!(exp_accounting_schema, exp_accounting_prefix, path, params = {})
|
44
|
+
explicit_request!(exp_accounting_schema, exp_accounting_prefix, 'POST', path, params)
|
45
|
+
end
|
46
|
+
def patch_explicit!(exp_accounting_schema, exp_accounting_prefix, path, params = {})
|
47
|
+
explicit_request!(exp_accounting_schema, exp_accounting_prefix, 'PATCH', path, params)
|
48
|
+
end
|
49
|
+
def delete_explicit!(exp_accounting_schema, exp_accounting_prefix, path)
|
50
|
+
explicit_request!(exp_accounting_schema, exp_accounting_prefix, 'DELETE', path, nil)
|
51
|
+
end
|
52
|
+
|
53
|
+
alias_method :put, :patch
|
54
|
+
alias_method :put!, :patch!
|
55
|
+
alias_method :put_explicit!, :patch_explicit!
|
56
|
+
|
57
|
+
def unwrap_request
|
58
|
+
unwrap_response(yield)
|
59
|
+
end
|
60
|
+
|
61
|
+
# do_request MUST be implemented by each specialized adapter, and returns a tuple: the request status and a JSONAPI string or hash with the result
|
62
|
+
def do_request(method, path, params) ; ; end
|
63
|
+
def explicit_do_request(exp_accounting_schema, exp_accounting_prefix, method, path, params) ; ; end
|
64
|
+
|
65
|
+
def request(method, path, params)
|
66
|
+
# As it is now, this method is EXACTLY the same as request!()
|
67
|
+
# And it cannot be reverted without affecting lots of changes already made in the app's controllers.
|
68
|
+
# TODO: end it, or end the !() version
|
69
|
+
# begin
|
70
|
+
unwrap_request do
|
71
|
+
do_request(method, path, params)
|
72
|
+
end
|
73
|
+
# THIS CAN'T BE DONE, because the same method cannot return both a single result (in case there is NOT an error) and a pair (in case there IS an error)
|
74
|
+
# rescue SP::Duh::JSONAPI::Exceptions::GenericModelError => e
|
75
|
+
# [
|
76
|
+
# e.status,
|
77
|
+
# e.result
|
78
|
+
# ]
|
79
|
+
# rescue Exception => e
|
80
|
+
# [
|
81
|
+
# SP::Duh::JSONAPI::Status::ERROR,
|
82
|
+
# get_error_response(path, e)
|
83
|
+
# ]
|
84
|
+
# end
|
85
|
+
end
|
86
|
+
|
87
|
+
def request!(method, path, params)
|
88
|
+
unwrap_request do
|
89
|
+
do_request(method, path, params)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def explicit_request!(exp_accounting_schema, exp_accounting_prefix, method, path, params)
|
94
|
+
unwrap_request do
|
95
|
+
explicit_do_request(exp_accounting_schema, exp_accounting_prefix, method, path, params)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
protected
|
100
|
+
|
101
|
+
def url(path) ; File.join(service.url, path) ; end
|
102
|
+
|
103
|
+
def url_with_params_for_query(path, params)
|
104
|
+
query = params_for_query(params)
|
105
|
+
query.blank? ? url(path) : url(path) + "?" + query
|
106
|
+
end
|
107
|
+
|
108
|
+
def params_for_query(params)
|
109
|
+
query = ""
|
110
|
+
if !params.blank?
|
111
|
+
case
|
112
|
+
when params.is_a?(Array)
|
113
|
+
# query = params.join('&')
|
114
|
+
query = params.map{ |v| URI.encode(URI.encode(v).gsub("'","''"), "&") }.join('&')
|
115
|
+
when params.is_a?(Hash)
|
116
|
+
query = params.map do |k,v|
|
117
|
+
if v.is_a?(String)
|
118
|
+
"#{k}=\"#{URI.encode(URI.encode(v).gsub("'","''"), "&")}\""
|
119
|
+
else
|
120
|
+
"#{k}=#{v}"
|
121
|
+
end
|
122
|
+
end.join('&')
|
123
|
+
else
|
124
|
+
query = params.to_s
|
125
|
+
end
|
126
|
+
end
|
127
|
+
query
|
128
|
+
end
|
129
|
+
|
130
|
+
def params_for_body(params)
|
131
|
+
params.blank? ? '' : params.to_json.gsub("'","''")
|
132
|
+
end
|
133
|
+
|
134
|
+
# unwrap_response SHOULD be implemented by each specialized adapter, and returns the request result as a JSONAPI string or hash and raises an exception if there was an error
|
135
|
+
def unwrap_response(response)
|
136
|
+
# As the method request() is EXACTLY the same as request!(), and it cannot be reverted without affecting lots of changes already made in the app's controllers...
|
137
|
+
# Allow for response being both a [ status, result ] pair (as of old) OR a single result (as of now)
|
138
|
+
if response.is_a?(Array)
|
139
|
+
status = response[0].to_i
|
140
|
+
result = response[1]
|
141
|
+
result
|
142
|
+
else
|
143
|
+
response
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def error_response(path, error)
|
148
|
+
{
|
149
|
+
errors: [
|
150
|
+
{
|
151
|
+
status: "#{SP::Duh::JSONAPI::Status::ERROR}",
|
152
|
+
code: error.message
|
153
|
+
}
|
154
|
+
],
|
155
|
+
links: { self: url(path) },
|
156
|
+
jsonapi: { version: SP::Duh::JSONAPI::VERSION }
|
157
|
+
}
|
158
|
+
end
|
159
|
+
|
160
|
+
# get_error_response MUST be implemented by each specialized adapter, and returns a JSONAPI error result as a string or hash
|
161
|
+
def get_error_response(path, error) ; ; end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module SP
|
2
|
+
module Duh
|
3
|
+
module JSONAPI
|
4
|
+
module Adapters
|
5
|
+
|
6
|
+
class Db < RawDb
|
7
|
+
|
8
|
+
protected
|
9
|
+
|
10
|
+
def get_error_response(path, error) ; HashWithIndifferentAccess.new(error_response(path, error)) ; end
|
11
|
+
|
12
|
+
def do_request(method, path, params)
|
13
|
+
process_result(do_request_on_the_db(method, path, params))
|
14
|
+
end
|
15
|
+
|
16
|
+
def explicit_do_request(exp_accounting_schema, exp_accounting_prefix, method, path, params)
|
17
|
+
process_result(explicit_do_request_on_the_db(exp_accounting_schema, exp_accounting_prefix, method, path, params))
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def is_error?(result) ; !result[:errors].blank? ; end
|
23
|
+
|
24
|
+
def process_result(result)
|
25
|
+
result = HashWithIndifferentAccess.new(result)
|
26
|
+
result[:response] = JSON.parse(result[:response])
|
27
|
+
raise SP::Duh::JSONAPI::Exceptions::GenericModelError.new(result[:response]) if is_error?(result[:response])
|
28
|
+
[ result[:http_status], result[:response] ]
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module SP
|
2
|
+
module Duh
|
3
|
+
module JSONAPI
|
4
|
+
module Adapters
|
5
|
+
|
6
|
+
class RawDb < Base
|
7
|
+
|
8
|
+
protected
|
9
|
+
|
10
|
+
def unwrap_response(response)
|
11
|
+
# As the method request() is EXACTLY the same as request!(), and it cannot be reverted without affecting lots of changes already made in the app's controllers...
|
12
|
+
# Allow for response being both a [ status, result ] pair (as of old) OR a single result (as of now)
|
13
|
+
if response.is_a?(Array)
|
14
|
+
status = response[0].to_i
|
15
|
+
result = response[1]
|
16
|
+
raise SP::Duh::JSONAPI::Exceptions::GenericModelError.new(result) if status != SP::Duh::JSONAPI::Status::OK
|
17
|
+
result
|
18
|
+
else
|
19
|
+
# No raise here, we do not know the status...
|
20
|
+
response
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_error_response(path, error) ; error_response(path, error).to_json ; end
|
25
|
+
|
26
|
+
def do_request(method, path, param)
|
27
|
+
process_result(do_request_on_the_db(method, path, params))
|
28
|
+
end
|
29
|
+
|
30
|
+
def explicit_do_request(accounting_schema, method, path, param)
|
31
|
+
process_result(explicit_do_request_on_the_db(accounting_schema, method, path, params))
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def user_id ; "'#{service.parameters.user_id}'" ; end
|
36
|
+
def company_id ; "'#{service.parameters.company_id}'" ; end
|
37
|
+
def company_schema ; service.parameters.company_schema.nil? ? 'NULL' : "'#{service.parameters.company_schema}'" ; end
|
38
|
+
def sharded_schema ; service.parameters.sharded_schema.nil? ? 'NULL' : "'#{service.parameters.sharded_schema}'" ; end
|
39
|
+
def accounting_schema ; service.parameters.accounting_schema.nil? ? 'NULL' : "'#{service.parameters.accounting_schema}'" ; end
|
40
|
+
def accounting_prefix ; service.parameters.accounting_prefix.nil? ? 'NULL' : "'#{service.parameters.accounting_prefix}'" ; end
|
41
|
+
|
42
|
+
def process_result(result)
|
43
|
+
raise SP::Duh::JSONAPI::Exceptions::GenericModelError.new(result) if is_error?(result)
|
44
|
+
[ SP::Duh::JSONAPI::Status::OK, result ]
|
45
|
+
end
|
46
|
+
|
47
|
+
# Implement the JSONAPI request by direct querying of the JSONAPI function in the database
|
48
|
+
def do_request_on_the_db(method, path, params)
|
49
|
+
jsonapi_query = if method == 'GET'
|
50
|
+
%Q[ SELECT * FROM public.jsonapi('#{method}', '#{url_with_params_for_query(path, params)}', '', #{user_id}, #{company_id}, #{company_schema}, #{sharded_schema}, #{accounting_schema}, #{accounting_prefix}) ]
|
51
|
+
else
|
52
|
+
%Q[ SELECT * FROM public.jsonapi('#{method}', '#{url(path)}', '#{params_for_body(params)}', #{user_id}, #{company_id}, #{company_schema}, #{sharded_schema}, #{accounting_schema}, #{accounting_prefix}) ]
|
53
|
+
end
|
54
|
+
response = service.connection.exec jsonapi_query
|
55
|
+
response.first if response.first
|
56
|
+
end
|
57
|
+
|
58
|
+
def explicit_do_request_on_the_db(exp_accounting_schema, exp_accounting_prefix, method, path, params)
|
59
|
+
_accounting_schema = "'#{exp_accounting_schema}'"
|
60
|
+
_accounting_prefix = "'#{exp_accounting_prefix}'"
|
61
|
+
|
62
|
+
jsonapi_query = if method == 'GET'
|
63
|
+
%Q[ SELECT * FROM public.jsonapi('#{method}', '#{url_with_params_for_query(path, params)}', '', #{user_id}, #{company_id}, #{company_schema}, #{sharded_schema}, #{_accounting_schema}, #{_accounting_prefix}) ]
|
64
|
+
else
|
65
|
+
%Q[ SELECT * FROM public.jsonapi('#{method}', '#{url(path)}', '#{params_for_body(params)}', #{user_id}, #{company_id}, #{company_schema}, #{sharded_schema}, #{_accounting_schema}, #{_accounting_prefix}) ]
|
66
|
+
end
|
67
|
+
response = service.connection.exec jsonapi_query
|
68
|
+
response.first if response.first
|
69
|
+
end
|
70
|
+
|
71
|
+
def is_error?(result) ; result =~ /^\s*{\s*"errors"\s*:/ ; end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
module SP
|
2
|
+
module Duh
|
3
|
+
module JSONAPI
|
4
|
+
|
5
|
+
class Configuration
|
6
|
+
|
7
|
+
CONFIGURATION_TABLE_NAME = 'public.jsonapi_config'
|
8
|
+
DEFAULT_SETTINGS_FILE = 'config/jsonapi/settings.yml'
|
9
|
+
|
10
|
+
@@publishers = []
|
11
|
+
|
12
|
+
def settings
|
13
|
+
@settings ||= {}
|
14
|
+
if @settings.blank?
|
15
|
+
load_settings_from_file(File.join(SP::Duh.root, DEFAULT_SETTINGS_FILE))
|
16
|
+
end
|
17
|
+
@settings
|
18
|
+
end
|
19
|
+
|
20
|
+
def settings=(hash)
|
21
|
+
@settings = hash
|
22
|
+
end
|
23
|
+
|
24
|
+
def resources ; @resources || [] ; end
|
25
|
+
def resource_names ; resources.map { |r| r.keys.first } ; end
|
26
|
+
def connection ; @pg_connection ; end
|
27
|
+
def url ; @url ; end
|
28
|
+
|
29
|
+
def publishers ; @@publishers || [] ; end
|
30
|
+
|
31
|
+
def initialize(pg_connection, url)
|
32
|
+
@pg_connection = pg_connection
|
33
|
+
@url = url
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.add_publisher(publisher)
|
37
|
+
begin
|
38
|
+
publisher = publisher.constantize if publisher.is_a?(String)
|
39
|
+
raise Exceptions::InvalidResourcePublisherError.new(publisher: publisher.name) if !publisher.include?(ResourcePublisher)
|
40
|
+
@@publishers << publisher
|
41
|
+
rescue StandardError => e
|
42
|
+
raise Exceptions::InvalidResourcePublisherError.new(publisher: publisher.is_a?(String) ? publisher : publisher.name)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def setup
|
47
|
+
begin
|
48
|
+
create_jsonapi_configuration_store()
|
49
|
+
rescue StandardError => e
|
50
|
+
raise Exceptions::GenericServiceError.new(e)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def exists?
|
55
|
+
check = connection.exec %Q[ SELECT COUNT(*) FROM #{Configuration::CONFIGURATION_TABLE_NAME} WHERE prefix = '#{url}' ]
|
56
|
+
return check.first.values.first.to_i > 0
|
57
|
+
end
|
58
|
+
|
59
|
+
def load_from_database
|
60
|
+
@resources = []
|
61
|
+
@settings = {}
|
62
|
+
configuration = connection.exec %Q[ SELECT config FROM #{Configuration::CONFIGURATION_TABLE_NAME} WHERE prefix = '#{url}' ]
|
63
|
+
if configuration.first
|
64
|
+
configuration = JSON.parse(configuration.first['config'])
|
65
|
+
@resources = configuration['resources']
|
66
|
+
@settings = configuration.reject { |k,v| k == 'resources' }
|
67
|
+
end
|
68
|
+
@resources
|
69
|
+
end
|
70
|
+
|
71
|
+
def load_from_publishers(replace = false)
|
72
|
+
@resources = []
|
73
|
+
@settings = {}
|
74
|
+
@@publishers.each do |publisher|
|
75
|
+
add_resources_from_folder(publisher.jsonapi_resources_root, replace)
|
76
|
+
end
|
77
|
+
@resources
|
78
|
+
end
|
79
|
+
|
80
|
+
def save
|
81
|
+
begin
|
82
|
+
if exists?
|
83
|
+
connection.exec %Q[
|
84
|
+
UPDATE #{Configuration::CONFIGURATION_TABLE_NAME} SET config='#{definition.to_json}' WHERE prefix='#{url}';
|
85
|
+
]
|
86
|
+
else
|
87
|
+
connection.exec %Q[
|
88
|
+
INSERT INTO #{Configuration::CONFIGURATION_TABLE_NAME} (prefix, config) VALUES ('#{url}','#{definition.to_json}');
|
89
|
+
]
|
90
|
+
end
|
91
|
+
rescue StandardError => e
|
92
|
+
raise Exceptions::SaveConfigurationError.new(nil, e)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def reload!
|
97
|
+
load_from_publishers(true)
|
98
|
+
save
|
99
|
+
@resources
|
100
|
+
end
|
101
|
+
|
102
|
+
def load_settings_from_file(file_name)
|
103
|
+
@settings = YAML.load_file(file_name)
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def create_jsonapi_configuration_store
|
109
|
+
connection.exec %Q[
|
110
|
+
CREATE TABLE IF NOT EXISTS #{Configuration::CONFIGURATION_TABLE_NAME} (
|
111
|
+
prefix varchar(64) PRIMARY KEY,
|
112
|
+
config text NOT NULL
|
113
|
+
);
|
114
|
+
]
|
115
|
+
end
|
116
|
+
|
117
|
+
def definition
|
118
|
+
settings.merge(resources: resources)
|
119
|
+
end
|
120
|
+
|
121
|
+
def add_resources_from_folder(folder_name, replace)
|
122
|
+
@resources ||= []
|
123
|
+
# First load resources at the root folder
|
124
|
+
Dir.glob(File.join(folder_name, '*.yml')) do |configuration_file|
|
125
|
+
add_resources_from_file(configuration_file, replace)
|
126
|
+
end
|
127
|
+
# Then load resources at the inner folders
|
128
|
+
Dir.glob(File.join(folder_name, '*', '*.yml')) do |configuration_file|
|
129
|
+
add_resources_from_file(configuration_file, replace)
|
130
|
+
end
|
131
|
+
@resources
|
132
|
+
end
|
133
|
+
|
134
|
+
def add_resources_from_file(configuration_file, replace)
|
135
|
+
_log "Processing resources from file #{configuration_file}", "JSONAPI::Configuration"
|
136
|
+
configuration = YAML.load_file(configuration_file)
|
137
|
+
if configuration.is_a? Hash
|
138
|
+
add_resource(configuration, configuration_file, replace)
|
139
|
+
else
|
140
|
+
if configuration.is_a? Array
|
141
|
+
configuration.each { |resource| add_resource(resource, configuration_file, replace) }
|
142
|
+
else
|
143
|
+
raise Exceptions::InvalidResourceConfigurationError.new(file: configuration_file)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def add_resource(resource, configuration_file, replace)
|
149
|
+
raise Exceptions::InvalidResourceConfigurationError.new(file: configuration_file) if (resource.keys.count != 1)
|
150
|
+
resource_name = resource.keys[0]
|
151
|
+
_log "Processing resource #{resource_name}", "JSONAPI::Configuration"
|
152
|
+
processed = false
|
153
|
+
@resources.each_with_index do |r, i|
|
154
|
+
if r.keys.include?(resource_name)
|
155
|
+
raise Exceptions::DuplicateResourceError.new(name: resource_name) if !replace
|
156
|
+
@resources[i] = resource
|
157
|
+
processed = true
|
158
|
+
break
|
159
|
+
end
|
160
|
+
end
|
161
|
+
@resources << resource if !processed
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|