spec/integration/schema/inferrer_spec.rb in rom-sql-1.0.1 vs spec/integration/schema/inferrer_spec.rb in rom-sql-1.0.2
- old
+ new
@@ -1,8 +1,12 @@
-RSpec.describe 'Schema inference for common datatypes' do
- include_context 'database setup'
+RSpec.describe 'Schema inference for common datatypes', seeds: false do
+ include_context 'users and tasks'
+ before do
+ inferrable_relations.concat %i(test_inferrence test_numeric)
+ end
+
let(:schema) { container.relations[dataset].schema }
def trunc_ts(time, drop_usec: false)
usec = drop_usec ? 0 : time.to_time.usec.floor
Time.mktime(time.year, time.month, time.day, time.hour, time.min, time.sec, usec)
@@ -20,46 +24,53 @@
context 'for simple table' do
let(:dataset) { :users }
let(:source) { ROM::Relation::Name[dataset] }
it 'can infer attributes for dataset' do
- expect(schema.to_h).to eql(
- id: ROM::SQL::Types::Serial.meta(name: :id, source: source),
- name: ROM::SQL::Types::String.meta(name: :name, source: source)
- )
+ expect(schema.to_h).
+ to eql(
+ id: ROM::SQL::Types::Serial.meta(name: :id, source: source),
+ name: ROM::SQL::Types::String.meta(name: :name, source: source)
+ )
end
end
context 'for a table with FKs' do
let(:dataset) { :tasks }
let(:source) { ROM::Relation::Name[:tasks] }
it 'can infer attributes for dataset' do
- expect(schema.to_h).to eql(
- id: ROM::SQL::Types::Serial.meta(name: :id, source: source),
- title: ROM::SQL::Types::String.optional.meta(name: :title, source: source),
- user_id: ROM::SQL::Types::Int.optional.meta(name: :user_id,
- foreign_key: true,
- source: source,
- target: :users)
- )
+ expect(schema.to_h).
+ to eql(
+ id: ROM::SQL::Types::Serial.meta(name: :id, source: source),
+ title: ROM::SQL::Types::String.optional.meta(name: :title, source: source),
+ user_id: ROM::SQL::Types::Int.optional.meta(
+ name: :user_id,
+ foreign_key: true,
+ source: source,
+ target: :users
+ )
+ )
end
end
context 'for complex table' do
before do |example|
ctx = self
- conn.drop_table?(:test_inferrence)
conn.create_table :test_inferrence do
primary_key :id
String :text, null: false
- Boolean :flag, null: false
Time :time
Date :date
- DateTime :datetime, null: false
+ if ctx.oracle?(example)
+ Date :datetime, null: false
+ else
+ DateTime :datetime, null: false
+ end
+
if ctx.sqlite?(example)
add_constraint(:test_constraint) { char_length(text) > 3 }
end
if ctx.postgres?(example)
@@ -71,74 +82,78 @@
end
let(:dataset) { :test_inferrence }
let(:source) { ROM::Relation::Name[dataset] }
- it 'can infer attributes for dataset' do
+ it 'can infer attributes for dataset' do |ex|
+ date_type = oracle?(ex) ? ROM::SQL::Types::Time : ROM::SQL::Types::Date
+
expect(schema.to_h).to eql(
id: ROM::SQL::Types::Serial.meta(name: :id, source: source),
text: ROM::SQL::Types::String.meta(name: :text, source: source),
- flag: ROM::SQL::Types::Bool.meta(name: :flag, source: source),
time: ROM::SQL::Types::Time.optional.meta(name: :time, source: source),
- date: ROM::SQL::Types::Date.optional.meta(name: :date, source: source),
+ date: date_type.optional.meta(name: :date, source: source),
datetime: ROM::SQL::Types::Time.meta(name: :datetime, source: source),
data: ROM::SQL::Types::Blob.optional.meta(name: :data, source: source),
)
end
end
context 'numeric datatypes' do
- before do |example|
- ctx = self
- conn.drop_table?(:test_numeric)
-
+ before do
conn.create_table :test_numeric do
primary_key :id
decimal :dec, null: false
decimal :dec_prec, size: 12, null: false
numeric :num, size: [5, 2], null: false
smallint :small
integer :int
- bigint :big
float :floating
double :double_p
end
end
let(:dataset) { :test_numeric }
let(:source) { ROM::Relation::Name[dataset] }
+ let(:integer) { ROM::SQL::Types::Int.meta(source: source) }
let(:decimal) { ROM::SQL::Types::Decimal.meta(source: source) }
it 'infers attributes with precision' do |example|
if mysql?(example)
default_precision = decimal.meta(name: :dec, precision: 10, scale: 0)
+ elsif oracle?(example)
+ # Oracle treats DECIMAL as NUMBER(38, 0)
+ default_precision = integer.meta(name: :dec)
else
default_precision = decimal.meta(name: :dec)
end
+ pending 'Add precision inferrence for Oracle' if oracle?(example)
+
expect(schema.to_h).to eql(
id: ROM::SQL::Types::Serial.meta(name: :id, source: source),
dec: default_precision,
dec_prec: decimal.meta(name: :dec_prec, precision: 12, scale: 0),
num: decimal.meta(name: :num, precision: 5, scale: 2),
small: ROM::SQL::Types::Int.optional.meta(name: :small, source: source),
int: ROM::SQL::Types::Int.optional.meta(name: :int, source: source),
- big: ROM::SQL::Types::Int.optional.meta(name: :big, source: source),
floating: ROM::SQL::Types::Float.optional.meta(name: :floating, source: source),
double_p: ROM::SQL::Types::Float.optional.meta(name: :double_p, source: source),
)
end
end
end
describe 'using commands with inferred schema' do
+ before do
+ inferrable_relations.concat %i(people)
+ end
+
let(:relation) { container.relation(:people) }
before do
- conn.drop_table?(:people)
-
conf.relation(:people) do
schema(dataset, infer: true)
end
conf.commands(:people) do
@@ -216,25 +231,30 @@
String :name, null: false
Date :birth_date, null: false
end
end
- it 'accetps Time' do
+ it 'accetps Time' do |ex|
time = Time.iso8601('1970-01-01T06:00:00')
result = create.call(name: 'Jade', birth_date: time)
+ # Oracle's Date type stores time
+ expected_date = oracle?(ex) ? time : Date.iso8601('1970-01-01T00:00:00')
- expect(result).to eql(id: 1, name: 'Jade', birth_date: Date.iso8601('1970-01-01T00:00:00'))
+ expect(result).to eql(id: 1, name: 'Jade', birth_date: expected_date)
end
end
unless metadata[:sqlite] && defined? JRUBY_VERSION
context 'timestamp' do
- before do
+ before do |ex|
+ ctx = self
+
conn.create_table :people do
primary_key :id
String :name, null: false
- Timestamp :created_at, null: false
+ # TODO: fix ROM, then Sequel to infer TIMESTAMP NOT NULL for Oracle
+ Timestamp :created_at, null: ctx.oracle?(ex)
end
end
it 'accepts Date' do
date = Date.today
@@ -257,10 +277,11 @@
expected_time = trunc_ts(now, drop_usec: mysql?(ex))
expect(result).to eql(id: 1, name: 'Jade', created_at: expected_time)
end
- if !metadata[:mysql]
+ # TODO: Find out if Oracle's adapter really doesn't support RFCs
+ if !metadata[:mysql] && !metadata[:oracle]
it 'accepts strings in RFC 2822' do
now = Time.now
result = create.call(name: 'Jade', created_at: now.rfc822)
expect(result).to eql(id: 1, name: 'Jade', created_at: trunc_ts(now, drop_usec: true))