rom-sql 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.travis.yml +12 -7
- data/CHANGELOG.md +28 -0
- data/Gemfile +6 -9
- data/README.md +5 -4
- data/circle.yml +10 -0
- data/lib/rom/plugins/relation/sql/auto_combine.rb +16 -3
- data/lib/rom/plugins/relation/sql/auto_wrap.rb +3 -2
- data/lib/rom/sql/association.rb +75 -0
- data/lib/rom/sql/association/many_to_many.rb +86 -0
- data/lib/rom/sql/association/many_to_one.rb +60 -0
- data/lib/rom/sql/association/name.rb +70 -0
- data/lib/rom/sql/association/one_to_many.rb +9 -0
- data/lib/rom/sql/association/one_to_one.rb +46 -0
- data/lib/rom/sql/association/one_to_one_through.rb +9 -0
- data/lib/rom/sql/commands.rb +2 -0
- data/lib/rom/sql/commands/create.rb +2 -2
- data/lib/rom/sql/commands/delete.rb +0 -1
- data/lib/rom/sql/commands/postgres.rb +76 -0
- data/lib/rom/sql/commands/update.rb +6 -3
- data/lib/rom/sql/commands_ext/postgres.rb +17 -0
- data/lib/rom/sql/gateway.rb +23 -15
- data/lib/rom/sql/header.rb +7 -1
- data/lib/rom/sql/plugin/assoc_macros.rb +3 -3
- data/lib/rom/sql/plugin/associates.rb +50 -9
- data/lib/rom/sql/qualified_attribute.rb +53 -0
- data/lib/rom/sql/relation.rb +76 -25
- data/lib/rom/sql/relation/reading.rb +138 -35
- data/lib/rom/sql/relation/writing.rb +21 -0
- data/lib/rom/sql/schema.rb +35 -0
- data/lib/rom/sql/schema/associations_dsl.rb +68 -0
- data/lib/rom/sql/schema/dsl.rb +27 -0
- data/lib/rom/sql/schema/inferrer.rb +80 -0
- data/lib/rom/sql/support/active_support_notifications.rb +27 -17
- data/lib/rom/sql/types.rb +11 -0
- data/lib/rom/sql/types/pg.rb +26 -0
- data/lib/rom/sql/version.rb +1 -1
- data/rom-sql.gemspec +4 -2
- data/spec/integration/association/many_to_many_spec.rb +137 -0
- data/spec/integration/association/many_to_one_spec.rb +110 -0
- data/spec/integration/association/one_to_many_spec.rb +58 -0
- data/spec/integration/association/one_to_one_spec.rb +57 -0
- data/spec/integration/association/one_to_one_through_spec.rb +90 -0
- data/spec/integration/combine_spec.rb +24 -24
- data/spec/integration/commands/create_spec.rb +215 -168
- data/spec/integration/commands/delete_spec.rb +88 -46
- data/spec/integration/commands/update_spec.rb +141 -60
- data/spec/integration/commands/upsert_spec.rb +83 -0
- data/spec/integration/gateway_spec.rb +9 -17
- data/spec/integration/migration_spec.rb +3 -5
- data/spec/integration/plugins/associates_spec.rb +168 -0
- data/spec/integration/plugins/auto_wrap_spec.rb +46 -0
- data/spec/integration/read_spec.rb +80 -77
- data/spec/integration/relation_schema_spec.rb +180 -0
- data/spec/integration/schema_inference_spec.rb +67 -0
- data/spec/integration/setup_spec.rb +22 -0
- data/spec/{support → integration/support}/active_support_notifications_spec.rb +0 -0
- data/spec/{support → integration/support}/rails_log_subscriber_spec.rb +0 -0
- data/spec/shared/database_setup.rb +46 -8
- data/spec/shared/relations.rb +8 -0
- data/spec/shared/users_and_accounts.rb +10 -0
- data/spec/shared/users_and_tasks.rb +20 -2
- data/spec/spec_helper.rb +64 -11
- data/spec/support/helpers.rb +9 -0
- data/spec/unit/association/many_to_many_spec.rb +89 -0
- data/spec/unit/association/many_to_one_spec.rb +81 -0
- data/spec/unit/association/name_spec.rb +68 -0
- data/spec/unit/association/one_to_many_spec.rb +62 -0
- data/spec/unit/association/one_to_one_spec.rb +62 -0
- data/spec/unit/association/one_to_one_through_spec.rb +69 -0
- data/spec/unit/association_errors_spec.rb +2 -4
- data/spec/unit/gateway_spec.rb +12 -3
- data/spec/unit/migration_tasks_spec.rb +3 -3
- data/spec/unit/migrator_spec.rb +2 -4
- data/spec/unit/{combined_associations_spec.rb → plugin/assoc_macros/combined_associations_spec.rb} +13 -19
- data/spec/unit/{many_to_many_spec.rb → plugin/assoc_macros/many_to_many_spec.rb} +9 -15
- data/spec/unit/{many_to_one_spec.rb → plugin/assoc_macros/many_to_one_spec.rb} +9 -14
- data/spec/unit/plugin/assoc_macros/one_to_many_spec.rb +78 -0
- data/spec/unit/plugin/base_view_spec.rb +11 -11
- data/spec/unit/plugin/pagination_spec.rb +62 -62
- data/spec/unit/relation_spec.rb +218 -146
- data/spec/unit/schema_spec.rb +15 -14
- data/spec/unit/types_spec.rb +40 -0
- metadata +105 -21
- data/.rubocop.yml +0 -74
- data/.rubocop_todo.yml +0 -21
- data/spec/unit/one_to_many_spec.rb +0 -83
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5da70a1471f9c0b3a27f10cacf6af54f060090be
|
4
|
+
data.tar.gz: 1f391fdbd269bbf0df9d0af23a5fc112948ce1f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f91c5854d45dc52b26ddb0eaca6dc465ff02db69bd145d6ce010c6eaa93571ac46842d68a6897e0b88fffb7639efe26c94435a035c0d4a0790be37defd846fa2
|
7
|
+
data.tar.gz: 879cf6a660eb79ab84b1adbfb33ede96613d786356457182d81bc3f00f2a7165fbe939d25b7bd0755242710469cffae650976252c9c19eeda37067a89a0407ec
|
data/.rspec
CHANGED
data/.travis.yml
CHANGED
@@ -1,28 +1,33 @@
|
|
1
1
|
language: ruby
|
2
2
|
sudo: false
|
3
3
|
cache: bundler
|
4
|
+
services:
|
5
|
+
- postgresql
|
6
|
+
- mysql
|
4
7
|
bundler_args: --without yard guard benchmarks tools
|
5
8
|
before_script:
|
6
9
|
- psql -c 'create database rom_sql;' -U postgres
|
10
|
+
- mysql -e 'create database rom_sql;'
|
7
11
|
script: "bundle exec rake ci"
|
8
12
|
rvm:
|
9
|
-
- 2.
|
10
|
-
- 2.
|
11
|
-
- 2.
|
12
|
-
- 2.3.0
|
13
|
+
- 2.1.9
|
14
|
+
- 2.2.5
|
15
|
+
- 2.3.1
|
13
16
|
- rbx-2
|
14
|
-
- jruby-
|
15
|
-
- jruby-head
|
17
|
+
- jruby-9.0.5.0
|
16
18
|
- ruby-head
|
17
19
|
env:
|
18
20
|
global:
|
19
21
|
- CODECLIMATE_REPO_TOKEN=03d7f66589572702b12426d2bc71c4de6281a96139e33b335b894264b1f8f0b0
|
20
22
|
- JRUBY_OPTS='--dev -J-Xmx1024M'
|
23
|
+
- PG_LTE_95='false'
|
21
24
|
matrix:
|
22
25
|
allow_failures:
|
23
|
-
- rvm: jruby-9000
|
24
26
|
- rvm: ruby-head
|
25
27
|
- rvm: jruby-head
|
28
|
+
include:
|
29
|
+
- rvm: jruby-head
|
30
|
+
before_install: gem install bundler --no-ri --no-rdoc
|
26
31
|
notifications:
|
27
32
|
webhooks:
|
28
33
|
urls:
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,31 @@
|
|
1
|
+
## v0.8.0 2016-07-27
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
* Support for relation schemas with SQL-specific data types (solnic + flash-gordon)
|
6
|
+
* One-To-Many support in schemas (solnic + flash-gordon)
|
7
|
+
* One-To-One support in schemas (solnic + flash-gordon)
|
8
|
+
* One-To-One-Through support in schemas (solnic + flash-gordon)
|
9
|
+
* Many-To-One support in schemas (solnic + flash-gordon)
|
10
|
+
* Many-To-Many support in schemas (solnic + flash-gordon)
|
11
|
+
* Support for `has_many`, `has_one` and `belongs_to` convenient methods in schema DSL (solnic)
|
12
|
+
* Support for custom PG types: `Types::PG::Array`, `Types::PG::Hash`, `Types::PG::JSON`, and `Types::PG::Bytea` (solnic + flash-gordon)
|
13
|
+
* Optional automatic schema inference for attributes and foreign keys based on DB metadata provided by Sequel (flash-gordon)
|
14
|
+
* Support for arbitrary dataset and FK names in schemas (flash-gordon)
|
15
|
+
* Support for native upserts in PostgreSQL >= 9.5 via `Commands::Postgres::Upsert` (gotar + flash-gordon)
|
16
|
+
|
17
|
+
### Changed
|
18
|
+
|
19
|
+
* `Create` and `Update` commands have `:schema` plugin enabled by default which sets input handler based on schema definition automatically (solnic)
|
20
|
+
* `associates` command plugin uses schema associations now (solnic)
|
21
|
+
* Dropped MRI 2.0.x support
|
22
|
+
|
23
|
+
### Fixed
|
24
|
+
|
25
|
+
* `Create` command properly materialize result when `:one` is set (AMHOL)
|
26
|
+
|
27
|
+
[Compare v0.7.0...v0.8.0](https://github.com/rom-rb/rom-sql/compare/v0.7.0...v0.8.0)
|
28
|
+
|
1
29
|
## v0.7.0 2016-01-06
|
2
30
|
|
3
31
|
### Added
|
data/Gemfile
CHANGED
@@ -6,16 +6,13 @@ group :test do
|
|
6
6
|
gem 'byebug', platforms: :mri
|
7
7
|
gem 'anima', '~> 0.2.0'
|
8
8
|
gem 'virtus'
|
9
|
-
gem 'activesupport'
|
9
|
+
gem 'activesupport', '~> 4.2'
|
10
10
|
gem 'rspec', '~> 3.1'
|
11
11
|
gem 'codeclimate-test-reporter', require: false
|
12
12
|
gem 'pg', platforms: [:mri, :rbx]
|
13
|
-
gem '
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
gem '
|
18
|
-
gem 'guard-rspec'
|
19
|
-
gem 'guard-rubocop'
|
20
|
-
gem 'rubocop', '~> 0.28'
|
13
|
+
gem 'mysql2', platforms: [:mri, :rbx]
|
14
|
+
gem 'jdbc-postgres', platforms: :jruby
|
15
|
+
gem 'jdbc-mysql', platforms: :jruby
|
16
|
+
gem 'sqlite3', platforms: [:mri, :rbx]
|
17
|
+
gem 'jdbc-sqlite3', platforms: :jruby
|
21
18
|
end
|
data/README.md
CHANGED
@@ -4,11 +4,11 @@
|
|
4
4
|
[codeclimate]: https://codeclimate.com/github/rom-rb/rom-sql
|
5
5
|
[inchpages]: http://inch-ci.org/github/rom-rb/rom-sql
|
6
6
|
|
7
|
-
#
|
7
|
+
# rom-sql
|
8
8
|
|
9
9
|
[![Gem Version](https://badge.fury.io/rb/rom-sql.svg)][gem]
|
10
10
|
[![Build Status](https://travis-ci.org/rom-rb/rom-sql.svg?branch=master)][travis]
|
11
|
-
[![Dependency Status](https://gemnasium.com/rom-rb/rom-sql.
|
11
|
+
[![Dependency Status](https://gemnasium.com/rom-rb/rom-sql.svg)][gemnasium]
|
12
12
|
[![Code Climate](https://codeclimate.com/github/rom-rb/rom-sql/badges/gpa.svg)][codeclimate]
|
13
13
|
[![Test Coverage](https://codeclimate.com/github/rom-rb/rom-sql/badges/coverage.svg)][codeclimate]
|
14
14
|
[![Inline docs](http://inch-ci.org/github/rom-rb/rom-sql.svg?branch=master)][inchpages]
|
@@ -17,7 +17,8 @@ RDBMS support for [Ruby Object Mapper](https://github.com/rom-rb/rom).
|
|
17
17
|
|
18
18
|
Resources:
|
19
19
|
|
20
|
-
- [
|
20
|
+
- [User Documentation](http://rom-rb.org/learn/sql/)
|
21
|
+
- [API Documentation](http://rubydoc.info/gems/rom-sql)
|
21
22
|
|
22
23
|
## Installation
|
23
24
|
|
@@ -35,7 +36,7 @@ Or install it yourself as:
|
|
35
36
|
|
36
37
|
$ gem install rom-sql
|
37
38
|
|
38
|
-
Check out [SQL guide](http://rom-rb.org/
|
39
|
+
Check out [SQL guide](http://rom-rb.org/learn/adapters/sql/) for usage examples.
|
39
40
|
|
40
41
|
## ROADMAP
|
41
42
|
|
data/circle.yml
ADDED
@@ -16,6 +16,7 @@ module ROM
|
|
16
16
|
def inherited(klass)
|
17
17
|
super
|
18
18
|
klass.auto_curry :for_combine
|
19
|
+
klass.auto_curry :preload
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
@@ -27,9 +28,21 @@ module ROM
|
|
27
28
|
# @return [SQL::Relation]
|
28
29
|
#
|
29
30
|
# @api private
|
30
|
-
def for_combine(
|
31
|
-
|
32
|
-
|
31
|
+
def for_combine(spec)
|
32
|
+
source_key, target_key, target =
|
33
|
+
case spec
|
34
|
+
when ROM::SQL::Association
|
35
|
+
[*spec.join_keys(__registry__).flatten, spec.call(__registry__)]
|
36
|
+
else
|
37
|
+
[*spec.flatten, self]
|
38
|
+
end
|
39
|
+
|
40
|
+
target.preload(source_key, target_key)
|
41
|
+
end
|
42
|
+
|
43
|
+
# @api private
|
44
|
+
def preload(source_key, target_key, source)
|
45
|
+
where(target_key => source.pluck(source_key.to_sym))
|
33
46
|
end
|
34
47
|
end
|
35
48
|
end
|
@@ -29,10 +29,11 @@ module ROM
|
|
29
29
|
# @api private
|
30
30
|
def for_wrap(keys, name)
|
31
31
|
other = __registry__[name]
|
32
|
+
other_dataset = other.name.dataset
|
32
33
|
|
33
|
-
inner_join(
|
34
|
+
inner_join(other_dataset, keys)
|
34
35
|
.select(*qualified.header.columns)
|
35
|
-
.select_append(*other.prefix(
|
36
|
+
.select_append(*other.prefix(other_dataset).qualified.header)
|
36
37
|
end
|
37
38
|
end
|
38
39
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'rom/support/constants'
|
2
|
+
require 'rom/sql/qualified_attribute'
|
3
|
+
require 'rom/sql/association/name'
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
module SQL
|
7
|
+
# Abstract association class
|
8
|
+
#
|
9
|
+
# @api public
|
10
|
+
class Association
|
11
|
+
include Dry::Equalizer(:source, :target, :result)
|
12
|
+
include Options
|
13
|
+
extend ClassMacros
|
14
|
+
|
15
|
+
defines :result
|
16
|
+
|
17
|
+
# @!attribute [r] source
|
18
|
+
# @return [ROM::Relation::Name] the source relation name
|
19
|
+
attr_reader :source
|
20
|
+
|
21
|
+
# @!attribute [r] target
|
22
|
+
# @return [ROM::Relation::Name] the target relation name
|
23
|
+
attr_reader :target
|
24
|
+
|
25
|
+
# @!attribute [r] relation
|
26
|
+
# @return [Symbol] an optional relation identifier for the target
|
27
|
+
option :relation, accepts: [Symbol], reader: true
|
28
|
+
|
29
|
+
# @!attribute [r] result
|
30
|
+
# @return [Symbol] either :one or :many
|
31
|
+
option :result, accepts: [Symbol], reader: true, default: -> assoc { assoc.class.result }
|
32
|
+
|
33
|
+
# @!attribute [r] as
|
34
|
+
# @return [Symbol] an optional association alias name
|
35
|
+
option :as, accepts: [Symbol], reader: true, default: -> assoc { assoc.target.to_sym }
|
36
|
+
|
37
|
+
alias_method :name, :as
|
38
|
+
|
39
|
+
# @api private
|
40
|
+
def initialize(source, target, options = EMPTY_HASH)
|
41
|
+
@source = Name[source]
|
42
|
+
@target = Name[options[:relation] || target, target, options[:as] || target]
|
43
|
+
super
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns a qualified attribute name for a given dataset
|
47
|
+
#
|
48
|
+
# This is compatible with Sequel's SQL generator and can be used in query
|
49
|
+
# DSL methods
|
50
|
+
#
|
51
|
+
# @param name [ROM::Relation::Name]
|
52
|
+
# @param attribute [Symbol]
|
53
|
+
#
|
54
|
+
# @return [QualifiedAttribute]
|
55
|
+
#
|
56
|
+
# @api public
|
57
|
+
def qualify(name, attribute)
|
58
|
+
QualifiedAttribute[name.dataset, attribute]
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
# @api private
|
64
|
+
def join_key_map(relations)
|
65
|
+
join_keys(relations).to_a.flatten.map(&:to_sym)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
require 'rom/sql/association/one_to_one'
|
72
|
+
require 'rom/sql/association/one_to_many'
|
73
|
+
require 'rom/sql/association/many_to_many'
|
74
|
+
require 'rom/sql/association/many_to_one'
|
75
|
+
require 'rom/sql/association/one_to_one_through'
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module ROM
|
2
|
+
module SQL
|
3
|
+
class Association
|
4
|
+
class ManyToMany < Association
|
5
|
+
attr_reader :through
|
6
|
+
|
7
|
+
result :many
|
8
|
+
|
9
|
+
option :through, default: nil, type: Symbol
|
10
|
+
|
11
|
+
# @api private
|
12
|
+
def initialize(*)
|
13
|
+
super
|
14
|
+
@through = Relation::Name[
|
15
|
+
options[:through] || options[:through_relation], options[:through]
|
16
|
+
]
|
17
|
+
end
|
18
|
+
|
19
|
+
# @api public
|
20
|
+
def call(relations)
|
21
|
+
join_rel = join_relation(relations)
|
22
|
+
assocs = join_rel.associations
|
23
|
+
|
24
|
+
left = assocs[target].call(relations)
|
25
|
+
right = relations[target.relation]
|
26
|
+
|
27
|
+
left_fk = join_rel.foreign_key(source.relation)
|
28
|
+
|
29
|
+
columns = right.header.exclude(left_fk).qualified.to_a
|
30
|
+
columns << left_fk unless right.header.names.include?(left_fk)
|
31
|
+
|
32
|
+
relation = left
|
33
|
+
.inner_join(source, join_keys(relations))
|
34
|
+
.select(*columns)
|
35
|
+
.order(*right.header.project(*right.primary_key).qualified)
|
36
|
+
|
37
|
+
relation.with(attributes: relation.header.names)
|
38
|
+
end
|
39
|
+
|
40
|
+
# @api public
|
41
|
+
def join_keys(relations)
|
42
|
+
with_keys(relations) { |source_key, target_key|
|
43
|
+
{ qualify(source, source_key) => qualify(through, target_key) }
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
# @api public
|
48
|
+
def combine_keys(relations)
|
49
|
+
Hash[*with_keys(relations)]
|
50
|
+
end
|
51
|
+
|
52
|
+
# @api private
|
53
|
+
def associate(relations, children, parent)
|
54
|
+
((spk, sfk), (tfk, tpk)) = join_key_map(relations)
|
55
|
+
|
56
|
+
children.map { |tuple|
|
57
|
+
{ sfk => tuple.fetch(spk), tfk => parent.fetch(tpk) }
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
# @api private
|
62
|
+
def join_relation(relations)
|
63
|
+
relations[through.relation]
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
|
68
|
+
# @api private
|
69
|
+
def with_keys(relations, &block)
|
70
|
+
source_key = relations[source.relation].primary_key
|
71
|
+
target_key = relations[through.relation].foreign_key(source.relation)
|
72
|
+
return [source_key, target_key] unless block
|
73
|
+
yield(source_key, target_key)
|
74
|
+
end
|
75
|
+
|
76
|
+
# @api private
|
77
|
+
def join_key_map(relations)
|
78
|
+
left = super
|
79
|
+
right = join_relation(relations).associations[target].join_key_map(relations)
|
80
|
+
|
81
|
+
[left, right]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module ROM
|
2
|
+
module SQL
|
3
|
+
class Association
|
4
|
+
class ManyToOne < Association
|
5
|
+
result :one
|
6
|
+
|
7
|
+
# @api public
|
8
|
+
def call(relations)
|
9
|
+
left = relations[target.relation]
|
10
|
+
right = relations[source.relation]
|
11
|
+
|
12
|
+
right_pk = right.schema.primary_key.map { |a| a.meta[:name] }
|
13
|
+
right_fk = right.foreign_key(target.relation)
|
14
|
+
|
15
|
+
pk_to_fk = Hash[right_pk.product(Array(left.foreign_key(source.relation)))]
|
16
|
+
|
17
|
+
columns = left.header.qualified.to_a + right.header
|
18
|
+
.project(*right_pk)
|
19
|
+
.rename(pk_to_fk)
|
20
|
+
.qualified.to_a
|
21
|
+
|
22
|
+
relation = left
|
23
|
+
.inner_join(source, right_fk => left.primary_key)
|
24
|
+
.select(*columns)
|
25
|
+
.order(*right.header.project(*right.primary_key).qualified)
|
26
|
+
|
27
|
+
relation.with(attributes: relation.header.names)
|
28
|
+
end
|
29
|
+
|
30
|
+
# @api public
|
31
|
+
def combine_keys(relations)
|
32
|
+
Hash[*with_keys(relations)]
|
33
|
+
end
|
34
|
+
|
35
|
+
# @api public
|
36
|
+
def join_keys(relations)
|
37
|
+
with_keys(relations) { |source_key, target_key|
|
38
|
+
{ qualify(source, source_key) => qualify(target, target_key) }
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
# @api private
|
43
|
+
def associate(relations, child, parent)
|
44
|
+
fk, pk = join_key_map(relations)
|
45
|
+
child.merge(fk => parent.fetch(pk))
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
# @api private
|
51
|
+
def with_keys(relations, &block)
|
52
|
+
source_key = relations[source.relation].foreign_key(target.relation)
|
53
|
+
target_key = relations[target.relation].primary_key
|
54
|
+
return [source_key, target_key] unless block
|
55
|
+
yield(source_key, target_key)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'dry/equalizer'
|
2
|
+
require 'rom/relation/name'
|
3
|
+
require 'rom/support/cache'
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
module SQL
|
7
|
+
class Association
|
8
|
+
class Name
|
9
|
+
include Dry::Equalizer.new(:relation_name, :key)
|
10
|
+
|
11
|
+
extend Cache
|
12
|
+
|
13
|
+
attr_reader :relation_name
|
14
|
+
|
15
|
+
attr_reader :key
|
16
|
+
|
17
|
+
alias_method :to_sym, :key
|
18
|
+
|
19
|
+
def self.[](*args)
|
20
|
+
fetch_or_store(args) do
|
21
|
+
rel, ds, aliaz = args
|
22
|
+
|
23
|
+
if rel.is_a?(ROM::Relation::Name)
|
24
|
+
new(rel, rel.dataset)
|
25
|
+
elsif rel.is_a?(self)
|
26
|
+
rel
|
27
|
+
elsif aliaz
|
28
|
+
new(ROM::Relation::Name[rel, ds], aliaz)
|
29
|
+
elsif ds.nil?
|
30
|
+
new(ROM::Relation::Name[rel], rel)
|
31
|
+
else
|
32
|
+
new(ROM::Relation::Name[rel, ds], ds)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize(relation_name, aliaz)
|
38
|
+
@relation_name = relation_name
|
39
|
+
@aliased = relation_name.dataset != aliaz
|
40
|
+
@key = aliased? ? aliaz : relation_name.dataset
|
41
|
+
end
|
42
|
+
|
43
|
+
def aliased?
|
44
|
+
@aliased
|
45
|
+
end
|
46
|
+
|
47
|
+
def inspect
|
48
|
+
if aliased?
|
49
|
+
"#{self.class}(#{relation_name.to_s} as #{key})"
|
50
|
+
else
|
51
|
+
"#{self.class}(#{relation_name.to_s})"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
alias_method :to_s, :inspect
|
55
|
+
|
56
|
+
def dataset
|
57
|
+
relation_name.dataset
|
58
|
+
end
|
59
|
+
|
60
|
+
def relation
|
61
|
+
relation_name.relation
|
62
|
+
end
|
63
|
+
|
64
|
+
def sql_literal_append(ds, sql)
|
65
|
+
ds.literal_append(sql, dataset)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|