declarative_mapper 0.0.5 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/declarative_mapper.rb +73 -22
- metadata +9 -14
- data/bin/declarative_mapper_generate +0 -71
- data/lib/csv_parser.rb +0 -58
- data/lib/module_helper.rb +0 -52
- data/templates/mapper_methods.rb.erb +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c029ea7248f2073b26234203b42a300ce9c45ebb31d1af048849505d85241ed
|
4
|
+
data.tar.gz: 3cf2c8725c01030166dfdf8a12c8d63ab82daeca2d116da2dc146a7886bb6c35
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06aa80ec644a7644cc871551d69b954ac062030ada18a53205d1afb535109acdb94f267751f7f524748d21011d7cfa549509752431124afdc8c9942566dd932e
|
7
|
+
data.tar.gz: fc42f26ff109fe9c61e04b14814f469028d2fc7dc4144d33ae8ce6991a0c481698b045106d4ae32e2c6417296b957f79a3675bcc4d59bb8c9a7aa27381412c23
|
data/lib/declarative_mapper.rb
CHANGED
@@ -1,42 +1,93 @@
|
|
1
|
-
|
1
|
+
require 'active_support/core_ext/hash/keys.rb'
|
2
|
+
require 'active_support/core_ext/string'
|
2
3
|
|
3
4
|
class DeclarativeMapper
|
4
|
-
|
5
|
+
def self.convert(mapper_methods, mapping_hash, csv_row)
|
6
|
+
deep_transform_values_with_path(mapping_hash) do |csv_field_name, path|
|
7
|
+
field_name = path.last
|
5
8
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
@project_path = client_path.sub("/#{@client_name}", '')
|
9
|
+
if needs_method?(csv_field_name)
|
10
|
+
parsed_signature =
|
11
|
+
parse_signature(csv_field_name, field_name)
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
+
args = argument_values(parsed_signature[:arguments], csv_row)
|
14
|
+
method_name = parsed_signature[:method_name]
|
15
|
+
|
16
|
+
unless shared_method?(csv_field_name)
|
17
|
+
method_name = path[0..-2].push(method_name).join('_')
|
18
|
+
end
|
19
|
+
|
20
|
+
mapper_methods.send(method_name, *args)
|
21
|
+
else
|
22
|
+
csv_row[csv_field_name]
|
23
|
+
end
|
24
|
+
end
|
13
25
|
end
|
14
26
|
|
15
|
-
def
|
16
|
-
|
27
|
+
def self.required_csv_fields(mapping_hash)
|
28
|
+
deep_inject(mapping_hash, []) do |value, sum|
|
29
|
+
if needs_method?(value)
|
30
|
+
sum += (parse_signature(value)[:arguments])
|
31
|
+
else
|
32
|
+
sum.push(value)
|
33
|
+
end
|
34
|
+
end.uniq.compact
|
35
|
+
end
|
17
36
|
|
18
|
-
|
37
|
+
def self.argument_values(argument_names, csv_row)
|
38
|
+
argument_names.map { |name| csv_row[name] }
|
19
39
|
end
|
20
40
|
|
21
|
-
|
41
|
+
def self.parse_signature(signature, field_name=nil)
|
42
|
+
match = signature.match(/^(.*)\((.*)\)/)
|
43
|
+
|
44
|
+
method_name = match[1]
|
45
|
+
method_name = field_name if method_name.empty?
|
22
46
|
|
23
|
-
|
24
|
-
|
47
|
+
{
|
48
|
+
arguments: match[2].gsub(/,\s+/, ',').split(','),
|
49
|
+
method_name: method_name
|
50
|
+
}
|
25
51
|
end
|
26
52
|
|
27
|
-
def
|
28
|
-
|
53
|
+
def self.shared_method?(signature)
|
54
|
+
!!(signature =~ /^.+\(.*\)/)
|
29
55
|
end
|
30
56
|
|
31
|
-
def
|
32
|
-
|
57
|
+
def self.needs_method?(signature)
|
58
|
+
!!(signature =~ /\(.*\)/)
|
33
59
|
end
|
34
60
|
|
35
|
-
|
36
|
-
|
61
|
+
# Example of usage:
|
62
|
+
#
|
63
|
+
# my_hash = {a: 0, b: {c: 1, d: 2, e: {f: 3}}}
|
64
|
+
# values = %w(mother washed the ceiling)
|
65
|
+
#
|
66
|
+
# result = deep_transform_values_with_path(my_hash) do |value, path|
|
67
|
+
# path.join('/') + '/' + values[value]
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# {:a=>"a/mother", :b=>{:c=>"b/c/washed", :d=>"b/d/the", :e=>{:f=>"b/e/f/ceiling"}}}
|
71
|
+
#
|
72
|
+
def self.deep_transform_values_with_path(object, path=[], &block)
|
73
|
+
case object
|
74
|
+
when Hash
|
75
|
+
object.map { |k, v| [k, deep_transform_values_with_path(v, path + [k], &block)] }.to_h
|
76
|
+
when Array
|
77
|
+
object.map { |e| deep_transform_values_with_path(e, path, &block) }
|
78
|
+
else
|
79
|
+
yield(object, path)
|
80
|
+
end
|
37
81
|
end
|
38
82
|
|
39
|
-
def
|
40
|
-
|
83
|
+
def self.deep_inject(object, acc, &block)
|
84
|
+
case object
|
85
|
+
when Hash
|
86
|
+
object.inject(acc) { |a, (k, v)| deep_inject(v, a, &block) }
|
87
|
+
when Array
|
88
|
+
object.inject(acc) { |a, e| deep_inject(e, a, &block) }
|
89
|
+
else
|
90
|
+
yield(object, acc)
|
91
|
+
end
|
41
92
|
end
|
42
93
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: declarative_mapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Nemytchenko
|
@@ -9,35 +9,30 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-06-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - "
|
18
|
+
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '0'
|
20
|
+
version: '1.0'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- - "
|
25
|
+
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: '0'
|
27
|
+
version: '1.0'
|
28
28
|
description:
|
29
29
|
email: install.vv@gmail.com
|
30
|
-
executables:
|
31
|
-
- declarative_mapper_generate
|
30
|
+
executables: []
|
32
31
|
extensions: []
|
33
32
|
extra_rdoc_files: []
|
34
33
|
files:
|
35
|
-
- bin/declarative_mapper_generate
|
36
|
-
- lib/csv_parser.rb
|
37
34
|
- lib/declarative_mapper.rb
|
38
|
-
|
39
|
-
- templates/mapper_methods.rb.erb
|
40
|
-
homepage: https://gitlab.com/installero/sync_prototype
|
35
|
+
homepage: https://github.com/installero/declarative_mapper
|
41
36
|
licenses:
|
42
37
|
- MIT
|
43
38
|
metadata: {}
|
@@ -56,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
56
51
|
- !ruby/object:Gem::Version
|
57
52
|
version: '0'
|
58
53
|
requirements: []
|
59
|
-
rubygems_version: 3.
|
54
|
+
rubygems_version: 3.1.4
|
60
55
|
signing_key:
|
61
56
|
specification_version: 4
|
62
57
|
summary: Creates an object from a csv row according to yml-file with mapping rules
|
@@ -1,71 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'active_support/core_ext/string'
|
4
|
-
require 'active_support/core_ext/hash/keys.rb'
|
5
|
-
|
6
|
-
require 'yaml'
|
7
|
-
require 'erb'
|
8
|
-
require 'fileutils'
|
9
|
-
|
10
|
-
require_relative '../lib/module_helper'
|
11
|
-
|
12
|
-
def normalize_args(string)
|
13
|
-
return if string.nil?
|
14
|
-
|
15
|
-
string.delete('() ').split(',').join(', ')
|
16
|
-
end
|
17
|
-
|
18
|
-
def customer_methods_only(hash)
|
19
|
-
hash.reject do |_, value|
|
20
|
-
!ModuleHelper.needs_method?(value) || ModuleHelper.shared_method?(value)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
unless ARGV[0]
|
25
|
-
puts "Yaml file name needed, example:"
|
26
|
-
puts
|
27
|
-
puts "ruby generate.rb akme/customers.yml"
|
28
|
-
puts
|
29
|
-
exit 1
|
30
|
-
end
|
31
|
-
|
32
|
-
yml_path = ARGV[0]
|
33
|
-
|
34
|
-
# Getting client & table names from yml file path
|
35
|
-
client_dir, yml_filename = File.split(yml_path)
|
36
|
-
|
37
|
-
table_name = File.basename(yml_filename, '.yml')
|
38
|
-
client_name = client_dir.split(File::SEPARATOR).last
|
39
|
-
|
40
|
-
# Getting list of methods (with arrays of args) from yml file
|
41
|
-
client_mapping = YAML.load_file(yml_path).deep_symbolize_keys[:mapping]
|
42
|
-
|
43
|
-
methods =
|
44
|
-
customer_methods_only(client_mapping)
|
45
|
-
.map { |key, value| [key, normalize_args(value)] }
|
46
|
-
.to_h
|
47
|
-
|
48
|
-
puts "Methods #{methods.keys.join(', ')} found"
|
49
|
-
|
50
|
-
# Getting mapper methods file template
|
51
|
-
template_path = "#{__dir__}/../templates/mapper_methods.rb.erb"
|
52
|
-
template = ERB.new(File.read(template_path), nil, '-')
|
53
|
-
|
54
|
-
# Constructing path for the methods file
|
55
|
-
methods_file_dir = File.join(client_dir, ModuleHelper::CLIENT_METHODS_FOLDER)
|
56
|
-
methods_file_name = "#{table_name}.rb"
|
57
|
-
methods_file_path = File.join(methods_file_dir, methods_file_name)
|
58
|
-
|
59
|
-
# Creating directory
|
60
|
-
FileUtils.mkdir_p(methods_file_dir) unless File.directory?(methods_file_dir)
|
61
|
-
|
62
|
-
# Writing to file
|
63
|
-
if File.exist?(methods_file_path)
|
64
|
-
puts "File #{methods_file_name} already exists!"
|
65
|
-
puts
|
66
|
-
else
|
67
|
-
File.write(methods_file_path, template.result(binding))
|
68
|
-
|
69
|
-
puts "Wrote to #{methods_file_name}!"
|
70
|
-
puts
|
71
|
-
end
|
data/lib/csv_parser.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
|
-
require 'active_support/core_ext/hash/keys.rb'
|
4
|
-
require 'active_support/core_ext/string'
|
5
|
-
|
6
|
-
require_relative 'module_helper'
|
7
|
-
|
8
|
-
class CSVParser
|
9
|
-
attr_reader :yml_path, :client_name, :table_name
|
10
|
-
|
11
|
-
def initialize(yml_path, client_name)
|
12
|
-
@yml_path = yml_path
|
13
|
-
@client_name = client_name
|
14
|
-
@table_name = File.basename(yml_path, '.yml')
|
15
|
-
end
|
16
|
-
|
17
|
-
def yml
|
18
|
-
@yml ||= YAML.load_file(yml_path).deep_symbolize_keys
|
19
|
-
end
|
20
|
-
|
21
|
-
def parse(csv_row)
|
22
|
-
ModuleHelper.deep_transform_values_with_path(mapping_hash) do |csv_field_name, path|
|
23
|
-
field_name = path.last
|
24
|
-
|
25
|
-
if ModuleHelper.needs_method?(csv_field_name)
|
26
|
-
parsed_signature =
|
27
|
-
ModuleHelper.parse_signature(csv_field_name, client_name, table_name, field_name)
|
28
|
-
|
29
|
-
args = argument_values(parsed_signature[:arguments], csv_row)
|
30
|
-
|
31
|
-
module_path = parsed_signature[:path]
|
32
|
-
module_path += path[0..-2] unless ModuleHelper.shared_method?(csv_field_name)
|
33
|
-
|
34
|
-
call_shared_or_client_method(
|
35
|
-
module_path,
|
36
|
-
parsed_signature[:method_name],
|
37
|
-
*args
|
38
|
-
)
|
39
|
-
else
|
40
|
-
csv_row[csv_field_name]
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def mapping_hash
|
48
|
-
yml[:mapping]
|
49
|
-
end
|
50
|
-
|
51
|
-
def call_shared_or_client_method(path, method_name, *args)
|
52
|
-
path.map(&:to_s).map(&:camelize).join('::').constantize.send(method_name, *args)
|
53
|
-
end
|
54
|
-
|
55
|
-
def argument_values(argument_names, csv_row)
|
56
|
-
argument_names.map { |name| csv_row[name] }
|
57
|
-
end
|
58
|
-
end
|
data/lib/module_helper.rb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
module ModuleHelper
|
2
|
-
CLIENT_METHODS_FOLDER = 'mapper_methods'
|
3
|
-
# 'shared/phone/number/normalize(phonenumber)'
|
4
|
-
# -> ['shared', 'phone', 'number'], 'normalize', ['phonenumber']
|
5
|
-
#
|
6
|
-
# '(status)', client_name: 'reliable', field_name: 'active'
|
7
|
-
# -> ['reliable', 'mapper_methods'], 'active', ['status']
|
8
|
-
def self.parse_signature(signature, client_name=nil, table_name=nil, field_name=nil)
|
9
|
-
match = signature.match(/^(.*)\((.*)\)/)
|
10
|
-
|
11
|
-
result = {arguments: match[2].gsub(/,\s+/, ',').split(',')}
|
12
|
-
|
13
|
-
if shared_method?(signature)
|
14
|
-
path = match[1].split('/')
|
15
|
-
|
16
|
-
result[:method_name] = path.pop.to_sym
|
17
|
-
result[:path] = path
|
18
|
-
else
|
19
|
-
result[:method_name] = field_name
|
20
|
-
result[:path] = [client_name, CLIENT_METHODS_FOLDER, table_name]
|
21
|
-
end
|
22
|
-
|
23
|
-
result
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.shared_method?(signature)
|
27
|
-
!!(signature =~ /^shared\//)
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.needs_method?(signature)
|
31
|
-
!!(signature =~ /\(.*\)/)
|
32
|
-
end
|
33
|
-
|
34
|
-
# Example of usage:
|
35
|
-
#
|
36
|
-
# my_hash = {a: 0, b: {c: 1, d: 2, e: {f: 3}}}
|
37
|
-
# values = %w(mother washed the ceiling)
|
38
|
-
#
|
39
|
-
# result = deep_transform_values_with_path(my_hash) do |value, path|
|
40
|
-
# path.join('/') + '/' + values[value]
|
41
|
-
# end
|
42
|
-
#
|
43
|
-
# {:a=>"a/mother", :b=>{:c=>"b/c/washed", :d=>"b/d/the", :e=>{:f=>"b/e/f/ceiling"}}}
|
44
|
-
#
|
45
|
-
def self.deep_transform_values_with_path(object, path=[], &block)
|
46
|
-
return yield(object, path) unless object.is_a?(Hash)
|
47
|
-
|
48
|
-
object.map do |key, value|
|
49
|
-
[key, deep_transform_values_with_path(value, path + [key], &block)]
|
50
|
-
end.to_h
|
51
|
-
end
|
52
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
module <%= client_name.camelize %>
|
2
|
-
module MapperMethods
|
3
|
-
module <%= table_name.camelize %>
|
4
|
-
<% methods.each_with_index do |(method_name, arg_names), index| -%>
|
5
|
-
def self.<%= method_name %>(<%= arg_names %>)
|
6
|
-
# Implement method <%= method_name %> here
|
7
|
-
end
|
8
|
-
<%= "\n" unless index == methods.count - 1 -%>
|
9
|
-
<% end -%>
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|