rom-sql 0.9.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/.travis.yml +1 -1
- data/CHANGELOG.md +32 -0
- data/Gemfile +4 -1
- data/lib/rom/plugins/relation/sql/auto_wrap.rb +1 -3
- data/lib/rom/sql/association.rb +33 -14
- data/lib/rom/sql/association/many_to_many.rb +17 -10
- data/lib/rom/sql/association/many_to_one.rb +29 -13
- data/lib/rom/sql/association/name.rb +12 -4
- data/lib/rom/sql/association/one_to_many.rb +21 -10
- data/lib/rom/sql/commands/create.rb +0 -1
- data/lib/rom/sql/commands/update.rb +1 -49
- data/lib/rom/sql/dsl.rb +29 -0
- data/lib/rom/sql/expression.rb +26 -0
- data/lib/rom/sql/function.rb +23 -0
- data/lib/rom/sql/gateway.rb +24 -9
- data/lib/rom/sql/migration.rb +6 -7
- data/lib/rom/sql/migration/migrator.rb +7 -8
- data/lib/rom/sql/order_dsl.rb +20 -0
- data/lib/rom/sql/plugin/associates.rb +58 -45
- data/lib/rom/sql/plugin/pagination.rb +8 -11
- data/lib/rom/sql/plugins.rb +0 -2
- data/lib/rom/sql/projection_dsl.rb +41 -0
- data/lib/rom/sql/qualified_attribute.rb +2 -2
- data/lib/rom/sql/relation.rb +35 -67
- data/lib/rom/sql/relation/reading.rb +77 -25
- data/lib/rom/sql/restriction_dsl.rb +24 -0
- data/lib/rom/sql/schema.rb +73 -7
- data/lib/rom/sql/schema/associations_dsl.rb +4 -3
- data/lib/rom/sql/schema/dsl.rb +5 -2
- data/lib/rom/sql/schema/inferrer.rb +21 -11
- data/lib/rom/sql/transaction.rb +19 -0
- data/lib/rom/sql/type.rb +76 -0
- data/lib/rom/sql/version.rb +1 -1
- data/rom-sql.gemspec +3 -4
- data/spec/extensions/postgres/inferrer_spec.rb +19 -9
- data/spec/integration/association/many_to_many/custom_fks_spec.rb +73 -0
- data/spec/integration/association/many_to_many/from_view_spec.rb +81 -0
- data/spec/integration/association/many_to_many_spec.rb +2 -2
- data/spec/integration/association/many_to_one/custom_fks_spec.rb +59 -0
- data/spec/integration/association/many_to_one/from_view_spec.rb +74 -0
- data/spec/integration/association/many_to_one/self_ref_spec.rb +51 -0
- data/spec/integration/association/many_to_one_spec.rb +4 -2
- data/spec/integration/association/one_to_many/custom_fks_spec.rb +48 -0
- data/spec/integration/association/one_to_many/from_view_spec.rb +57 -0
- data/spec/integration/association/one_to_many/self_ref_spec.rb +52 -0
- data/spec/integration/association/one_to_many_spec.rb +1 -1
- data/spec/integration/association/one_to_one_spec.rb +1 -1
- data/spec/integration/association/one_to_one_through_spec.rb +2 -2
- data/spec/integration/commands/create_spec.rb +11 -27
- data/spec/integration/commands/update_spec.rb +54 -109
- data/spec/integration/gateway_spec.rb +31 -17
- data/spec/integration/plugins/associates_spec.rb +27 -0
- data/spec/integration/plugins/auto_wrap_spec.rb +8 -8
- data/spec/integration/schema/call_spec.rb +24 -0
- data/spec/integration/schema/prefix_spec.rb +18 -0
- data/spec/integration/schema/qualified_spec.rb +18 -0
- data/spec/integration/schema/rename_spec.rb +23 -0
- data/spec/integration/schema/view_spec.rb +29 -0
- data/spec/integration/schema_inference_spec.rb +31 -14
- data/spec/spec_helper.rb +2 -2
- data/spec/support/helpers.rb +7 -0
- data/spec/unit/gateway_spec.rb +5 -4
- data/spec/unit/projection_dsl_spec.rb +54 -0
- data/spec/unit/relation/dataset_spec.rb +3 -3
- data/spec/unit/relation/distinct_spec.rb +8 -7
- data/spec/unit/relation/exclude_spec.rb +2 -4
- data/spec/unit/relation/having_spec.rb +6 -4
- data/spec/unit/relation/inner_join_spec.rb +47 -2
- data/spec/unit/relation/invert_spec.rb +2 -3
- data/spec/unit/relation/left_join_spec.rb +44 -3
- data/spec/unit/relation/order_spec.rb +40 -0
- data/spec/unit/relation/prefix_spec.rb +2 -0
- data/spec/unit/relation/project_spec.rb +3 -1
- data/spec/unit/relation/qualified_columns_spec.rb +2 -0
- data/spec/unit/relation/rename_spec.rb +2 -0
- data/spec/unit/relation/right_join_spec.rb +59 -0
- data/spec/unit/relation/select_append_spec.rb +21 -0
- data/spec/unit/relation/select_spec.rb +41 -0
- data/spec/unit/relation/where_spec.rb +28 -0
- data/spec/unit/restriction_dsl_spec.rb +34 -0
- metadata +62 -40
- data/lib/rom/plugins/relation/sql/base_view.rb +0 -31
- data/lib/rom/sql/header.rb +0 -61
- data/lib/rom/sql/plugin/assoc_macros.rb +0 -133
- data/lib/rom/sql/plugin/assoc_macros/class_interface.rb +0 -128
- data/spec/integration/read_spec.rb +0 -111
- data/spec/unit/association_errors_spec.rb +0 -19
- data/spec/unit/plugin/assoc_macros/combined_associations_spec.rb +0 -73
- data/spec/unit/plugin/assoc_macros/many_to_many_spec.rb +0 -53
- data/spec/unit/plugin/assoc_macros/many_to_one_spec.rb +0 -61
- data/spec/unit/plugin/assoc_macros/one_to_many_spec.rb +0 -78
- data/spec/unit/plugin/base_view_spec.rb +0 -18
data/lib/rom/sql/dsl.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module ROM
|
2
|
+
module SQL
|
3
|
+
class DSL < BasicObject
|
4
|
+
# @api private
|
5
|
+
attr_reader :schema
|
6
|
+
|
7
|
+
# @api private
|
8
|
+
def initialize(schema)
|
9
|
+
@schema = schema
|
10
|
+
end
|
11
|
+
|
12
|
+
# @api private
|
13
|
+
def call(&block)
|
14
|
+
result = instance_exec(&block)
|
15
|
+
|
16
|
+
if result.is_a?(::Array)
|
17
|
+
result
|
18
|
+
else
|
19
|
+
[result]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# @api private
|
24
|
+
def respond_to_missing?(name, include_private = false)
|
25
|
+
super || schema.key?(name)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ROM
|
2
|
+
module SQL
|
3
|
+
class Expression
|
4
|
+
attr_reader :expr, :type
|
5
|
+
|
6
|
+
def initialize(type, expr = type.sql_expr)
|
7
|
+
@type = type
|
8
|
+
@expr = expr
|
9
|
+
end
|
10
|
+
|
11
|
+
def sql_literal(ds)
|
12
|
+
expr.sql_literal(ds)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def method_missing(meth, *args, &block)
|
18
|
+
if type.respond_to?(meth)
|
19
|
+
self.class.new(type.__send__(meth, *args, &block))
|
20
|
+
else
|
21
|
+
self.class.new(type, expr.__send__(meth, *args, &block))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ROM
|
2
|
+
module SQL
|
3
|
+
class Function < ROM::Schema::Type
|
4
|
+
def as(name)
|
5
|
+
meta(name: name)
|
6
|
+
end
|
7
|
+
|
8
|
+
def sql_literal(ds)
|
9
|
+
func.as(name).sql_literal(ds)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def func
|
15
|
+
Sequel::SQL::Function.new(meta[:op], *meta[:args])
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing(op, *args)
|
19
|
+
meta(op: op, args: args)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/rom/sql/gateway.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
require 'logger'
|
2
2
|
|
3
|
+
require 'dry/core/constants'
|
4
|
+
|
5
|
+
require 'rom/types'
|
3
6
|
require 'rom/gateway'
|
4
7
|
require 'rom/sql/migration'
|
5
8
|
require 'rom/sql/commands'
|
9
|
+
require 'rom/sql/transaction'
|
6
10
|
|
7
11
|
module ROM
|
8
12
|
module SQL
|
@@ -16,7 +20,7 @@ module ROM
|
|
16
20
|
#
|
17
21
|
# @api public
|
18
22
|
class Gateway < ROM::Gateway
|
19
|
-
include
|
23
|
+
include Dry::Core::Constants
|
20
24
|
include Migration
|
21
25
|
|
22
26
|
class << self
|
@@ -24,7 +28,7 @@ module ROM
|
|
24
28
|
end
|
25
29
|
|
26
30
|
CONNECTION_EXTENSIONS = {
|
27
|
-
postgres: %i(pg_array pg_json)
|
31
|
+
postgres: %i(pg_array pg_json pg_enum)
|
28
32
|
}.freeze
|
29
33
|
|
30
34
|
# Return optionally configured logger
|
@@ -34,6 +38,9 @@ module ROM
|
|
34
38
|
# @api public
|
35
39
|
attr_reader :logger
|
36
40
|
|
41
|
+
# @api private
|
42
|
+
attr_reader :options
|
43
|
+
|
37
44
|
# SQL gateway interface
|
38
45
|
#
|
39
46
|
# @overload connect(uri, options)
|
@@ -55,14 +62,13 @@ module ROM
|
|
55
62
|
# gateway = ROM::SQL::Gateway.new(DB)
|
56
63
|
#
|
57
64
|
# @api public
|
58
|
-
def initialize(uri, options =
|
59
|
-
|
60
|
-
conn_options = options.reject { |k, _| repo_options.include?(k) }
|
61
|
-
|
62
|
-
@connection = connect(uri, conn_options)
|
65
|
+
def initialize(uri, options = EMPTY_HASH)
|
66
|
+
@connection = connect(uri, options)
|
63
67
|
load_extensions(Array(options[:extensions]))
|
64
68
|
|
65
|
-
|
69
|
+
@options = options
|
70
|
+
|
71
|
+
super
|
66
72
|
|
67
73
|
self.class.instance = self
|
68
74
|
end
|
@@ -191,8 +197,17 @@ module ROM
|
|
191
197
|
ROM::SQL.load_extensions(db_type)
|
192
198
|
end
|
193
199
|
|
194
|
-
extensions = (CONNECTION_EXTENSIONS.fetch(db_type)
|
200
|
+
extensions = (CONNECTION_EXTENSIONS.fetch(db_type, EMPTY_ARRAY) + exts).uniq
|
195
201
|
connection.extension(*extensions)
|
202
|
+
|
203
|
+
# this will be default in Sequel 5.0.0 and since we don't rely
|
204
|
+
# on dataset mutation it is safe to enable it already
|
205
|
+
connection.extension(:freeze_datasets) unless RUBY_ENGINE == 'rbx'
|
206
|
+
end
|
207
|
+
|
208
|
+
# @api private
|
209
|
+
def transaction_runner(_)
|
210
|
+
ROM::SQL::Transaction.new(connection)
|
196
211
|
end
|
197
212
|
end
|
198
213
|
end
|
data/lib/rom/sql/migration.rb
CHANGED
@@ -30,13 +30,12 @@ module ROM
|
|
30
30
|
module Migration
|
31
31
|
Sequel.extension :migration
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
33
|
+
# @api public
|
34
|
+
attr_reader :migrator
|
35
|
+
|
36
|
+
# @api private
|
37
|
+
def initialize(uri, options = EMPTY_HASH)
|
38
|
+
@migrator = options.fetch(:migrator) { Migrator.new(connection) }
|
40
39
|
end
|
41
40
|
|
42
41
|
# @see ROM::SQL::Migration.pending?
|
@@ -1,20 +1,19 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'rom/types'
|
3
|
+
require 'rom/initializer'
|
4
|
+
|
1
5
|
module ROM
|
2
6
|
module SQL
|
3
7
|
module Migration
|
4
8
|
class Migrator
|
5
|
-
|
9
|
+
extend Initializer
|
6
10
|
|
7
11
|
DEFAULT_PATH = 'db/migrate'.freeze
|
8
12
|
VERSION_FORMAT = '%Y%m%d%H%M%S'.freeze
|
9
13
|
|
10
|
-
|
11
|
-
|
12
|
-
attr_reader :connection
|
14
|
+
param :connection
|
13
15
|
|
14
|
-
|
15
|
-
super
|
16
|
-
@connection = connection
|
17
|
-
end
|
16
|
+
option :path, type: ROM::Types.Definition(Pathname), reader: true, default: proc { DEFAULT_PATH }
|
18
17
|
|
19
18
|
def run(options = {})
|
20
19
|
Sequel::Migrator.run(connection, path.to_s, options)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rom/sql/dsl'
|
2
|
+
require 'rom/sql/expression'
|
3
|
+
|
4
|
+
module ROM
|
5
|
+
module SQL
|
6
|
+
class OrderDSL < DSL
|
7
|
+
private
|
8
|
+
|
9
|
+
# @api private
|
10
|
+
def method_missing(meth, *args, &block)
|
11
|
+
if schema.key?(meth)
|
12
|
+
attr = schema[meth]
|
13
|
+
::ROM::SQL::Expression.new(schema[meth])
|
14
|
+
else
|
15
|
+
::Sequel::VIRTUAL_ROW.__send__(meth, *args, &block)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'rom/support/deprecations'
|
2
|
-
|
3
1
|
module ROM
|
4
2
|
module SQL
|
5
3
|
module Plugin
|
@@ -9,51 +7,38 @@ module ROM
|
|
9
7
|
module Associates
|
10
8
|
# @api private
|
11
9
|
def self.included(klass)
|
12
|
-
klass.
|
13
|
-
|
14
|
-
|
10
|
+
klass.class_eval do
|
11
|
+
extend ClassMethods
|
12
|
+
include InstanceMethods
|
13
|
+
defines :associations
|
15
14
|
|
16
|
-
|
17
|
-
attr_reader :assoc, :__registry__
|
15
|
+
associations []
|
18
16
|
|
19
|
-
|
20
|
-
def initialize(*)
|
21
|
-
super
|
22
|
-
@__registry__ = relation.__registry__
|
23
|
-
assoc_name, assoc_opts = self.class.associations[0]
|
24
|
-
@assoc =
|
25
|
-
if assoc_opts.any?
|
26
|
-
assoc_opts[:key]
|
27
|
-
else
|
28
|
-
relation.associations[assoc_name]
|
29
|
-
end
|
17
|
+
option :associations, reader: true, optional: true, default: -> cmd { cmd.class.associations }
|
30
18
|
end
|
19
|
+
super
|
20
|
+
end
|
31
21
|
|
22
|
+
module InstanceMethods
|
32
23
|
# Set fk on tuples from parent tuple
|
33
24
|
#
|
34
25
|
# @param [Array<Hash>, Hash] tuples The input tuple(s)
|
35
26
|
# @param [Hash] parent The parent tuple with its pk already set
|
36
27
|
#
|
37
|
-
# @return [Array<Hash
|
38
|
-
#
|
39
|
-
# @overload SQL::Commands::Create#execute
|
28
|
+
# @return [Array<Hash>]
|
40
29
|
#
|
41
30
|
# @api public
|
42
|
-
def
|
31
|
+
def associate(tuples, parent, assoc:, keys:)
|
43
32
|
input_tuples =
|
44
33
|
case assoc
|
45
|
-
when
|
46
|
-
fk, pk =
|
34
|
+
when Symbol
|
35
|
+
fk, pk = keys
|
47
36
|
|
48
|
-
|
37
|
+
with_input_tuples(tuples).map { |tuple|
|
49
38
|
tuple.merge(fk => parent.fetch(pk))
|
50
39
|
}
|
51
|
-
|
52
|
-
super(input_tuples)
|
53
40
|
when Association::ManyToMany
|
54
|
-
|
55
|
-
|
56
|
-
join_tuples = assoc.associate(__registry__, new_tuples, parent)
|
41
|
+
join_tuples = assoc.associate(__registry__, tuples, parent)
|
57
42
|
join_relation = assoc.join_relation(__registry__)
|
58
43
|
join_relation.multi_insert(join_tuples)
|
59
44
|
|
@@ -63,22 +48,54 @@ module ROM
|
|
63
48
|
|
64
49
|
pk_extend = { fk => parent[pk] }
|
65
50
|
|
66
|
-
|
51
|
+
tuples.map { |tuple| tuple.update(pk_extend) }
|
67
52
|
when Association
|
68
|
-
|
53
|
+
with_input_tuples(tuples).map { |tuple|
|
69
54
|
assoc.associate(relation.__registry__, tuple, parent)
|
70
55
|
}
|
71
|
-
super(input_tuples)
|
72
56
|
end
|
73
57
|
end
|
58
|
+
|
59
|
+
# @api public
|
60
|
+
def with_association(name, opts = EMPTY_HASH)
|
61
|
+
self.class.build(relation, options.merge(associations: [[name, opts]]))
|
62
|
+
end
|
63
|
+
|
64
|
+
# @api private
|
65
|
+
def __registry__
|
66
|
+
relation.__registry__
|
67
|
+
end
|
74
68
|
end
|
75
69
|
|
76
70
|
module ClassMethods
|
77
|
-
# @
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
super
|
71
|
+
# @see ROM::Command::ClassInterface.build
|
72
|
+
#
|
73
|
+
# @api public
|
74
|
+
def build(relation, options = EMPTY_HASH)
|
75
|
+
command = super
|
76
|
+
associations = command.associations
|
77
|
+
|
78
|
+
before_hooks = associations.each_with_object([]) do |(name, opts), acc|
|
79
|
+
relation.associations.try(name) do |assoc|
|
80
|
+
unless assoc.is_a?(Association::ManyToMany)
|
81
|
+
acc << { associate: { assoc: assoc, keys: assoc.join_keys(relation.__registry__) } }
|
82
|
+
else
|
83
|
+
true
|
84
|
+
end
|
85
|
+
end or acc << { associate: { assoc: name, keys: opts[:key] } }
|
86
|
+
end
|
87
|
+
|
88
|
+
after_hooks = associations.each_with_object([]) do |(name, opts), acc|
|
89
|
+
next unless relation.associations.key?(name)
|
90
|
+
|
91
|
+
assoc = relation.associations[name]
|
92
|
+
|
93
|
+
if assoc.is_a?(Association::ManyToMany)
|
94
|
+
acc << { associate: { assoc: assoc, keys: assoc.join_keys(relation.__registry__) } }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
command.before(*before_hooks).after(*after_hooks)
|
82
99
|
end
|
83
100
|
|
84
101
|
# Set command to associate tuples with a parent tuple using provided keys
|
@@ -102,17 +119,13 @@ module ROM
|
|
102
119
|
# @option options [Array] :key The association keys
|
103
120
|
#
|
104
121
|
# @api public
|
105
|
-
def associates(name, options =
|
122
|
+
def associates(name, options = EMPTY_HASH)
|
106
123
|
if associations.map(&:first).include?(name)
|
107
124
|
raise ArgumentError,
|
108
|
-
|
125
|
+
"#{name} association is already defined for #{self.class}"
|
109
126
|
end
|
110
127
|
|
111
|
-
|
112
|
-
|
113
|
-
include InstanceMethods
|
114
|
-
|
115
|
-
associations << [name, options]
|
128
|
+
associations(associations.dup << [name, options])
|
116
129
|
end
|
117
130
|
end
|
118
131
|
end
|
@@ -1,20 +1,17 @@
|
|
1
|
+
require 'rom/initializer'
|
2
|
+
|
1
3
|
module ROM
|
2
4
|
module SQL
|
3
5
|
module Plugin
|
4
6
|
module Pagination
|
5
7
|
class Pager
|
6
|
-
|
8
|
+
extend Initializer
|
7
9
|
include Dry::Equalizer(:dataset, :options)
|
8
10
|
|
9
|
-
|
10
|
-
option :per_page, reader: true
|
11
|
-
|
12
|
-
attr_reader :dataset
|
11
|
+
param :dataset
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
@dataset = dataset
|
17
|
-
end
|
13
|
+
option :current_page, reader: true, default: proc { 1 }
|
14
|
+
option :per_page, reader: true
|
18
15
|
|
19
16
|
def next_page
|
20
17
|
num = current_page + 1
|
@@ -71,7 +68,7 @@ module ROM
|
|
71
68
|
# @api public
|
72
69
|
def page(num)
|
73
70
|
next_pager = pager.at(dataset, num)
|
74
|
-
|
71
|
+
new(next_pager.dataset, pager: next_pager)
|
75
72
|
end
|
76
73
|
|
77
74
|
# Set limit for pagination
|
@@ -82,7 +79,7 @@ module ROM
|
|
82
79
|
# @api public
|
83
80
|
def per_page(num)
|
84
81
|
next_pager = pager.at(dataset, pager.current_page, num)
|
85
|
-
|
82
|
+
new(next_pager.dataset, pager: next_pager)
|
86
83
|
end
|
87
84
|
end
|
88
85
|
end
|
data/lib/rom/sql/plugins.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
|
-
require 'rom/sql/plugin/assoc_macros'
|
2
1
|
require 'rom/sql/plugin/associates'
|
3
2
|
require 'rom/sql/plugin/pagination'
|
4
3
|
|
5
4
|
ROM.plugins do
|
6
5
|
adapter :sql do
|
7
|
-
register :assoc_macros, ROM::SQL::Plugin::AssocMacros, type: :relation
|
8
6
|
register :pagination, ROM::SQL::Plugin::Pagination, type: :relation
|
9
7
|
register :associates, ROM::SQL::Plugin::Associates, type: :command
|
10
8
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rom/sql/dsl'
|
2
|
+
require 'rom/sql/function'
|
3
|
+
|
4
|
+
module ROM
|
5
|
+
module SQL
|
6
|
+
class ProjectionDSL < DSL
|
7
|
+
# @api private
|
8
|
+
def respond_to_missing?(name, include_private = false)
|
9
|
+
super || type(name)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
# @api private
|
15
|
+
def type(identifier)
|
16
|
+
type_name = ::Dry::Core::Inflector.classify(identifier)
|
17
|
+
types.const_get(type_name) if types.const_defined?(type_name)
|
18
|
+
end
|
19
|
+
|
20
|
+
# @api private
|
21
|
+
def types
|
22
|
+
::ROM::SQL::Types
|
23
|
+
end
|
24
|
+
|
25
|
+
# @api private
|
26
|
+
def method_missing(meth, *args, &block)
|
27
|
+
if schema.key?(meth)
|
28
|
+
schema[meth]
|
29
|
+
else
|
30
|
+
type = type(meth)
|
31
|
+
|
32
|
+
if type
|
33
|
+
::ROM::SQL::Function.new(type)
|
34
|
+
else
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|