rom-mapper 0.5.1 → 1.0.0.beta1
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 +4 -4
- data/CHANGELOG.md +8 -0
- data/LICENSE +1 -1
- data/README.md +1 -9
- data/lib/rom-mapper.rb +1 -1
- data/lib/rom/header/attribute.rb +2 -0
- data/lib/rom/mapper.rb +2 -2
- data/lib/rom/mapper/builder.rb +37 -0
- data/lib/rom/mapper/configuration_plugin.rb +26 -0
- data/lib/rom/mapper/mapper_dsl.rb +43 -0
- data/lib/rom/mapper/version.rb +1 -1
- data/lib/rom/mapper_compiler.rb +71 -0
- data/lib/rom/open_struct.rb +35 -0
- data/lib/rom/processor/transproc.rb +6 -2
- data/lib/rom/struct.rb +113 -0
- data/lib/rom/struct_compiler.rb +94 -0
- metadata +19 -31
- data/.gitignore +0 -19
- data/.rspec +0 -3
- data/.ruby-gemset +0 -1
- data/.travis.yml +0 -23
- data/Gemfile +0 -31
- data/Guardfile +0 -19
- data/Rakefile +0 -16
- data/rakelib/benchmark.rake +0 -15
- data/rakelib/mutant.rake +0 -16
- data/rakelib/rubocop.rake +0 -18
- data/rom-mapper.gemspec +0 -22
- data/spec/integration/mapper_spec.rb +0 -113
- data/spec/spec_helper.rb +0 -57
- data/spec/support/constant_leak_finder.rb +0 -14
- data/spec/support/mutant.rb +0 -10
- data/spec/unit/rom/mapper/dsl_spec.rb +0 -479
- data/spec/unit/rom/mapper/model_dsl_spec.rb +0 -19
- data/spec/unit/rom/mapper_spec.rb +0 -83
- data/spec/unit/rom/processor/transproc_spec.rb +0 -506
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'dry/core/inflector'
|
2
|
+
require 'dry/core/class_builder'
|
3
|
+
require 'dry/types/compiler'
|
4
|
+
|
5
|
+
require 'rom/initializer'
|
6
|
+
require 'rom/types'
|
7
|
+
require 'rom/cache'
|
8
|
+
require 'rom/struct'
|
9
|
+
require 'rom/open_struct'
|
10
|
+
require 'rom/schema/attribute'
|
11
|
+
|
12
|
+
module ROM
|
13
|
+
# @api private
|
14
|
+
class StructCompiler < Dry::Types::Compiler
|
15
|
+
extend Initializer
|
16
|
+
|
17
|
+
param :registry, default: -> { Dry::Types }
|
18
|
+
option :cache, default: -> { Cache.new }
|
19
|
+
|
20
|
+
def initialize(*args)
|
21
|
+
super
|
22
|
+
@cache = cache.namespaced(:structs)
|
23
|
+
end
|
24
|
+
|
25
|
+
def call(*args)
|
26
|
+
cache.fetch_or_store(args.hash) do
|
27
|
+
name, header, ns = args
|
28
|
+
attributes = header.map(&method(:visit)).compact
|
29
|
+
|
30
|
+
if attributes.empty?
|
31
|
+
ROM::OpenStruct
|
32
|
+
else
|
33
|
+
build_class(name, ROM::Struct, ns) do |klass|
|
34
|
+
attributes.each do |(name, type)|
|
35
|
+
klass.attribute(name, type)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
alias_method :[], :call
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def visit_relation(node)
|
46
|
+
_, header, meta = node
|
47
|
+
name = meta[:combine_name] || meta[:alias]
|
48
|
+
namespace = meta.fetch(:struct_namespace)
|
49
|
+
|
50
|
+
model = meta[:model] || call(name, header, namespace)
|
51
|
+
|
52
|
+
member =
|
53
|
+
if model < Dry::Struct
|
54
|
+
model
|
55
|
+
else
|
56
|
+
Dry::Types::Definition.new(model).constructor(&model.method(:new))
|
57
|
+
end
|
58
|
+
|
59
|
+
if meta[:combine_type] == :many
|
60
|
+
[name, Types::Array.member(member)]
|
61
|
+
else
|
62
|
+
[name, member.optional]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def visit_attribute(node)
|
67
|
+
name, type, meta = node
|
68
|
+
|
69
|
+
[meta[:alias] && !meta[:wrapped] ? meta[:alias] : name, visit(type).meta(meta)]
|
70
|
+
end
|
71
|
+
|
72
|
+
def visit_constructor(node)
|
73
|
+
definition, fn_register_name, meta = node
|
74
|
+
|
75
|
+
visit(definition)
|
76
|
+
end
|
77
|
+
|
78
|
+
def visit_constrained(node)
|
79
|
+
definition, rule = node
|
80
|
+
|
81
|
+
visit(definition)
|
82
|
+
end
|
83
|
+
|
84
|
+
def build_class(name, parent, ns, &block)
|
85
|
+
Dry::Core::ClassBuilder.
|
86
|
+
new(name: class_name(name), parent: parent, namespace: ns).
|
87
|
+
call(&block)
|
88
|
+
end
|
89
|
+
|
90
|
+
def class_name(name)
|
91
|
+
Dry::Core::Inflector.classify(Dry::Core::Inflector.singularize(name))
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rom-mapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-equalizer
|
@@ -30,20 +30,20 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0.
|
33
|
+
version: '0.3'
|
34
34
|
- - ">="
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: 0.
|
36
|
+
version: 0.3.1
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
41
|
- - "~>"
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: '0.
|
43
|
+
version: '0.3'
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 0.
|
46
|
+
version: 0.3.1
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: transproc
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,45 +86,33 @@ dependencies:
|
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '3.5'
|
89
|
-
description:
|
90
|
-
email: piotr.solnica@gmail.com
|
89
|
+
description: Standalone data mappers integrated with rom-rb
|
90
|
+
email: piotr.solnica+oss@gmail.com
|
91
91
|
executables: []
|
92
92
|
extensions: []
|
93
93
|
extra_rdoc_files: []
|
94
94
|
files:
|
95
|
-
- ".gitignore"
|
96
|
-
- ".rspec"
|
97
|
-
- ".ruby-gemset"
|
98
|
-
- ".travis.yml"
|
99
95
|
- CHANGELOG.md
|
100
|
-
- Gemfile
|
101
|
-
- Guardfile
|
102
96
|
- LICENSE
|
103
97
|
- README.md
|
104
|
-
- Rakefile
|
105
98
|
- lib/rom-mapper.rb
|
106
99
|
- lib/rom/header.rb
|
107
100
|
- lib/rom/header/attribute.rb
|
108
101
|
- lib/rom/mapper.rb
|
109
102
|
- lib/rom/mapper/attribute_dsl.rb
|
103
|
+
- lib/rom/mapper/builder.rb
|
104
|
+
- lib/rom/mapper/configuration_plugin.rb
|
110
105
|
- lib/rom/mapper/dsl.rb
|
106
|
+
- lib/rom/mapper/mapper_dsl.rb
|
111
107
|
- lib/rom/mapper/model_dsl.rb
|
112
108
|
- lib/rom/mapper/version.rb
|
109
|
+
- lib/rom/mapper_compiler.rb
|
113
110
|
- lib/rom/model_builder.rb
|
111
|
+
- lib/rom/open_struct.rb
|
114
112
|
- lib/rom/processor.rb
|
115
113
|
- lib/rom/processor/transproc.rb
|
116
|
-
-
|
117
|
-
-
|
118
|
-
- rakelib/rubocop.rake
|
119
|
-
- rom-mapper.gemspec
|
120
|
-
- spec/integration/mapper_spec.rb
|
121
|
-
- spec/spec_helper.rb
|
122
|
-
- spec/support/constant_leak_finder.rb
|
123
|
-
- spec/support/mutant.rb
|
124
|
-
- spec/unit/rom/mapper/dsl_spec.rb
|
125
|
-
- spec/unit/rom/mapper/model_dsl_spec.rb
|
126
|
-
- spec/unit/rom/mapper_spec.rb
|
127
|
-
- spec/unit/rom/processor/transproc_spec.rb
|
114
|
+
- lib/rom/struct.rb
|
115
|
+
- lib/rom/struct_compiler.rb
|
128
116
|
homepage: http://rom-rb.org
|
129
117
|
licenses:
|
130
118
|
- MIT
|
@@ -140,13 +128,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
140
128
|
version: '0'
|
141
129
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
130
|
requirements:
|
143
|
-
- - "
|
131
|
+
- - ">"
|
144
132
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
133
|
+
version: 1.3.1
|
146
134
|
requirements: []
|
147
135
|
rubyforge_project:
|
148
|
-
rubygems_version: 2.6.
|
136
|
+
rubygems_version: 2.6.12
|
149
137
|
signing_key:
|
150
138
|
specification_version: 4
|
151
|
-
summary:
|
139
|
+
summary: Standalone data mappers integrated with rom-rb
|
152
140
|
test_files: []
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/.ruby-gemset
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
rom
|
data/.travis.yml
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
dist: trusty
|
3
|
-
sudo: false
|
4
|
-
cache: bundler
|
5
|
-
bundler_args: --without sql benchmarks console tools
|
6
|
-
script: "bundle exec rake ci"
|
7
|
-
after_success:
|
8
|
-
- '[ -d coverage ] && bundle exec codeclimate-test-reporter'
|
9
|
-
rvm:
|
10
|
-
- 2.2.7
|
11
|
-
- 2.3.4
|
12
|
-
- 2.4.1
|
13
|
-
- jruby-9.1.8.0
|
14
|
-
env:
|
15
|
-
global:
|
16
|
-
- JRUBY_OPTS='--dev -J-Xmx1024M'
|
17
|
-
notifications:
|
18
|
-
webhooks:
|
19
|
-
urls:
|
20
|
-
- https://webhooks.gitter.im/e/39e1225f489f38b0bd09
|
21
|
-
on_success: change
|
22
|
-
on_failure: always
|
23
|
-
on_start: false
|
data/Gemfile
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gemspec
|
4
|
-
|
5
|
-
group :test do
|
6
|
-
gem 'anima', '~> 0.3.0'
|
7
|
-
gem 'virtus'
|
8
|
-
gem 'inflecto', '~> 0.0', '>= 0.0.2'
|
9
|
-
|
10
|
-
gem 'codeclimate-test-reporter', require: false
|
11
|
-
gem 'simplecov', require: false
|
12
|
-
end
|
13
|
-
|
14
|
-
group :benchmarks do
|
15
|
-
gem 'benchmark-ips', '~> 2.2'
|
16
|
-
end
|
17
|
-
|
18
|
-
group :tools do
|
19
|
-
gem 'rubocop', '~> 0.31'
|
20
|
-
|
21
|
-
gem 'guard'
|
22
|
-
gem 'guard-rspec'
|
23
|
-
gem 'guard-rubocop'
|
24
|
-
|
25
|
-
gem 'byebug'
|
26
|
-
|
27
|
-
platform :mri do
|
28
|
-
gem 'mutant', '~> 0.8.0'
|
29
|
-
gem 'mutant-rspec'
|
30
|
-
end
|
31
|
-
end
|
data/Guardfile
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
guard :rspec do
|
2
|
-
#run all specs if configuration is modified
|
3
|
-
watch('Guardfile') { 'spec' }
|
4
|
-
watch('Gemfile.lock') { 'spec' }
|
5
|
-
watch('spec/spec_helper.rb') { 'spec' }
|
6
|
-
|
7
|
-
# run all specs if supporting files files are modified
|
8
|
-
watch(%r{\Aspec/(?:lib|support|shared)/.+\.rb\z}) { 'spec' }
|
9
|
-
|
10
|
-
# run unit specs if associated lib code is modified
|
11
|
-
watch(%r{\Alib/(.+)\.rb\z}) { |m| Dir["spec/unit/#{m[1]}"] }
|
12
|
-
watch(%r{\Alib/(.+)/support/(.+)\.rb\z}) { |m| Dir["spec/unit/#{m[1]}/#{m[2]}"] }
|
13
|
-
watch("lib/#{File.basename(File.expand_path('../', __FILE__))}.rb") { 'spec' }
|
14
|
-
|
15
|
-
# run a spec if it is modified
|
16
|
-
watch(%r{\Aspec/(?:unit|integration)/.+_spec\.rb\z})
|
17
|
-
|
18
|
-
notification :tmux, :display_message => true
|
19
|
-
end
|
data/Rakefile
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
2
|
-
require "rspec/core/rake_task"
|
3
|
-
require "rake/testtask"
|
4
|
-
|
5
|
-
RSpec::Core::RakeTask.new(:spec)
|
6
|
-
task default: [:ci]
|
7
|
-
|
8
|
-
desc 'Run specs in isolation'
|
9
|
-
task :"spec:isolation" do
|
10
|
-
FileList["spec/**/*_spec.rb"].each do |spec|
|
11
|
-
sh "rspec", spec
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
desc "Run CI tasks"
|
16
|
-
task ci: [:spec]
|
data/rakelib/benchmark.rake
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
desc "Run benchmarks (tweak count via COUNT envvar)"
|
2
|
-
task :benchmark do
|
3
|
-
FileList["benchmarks/**/*_bench.rb"].each do |bench|
|
4
|
-
sh "ruby #{bench}"
|
5
|
-
end
|
6
|
-
end
|
7
|
-
|
8
|
-
namespace :benchmark do
|
9
|
-
desc "Verify benchmarks"
|
10
|
-
task :verify do
|
11
|
-
ENV['VERIFY'] = "true"
|
12
|
-
ENV['COUNT'] = "1"
|
13
|
-
Rake::Task[:benchmark].invoke
|
14
|
-
end
|
15
|
-
end
|
data/rakelib/mutant.rake
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
desc "Run mutant against a specific subject"
|
2
|
-
task :mutant do
|
3
|
-
subject = ARGV.last
|
4
|
-
if subject == 'mutant'
|
5
|
-
abort "usage: rake mutant SUBJECT\nexample: rake mutant ROM::Header"
|
6
|
-
else
|
7
|
-
opts = {
|
8
|
-
'include' => 'lib',
|
9
|
-
'require' => 'rom',
|
10
|
-
'use' => 'rspec',
|
11
|
-
'ignore-subject' => "#{subject}#respond_to_missing?"
|
12
|
-
}.to_a.map { |k, v| "--#{k} #{v}" }.join(' ')
|
13
|
-
|
14
|
-
exec("bundle exec mutant #{opts} #{subject}")
|
15
|
-
end
|
16
|
-
end
|
data/rakelib/rubocop.rake
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require "rubocop/rake_task"
|
3
|
-
|
4
|
-
Rake::Task[:default].enhance [:rubocop]
|
5
|
-
|
6
|
-
RuboCop::RakeTask.new do |task|
|
7
|
-
task.options << "--display-cop-names"
|
8
|
-
end
|
9
|
-
|
10
|
-
namespace :rubocop do
|
11
|
-
desc 'Generate a configuration file acting as a TODO list.'
|
12
|
-
task :auto_gen_config do
|
13
|
-
exec "bundle exec rubocop --auto-gen-config"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
rescue LoadError
|
18
|
-
end
|
data/rom-mapper.gemspec
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
require File.expand_path('../lib/rom/mapper/version', __FILE__)
|
2
|
-
|
3
|
-
Gem::Specification.new do |gem|
|
4
|
-
gem.name = "rom-mapper"
|
5
|
-
gem.description = "ROM mapper component"
|
6
|
-
gem.summary = gem.description
|
7
|
-
gem.authors = 'Piotr Solnica'
|
8
|
-
gem.email = 'piotr.solnica@gmail.com'
|
9
|
-
gem.homepage = 'http://rom-rb.org'
|
10
|
-
gem.require_paths = [ 'lib' ]
|
11
|
-
gem.version = ROM::Mapper::VERSION.dup
|
12
|
-
gem.files = `git ls-files`.split("\n")
|
13
|
-
gem.test_files = `git ls-files -- {spec}/*`.split("\n")
|
14
|
-
gem.license = 'MIT'
|
15
|
-
|
16
|
-
gem.add_dependency 'dry-equalizer', '~> 0.2'
|
17
|
-
gem.add_dependency 'dry-core', '~> 0.2', '>= 0.2.3'
|
18
|
-
gem.add_dependency 'transproc', '~> 1.0'
|
19
|
-
|
20
|
-
gem.add_development_dependency 'rake', '~> 11.3'
|
21
|
-
gem.add_development_dependency 'rspec', '~> 3.5'
|
22
|
-
end
|
@@ -1,113 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe ROM::Mapper do
|
4
|
-
let(:mapper_klass) do
|
5
|
-
Class.new(ROM::Mapper).tap do |mapper_klass|
|
6
|
-
mapper_klass.class_eval(&mapper_body)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
let(:mapper) { mapper_klass.build }
|
10
|
-
|
11
|
-
subject { mapper.call(tuples) }
|
12
|
-
|
13
|
-
describe '.attribute' do
|
14
|
-
context 'with block' do
|
15
|
-
let(:tuples) { [{ key: 'bar' }] }
|
16
|
-
let(:results) { [{ key: 'foo_bar' }] }
|
17
|
-
let(:mapper_body) do
|
18
|
-
proc do
|
19
|
-
attribute(:key) { |key| [prefix, key].join('_') }
|
20
|
-
|
21
|
-
def prefix
|
22
|
-
'foo'
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'creates the attribute from the proc with the mapper as the binding' do
|
28
|
-
is_expected.to match_array(results)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
context 'when copying aliased keys to multiple attributes' do
|
33
|
-
let(:tuples) { [{ key: 'bar' }] }
|
34
|
-
let(:results) { [{ key: 'bar', key2: 'bar', key3: 'bar' }] }
|
35
|
-
let(:mapper_body) do
|
36
|
-
proc do
|
37
|
-
copy_keys true
|
38
|
-
attribute([:key2, :key3], from: :key)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'creates attributes by copying keys rather than renaming' do
|
43
|
-
is_expected.to match_array(results)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
describe '.embedded' do
|
49
|
-
context 'with block' do
|
50
|
-
let(:tuples) { [{ items: { key: 'bar' } }] }
|
51
|
-
let(:results) { [{ items: { key: 'foo_bar' } }] }
|
52
|
-
let(:mapper_body) do
|
53
|
-
proc do
|
54
|
-
embedded :items, type: :hash do
|
55
|
-
attribute(:key) { |key| [prefix, key].join('_') }
|
56
|
-
end
|
57
|
-
|
58
|
-
def prefix
|
59
|
-
'foo'
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'creates the attribute from the proc with the mapper as the binding' do
|
65
|
-
is_expected.to match_array(results)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe '.wrap' do
|
71
|
-
context 'attribute with block' do
|
72
|
-
let(:tuples) { [{ key: 'bar' }] }
|
73
|
-
let(:results) { [{ items: { key: 'foo_bar' } }] }
|
74
|
-
let(:mapper_body) do
|
75
|
-
proc do
|
76
|
-
wrap :items do
|
77
|
-
attribute(:key) { |key| [prefix, key].join('_') }
|
78
|
-
end
|
79
|
-
|
80
|
-
def prefix
|
81
|
-
'foo'
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'creates the attribute from the proc with the mapper as the binding' do
|
87
|
-
is_expected.to match_array(results)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
describe '.unwrap' do
|
93
|
-
context 'attribute with block' do
|
94
|
-
let(:tuples) { [{ items: { key: 'bar' } }] }
|
95
|
-
let(:results) { [{ key: 'foo_bar' }] }
|
96
|
-
let(:mapper_body) do
|
97
|
-
proc do
|
98
|
-
unwrap :items do
|
99
|
-
attribute(:key) { |key| [prefix, key].join('_') }
|
100
|
-
end
|
101
|
-
|
102
|
-
def prefix
|
103
|
-
'foo'
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'creates the attribute from the proc with the mapper as the binding' do
|
109
|
-
is_expected.to match_array(results)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|