rom-sql 1.0.0.beta1 → 1.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
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