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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 11ef8c53c46264b6203d44eaad523cda0815845e
4
- data.tar.gz: c2514bbd7868d4591cd2a714e158bfafa2a36fbf
3
+ metadata.gz: 240c81ee43a6d5edfbf9b599d7a031196a686978
4
+ data.tar.gz: 6abdfcd3fdeef06cbbf0794dbb0ebbde658e043e
5
5
  SHA512:
6
- metadata.gz: 1d21a1a74c17f0489431b31d648e58cb0fce934808811111f6e01fc11f4307096884fdc7c8246bc302ce41cd5ea992be9e12a48123841797d8dacab5bc2c88df
7
- data.tar.gz: 5dc78196284dfeb55ac969afcb79510db21fa31bf5238f26209d8bdbe1ed919a929130313dd9600c07842b110facc88487a7c4e137642293f3f885075b210172
6
+ metadata.gz: cdfd38e021013963c48d176d44f7872dd737728254ad066b03a13ded7c90553fd6017651300bd169a6231841f4386e57ce8eb58275c3218b70938a13e42d56cf
7
+ data.tar.gz: 81459e9c88292c2c37218074ab7adf37070852455604829d95cf360bb12565aca97b6b782bbd1f88b0466b86b73421d9ce05157f008246bcd7d278092e196535
@@ -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)
@@ -1,22 +1,30 @@
1
1
  module ROM
2
2
  module SQL
3
3
  class Function < ROM::Schema::Type
4
- def as(name)
5
- meta(name: name)
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 sql_literal(ds)
9
- func.as(name).sql_literal(ds)
12
+ def name
13
+ meta[:alias] || super
10
14
  end
11
15
 
12
16
  private
13
17
 
14
18
  def func
15
- Sequel::SQL::Function.new(meta[:op], *meta[:args])
19
+ meta[:func]
16
20
  end
17
21
 
18
- def method_missing(op, *args)
19
- meta(op: op, args: args)
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
@@ -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
- attr = schema[meth]
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
@@ -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
- # Set primary key
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
- ::ROM::SQL::Expression.new(schema[meth])
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
@@ -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.sql_literal(ds)
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.expr(to_sym)
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
@@ -1,5 +1,5 @@
1
1
  module ROM
2
2
  module SQL
3
- VERSION = '1.0.0.beta1'.freeze
3
+ VERSION = '1.0.0.beta2'.freeze
4
4
  end
5
5
  end
@@ -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
@@ -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| ROM::SQL::Type.new(value.meta(name: key)) }
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, :sqlite, helpers: true do
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(["count(`id`) AS 'count'"])
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.type).to eql(schema[:id])
27
- expect(dsl.name.type).to eql(schema[: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.beta1
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-09 00:00:00.000000000 Z
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
@@ -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