sp-duh 2.0.6
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.
- 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
|