rom-sql 0.7.0 → 0.8.0
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/.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]
|
10
10
|
[][travis]
|
11
|
-
[][gemnasium]
|
12
12
|
[][codeclimate]
|
13
13
|
[][codeclimate]
|
14
14
|
[][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
|