rom-sql 2.0.0.beta2 → 2.0.0.beta3
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 +66 -0
- data/lib/rom/plugins/relation/sql/postgres/explain.rb +54 -0
- data/lib/rom/sql.rb +1 -1
- data/lib/rom/sql/attribute.rb +17 -18
- data/lib/rom/sql/errors.rb +3 -0
- data/lib/rom/sql/extensions/mysql.rb +1 -1
- data/lib/rom/sql/extensions/mysql/type_builder.rb +28 -0
- data/lib/rom/sql/extensions/postgres.rb +3 -1
- data/lib/rom/sql/extensions/postgres/commands.rb +30 -13
- data/lib/rom/sql/extensions/postgres/{attributes_inferrer.rb → type_builder.rb} +24 -28
- data/lib/rom/sql/extensions/postgres/type_serializer.rb +39 -0
- data/lib/rom/sql/extensions/postgres/types.rb +24 -477
- data/lib/rom/sql/extensions/postgres/types/array.rb +163 -0
- data/lib/rom/sql/extensions/postgres/types/geometric.rb +135 -0
- data/lib/rom/sql/extensions/postgres/types/json.rb +235 -0
- data/lib/rom/sql/extensions/postgres/types/network.rb +15 -0
- data/lib/rom/sql/extensions/sqlite.rb +1 -1
- data/lib/rom/sql/extensions/sqlite/{attributes_inferrer.rb → type_builder.rb} +5 -5
- data/lib/rom/sql/extensions/sqlite/types.rb +8 -3
- data/lib/rom/sql/foreign_key.rb +17 -0
- data/lib/rom/sql/function.rb +86 -8
- data/lib/rom/sql/gateway.rb +26 -26
- data/lib/rom/sql/index.rb +4 -0
- data/lib/rom/sql/migration.rb +3 -3
- data/lib/rom/sql/migration/inline_runner.rb +9 -83
- data/lib/rom/sql/migration/migrator.rb +35 -12
- data/lib/rom/sql/migration/recorder.rb +21 -0
- data/lib/rom/sql/migration/runner.rb +115 -0
- data/lib/rom/sql/migration/schema_diff.rb +108 -53
- data/lib/rom/sql/migration/writer.rb +61 -0
- data/lib/rom/sql/relation.rb +2 -1
- data/lib/rom/sql/relation/reading.rb +63 -3
- data/lib/rom/sql/relation/writing.rb +38 -0
- data/lib/rom/sql/schema.rb +9 -3
- data/lib/rom/sql/schema/attributes_inferrer.rb +3 -119
- data/lib/rom/sql/schema/inferrer.rb +99 -18
- data/lib/rom/sql/schema/type_builder.rb +94 -0
- data/lib/rom/sql/type_dsl.rb +30 -0
- data/lib/rom/sql/type_extensions.rb +11 -6
- data/lib/rom/sql/type_serializer.rb +46 -0
- data/lib/rom/sql/types.rb +12 -0
- data/lib/rom/sql/version.rb +1 -1
- metadata +26 -244
- data/.codeclimate.yml +0 -15
- data/.gitignore +0 -17
- data/.rspec +0 -3
- data/.travis.yml +0 -39
- data/.yardopts +0 -2
- data/Gemfile +0 -33
- data/Guardfile +0 -24
- data/LICENSE.txt +0 -22
- data/Rakefile +0 -19
- data/circle.yml +0 -10
- data/lib/rom/sql/extensions/mysql/attributes_inferrer.rb +0 -10
- data/lib/rom/sql/relation/sequel_api.rb +0 -133
- data/log/.gitkeep +0 -0
- data/rom-sql.gemspec +0 -29
- data/spec/extensions/postgres/attribute_spec.rb +0 -217
- data/spec/extensions/postgres/integration_spec.rb +0 -59
- data/spec/extensions/postgres/types_spec.rb +0 -252
- data/spec/extensions/sqlite/types_spec.rb +0 -11
- data/spec/fixtures/migrations/20150403090603_create_carrots.rb +0 -8
- data/spec/integration/associations/many_to_many/custom_fks_spec.rb +0 -76
- data/spec/integration/associations/many_to_many/from_view_spec.rb +0 -88
- data/spec/integration/associations/many_to_many_spec.rb +0 -162
- data/spec/integration/associations/many_to_one/custom_fks_spec.rb +0 -64
- data/spec/integration/associations/many_to_one/from_view_spec.rb +0 -84
- data/spec/integration/associations/many_to_one/self_ref_spec.rb +0 -53
- data/spec/integration/associations/many_to_one_spec.rb +0 -117
- data/spec/integration/associations/one_to_many/custom_fks_spec.rb +0 -54
- data/spec/integration/associations/one_to_many/from_view_spec.rb +0 -57
- data/spec/integration/associations/one_to_many/self_ref_spec.rb +0 -54
- data/spec/integration/associations/one_to_many_spec.rb +0 -86
- data/spec/integration/associations/one_to_one_spec.rb +0 -69
- data/spec/integration/associations/one_to_one_through_spec.rb +0 -92
- data/spec/integration/auto_migrations/errors_spec.rb +0 -31
- data/spec/integration/auto_migrations/indexes_spec.rb +0 -253
- data/spec/integration/auto_migrations/managing_columns_spec.rb +0 -156
- data/spec/integration/auto_migrations/postgres/column_types_spec.rb +0 -63
- data/spec/integration/combine_with_spec.rb +0 -43
- data/spec/integration/commands/create_spec.rb +0 -304
- data/spec/integration/commands/delete_spec.rb +0 -84
- data/spec/integration/commands/update_spec.rb +0 -90
- data/spec/integration/commands/upsert_spec.rb +0 -83
- data/spec/integration/gateway_spec.rb +0 -107
- data/spec/integration/migration_spec.rb +0 -55
- data/spec/integration/plugins/associates/many_to_many_spec.rb +0 -69
- data/spec/integration/plugins/associates_spec.rb +0 -250
- data/spec/integration/plugins/auto_restrictions_spec.rb +0 -74
- data/spec/integration/relation_schema_spec.rb +0 -271
- data/spec/integration/schema/call_spec.rb +0 -24
- data/spec/integration/schema/inferrer/mysql_spec.rb +0 -45
- data/spec/integration/schema/inferrer/postgres_spec.rb +0 -203
- data/spec/integration/schema/inferrer/sqlite_spec.rb +0 -37
- data/spec/integration/schema/inferrer_spec.rb +0 -390
- data/spec/integration/schema/prefix_spec.rb +0 -16
- data/spec/integration/schema/qualified_spec.rb +0 -16
- data/spec/integration/schema/rename_spec.rb +0 -21
- data/spec/integration/schema/view_spec.rb +0 -29
- data/spec/integration/sequel_api_spec.rb +0 -36
- data/spec/integration/setup_spec.rb +0 -26
- data/spec/integration/support/active_support_notifications_spec.rb +0 -24
- data/spec/integration/support/rails_log_subscriber_spec.rb +0 -30
- data/spec/integration/wrap_spec.rb +0 -91
- data/spec/shared/accounts.rb +0 -48
- data/spec/shared/database_setup.rb +0 -70
- data/spec/shared/notes.rb +0 -23
- data/spec/shared/posts.rb +0 -34
- data/spec/shared/puppies.rb +0 -15
- data/spec/shared/relations.rb +0 -8
- data/spec/shared/users.rb +0 -32
- data/spec/shared/users_and_tasks.rb +0 -50
- data/spec/spec_helper.rb +0 -122
- data/spec/support/env_helper.rb +0 -25
- data/spec/support/helpers.rb +0 -24
- data/spec/support/oracle/create_users.sql +0 -7
- data/spec/support/oracle/set_sys_passwords.sql +0 -2
- data/spec/support/test_configuration.rb +0 -16
- data/spec/unit/attribute_spec.rb +0 -104
- data/spec/unit/function_spec.rb +0 -48
- data/spec/unit/gateway_spec.rb +0 -70
- data/spec/unit/logger_spec.rb +0 -14
- data/spec/unit/migration_tasks_spec.rb +0 -111
- data/spec/unit/migrator_spec.rb +0 -25
- data/spec/unit/order_dsl_spec.rb +0 -43
- data/spec/unit/plugin/associates_spec.rb +0 -94
- data/spec/unit/plugin/pagination_spec.rb +0 -91
- data/spec/unit/plugin/timestamp_spec.rb +0 -117
- data/spec/unit/projection_dsl_spec.rb +0 -110
- data/spec/unit/relation/assoc_spec.rb +0 -87
- data/spec/unit/relation/associations_spec.rb +0 -27
- data/spec/unit/relation/avg_spec.rb +0 -11
- data/spec/unit/relation/by_pk_spec.rb +0 -62
- data/spec/unit/relation/dataset_spec.rb +0 -50
- data/spec/unit/relation/distinct_spec.rb +0 -15
- data/spec/unit/relation/exclude_spec.rb +0 -11
- data/spec/unit/relation/exist_predicate_spec.rb +0 -25
- data/spec/unit/relation/exists_spec.rb +0 -18
- data/spec/unit/relation/fetch_spec.rb +0 -21
- data/spec/unit/relation/group_spec.rb +0 -61
- data/spec/unit/relation/having_spec.rb +0 -22
- data/spec/unit/relation/inner_join_spec.rb +0 -158
- data/spec/unit/relation/inspect_spec.rb +0 -11
- data/spec/unit/relation/instrument_spec.rb +0 -45
- data/spec/unit/relation/invert_spec.rb +0 -11
- data/spec/unit/relation/left_join_spec.rb +0 -55
- data/spec/unit/relation/lock_spec.rb +0 -93
- data/spec/unit/relation/map_spec.rb +0 -16
- data/spec/unit/relation/max_spec.rb +0 -11
- data/spec/unit/relation/min_spec.rb +0 -11
- data/spec/unit/relation/order_spec.rb +0 -51
- data/spec/unit/relation/pluck_spec.rb +0 -11
- data/spec/unit/relation/prefix_spec.rb +0 -29
- data/spec/unit/relation/primary_key_spec.rb +0 -27
- data/spec/unit/relation/project_spec.rb +0 -24
- data/spec/unit/relation/qualified_columns_spec.rb +0 -30
- data/spec/unit/relation/qualified_spec.rb +0 -25
- data/spec/unit/relation/read_spec.rb +0 -25
- data/spec/unit/relation/rename_spec.rb +0 -23
- data/spec/unit/relation/right_join_spec.rb +0 -57
- data/spec/unit/relation/select_append_spec.rb +0 -21
- data/spec/unit/relation/select_spec.rb +0 -40
- data/spec/unit/relation/sum_spec.rb +0 -11
- data/spec/unit/relation/union_spec.rb +0 -19
- data/spec/unit/relation/unique_predicate_spec.rb +0 -18
- data/spec/unit/relation/where_spec.rb +0 -133
- data/spec/unit/restriction_dsl_spec.rb +0 -34
- data/spec/unit/schema_spec.rb +0 -25
- data/spec/unit/types_spec.rb +0 -65
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
RSpec.describe ROM::Relation, '#distinct' do
|
|
2
|
-
subject(:relation) { relations[:users] }
|
|
3
|
-
|
|
4
|
-
include_context 'users and tasks'
|
|
5
|
-
|
|
6
|
-
before do
|
|
7
|
-
relation.insert id: 3, name: 'Jane'
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
with_adapters :postgres do
|
|
11
|
-
it 'delegates to dataset and returns a new relation' do
|
|
12
|
-
expect(relation.distinct(:name).order(:name).group(:name, :id).to_a).to eql([{ id: 1, name: 'Jane' }, { id: 2, name: 'Joe' }])
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
RSpec.describe ROM::Relation, '#exclude' do
|
|
2
|
-
subject(:relation) { relations[:users] }
|
|
3
|
-
|
|
4
|
-
include_context 'users and tasks'
|
|
5
|
-
|
|
6
|
-
with_adapters do
|
|
7
|
-
it 'delegates to dataset and returns a new relation' do
|
|
8
|
-
expect(relation.exclude(name: 'Jane').to_a).to eql([{ id: 2, name: 'Joe' }])
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
end
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
RSpec.describe ROM::Relation, '#exist?' do
|
|
2
|
-
include_context 'users and tasks'
|
|
3
|
-
|
|
4
|
-
subject(:relation) { users }
|
|
5
|
-
|
|
6
|
-
with_adapters do
|
|
7
|
-
it 'returns true if relation has at least one tuple' do
|
|
8
|
-
expect(relation.exist?).to be(true)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
it 'returns false if relation is empty' do
|
|
12
|
-
expect(relation.where(name: 'Klaus').exist?).to be(false)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
it 'accepts a condition' do
|
|
16
|
-
expect(relation.exist?(name: 'Jane')).to be(true)
|
|
17
|
-
expect(relation.exist?(name: 'Klaus')).to be(false)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it 'accepts a block' do
|
|
21
|
-
expect(relation.exist? { name.is('Jane') }).to be true
|
|
22
|
-
expect(relation.exist? { name.is('Klaus') }).to be false
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
RSpec.describe ROM::Relation, '#exists' do
|
|
2
|
-
include_context 'users and tasks'
|
|
3
|
-
|
|
4
|
-
let(:tasks) { container.relations.tasks }
|
|
5
|
-
let(:users) { container.relations.users }
|
|
6
|
-
|
|
7
|
-
with_adapters do
|
|
8
|
-
it 'returns true if subquery has at least one tuple' do
|
|
9
|
-
subquery = tasks.where(tasks[:user_id].qualified => users[:id].qualified)
|
|
10
|
-
expect(users.where { exists(subquery) }.count).to eql(2)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it 'returns false if subquery is empty' do
|
|
14
|
-
subquery = tasks.where(false)
|
|
15
|
-
expect(users.where { exists(subquery) }.count).to eql(0)
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
RSpec.describe ROM::Relation, '#fetch' do
|
|
2
|
-
subject(:relation) { container.relations.users }
|
|
3
|
-
|
|
4
|
-
include_context 'users and tasks'
|
|
5
|
-
|
|
6
|
-
with_adapters do
|
|
7
|
-
describe '#fetch' do
|
|
8
|
-
it 'returns a single tuple identified by the pk' do
|
|
9
|
-
expect(relation.fetch(1)).to eql(id: 1, name: 'Jane')
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
it 'raises when tuple was not found' do
|
|
13
|
-
expect { relation.fetch(535315412) }.to raise_error(ROM::TupleCountMismatchError)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it 'raises when more tuples were returned' do
|
|
17
|
-
expect { relation.fetch([1, 2]) }.to raise_error(ROM::TupleCountMismatchError)
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
RSpec.describe ROM::Relation, '#group' do
|
|
2
|
-
subject(:relation) { relations[:users] }
|
|
3
|
-
|
|
4
|
-
let(:notes) { relations[:notes] }
|
|
5
|
-
|
|
6
|
-
include_context 'users and tasks'
|
|
7
|
-
|
|
8
|
-
with_adapters do
|
|
9
|
-
it 'groups by provided attribute name' do |example|
|
|
10
|
-
# Oracle doesn't support concise GROUP BY
|
|
11
|
-
group_by = oracle?(example) ? %i(id name) : %i(id)
|
|
12
|
-
grouped = relation.
|
|
13
|
-
qualified.
|
|
14
|
-
left_join(:tasks, tasks[:user_id].qualified => relation[:id].qualified).
|
|
15
|
-
group(*group_by)
|
|
16
|
-
|
|
17
|
-
expect(grouped.to_a).to eql([{ id: 1, name: 'Jane' }, { id: 2, name: 'Joe'}])
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it 'groups by provided attribute name in a block' do
|
|
21
|
-
grouped = relation.
|
|
22
|
-
qualified.
|
|
23
|
-
left_join(:tasks, tasks[:user_id].qualified => relation[:id].qualified).
|
|
24
|
-
group { [id.qualified, name.qualified] }
|
|
25
|
-
|
|
26
|
-
expect(grouped.to_a).to eql([{ id: 1, name: 'Jane' }, { id: 2, name: 'Joe'}])
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it 'groups by aliased attributes' do
|
|
30
|
-
grouped = relation.
|
|
31
|
-
select { id.as(:user_id) }.
|
|
32
|
-
group(:id)
|
|
33
|
-
|
|
34
|
-
expect(grouped.to_a).to eql([{ user_id: 1 }, { user_id: 2 }])
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
with_adapters :postgres do
|
|
39
|
-
include_context 'notes'
|
|
40
|
-
|
|
41
|
-
it 'groups by provided attribute name in and attributes from a block' do
|
|
42
|
-
grouped = relation.
|
|
43
|
-
qualified.
|
|
44
|
-
left_join(:tasks, tasks[:user_id].qualified => relation[:id].qualified).
|
|
45
|
-
group(tasks[:title]) { id.qualified }
|
|
46
|
-
|
|
47
|
-
expect(grouped.to_a).to eql([{ id: 1, name: 'Jane' }, { id: 2, name: 'Joe'}])
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it 'groups by a function' do
|
|
51
|
-
notes.insert user_id: 1, text: 'Foo', created_at: Time.now, updated_at: Time.now
|
|
52
|
-
|
|
53
|
-
grouped = notes
|
|
54
|
-
.select { [int::count(id), time::date_trunc('day', created_at).as(:date)] }
|
|
55
|
-
.group { date_trunc('day', created_at) }
|
|
56
|
-
.order(nil)
|
|
57
|
-
|
|
58
|
-
expect(grouped.to_a).to eql([ count: 1, date: Date.today.to_time ])
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
RSpec.describe ROM::Relation, '#having' do
|
|
2
|
-
subject(:relation) do
|
|
3
|
-
relations[:users]
|
|
4
|
-
.inner_join(:tasks, user_id: :id)
|
|
5
|
-
.qualified
|
|
6
|
-
.select_group(:id, :name)
|
|
7
|
-
.select_append { int::count(:tasks).as(:task_count) }
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
include_context 'users and tasks'
|
|
11
|
-
|
|
12
|
-
with_adapters :postgres do
|
|
13
|
-
before do
|
|
14
|
-
conn[:tasks].insert(id: 3, user_id: 2, title: "Joe's another task")
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it 'restricts a relation using HAVING clause' do
|
|
18
|
-
expect(relation.having { count(id.qualified) >= 2 }.to_a).
|
|
19
|
-
to eq([{ id: 2, name: 'Joe', task_count: 2 }])
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
RSpec.describe ROM::Relation, '#inner_join' do
|
|
2
|
-
subject(:relation) { relations[:users] }
|
|
3
|
-
|
|
4
|
-
let(:puzzles) { relations[:puzzles] }
|
|
5
|
-
|
|
6
|
-
include_context 'users and tasks'
|
|
7
|
-
|
|
8
|
-
with_adapters do
|
|
9
|
-
it 'joins relations using inner join' do
|
|
10
|
-
relation.insert id: 3, name: 'Jade'
|
|
11
|
-
|
|
12
|
-
result = relation.
|
|
13
|
-
inner_join(:tasks, user_id: :id).
|
|
14
|
-
select(:name, tasks[:title])
|
|
15
|
-
|
|
16
|
-
expect(result.schema.map(&:name)).to eql(%i[name title])
|
|
17
|
-
|
|
18
|
-
expect(result.to_a).to eql([
|
|
19
|
-
{ name: 'Jane', title: "Jane's task" },
|
|
20
|
-
{ name: 'Joe', title: "Joe's task" }
|
|
21
|
-
])
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it 'allows specifying table_aliases' do
|
|
25
|
-
relation.insert id: 3, name: 'Jade'
|
|
26
|
-
|
|
27
|
-
result = relation.
|
|
28
|
-
inner_join(:tasks, {user_id: :id}, table_alias: :t1).
|
|
29
|
-
select(:name, tasks[:title])
|
|
30
|
-
|
|
31
|
-
expect(result.schema.map(&:name)).to eql(%i[name title])
|
|
32
|
-
|
|
33
|
-
expect(result.to_a).to eql([
|
|
34
|
-
{ name: 'Jane', title: "Jane's task" },
|
|
35
|
-
{ name: 'Joe', title: "Joe's task" }
|
|
36
|
-
])
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
context 'with associations' do
|
|
40
|
-
before do
|
|
41
|
-
inferrable_relations.concat %i(puzzles)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
before do
|
|
45
|
-
conn.create_table(:puzzles) do
|
|
46
|
-
primary_key :id
|
|
47
|
-
foreign_key :author_id, :users, null: false
|
|
48
|
-
column :text, String, null: false
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
conf.relation(:users) do
|
|
52
|
-
schema(infer: true) do
|
|
53
|
-
associations do
|
|
54
|
-
has_many :tasks
|
|
55
|
-
has_many :tasks, as: :todos, relation: :tasks
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
conf.relation(:task_tags) do
|
|
61
|
-
schema(infer: true) do
|
|
62
|
-
associations do
|
|
63
|
-
belongs_to :tasks
|
|
64
|
-
belongs_to :tags
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
conf.relation(:tasks) do
|
|
70
|
-
schema(infer: true) do
|
|
71
|
-
associations do
|
|
72
|
-
belongs_to :user
|
|
73
|
-
has_many :task_tags
|
|
74
|
-
has_many :tags, through: :task_tags
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
conf.relation(:puzzles) do
|
|
80
|
-
schema(infer: true) do
|
|
81
|
-
associations do
|
|
82
|
-
belongs_to :users, as: :author
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
relation.insert id: 3, name: 'Jade'
|
|
88
|
-
puzzles.insert id: 1, author_id: 1, text: 'solved by Jane'
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
it 'joins relation with join keys inferred' do
|
|
92
|
-
result = relation.
|
|
93
|
-
inner_join(tasks).
|
|
94
|
-
select(:name, tasks[:title])
|
|
95
|
-
|
|
96
|
-
expect(result.schema.map(&:name)).to eql(%i[name title])
|
|
97
|
-
|
|
98
|
-
expect(result.to_a).to eql([
|
|
99
|
-
{ name: 'Jane', title: "Jane's task" },
|
|
100
|
-
{ name: 'Joe', title: "Joe's task" }
|
|
101
|
-
])
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
let(:task_relation_proxy) { Class.new{ def name; ROM::Relation::Name.new(:tasks); end }.new }
|
|
105
|
-
|
|
106
|
-
it 'joins relation with relation proxy objects' do
|
|
107
|
-
result = relation.
|
|
108
|
-
inner_join(task_relation_proxy).
|
|
109
|
-
select(:name, tasks[:title])
|
|
110
|
-
|
|
111
|
-
expect(result.schema.map(&:name)).to eql(%i[name title])
|
|
112
|
-
|
|
113
|
-
expect(result.to_a).to eql([
|
|
114
|
-
{ name: 'Jane', title: "Jane's task" },
|
|
115
|
-
{ name: 'Joe', title: "Joe's task" }
|
|
116
|
-
])
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
it 'joins relation with join keys inferred for m:m-through' do
|
|
120
|
-
result = tasks.inner_join(tags)
|
|
121
|
-
|
|
122
|
-
expect(result.to_a).to eql([{ id: 1, user_id: 2, title: "Joe's task" }])
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
it 'joins by association name if no condition provided' do
|
|
126
|
-
result = relation.
|
|
127
|
-
inner_join(:tasks).
|
|
128
|
-
select(:name, tasks[:title])
|
|
129
|
-
|
|
130
|
-
expect(result.schema.map(&:name)).to eql(%i[name title])
|
|
131
|
-
|
|
132
|
-
expect(result.to_a).to eql([
|
|
133
|
-
{ name: 'Jane', title: "Jane's task" },
|
|
134
|
-
{ name: 'Joe', title: "Joe's task" }
|
|
135
|
-
])
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
it 'joins if association name differs from relation name' do
|
|
139
|
-
result = relation.
|
|
140
|
-
inner_join(:todos).
|
|
141
|
-
select(:name, tasks[:title])
|
|
142
|
-
|
|
143
|
-
expect(result.schema.map(&:name)).to eql(%i[name title])
|
|
144
|
-
|
|
145
|
-
expect(result.to_a).to eql([
|
|
146
|
-
{ name: 'Jane', title: "Jane's task" },
|
|
147
|
-
{ name: 'Joe', title: "Joe's task" }
|
|
148
|
-
])
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
it 'joins by relation if association name differs from relation name' do
|
|
152
|
-
result = puzzles.inner_join(users).select(users[:name], puzzles[:text])
|
|
153
|
-
|
|
154
|
-
expect(result.to_a).to eql([ name: 'Jane', text: "solved by Jane" ])
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
end
|
|
158
|
-
end
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
RSpec.describe ROM::SQL::Relation, '#instrument', :sqlite do
|
|
2
|
-
include_context 'users and tasks'
|
|
3
|
-
|
|
4
|
-
subject(:relation) do
|
|
5
|
-
relations[:users]
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
let(:notifications) do
|
|
9
|
-
spy(:notifications)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
before do
|
|
13
|
-
conf.plugin(:sql, relations: :instrumentation) do |p|
|
|
14
|
-
p.notifications = notifications
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it 'instruments relation materialization' do
|
|
19
|
-
users.to_a
|
|
20
|
-
|
|
21
|
-
expect(notifications).
|
|
22
|
-
to have_received(:instrument).with(:sql, name: :users, query: users.dataset.sql)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it 'instruments methods that return a single tuple' do
|
|
26
|
-
users.first
|
|
27
|
-
|
|
28
|
-
expect(notifications).
|
|
29
|
-
to have_received(:instrument).with(:sql, name: :users, query: users.limit(1).dataset.sql)
|
|
30
|
-
|
|
31
|
-
users.last
|
|
32
|
-
|
|
33
|
-
expect(notifications).
|
|
34
|
-
to have_received(:instrument).with(:sql, name: :users, query: users.reverse.limit(1).dataset.sql)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
it 'instruments aggregation methods' do
|
|
38
|
-
pending "no idea how to make this work with sequel"
|
|
39
|
-
|
|
40
|
-
users.count
|
|
41
|
-
|
|
42
|
-
expect(notifications).
|
|
43
|
-
to have_received(:instrument).with(:sql, name: :users, query: 'SELECT COUNT(*) FROM users')
|
|
44
|
-
end
|
|
45
|
-
end
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
RSpec.describe ROM::Relation, '#invert' do
|
|
2
|
-
subject(:relation) { relations[:users] }
|
|
3
|
-
|
|
4
|
-
include_context 'users and tasks'
|
|
5
|
-
|
|
6
|
-
with_adapters do
|
|
7
|
-
it 'delegates to dataset and returns a new relation' do
|
|
8
|
-
expect(relation.where(name: 'Jane').invert.to_a).to eql([{ id: 2, name: 'Joe' }])
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
end
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
RSpec.describe ROM::Relation, '#left_join' do
|
|
2
|
-
subject(:relation) { relations[:users] }
|
|
3
|
-
|
|
4
|
-
include_context 'users and tasks'
|
|
5
|
-
|
|
6
|
-
with_adapters do
|
|
7
|
-
it 'joins relations using left outer join' do
|
|
8
|
-
relation.insert id: 3, name: 'Jade'
|
|
9
|
-
|
|
10
|
-
result = relation.
|
|
11
|
-
left_join(:tasks, user_id: :id).
|
|
12
|
-
select(:name, tasks[:title])
|
|
13
|
-
|
|
14
|
-
expect(result.schema.map(&:name)).to eql(%i[name title])
|
|
15
|
-
|
|
16
|
-
expect(result.to_a).to match_array([
|
|
17
|
-
{ name: 'Joe', title: "Joe's task" },
|
|
18
|
-
{ name: 'Jane', title: "Jane's task" },
|
|
19
|
-
{ name: 'Jade', title: nil }
|
|
20
|
-
])
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
context 'with associations' do
|
|
24
|
-
before do
|
|
25
|
-
conf.relation(:users) do
|
|
26
|
-
schema(infer: true) do
|
|
27
|
-
associations { has_many :tasks }
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
conf.relation(:tasks) do
|
|
32
|
-
schema(infer: true) do
|
|
33
|
-
associations { belongs_to :user }
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
relation.insert id: 3, name: 'Jade'
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
it 'joins relation with join keys inferred' do
|
|
41
|
-
result = relation.
|
|
42
|
-
left_join(tasks).
|
|
43
|
-
select(:name, tasks[:title])
|
|
44
|
-
|
|
45
|
-
expect(result.schema.map(&:name)).to eql(%i[name title])
|
|
46
|
-
|
|
47
|
-
expect(result.to_a).to eql([
|
|
48
|
-
{ name: 'Jane', title: "Jane's task" },
|
|
49
|
-
{ name: 'Joe', title: "Joe's task" },
|
|
50
|
-
{ name: 'Jade', title: nil }
|
|
51
|
-
])
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|