rom-sql 1.3.5 → 2.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -7
- data/Gemfile +7 -5
- data/lib/rom/plugins/relation/sql/auto_restrictions.rb +11 -17
- data/lib/rom/sql.rb +3 -2
- data/lib/rom/sql/associations.rb +5 -0
- data/lib/rom/sql/associations/core.rb +20 -0
- data/lib/rom/sql/associations/many_to_many.rb +83 -0
- data/lib/rom/sql/associations/many_to_one.rb +55 -0
- data/lib/rom/sql/associations/one_to_many.rb +31 -0
- data/lib/rom/sql/{association → associations}/one_to_one.rb +3 -2
- data/lib/rom/sql/{association → associations}/one_to_one_through.rb +3 -2
- data/lib/rom/sql/associations/self_ref.rb +39 -0
- data/lib/rom/sql/attribute.rb +44 -54
- data/lib/rom/sql/errors.rb +2 -0
- data/lib/rom/sql/extensions/mysql.rb +1 -1
- data/lib/rom/sql/extensions/mysql/attributes_inferrer.rb +10 -0
- data/lib/rom/sql/extensions/postgres.rb +1 -1
- data/lib/rom/sql/extensions/postgres/{inferrer.rb → attributes_inferrer.rb} +4 -4
- data/lib/rom/sql/extensions/postgres/types.rb +9 -19
- data/lib/rom/sql/extensions/sqlite.rb +1 -1
- data/lib/rom/sql/extensions/sqlite/{inferrer.rb → attributes_inferrer.rb} +2 -2
- data/lib/rom/sql/gateway.rb +29 -30
- data/lib/rom/sql/index.rb +13 -0
- data/lib/rom/sql/migration.rb +10 -0
- data/lib/rom/sql/migration/inline_runner.rb +86 -0
- data/lib/rom/sql/migration/migrator.rb +17 -0
- data/lib/rom/sql/migration/schema_diff.rb +177 -0
- data/lib/rom/sql/plugin/associates.rb +11 -45
- data/lib/rom/sql/plugin/pagination.rb +4 -4
- data/lib/rom/sql/relation.rb +22 -42
- data/lib/rom/sql/relation/reading.rb +3 -3
- data/lib/rom/sql/schema.rb +14 -21
- data/lib/rom/sql/schema/associations_dsl.rb +7 -6
- data/lib/rom/sql/schema/attributes_inferrer.rb +164 -0
- data/lib/rom/sql/schema/inferrer.rb +40 -141
- data/lib/rom/sql/type_extensions.rb +44 -0
- data/lib/rom/sql/version.rb +1 -1
- data/lib/rom/sql/wrap.rb +25 -0
- data/rom-sql.gemspec +2 -2
- data/spec/integration/{association → associations}/many_to_many/custom_fks_spec.rb +4 -2
- data/spec/integration/{association → associations}/many_to_many/from_view_spec.rb +2 -2
- data/spec/integration/{association → associations}/many_to_many_spec.rb +25 -30
- data/spec/integration/{association → associations}/many_to_one/custom_fks_spec.rb +5 -3
- data/spec/integration/{association → associations}/many_to_one/from_view_spec.rb +3 -3
- data/spec/integration/{association → associations}/many_to_one/self_ref_spec.rb +2 -2
- data/spec/integration/{association → associations}/many_to_one_spec.rb +20 -38
- data/spec/integration/{association → associations}/one_to_many/custom_fks_spec.rb +4 -2
- data/spec/integration/{association → associations}/one_to_many/from_view_spec.rb +2 -2
- data/spec/integration/{association → associations}/one_to_many/self_ref_spec.rb +2 -2
- data/spec/integration/{association → associations}/one_to_many_spec.rb +24 -11
- data/spec/integration/{association → associations}/one_to_one_spec.rb +13 -9
- data/spec/integration/{association → associations}/one_to_one_through_spec.rb +15 -11
- data/spec/integration/auto_migrations/errors_spec.rb +31 -0
- data/spec/integration/auto_migrations/indexes_spec.rb +109 -0
- data/spec/integration/auto_migrations/managing_columns_spec.rb +156 -0
- data/spec/integration/auto_migrations/postgres/column_types_spec.rb +63 -0
- data/spec/integration/commands/create_spec.rb +2 -4
- data/spec/integration/commands/delete_spec.rb +2 -2
- data/spec/integration/commands/update_spec.rb +2 -0
- data/spec/integration/graph_spec.rb +9 -3
- data/spec/integration/plugins/associates_spec.rb +16 -55
- data/spec/integration/plugins/auto_restrictions_spec.rb +0 -11
- data/spec/integration/relation_schema_spec.rb +49 -25
- data/spec/integration/schema/inferrer/postgres_spec.rb +1 -1
- data/spec/integration/schema/inferrer_spec.rb +7 -18
- data/spec/integration/setup_spec.rb +4 -0
- data/spec/integration/{plugins/auto_wrap_spec.rb → wrap_spec.rb} +13 -36
- data/spec/shared/accounts.rb +4 -0
- data/spec/shared/database_setup.rb +2 -1
- data/spec/shared/notes.rb +2 -0
- data/spec/shared/posts.rb +2 -0
- data/spec/shared/puppies.rb +2 -0
- data/spec/shared/relations.rb +2 -2
- data/spec/shared/users.rb +2 -0
- data/spec/shared/users_and_tasks.rb +4 -0
- data/spec/spec_helper.rb +3 -6
- data/spec/support/helpers.rb +11 -8
- data/spec/support/test_configuration.rb +16 -0
- data/spec/unit/plugin/associates_spec.rb +5 -10
- data/spec/unit/plugin/pagination_spec.rb +9 -9
- data/spec/unit/plugin/timestamp_spec.rb +9 -9
- data/spec/unit/relation/dataset_spec.rb +7 -5
- data/spec/unit/relation/inner_join_spec.rb +2 -15
- data/spec/unit/relation/primary_key_spec.rb +1 -1
- data/spec/unit/schema_spec.rb +6 -4
- metadata +65 -70
- data/lib/rom/plugins/relation/sql/auto_combine.rb +0 -71
- data/lib/rom/plugins/relation/sql/auto_wrap.rb +0 -62
- data/lib/rom/sql/association.rb +0 -103
- data/lib/rom/sql/association/many_to_many.rb +0 -119
- data/lib/rom/sql/association/many_to_one.rb +0 -73
- data/lib/rom/sql/association/name.rb +0 -78
- data/lib/rom/sql/association/one_to_many.rb +0 -60
- data/lib/rom/sql/extensions/mysql/inferrer.rb +0 -10
- data/lib/rom/sql/qualified_attribute.rb +0 -53
- data/lib/rom/sql/schema/dsl.rb +0 -75
- data/spec/unit/association/many_to_many_spec.rb +0 -89
- data/spec/unit/association/many_to_one_spec.rb +0 -81
- data/spec/unit/association/name_spec.rb +0 -68
- data/spec/unit/association/one_to_many_spec.rb +0 -82
- data/spec/unit/association/one_to_one_spec.rb +0 -83
- data/spec/unit/association/one_to_one_through_spec.rb +0 -69
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff0be19f60330b9224eaf421b85ad113000c1558
|
4
|
+
data.tar.gz: 3ccb799110fbc7543f3e9ef9ebd511193c700ab6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe36e8c1a886f3231385d3ff9709aa11a4ad13b63b313ec5fd07fc76af0537327184bef102af03c66331750b76d0edfd7838e1ec4e02e8189ac56f91c7749203
|
7
|
+
data.tar.gz: 3192a10d465305f01d780e4db7af846c14c3c09509afb59f5cdad770383234ab59fc80b49431270aa863adeb7a51f7f3867a05c48cdfde084c7ed1ac1ea83a19
|
data/CHANGELOG.md
CHANGED
@@ -1,18 +1,24 @@
|
|
1
|
-
##
|
1
|
+
## v2.0.0 to-be-released
|
2
2
|
|
3
|
-
###
|
3
|
+
### Added
|
4
4
|
|
5
|
-
*
|
5
|
+
* Support for schema plugins (flash-gordon)
|
6
|
+
* Support for auto migrations (flash-gordon)
|
6
7
|
|
7
|
-
|
8
|
+
### Changed
|
8
9
|
|
9
|
-
|
10
|
+
* [BREAKING] based on rom 4.0 now
|
11
|
+
* [BREAKING] `Associates` command plugin requires associations now (solnic)
|
12
|
+
* `ManyToOne` no longer uses a join (solnic)
|
13
|
+
* `AutoCombine` and `AutoWrap` plugins were removed as this functionality is provided by core API (solnic)
|
10
14
|
|
11
15
|
### Fixed
|
12
16
|
|
13
|
-
*
|
17
|
+
* Self-ref associations work correctly with custom FKs (solnic)
|
18
|
+
* Aliased associations with custom FKs work correctly (solnic)
|
19
|
+
* Defining a custom dataset block no longer prevents default views like `by_pk` to be defined (solnic)
|
14
20
|
|
15
|
-
[Compare v1.3.3
|
21
|
+
[Compare v1.3.3...master](https://github.com/rom-rb/rom-sql/compare/v1.3.3...master)
|
16
22
|
|
17
23
|
## v1.3.3 2017-05-30
|
18
24
|
|
data/Gemfile
CHANGED
@@ -2,7 +2,13 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
gem '
|
5
|
+
gem 'dry-types', git: 'https://github.com/dry-rb/dry-types', branch: 'master'
|
6
|
+
|
7
|
+
gem 'rom', git: 'https://github.com/rom-rb/rom', branch: 'master' do
|
8
|
+
gem 'rom-core'
|
9
|
+
gem 'rom-mapper'
|
10
|
+
gem 'rom-repository', group: :tools
|
11
|
+
end
|
6
12
|
|
7
13
|
group :test do
|
8
14
|
gem 'pry-byebug', platforms: :mri
|
@@ -25,7 +31,3 @@ group :test do
|
|
25
31
|
gem 'jdbc-sqlite3', platforms: :jruby
|
26
32
|
gem 'ruby-oci8', platforms: :mri if ENV['ROM_USE_ORACLE']
|
27
33
|
end
|
28
|
-
|
29
|
-
group :tools do
|
30
|
-
gem 'rom-repository', git: 'https://github.com/rom-rb/rom-repository.git', branch: 'master'
|
31
|
-
end
|
@@ -1,12 +1,11 @@
|
|
1
|
+
require 'rom/support/notifications'
|
2
|
+
|
1
3
|
module ROM
|
2
4
|
module Plugins
|
3
5
|
module Relation
|
4
6
|
module SQL
|
5
7
|
# Generates methods for restricting relations by their indexed attributes
|
6
8
|
#
|
7
|
-
# This plugin must be enabled for the whole adapter, `use` won't work as
|
8
|
-
# schema is not yet available, unless it was defined explicitly.
|
9
|
-
#
|
10
9
|
# @example
|
11
10
|
# rom = ROM.container(:sql, 'sqlite::memory') do |config|
|
12
11
|
# config.create_table(:users) do
|
@@ -26,26 +25,21 @@ module ROM
|
|
26
25
|
#
|
27
26
|
# @api public
|
28
27
|
module AutoRestrictions
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
28
|
+
extend Notifications::Listener
|
29
|
+
|
30
|
+
subscribe('configuration.relations.schema.set', adapter: :sql) do |event|
|
31
|
+
schema = event[:schema]
|
32
|
+
relation = event[:relation]
|
35
33
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
raise EmptySchemaError, klass if schema.nil?
|
40
|
-
methods, mod = restriction_methods(schema)
|
41
|
-
klass.include(mod)
|
42
|
-
methods.each { |meth| klass.auto_curry(meth) }
|
34
|
+
methods, mod = AutoRestrictions.restriction_methods(schema)
|
35
|
+
relation.include(mod)
|
36
|
+
methods.each { |meth| relation.auto_curry(meth) }
|
43
37
|
end
|
44
38
|
|
45
39
|
def self.restriction_methods(schema)
|
46
40
|
mod = Module.new
|
47
41
|
|
48
|
-
indexed_attrs = schema.
|
42
|
+
indexed_attrs = schema.indexes.map { |index| index.attributes[0] }.uniq
|
49
43
|
|
50
44
|
methods = indexed_attrs.map do |attr|
|
51
45
|
meth_name = :"by_#{attr.name}"
|
data/lib/rom/sql.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require 'dry
|
1
|
+
require 'dry/equalizer'
|
2
2
|
require 'sequel'
|
3
|
-
require 'rom'
|
3
|
+
require 'rom/core'
|
4
4
|
|
5
5
|
require 'rom/sql/version'
|
6
6
|
require 'rom/sql/errors'
|
@@ -9,6 +9,7 @@ require 'rom/configuration_dsl'
|
|
9
9
|
|
10
10
|
require 'rom/sql/plugins'
|
11
11
|
require 'rom/sql/relation'
|
12
|
+
require 'rom/sql/associations'
|
12
13
|
require 'rom/sql/gateway'
|
13
14
|
require 'rom/sql/migration'
|
14
15
|
require 'rom/sql/extensions'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ROM
|
2
|
+
module SQL
|
3
|
+
module Associations
|
4
|
+
# Core SQL association API
|
5
|
+
#
|
6
|
+
# @api private
|
7
|
+
module Core
|
8
|
+
# @api private
|
9
|
+
def preload(target, loaded)
|
10
|
+
source_key, target_key = join_keys.flatten(1)
|
11
|
+
|
12
|
+
target_pks = loaded.pluck(source_key.key)
|
13
|
+
target_pks.uniq!
|
14
|
+
|
15
|
+
target.where(target_key => target_pks)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'rom/associations/many_to_many'
|
2
|
+
require 'rom/sql/associations/core'
|
3
|
+
|
4
|
+
module ROM
|
5
|
+
module SQL
|
6
|
+
module Associations
|
7
|
+
class ManyToMany < ROM::Associations::ManyToMany
|
8
|
+
include Associations::Core
|
9
|
+
|
10
|
+
# @api public
|
11
|
+
def call(target: self.target)
|
12
|
+
left = join_assoc.(target: target)
|
13
|
+
|
14
|
+
schema =
|
15
|
+
if left.schema.key?(foreign_key)
|
16
|
+
if target != self.target
|
17
|
+
target.schema.merge(join_schema)
|
18
|
+
else
|
19
|
+
left.schema.project(*columns)
|
20
|
+
end
|
21
|
+
else
|
22
|
+
target_schema
|
23
|
+
end.qualified
|
24
|
+
|
25
|
+
relation = left.join(source.name.dataset, join_keys)
|
26
|
+
|
27
|
+
if view
|
28
|
+
apply_view(schema, relation)
|
29
|
+
else
|
30
|
+
schema.(relation)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# @api public
|
35
|
+
def join(type, source = self.source, target = self.target)
|
36
|
+
through_assoc = source.associations[through]
|
37
|
+
joined = through_assoc.join(type, source)
|
38
|
+
joined.__send__(type, target.name.dataset, join_keys).qualified
|
39
|
+
end
|
40
|
+
|
41
|
+
# @api public
|
42
|
+
def join_keys
|
43
|
+
{ source_attr => target_attr }
|
44
|
+
end
|
45
|
+
|
46
|
+
# @api public
|
47
|
+
def source_attr
|
48
|
+
source[source_key].qualified
|
49
|
+
end
|
50
|
+
|
51
|
+
# @api public
|
52
|
+
def target_attr
|
53
|
+
join_relation[target_key].qualified
|
54
|
+
end
|
55
|
+
|
56
|
+
# @api private
|
57
|
+
def persist(children, parents)
|
58
|
+
join_tuples = associate(children, parents)
|
59
|
+
join_relation.multi_insert(join_tuples)
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
# @api private
|
65
|
+
def target_schema
|
66
|
+
target.schema.merge(join_schema)
|
67
|
+
end
|
68
|
+
|
69
|
+
# @api private
|
70
|
+
def join_schema
|
71
|
+
join_relation.schema.project(foreign_key)
|
72
|
+
end
|
73
|
+
|
74
|
+
# @api private
|
75
|
+
def columns
|
76
|
+
target_schema.map(&:name)
|
77
|
+
end
|
78
|
+
|
79
|
+
memoize :join_keys, :target_schema, :join_schema, :columns
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'rom/associations/many_to_one'
|
2
|
+
require 'rom/sql/associations/core'
|
3
|
+
require 'rom/sql/associations/self_ref'
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
module SQL
|
7
|
+
module Associations
|
8
|
+
class ManyToOne < ROM::Associations::ManyToOne
|
9
|
+
include Associations::Core
|
10
|
+
include Associations::SelfRef
|
11
|
+
|
12
|
+
# @api public
|
13
|
+
def call(target: self.target, preload: false)
|
14
|
+
if preload
|
15
|
+
schema = target.schema.qualified
|
16
|
+
relation = target
|
17
|
+
else
|
18
|
+
right = source
|
19
|
+
|
20
|
+
target_pk = target.schema.primary_key_name
|
21
|
+
right_fk = target.foreign_key(source.name)
|
22
|
+
|
23
|
+
target_schema = target.schema
|
24
|
+
right_schema = right.schema.project_pk
|
25
|
+
|
26
|
+
schema =
|
27
|
+
if target.schema.key?(right_fk)
|
28
|
+
target_schema
|
29
|
+
else
|
30
|
+
target_schema.merge(right_schema.project_fk(target_pk => right_fk))
|
31
|
+
end.qualified
|
32
|
+
|
33
|
+
relation = target.join(source_table, join_keys)
|
34
|
+
end
|
35
|
+
|
36
|
+
if view
|
37
|
+
apply_view(schema, relation)
|
38
|
+
else
|
39
|
+
schema.(relation)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# @api public
|
44
|
+
def join(type, source = self.source, target = self.target)
|
45
|
+
source.__send__(type, target.name.dataset, join_keys).qualified
|
46
|
+
end
|
47
|
+
|
48
|
+
# @api private
|
49
|
+
def prepare(target)
|
50
|
+
call(target: target, preload: true)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rom/associations/one_to_many'
|
2
|
+
require 'rom/sql/associations/core'
|
3
|
+
require 'rom/sql/associations/self_ref'
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
module SQL
|
7
|
+
module Associations
|
8
|
+
class OneToMany < ROM::Associations::OneToMany
|
9
|
+
include Associations::Core
|
10
|
+
include Associations::SelfRef
|
11
|
+
|
12
|
+
# @api public
|
13
|
+
def call(target: self.target)
|
14
|
+
schema = target.schema.qualified
|
15
|
+
relation = target.join(source_table, join_keys)
|
16
|
+
|
17
|
+
if view
|
18
|
+
apply_view(schema, relation)
|
19
|
+
else
|
20
|
+
schema.(relation)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# @api public
|
25
|
+
def join(type, source = self.source, target = self.target)
|
26
|
+
source.__send__(type, target.name.dataset, join_keys).qualified
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module ROM
|
2
|
+
module SQL
|
3
|
+
module Associations
|
4
|
+
module SelfRef
|
5
|
+
def self.included(klass)
|
6
|
+
super
|
7
|
+
klass.memoize :join_keys, :source_table, :source_alias, :source_attr, :target_attr
|
8
|
+
end
|
9
|
+
|
10
|
+
# @api public
|
11
|
+
def join_keys
|
12
|
+
{ source_attr => target_attr }
|
13
|
+
end
|
14
|
+
|
15
|
+
# @api public
|
16
|
+
def source_attr
|
17
|
+
source[source_key].qualified(source_alias)
|
18
|
+
end
|
19
|
+
|
20
|
+
# @api public
|
21
|
+
def target_attr
|
22
|
+
target[target_key].qualified
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
# @api private
|
28
|
+
def source_table
|
29
|
+
self_ref? ? Sequel.as(source.name.dataset, source_alias) : source.name.dataset
|
30
|
+
end
|
31
|
+
|
32
|
+
# @api private
|
33
|
+
def source_alias
|
34
|
+
self_ref? ? :"#{source.name.dataset.to_s[0]}_0" : source.name.dataset
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/rom/sql/attribute.rb
CHANGED
@@ -2,6 +2,8 @@ require 'sequel/core'
|
|
2
2
|
require 'dry/core/cache'
|
3
3
|
|
4
4
|
require 'rom/schema/attribute'
|
5
|
+
|
6
|
+
require 'rom/sql/type_extensions'
|
5
7
|
require 'rom/sql/projection_dsl'
|
6
8
|
|
7
9
|
module ROM
|
@@ -12,57 +14,11 @@ module ROM
|
|
12
14
|
class Attribute < ROM::Schema::Attribute
|
13
15
|
OPERATORS = %i[>= <= > <].freeze
|
14
16
|
NONSTANDARD_EQUALITY_VALUES = [true, false, nil].freeze
|
17
|
+
INDEXED = Set.new([true]).freeze
|
15
18
|
|
16
19
|
# Error raised when an attribute cannot be qualified
|
17
20
|
QualifyError = Class.new(StandardError)
|
18
21
|
|
19
|
-
# Type-specific methods
|
20
|
-
#
|
21
|
-
# @api public
|
22
|
-
module TypeExtensions
|
23
|
-
class << self
|
24
|
-
# Gets extensions for a type
|
25
|
-
#
|
26
|
-
# @param [Dry::Types::Type] type
|
27
|
-
#
|
28
|
-
# @return [Hash]
|
29
|
-
#
|
30
|
-
# @api public
|
31
|
-
def [](wrapped)
|
32
|
-
type = wrapped.default? ? wrapped.type : wrapped
|
33
|
-
type = type.optional? ? type.right : type
|
34
|
-
@types[type.meta[:database]][type.meta[:db_type]] || EMPTY_HASH
|
35
|
-
end
|
36
|
-
|
37
|
-
# Registers a set of operations supported for a specific type
|
38
|
-
#
|
39
|
-
# @example
|
40
|
-
# ROM::SQL::Attribute::TypeExtensions.register(ROM::SQL::Types::PG::JSONB) do
|
41
|
-
# def contain(type, expr, keys)
|
42
|
-
# Attribute[Types::Bool].meta(sql_expr: expr.pg_jsonb.contains(value))
|
43
|
-
# end
|
44
|
-
# end
|
45
|
-
#
|
46
|
-
# @param [Dry::Types::Type] type Type
|
47
|
-
#
|
48
|
-
# @api public
|
49
|
-
def register(type, &block)
|
50
|
-
extensions = @types[type.meta[:database]]
|
51
|
-
db_type = type.meta[:db_type]
|
52
|
-
|
53
|
-
raise ArgumentError, "Type #{ type } already registered" if @types.key?(type)
|
54
|
-
mod = Module.new(&block)
|
55
|
-
ctx = Object.new.extend(mod)
|
56
|
-
functions = mod.public_instance_methods.each_with_object({}) { |m, ms| ms[m] = ctx.method(m) }
|
57
|
-
extensions[db_type] = functions
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
@types = ::Hash.new do |hash, database|
|
62
|
-
hash[database] = {}
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
22
|
extend Dry::Core::Cache
|
67
23
|
|
68
24
|
# @api private
|
@@ -104,12 +60,12 @@ module ROM
|
|
104
60
|
# @return [SQL::Attribute]
|
105
61
|
#
|
106
62
|
# @api public
|
107
|
-
def qualified
|
63
|
+
def qualified(table_alias = nil)
|
108
64
|
return self if qualified?
|
109
65
|
|
110
66
|
case sql_expr
|
111
67
|
when Sequel::SQL::AliasedExpression, Sequel::SQL::Identifier
|
112
|
-
type = meta(qualified: true)
|
68
|
+
type = meta(qualified: table_alias || true)
|
113
69
|
type.meta(sql_expr: type.to_sql_name)
|
114
70
|
else
|
115
71
|
raise QualifyError, "can't qualify #{name.inspect} (#{sql_expr.inspect})"
|
@@ -155,7 +111,7 @@ module ROM
|
|
155
111
|
#
|
156
112
|
# @api public
|
157
113
|
def qualified?
|
158
|
-
meta[:qualified].equal?(true)
|
114
|
+
meta[:qualified].equal?(true) || meta[:qualified].is_a?(Symbol)
|
159
115
|
end
|
160
116
|
|
161
117
|
# Return a new attribute marked as a FK
|
@@ -188,9 +144,9 @@ module ROM
|
|
188
144
|
def to_sym
|
189
145
|
@_to_sym ||=
|
190
146
|
if qualified? && aliased?
|
191
|
-
:"#{
|
147
|
+
:"#{table_name}__#{name}___#{meta[:alias]}"
|
192
148
|
elsif qualified?
|
193
|
-
:"#{
|
149
|
+
:"#{table_name}__#{name}"
|
194
150
|
elsif aliased?
|
195
151
|
:"#{name}___#{meta[:alias]}"
|
196
152
|
else
|
@@ -319,9 +275,9 @@ module ROM
|
|
319
275
|
def to_sql_name
|
320
276
|
@_to_sql_name ||=
|
321
277
|
if qualified? && aliased?
|
322
|
-
Sequel.qualify(
|
278
|
+
Sequel.qualify(table_name, name).as(meta[:alias])
|
323
279
|
elsif qualified?
|
324
|
-
Sequel.qualify(
|
280
|
+
Sequel.qualify(table_name, name)
|
325
281
|
elsif aliased?
|
326
282
|
Sequel.as(name, meta[:alias])
|
327
283
|
else
|
@@ -329,6 +285,27 @@ module ROM
|
|
329
285
|
end
|
330
286
|
end
|
331
287
|
|
288
|
+
# @api public
|
289
|
+
def indexed?
|
290
|
+
!indexes.empty?
|
291
|
+
end
|
292
|
+
|
293
|
+
# @api public
|
294
|
+
def indexes
|
295
|
+
if meta[:index] == true
|
296
|
+
INDEXED
|
297
|
+
else
|
298
|
+
meta[:index] || EMPTY_SET
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
# @api private
|
303
|
+
def meta_ast
|
304
|
+
meta = super
|
305
|
+
meta[:index] = indexes if indexed?
|
306
|
+
meta
|
307
|
+
end
|
308
|
+
|
332
309
|
private
|
333
310
|
|
334
311
|
# Return Sequel Expression object for an attribute
|
@@ -372,6 +349,19 @@ module ROM
|
|
372
349
|
type[value]
|
373
350
|
end
|
374
351
|
end
|
352
|
+
|
353
|
+
# Return source table name or its alias
|
354
|
+
#
|
355
|
+
# @api private
|
356
|
+
def table_name
|
357
|
+
if qualified? && meta[:qualified].is_a?(Symbol)
|
358
|
+
meta[:qualified]
|
359
|
+
else
|
360
|
+
source.dataset
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
memoize :joined, :to_sql_name, :table_name, :canonical
|
375
365
|
end
|
376
366
|
end
|
377
367
|
end
|