rom-sql 1.0.0.beta1 → 1.0.0.beta2
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 +1 -0
- data/lib/rom/sql/function.rb +15 -7
- data/lib/rom/sql/order_dsl.rb +1 -3
- data/lib/rom/sql/relation.rb +1 -19
- data/lib/rom/sql/restriction_dsl.rb +1 -2
- data/lib/rom/sql/schema/inferrer.rb +15 -2
- data/lib/rom/sql/type.rb +22 -2
- data/lib/rom/sql/version.rb +1 -1
- data/spec/integration/schema_inference_spec.rb +9 -1
- data/spec/support/helpers.rb +2 -1
- data/spec/unit/projection_dsl_spec.rb +43 -3
- data/spec/unit/restriction_dsl_spec.rb +2 -2
- metadata +2 -3
- data/lib/rom/sql/expression.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 240c81ee43a6d5edfbf9b599d7a031196a686978
|
4
|
+
data.tar.gz: 6abdfcd3fdeef06cbbf0794dbb0ebbde658e043e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cdfd38e021013963c48d176d44f7872dd737728254ad066b03a13ded7c90553fd6017651300bd169a6231841f4386e57ce8eb58275c3218b70938a13e42d56cf
|
7
|
+
data.tar.gz: 81459e9c88292c2c37218074ab7adf37070852455604829d95cf360bb12565aca97b6b782bbd1f88b0466b86b73421d9ce05157f008246bcd7d278092e196535
|
data/CHANGELOG.md
CHANGED
@@ -21,6 +21,7 @@ Please refer to [the upgrading guide](https://github.com/rom-rb/rom-sql/wiki/Upg
|
|
21
21
|
|
22
22
|
* [BREAKING] `Relation#header` has been removed in favor of schemas (solnic)
|
23
23
|
* [BREAKING] `Relation#base` has been removed as now a vanilla relation *is a base relation view* (solnic)
|
24
|
+
* [BREAKING] Deprecated `Relation.primary_key` has been removed in favor of schema (solnic)
|
24
25
|
* [BREAKING] Deprecated `Commands::Update#change` has been removed (solnic)
|
25
26
|
* [BREAKING] Deprecated `Commands.validator` has been removed (solnic)
|
26
27
|
* [BREAKING] `assoc_macros` plugin has been removed, please use associations from now (solnic)
|
data/lib/rom/sql/function.rb
CHANGED
@@ -1,22 +1,30 @@
|
|
1
1
|
module ROM
|
2
2
|
module SQL
|
3
3
|
class Function < ROM::Schema::Type
|
4
|
-
def
|
5
|
-
|
4
|
+
def sql_literal(ds)
|
5
|
+
if name
|
6
|
+
func.as(name).sql_literal(ds)
|
7
|
+
else
|
8
|
+
func.sql_literal(ds)
|
9
|
+
end
|
6
10
|
end
|
7
11
|
|
8
|
-
def
|
9
|
-
|
12
|
+
def name
|
13
|
+
meta[:alias] || super
|
10
14
|
end
|
11
15
|
|
12
16
|
private
|
13
17
|
|
14
18
|
def func
|
15
|
-
|
19
|
+
meta[:func]
|
16
20
|
end
|
17
21
|
|
18
|
-
def method_missing(
|
19
|
-
|
22
|
+
def method_missing(meth, *args)
|
23
|
+
if func && func.respond_to?(meth)
|
24
|
+
meta(func: func.__send__(meth, *args))
|
25
|
+
else
|
26
|
+
meta(func: Sequel::SQL::Function.new(meth.to_s.upcase, *args))
|
27
|
+
end
|
20
28
|
end
|
21
29
|
end
|
22
30
|
end
|
data/lib/rom/sql/order_dsl.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'rom/sql/dsl'
|
2
|
-
require 'rom/sql/expression'
|
3
2
|
|
4
3
|
module ROM
|
5
4
|
module SQL
|
@@ -9,8 +8,7 @@ module ROM
|
|
9
8
|
# @api private
|
10
9
|
def method_missing(meth, *args, &block)
|
11
10
|
if schema.key?(meth)
|
12
|
-
|
13
|
-
::ROM::SQL::Expression.new(schema[meth])
|
11
|
+
schema[meth]
|
14
12
|
else
|
15
13
|
::Sequel::VIRTUAL_ROW.__send__(meth, *args, &block)
|
16
14
|
end
|
data/lib/rom/sql/relation.rb
CHANGED
@@ -8,8 +8,6 @@ require 'rom/plugins/relation/key_inference'
|
|
8
8
|
require 'rom/plugins/relation/sql/auto_combine'
|
9
9
|
require 'rom/plugins/relation/sql/auto_wrap'
|
10
10
|
|
11
|
-
require 'dry/core/deprecations'
|
12
|
-
|
13
11
|
module ROM
|
14
12
|
module SQL
|
15
13
|
# Sequel-specific relation extensions
|
@@ -88,23 +86,7 @@ module ROM
|
|
88
86
|
names.map { |col| :"#{table}__#{col}" }
|
89
87
|
end
|
90
88
|
|
91
|
-
|
92
|
-
#
|
93
|
-
# @deprecated
|
94
|
-
#
|
95
|
-
# @api public
|
96
|
-
def self.primary_key(value)
|
97
|
-
Dry::Core::Deprecations.announce(
|
98
|
-
:primary_key,
|
99
|
-
"use schema definition to configure primary key",
|
100
|
-
tag: :rom
|
101
|
-
)
|
102
|
-
option :primary_key, reader: true, default: value
|
103
|
-
end
|
104
|
-
|
105
|
-
option :primary_key, reader: true, default: -> rel {
|
106
|
-
rel.schema? ? rel.schema.primary_key_name : :id
|
107
|
-
}
|
89
|
+
option :primary_key, reader: true, default: -> rel { rel.schema.primary_key_name }
|
108
90
|
|
109
91
|
# Return raw column names
|
110
92
|
#
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'rom/sql/dsl'
|
2
|
-
require 'rom/sql/expression'
|
3
2
|
|
4
3
|
module ROM
|
5
4
|
module SQL
|
@@ -14,7 +13,7 @@ module ROM
|
|
14
13
|
# @api private
|
15
14
|
def method_missing(meth, *args, &block)
|
16
15
|
if schema.key?(meth)
|
17
|
-
|
16
|
+
schema[meth]
|
18
17
|
else
|
19
18
|
::Sequel::VIRTUAL_ROW.__send__(meth, *args, &block)
|
20
19
|
end
|
@@ -12,6 +12,7 @@ module ROM
|
|
12
12
|
ruby_type_mapping(
|
13
13
|
integer: Types::Int,
|
14
14
|
string: Types::String,
|
15
|
+
time: Types::Time,
|
15
16
|
date: Types::Date,
|
16
17
|
datetime: Types::Time,
|
17
18
|
boolean: Types::Bool,
|
@@ -24,6 +25,8 @@ module ROM
|
|
24
25
|
|
25
26
|
db_registry Hash.new(self)
|
26
27
|
|
28
|
+
CONSTRAINT_DB_TYPE = 'add_constraint'.freeze
|
29
|
+
|
27
30
|
def self.inherited(klass)
|
28
31
|
super
|
29
32
|
|
@@ -42,7 +45,7 @@ module ROM
|
|
42
45
|
def call(source, gateway)
|
43
46
|
dataset = source.dataset
|
44
47
|
|
45
|
-
columns = gateway.connection.schema(dataset)
|
48
|
+
columns = filter_columns(gateway.connection.schema(dataset))
|
46
49
|
fks = fks_for(gateway, dataset)
|
47
50
|
|
48
51
|
inferred = columns.map do |(name, definition)|
|
@@ -58,6 +61,10 @@ module ROM
|
|
58
61
|
|
59
62
|
private
|
60
63
|
|
64
|
+
def filter_columns(schema)
|
65
|
+
schema.reject { |(_, definition)| definition[:db_type] == CONSTRAINT_DB_TYPE }
|
66
|
+
end
|
67
|
+
|
61
68
|
def build_type(primary_key:, db_type:, type:, allow_null:, foreign_key:, **rest)
|
62
69
|
if primary_key
|
63
70
|
map_pk_type(type, db_type)
|
@@ -77,7 +84,13 @@ module ROM
|
|
77
84
|
end
|
78
85
|
|
79
86
|
def map_type(ruby_type, db_type, **_kw)
|
80
|
-
self.class.ruby_type_mapping[ruby_type]
|
87
|
+
type = self.class.ruby_type_mapping[ruby_type]
|
88
|
+
|
89
|
+
if db_type.is_a?(String) && db_type.include?('numeric') || db_type.include?('decimal')
|
90
|
+
self.class.ruby_type_mapping[:decimal]
|
91
|
+
else
|
92
|
+
type
|
93
|
+
end
|
81
94
|
end
|
82
95
|
|
83
96
|
# @api private
|
data/lib/rom/sql/type.rb
CHANGED
@@ -12,6 +12,11 @@ module ROM
|
|
12
12
|
meta(foreign_key: true)
|
13
13
|
end
|
14
14
|
|
15
|
+
# @api public
|
16
|
+
def as(name)
|
17
|
+
super.meta(sql_expr: sql_expr.as(name))
|
18
|
+
end
|
19
|
+
|
15
20
|
# Return a new type marked as qualified
|
16
21
|
#
|
17
22
|
# @return [SQL::Type]
|
@@ -64,12 +69,27 @@ module ROM
|
|
64
69
|
|
65
70
|
# @api private
|
66
71
|
def sql_literal(ds)
|
67
|
-
sql_expr
|
72
|
+
if sql_expr
|
73
|
+
sql_expr.sql_literal(ds)
|
74
|
+
else
|
75
|
+
Sequel[to_sym].sql_literal(ds)
|
76
|
+
end
|
68
77
|
end
|
69
78
|
|
79
|
+
private
|
80
|
+
|
70
81
|
# @api private
|
71
82
|
def sql_expr
|
72
|
-
Sequel
|
83
|
+
@sql_expr ||= (meta[:sql_expr] || Sequel[to_sym])
|
84
|
+
end
|
85
|
+
|
86
|
+
# @api private
|
87
|
+
def method_missing(meth, *args, &block)
|
88
|
+
if sql_expr.respond_to?(meth)
|
89
|
+
meta(sql_expr: sql_expr.__send__(meth, *args, &block))
|
90
|
+
else
|
91
|
+
super
|
92
|
+
end
|
73
93
|
end
|
74
94
|
end
|
75
95
|
end
|
data/lib/rom/sql/version.rb
CHANGED
@@ -54,8 +54,14 @@ RSpec.describe 'Schema inference for common datatypes' do
|
|
54
54
|
primary_key :id
|
55
55
|
String :text, null: false
|
56
56
|
Boolean :flag, null: false
|
57
|
+
Time :time
|
57
58
|
Date :date
|
58
59
|
DateTime :datetime, null: false
|
60
|
+
BigDecimal :bigdec
|
61
|
+
|
62
|
+
if ctx.sqlite?(example)
|
63
|
+
add_constraint(:test_constraint) { char_length(text) > 3 }
|
64
|
+
end
|
59
65
|
|
60
66
|
if ctx.postgres?(example)
|
61
67
|
Bytea :data
|
@@ -73,9 +79,11 @@ RSpec.describe 'Schema inference for common datatypes' do
|
|
73
79
|
id: ROM::SQL::Types::Serial.meta(name: :id, source: source),
|
74
80
|
text: ROM::SQL::Types::String.meta(name: :text, source: source),
|
75
81
|
flag: ROM::SQL::Types::Bool.meta(name: :flag, source: source),
|
82
|
+
time: ROM::SQL::Types::Time.optional.meta(name: :time, source: source),
|
76
83
|
date: ROM::SQL::Types::Date.optional.meta(name: :date, source: source),
|
77
84
|
datetime: ROM::SQL::Types::Time.meta(name: :datetime, source: source),
|
78
|
-
data: ROM::SQL::Types::Blob.optional.meta(name: :data, source: source)
|
85
|
+
data: ROM::SQL::Types::Blob.optional.meta(name: :data, source: source),
|
86
|
+
bigdec: ROM::SQL::Types::Decimal.optional.meta(name: :bigdec, source: source)
|
79
87
|
)
|
80
88
|
end
|
81
89
|
end
|
data/spec/support/helpers.rb
CHANGED
@@ -10,7 +10,8 @@ module Helpers
|
|
10
10
|
def define_schema(name, attrs)
|
11
11
|
ROM::SQL::Schema.define(
|
12
12
|
name,
|
13
|
-
attributes: attrs.map { |key, value|
|
13
|
+
attributes: attrs.map { |key, value| value.meta(name: key, source: ROM::Relation::Name.new(name)) },
|
14
|
+
type_class: ROM::SQL::Type
|
14
15
|
)
|
15
16
|
end
|
16
17
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
RSpec.describe ROM::SQL::ProjectionDSL, :
|
3
|
+
RSpec.describe ROM::SQL::ProjectionDSL, :postgres, helpers: true do
|
4
4
|
include_context 'database setup'
|
5
5
|
|
6
6
|
subject(:dsl) do
|
@@ -8,7 +8,7 @@ RSpec.describe ROM::SQL::ProjectionDSL, :sqlite, helpers: true do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
let(:schema) do
|
11
|
-
define_schema(:users, id: ROM::SQL::Types::Serial, name: ROM::SQL::Types::String)
|
11
|
+
define_schema(:users, id: ROM::SQL::Types::Serial, name: ROM::SQL::Types::String, meta: ROM::SQL::Types::PG::JSONB)
|
12
12
|
end
|
13
13
|
|
14
14
|
let(:ds) do
|
@@ -21,7 +21,47 @@ RSpec.describe ROM::SQL::ProjectionDSL, :sqlite, helpers: true do
|
|
21
21
|
.call { int::count(id).as(:count) }
|
22
22
|
.map { |attr| attr.sql_literal(ds) }
|
23
23
|
|
24
|
-
expect(literals).to eql(["
|
24
|
+
expect(literals).to eql([%(COUNT("id") AS "count")])
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'supports chaining attribute db functions' do
|
28
|
+
literals = dsl
|
29
|
+
.call { meta.pg_jsonb.get_text("name").as(:name) }
|
30
|
+
.map { |attr| attr.sql_literal(ds) }
|
31
|
+
|
32
|
+
expect(literals).to eql([%{("meta" ->> 'name') AS "name"}])
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'supports functions with args and chaining with other functions' do
|
36
|
+
literals = dsl
|
37
|
+
.call { int::count(id.qualified).distinct }
|
38
|
+
.map { |attr| attr.sql_literal(ds) }
|
39
|
+
|
40
|
+
expect(literals).to eql([%(COUNT(DISTINCT "users"."id"))])
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'supports functions with args and chaining with other functions and an alias' do
|
44
|
+
literals = dsl
|
45
|
+
.call { int::count(id.qualified).distinct.as(:count) }
|
46
|
+
.map { |attr| attr.sql_literal(ds) }
|
47
|
+
|
48
|
+
expect(literals).to eql([%(COUNT(DISTINCT "users"."id") AS "count")])
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'supports functions with arg being an attribute' do
|
52
|
+
literals = dsl
|
53
|
+
.call { int::count(id).as(:count) }
|
54
|
+
.map { |attr| attr.sql_literal(ds) }
|
55
|
+
|
56
|
+
expect(literals).to eql([%(COUNT("id") AS "count")])
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'supports functions with arg being a qualified attribute' do
|
60
|
+
literals = dsl
|
61
|
+
.call { int::count(id.qualified).as(:count) }
|
62
|
+
.map { |attr| attr.sql_literal(ds) }
|
63
|
+
|
64
|
+
expect(literals).to eql([%(COUNT("users"."id") AS "count")])
|
25
65
|
end
|
26
66
|
end
|
27
67
|
|
@@ -23,8 +23,8 @@ RSpec.describe ROM::SQL::RestrictionDSL, :sqlite, helpers: true do
|
|
23
23
|
|
24
24
|
describe '#method_missing' do
|
25
25
|
it 'responds to methods matching attribute names' do
|
26
|
-
expect(dsl.id.
|
27
|
-
expect(dsl.name.
|
26
|
+
expect(dsl.id.name).to be(:id)
|
27
|
+
expect(dsl.name.name).to be(:name)
|
28
28
|
end
|
29
29
|
|
30
30
|
it 'delegates to sequel virtual row' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rom-sql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.beta2
|
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-01-
|
11
|
+
date: 2017-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|
@@ -151,7 +151,6 @@ files:
|
|
151
151
|
- lib/rom/sql/dsl.rb
|
152
152
|
- lib/rom/sql/error.rb
|
153
153
|
- lib/rom/sql/errors.rb
|
154
|
-
- lib/rom/sql/expression.rb
|
155
154
|
- lib/rom/sql/extensions.rb
|
156
155
|
- lib/rom/sql/extensions/active_support_notifications.rb
|
157
156
|
- lib/rom/sql/extensions/postgres.rb
|
data/lib/rom/sql/expression.rb
DELETED
@@ -1,26 +0,0 @@
|
|
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
|