dbee-active_record 2.1.2 → 2.2.0
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/.rubocop.yml +1 -1
- data/.travis.yml +2 -1
- data/CHANGELOG.md +6 -0
- data/Guardfile +2 -1
- data/dbee-active_record.gemspec +6 -2
- data/lib/dbee/providers/active_record_provider.rb +3 -3
- data/lib/dbee/providers/active_record_provider/expression_builder.rb +61 -51
- data/lib/dbee/providers/active_record_provider/version.rb +1 -1
- data/spec/dbee/providers/active_record_provider/expression_builder_spec.rb +13 -40
- data/spec/dbee/providers/active_record_provider_spec.rb +15 -15
- data/spec/fixtures/active_record_snapshots/five_table_query.yaml +1 -0
- data/spec/fixtures/active_record_snapshots/multiple_same_table_query_with_static_constraints.yaml +1 -0
- data/spec/fixtures/active_record_snapshots/one_table_empty_query.yaml +1 -0
- data/spec/fixtures/active_record_snapshots/one_table_query.yaml +1 -0
- data/spec/fixtures/active_record_snapshots/one_table_query_with_ascending_sort.yaml +1 -0
- data/spec/fixtures/active_record_snapshots/one_table_query_with_descending_sort.yaml +1 -0
- data/spec/fixtures/active_record_snapshots/one_table_query_with_filters.yaml +1 -0
- data/spec/fixtures/active_record_snapshots/one_table_query_with_limit.yaml +1 -0
- data/spec/fixtures/active_record_snapshots/one_table_query_with_multiple_sorts.yaml +1 -0
- data/spec/fixtures/active_record_snapshots/partitioner_example_1_query.yaml +1 -0
- data/spec/fixtures/active_record_snapshots/partitioner_example_2_query.yaml +1 -0
- data/spec/fixtures/active_record_snapshots/reverse_polymorphic_query.yaml +1 -0
- data/spec/fixtures/active_record_snapshots/two_table_query.yaml +1 -0
- data/spec/fixtures/active_record_snapshots/two_table_query_with_aggregation.yaml +1 -0
- data/spec/fixtures/active_record_snapshots/two_table_query_with_pivoting.yaml +1 -0
- data/spec/fixtures/models.yaml +110 -102
- data/spec/spec_helper.rb +8 -1
- metadata +51 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9ad362290b7ac95e9ad1c466868f81bad354df55b9772742c9bf6591f9f762d
|
4
|
+
data.tar.gz: 0ff078fc8e40af83f984729f3320856af95cf95b3562f97bc17b0b8787342a12
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93b68e1d07bfe82c469d1169d7e94fa2dece7a7f32fc01adcf895356bdfa285d7d1352b1a37e3bd7b50e1023551160988b4dc7a49c97d904b1b4c37d77d1e676
|
7
|
+
data.tar.gz: 44aa0eda58e8d5f50f9d99d1b44a81ade7781ba9cad9cf35b47e6b3dcab2f2699c69898e774b33c3a00c535b4927481b3bb62411856f607ff78b24e34dd320a5
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
env:
|
2
2
|
global:
|
3
3
|
- CC_TEST_REPORTER_ID=036a8fd92cf0c323c9704c041015837d14889e47de936bab18287626ff3372c1
|
4
|
+
- DISABLE_RSPEC_FOCUS=true
|
4
5
|
language: ruby
|
5
6
|
services:
|
6
7
|
- mysql
|
@@ -8,7 +9,7 @@ rvm:
|
|
8
9
|
# Build on the latest stable of all supported Rubies (https://www.ruby-lang.org/en/downloads/):
|
9
10
|
- 2.5.8
|
10
11
|
- 2.6.6
|
11
|
-
- 2.7.
|
12
|
+
- 2.7.2
|
12
13
|
env:
|
13
14
|
- AR_VERSION=5
|
14
15
|
- AR_VERSION=6
|
data/CHANGELOG.md
CHANGED
data/Guardfile
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
command = 'DISABLE_SIMPLECOV=true bundle exec rspec --format=documentation --order=defined'
|
4
|
+
guard :rspec, cmd: command do
|
4
5
|
require 'guard/rspec/dsl'
|
5
6
|
dsl = Guard::RSpec::Dsl.new(self)
|
6
7
|
|
data/dbee-active_record.gemspec
CHANGED
@@ -42,7 +42,7 @@ Gem::Specification.new do |s|
|
|
42
42
|
end
|
43
43
|
|
44
44
|
s.add_dependency('activerecord', activerecord_version)
|
45
|
-
s.add_dependency('dbee', '~>
|
45
|
+
s.add_dependency('dbee', '~>3')
|
46
46
|
|
47
47
|
s.add_development_dependency('guard-rspec', '~>4.7')
|
48
48
|
s.add_development_dependency('mysql2', '~>0.5')
|
@@ -50,8 +50,12 @@ Gem::Specification.new do |s|
|
|
50
50
|
s.add_development_dependency('pry-byebug')
|
51
51
|
s.add_development_dependency('rake', '~> 13')
|
52
52
|
s.add_development_dependency('rspec', '~> 3.8')
|
53
|
-
s.add_development_dependency('rubocop', '~>
|
53
|
+
s.add_development_dependency('rubocop', '~> 1')
|
54
|
+
s.add_development_dependency('rubocop-rake')
|
55
|
+
s.add_development_dependency('rubocop-rspec')
|
54
56
|
s.add_development_dependency('simplecov', '~>0.19.0')
|
55
57
|
s.add_development_dependency('simplecov-console', '~>0.7.0')
|
56
58
|
s.add_development_dependency('sqlite3', '~>1')
|
59
|
+
# Helpful to spot differences in longer SQL queries:
|
60
|
+
s.add_development_dependency('super_diff', '~>0.6')
|
57
61
|
end
|
@@ -35,12 +35,12 @@ module Dbee
|
|
35
35
|
@column_alias_maker = alias_maker(column_prefix)
|
36
36
|
end
|
37
37
|
|
38
|
-
def sql(
|
38
|
+
def sql(schema, query)
|
39
39
|
ExpressionBuilder.new(
|
40
|
-
|
40
|
+
schema,
|
41
41
|
table_alias_maker,
|
42
42
|
column_alias_maker
|
43
|
-
).
|
43
|
+
).to_sql(query)
|
44
44
|
end
|
45
45
|
|
46
46
|
private
|
@@ -12,48 +12,21 @@ require_relative 'maker'
|
|
12
12
|
module Dbee
|
13
13
|
module Providers
|
14
14
|
class ActiveRecordProvider
|
15
|
-
# This class can generate an Arel expression tree
|
15
|
+
# This class can generate an Arel expression tree given a Dbee::Schema
|
16
|
+
# and Dbee::Query.
|
16
17
|
class ExpressionBuilder < Maker # :nodoc: all
|
17
18
|
class MissingConstraintError < StandardError; end
|
18
19
|
|
19
|
-
def initialize(
|
20
|
+
def initialize(schema, table_alias_maker, column_alias_maker)
|
20
21
|
super(column_alias_maker)
|
21
22
|
|
22
|
-
@
|
23
|
+
@schema = schema
|
23
24
|
@table_alias_maker = table_alias_maker
|
24
|
-
|
25
|
-
clear
|
26
|
-
end
|
27
|
-
|
28
|
-
def clear
|
29
|
-
@requires_group_by = false
|
30
|
-
@group_by_columns = []
|
31
|
-
@base_table = make_table(model.table, model.name)
|
32
|
-
@select_all = true
|
33
|
-
|
34
|
-
build(base_table)
|
35
|
-
|
36
|
-
add_partitioners(base_table, model.partitioners)
|
37
|
-
end
|
38
|
-
|
39
|
-
def add(query)
|
40
|
-
return self unless query
|
41
|
-
|
42
|
-
query.fields.each { |field| add_field(field) }
|
43
|
-
query.sorters.each { |sorter| add_sorter(sorter) }
|
44
|
-
query.filters.each { |filter| add_filter(filter) }
|
45
|
-
|
46
|
-
add_limit(query.limit)
|
47
|
-
|
48
|
-
self
|
49
25
|
end
|
50
26
|
|
51
|
-
def to_sql
|
52
|
-
|
53
|
-
|
54
|
-
statement.group(group_by_columns) unless group_by_columns.empty?
|
55
|
-
@group_by_columns = []
|
56
|
-
end
|
27
|
+
def to_sql(query)
|
28
|
+
reset_query_state
|
29
|
+
build_query(query)
|
57
30
|
|
58
31
|
return statement.project(select_maker.star(base_table)).to_sql if select_all
|
59
32
|
|
@@ -63,19 +36,46 @@ module Dbee
|
|
63
36
|
private
|
64
37
|
|
65
38
|
attr_reader :base_table,
|
39
|
+
:key_paths_to_arel_columns,
|
40
|
+
:from_model,
|
66
41
|
:statement,
|
67
|
-
:model,
|
68
42
|
:table_alias_maker,
|
69
43
|
:requires_group_by,
|
70
44
|
:group_by_columns,
|
71
|
-
:
|
45
|
+
:schema,
|
46
|
+
:select_all,
|
47
|
+
:tables
|
48
|
+
|
49
|
+
def reset_query_state
|
50
|
+
@base_table = nil
|
51
|
+
@key_paths_to_arel_columns = {}
|
52
|
+
@from_model = nil
|
53
|
+
@group_by_columns = []
|
54
|
+
@requires_group_by = false
|
55
|
+
@select_all = true
|
56
|
+
@tables = {}
|
57
|
+
end
|
72
58
|
|
73
|
-
def
|
74
|
-
|
59
|
+
def build_query(query)
|
60
|
+
establish_query_base(query)
|
61
|
+
process_fields_sorters_and_filters(query)
|
62
|
+
|
63
|
+
add_partitioners(base_table, from_model.partitioners)
|
64
|
+
add_limit(query.limit)
|
65
|
+
|
66
|
+
statement.group(group_by_columns) if requires_group_by && !group_by_columns.empty?
|
75
67
|
end
|
76
68
|
|
77
|
-
def
|
78
|
-
@
|
69
|
+
def establish_query_base(query)
|
70
|
+
@from_model = schema.model_for_name!(query.from)
|
71
|
+
@base_table = make_table(from_model.table, @from_model.name)
|
72
|
+
build(base_table)
|
73
|
+
end
|
74
|
+
|
75
|
+
def process_fields_sorters_and_filters(query)
|
76
|
+
query.fields.each { |field| add_field(field) }
|
77
|
+
query.sorters.each { |sorter| add_sorter(sorter) }
|
78
|
+
query.filters.each { |filter| add_filter(filter) }
|
79
79
|
end
|
80
80
|
|
81
81
|
def add_filter(filter)
|
@@ -151,33 +151,43 @@ module Dbee
|
|
151
151
|
self
|
152
152
|
end
|
153
153
|
|
154
|
-
def table(
|
155
|
-
table = make_table(model.table,
|
154
|
+
def table(ancestor_names, relationship, model, previous_table)
|
155
|
+
table = make_table(model.table, ancestor_names)
|
156
156
|
|
157
|
-
on = constraint_maker.make(
|
157
|
+
on = constraint_maker.make(relationship.constraints, table, previous_table)
|
158
158
|
|
159
|
-
raise MissingConstraintError, "for: #{
|
159
|
+
raise MissingConstraintError, "for: #{ancestor_names}" unless on
|
160
160
|
|
161
161
|
build(statement.join(table, ::Arel::Nodes::OuterJoin))
|
162
162
|
build(statement.on(on))
|
163
163
|
|
164
164
|
add_partitioners(table, model.partitioners)
|
165
165
|
|
166
|
-
tables[
|
166
|
+
tables[ancestor_names] = table
|
167
167
|
end
|
168
168
|
|
169
|
-
|
170
|
-
|
171
|
-
|
169
|
+
# Travel the query path returning the table at the end of the path.
|
170
|
+
#
|
171
|
+
# Side effect: intermediate tables are created along the way and are
|
172
|
+
# added to the "tables" hash keyed by path.
|
173
|
+
def traverse_query_path(expanded_query_path)
|
174
|
+
visited_path = []
|
175
|
+
|
176
|
+
expanded_query_path.inject(base_table) do |prev_model, (relationship, next_model)|
|
177
|
+
visited_path += [relationship.name]
|
178
|
+
if tables.key?(visited_path)
|
179
|
+
tables[visited_path]
|
180
|
+
else
|
181
|
+
table(visited_path, relationship, next_model, prev_model)
|
182
|
+
end
|
172
183
|
end
|
173
184
|
end
|
174
185
|
|
175
186
|
def add_key_path(key_path)
|
176
187
|
return key_paths_to_arel_columns[key_path] if key_paths_to_arel_columns.key?(key_path)
|
177
188
|
|
178
|
-
|
179
|
-
|
180
|
-
table = traverse_ancestors(ancestors)
|
189
|
+
expanded_query_path = schema.expand_query_path(from_model, key_path)
|
190
|
+
table = traverse_query_path(expanded_query_path)
|
181
191
|
|
182
192
|
arel_column = table[key_path.column_name]
|
183
193
|
|
@@ -11,11 +11,14 @@ require 'spec_helper'
|
|
11
11
|
require 'db_helper'
|
12
12
|
|
13
13
|
describe Dbee::Providers::ActiveRecordProvider::ExpressionBuilder do
|
14
|
-
let(:
|
14
|
+
let(:schema) { Dbee::Schema.new(models['Patients']) }
|
15
15
|
let(:alias_maker) { Dbee::Providers::ActiveRecordProvider::SafeAliasMaker.new }
|
16
16
|
|
17
|
+
let(:empty_query) { Dbee::Query.make(from: :patients) }
|
18
|
+
|
17
19
|
let(:id_and_average_query) do
|
18
20
|
Dbee::Query.make(
|
21
|
+
from: :patients,
|
19
22
|
fields: [
|
20
23
|
{
|
21
24
|
key_path: :id,
|
@@ -43,6 +46,7 @@ describe Dbee::Providers::ActiveRecordProvider::ExpressionBuilder do
|
|
43
46
|
|
44
47
|
let(:first_and_count_query) do
|
45
48
|
Dbee::Query.make(
|
49
|
+
from: :patients,
|
46
50
|
fields: [
|
47
51
|
{
|
48
52
|
key_path: :first,
|
@@ -57,60 +61,29 @@ describe Dbee::Providers::ActiveRecordProvider::ExpressionBuilder do
|
|
57
61
|
)
|
58
62
|
end
|
59
63
|
|
60
|
-
subject { described_class.new(
|
64
|
+
subject { described_class.new(schema, alias_maker, alias_maker) }
|
61
65
|
|
62
66
|
before(:all) do
|
63
67
|
connect_to_db(:sqlite)
|
64
68
|
end
|
65
69
|
|
66
|
-
describe '#clear' do
|
67
|
-
it 'provides fluent interface (returns self)' do
|
68
|
-
expect(subject.clear).to eq(subject)
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'resets selecting, grouping, sorting, and filtering' do
|
72
|
-
subject.add(id_and_average_query)
|
73
|
-
|
74
|
-
sql = subject.to_sql
|
75
|
-
|
76
|
-
expect(sql).not_to include('*')
|
77
|
-
expect(sql).to include('GROUP')
|
78
|
-
expect(sql).to include('WHERE')
|
79
|
-
expect(sql).to include('ORDER')
|
80
|
-
|
81
|
-
sql = subject.clear.to_sql
|
82
|
-
|
83
|
-
expect(sql).to include('*')
|
84
|
-
expect(sql).not_to include('GROUP')
|
85
|
-
expect(sql).not_to include('WHERE')
|
86
|
-
expect(sql).not_to include('ORDER')
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
70
|
describe '#to_sql' do
|
91
71
|
specify 'when called with no fields, then called with fields removes star select' do
|
92
|
-
expect(subject.to_sql).to include('*')
|
93
|
-
|
94
|
-
subject.add(id_and_average_query)
|
95
|
-
|
96
|
-
expect(subject.to_sql).not_to include('*')
|
72
|
+
expect(subject.to_sql(empty_query)).to include('*')
|
73
|
+
expect(subject.to_sql(id_and_average_query)).not_to include('*')
|
97
74
|
end
|
98
75
|
|
99
76
|
context 'with aggregation' do
|
100
77
|
it 'generates the same sql when called multiple times' do
|
101
|
-
subject.
|
102
|
-
|
103
|
-
first_sql = subject.to_sql
|
104
|
-
second_sql = subject.to_sql
|
78
|
+
first_sql = subject.to_sql(id_and_average_query)
|
79
|
+
second_sql = subject.to_sql(id_and_average_query)
|
105
80
|
|
106
81
|
expect(first_sql).to eq(second_sql)
|
107
82
|
|
108
|
-
subject.
|
109
|
-
|
110
|
-
first_sql = subject.to_sql
|
111
|
-
second_sql = subject.to_sql
|
83
|
+
third_sql = subject.to_sql(first_and_count_query)
|
84
|
+
fourth_sql = subject.to_sql(first_and_count_query)
|
112
85
|
|
113
|
-
expect(
|
86
|
+
expect(third_sql).to eq(fourth_sql)
|
114
87
|
end
|
115
88
|
end
|
116
89
|
end
|
@@ -17,14 +17,13 @@ describe Dbee::Providers::ActiveRecordProvider do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'errors when joining tables with no constraints' do
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
{ name: :logins }
|
24
|
-
]
|
20
|
+
schema_hash = {
|
21
|
+
users: { relationships: { logins: nil } },
|
22
|
+
logins: nil
|
25
23
|
}
|
26
24
|
|
27
25
|
query_hash = {
|
26
|
+
from: :users,
|
28
27
|
fields: [
|
29
28
|
{ key_path: 'id' },
|
30
29
|
{ key_path: 'logins.id' }
|
@@ -32,11 +31,11 @@ describe Dbee::Providers::ActiveRecordProvider do
|
|
32
31
|
}
|
33
32
|
|
34
33
|
query = Dbee::Query.make(query_hash)
|
35
|
-
|
34
|
+
schema = Dbee::Schema.new(schema_hash)
|
36
35
|
|
37
36
|
error_class = Dbee::Providers::ActiveRecordProvider::ExpressionBuilder::MissingConstraintError
|
38
37
|
|
39
|
-
expect { described_class.new.sql(
|
38
|
+
expect { described_class.new.sql(schema, query) }.to raise_error(error_class)
|
40
39
|
end
|
41
40
|
end
|
42
41
|
|
@@ -55,12 +54,13 @@ describe Dbee::Providers::ActiveRecordProvider do
|
|
55
54
|
yaml_fixture_files('active_record_snapshots').each_pair do |filename, snapshot|
|
56
55
|
specify File.basename(filename) do
|
57
56
|
model_name = snapshot['model_name']
|
57
|
+
|
58
58
|
query = Dbee::Query.make(snapshot['query'])
|
59
|
-
|
59
|
+
schema = Dbee::Schema.new(models[model_name])
|
60
60
|
|
61
61
|
expected_5_sql = snapshot[key].to_s.chomp.tr("\n", ' ')
|
62
62
|
expected_6_sql = expected_5_sql.gsub(' ', ' ').gsub("'t'", '1').gsub("'f'", '0')
|
63
|
-
actual_sql = described_class.new(readable: readable).sql(
|
63
|
+
actual_sql = described_class.new(readable: readable).sql(schema, query)
|
64
64
|
|
65
65
|
error_msg = <<~ERROR_MSG
|
66
66
|
Expected 5 SQL: #{expected_5_sql}
|
@@ -93,9 +93,9 @@ describe Dbee::Providers::ActiveRecordProvider do
|
|
93
93
|
specify File.basename(filename) do
|
94
94
|
model_name = snapshot['model_name']
|
95
95
|
query = Dbee::Query.make(snapshot['query'])
|
96
|
-
|
96
|
+
schema = Dbee::Schema.new(models[model_name])
|
97
97
|
|
98
|
-
sql = described_class.new(readable: readable).sql(
|
98
|
+
sql = described_class.new(readable: readable).sql(schema, query)
|
99
99
|
|
100
100
|
expect { ActiveRecord::Base.connection.execute(sql) }.to_not raise_error
|
101
101
|
end
|
@@ -126,10 +126,10 @@ describe Dbee::Providers::ActiveRecordProvider do
|
|
126
126
|
|
127
127
|
let(:snapshot) { yaml_file_read(*snapshot_path) }
|
128
128
|
let(:query) { Dbee::Query.make(snapshot['query']) }
|
129
|
-
let(:
|
129
|
+
let(:schema) { Dbee::Schema.new(models['Patients']) }
|
130
130
|
|
131
131
|
it 'pivots table rows into columns' do
|
132
|
-
sql = described_class.new.sql(
|
132
|
+
sql = described_class.new.sql(schema, query)
|
133
133
|
|
134
134
|
results = ActiveRecord::Base.connection.execute(sql)
|
135
135
|
|
@@ -171,10 +171,10 @@ describe Dbee::Providers::ActiveRecordProvider do
|
|
171
171
|
|
172
172
|
let(:snapshot) { yaml_file_read(*snapshot_path) }
|
173
173
|
let(:query) { Dbee::Query.make(snapshot['query']) }
|
174
|
-
let(:
|
174
|
+
let(:schema) { Dbee::Schema.new(models['Patients']) }
|
175
175
|
|
176
176
|
it 'executes correct SQL aggregate functions' do
|
177
|
-
sql = described_class.new.sql(
|
177
|
+
sql = described_class.new.sql(schema, query)
|
178
178
|
results = ActiveRecord::Base.connection.execute(sql)
|
179
179
|
|
180
180
|
expect(results[0]).to include(
|
data/spec/fixtures/models.yaml
CHANGED
@@ -1,125 +1,133 @@
|
|
1
1
|
Theaters, Members, and Movies:
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
2
|
+
theaters:
|
3
|
+
relationships:
|
4
|
+
members:
|
5
|
+
constraints:
|
6
|
+
- type: reference
|
7
|
+
parent: id
|
8
|
+
name: tid
|
9
|
+
- type: reference
|
10
|
+
parent: partition
|
11
|
+
name: partition
|
12
|
+
members:
|
13
|
+
relationships:
|
14
|
+
demos:
|
15
|
+
model: demographics
|
16
|
+
constraints:
|
17
|
+
- type: reference
|
18
|
+
parent: id
|
19
|
+
name: member_id
|
20
|
+
movies:
|
21
|
+
constraints:
|
22
|
+
- type: reference
|
23
|
+
parent: id
|
24
|
+
name: member_id
|
25
|
+
favorite_comic_movies:
|
26
|
+
model: movies
|
27
|
+
constraints:
|
28
|
+
- type: reference
|
29
|
+
parent: id
|
30
|
+
name: member_id
|
31
|
+
- type: static
|
32
|
+
name: genre
|
33
|
+
value: comic
|
34
|
+
favorite_mystery_movies:
|
35
|
+
model: movies
|
36
|
+
constraints:
|
37
|
+
- type: reference
|
38
|
+
parent: id
|
39
|
+
name: member_id
|
40
|
+
- type: static
|
41
|
+
name: genre
|
42
|
+
value: mystery
|
43
|
+
favorite_comedy_movies:
|
44
|
+
model: movies
|
45
|
+
constraints:
|
46
|
+
- type: reference
|
47
|
+
parent: id
|
48
|
+
name: member_id
|
49
|
+
- type: static
|
50
|
+
name: genre
|
51
|
+
value: comedy
|
52
|
+
demographics:
|
53
|
+
table: demographics
|
54
|
+
relationships:
|
55
|
+
phone_numbers:
|
56
|
+
constraints:
|
57
|
+
- type: reference
|
58
|
+
parent: id
|
59
|
+
name: demographic_id
|
60
|
+
phone_numbers:
|
61
|
+
movies:
|
62
|
+
|
61
63
|
Reverse Polymorphic Example:
|
62
64
|
# In this example, an animal has a toy, but that toy is either a dog or cat toy, depending on
|
63
65
|
# the type of the animal. So for this to work in this direction, static constraints pointed
|
64
66
|
# at the parent (animals) is needed.
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
67
|
+
animals:
|
68
|
+
relationships:
|
69
|
+
dog_toy:
|
70
|
+
model: dog_toys
|
69
71
|
constraints:
|
70
72
|
- parent: toy_id
|
71
73
|
name: id
|
72
74
|
- type: static
|
73
75
|
parent: type
|
74
76
|
value: Dog
|
75
|
-
|
76
|
-
|
77
|
+
cat_toy:
|
78
|
+
model: cat_toys
|
77
79
|
constraints:
|
78
80
|
- parent: toy_id
|
79
81
|
name: id
|
80
82
|
- type: static
|
81
83
|
parent: type
|
82
84
|
value: Cat
|
85
|
+
dog_toys:
|
86
|
+
cat_toys:
|
83
87
|
|
84
88
|
Partitioner Example 1:
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
dogs:
|
90
|
+
table: animals
|
91
|
+
partitioners:
|
92
|
+
- name: type
|
93
|
+
value: Dog
|
94
|
+
- name: deleted
|
95
|
+
value: false
|
92
96
|
|
93
97
|
Partitioner Example 2:
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
98
|
+
owners:
|
99
|
+
relationships:
|
100
|
+
dogs:
|
101
|
+
constraints:
|
102
|
+
- name: owner_id
|
103
|
+
parent: id
|
104
|
+
dogs:
|
105
|
+
table: animals
|
106
|
+
partitioners:
|
107
|
+
- name: type
|
108
|
+
value: Dog
|
109
|
+
- name: deleted
|
110
|
+
value: false
|
106
111
|
|
107
112
|
Patients:
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
113
|
+
patients:
|
114
|
+
relationships:
|
115
|
+
patient_payments:
|
116
|
+
constraints:
|
117
|
+
- type: reference
|
118
|
+
parent: id
|
119
|
+
name: patient_id
|
120
|
+
patient_field_values:
|
121
|
+
constraints:
|
122
|
+
- type: reference
|
123
|
+
parent: id
|
124
|
+
name: patient_id
|
125
|
+
patient_field_values:
|
126
|
+
relationships:
|
127
|
+
fields:
|
128
|
+
constraints:
|
129
|
+
- type: reference
|
130
|
+
parent: field_id
|
131
|
+
name: id
|
132
|
+
patient_payments:
|
133
|
+
fields:
|
data/spec/spec_helper.rb
CHANGED
@@ -7,8 +7,15 @@
|
|
7
7
|
# LICENSE file in the root directory of this source tree.
|
8
8
|
#
|
9
9
|
|
10
|
-
require 'yaml'
|
11
10
|
require 'pry'
|
11
|
+
require 'super_diff/rspec'
|
12
|
+
require 'yaml'
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
# Allow for disabling auto focus mode in certain environments like CI to
|
16
|
+
# prevent false positives when only a subset of the suite passes.
|
17
|
+
config.filter_run_when_matching :focus unless ENV['DISABLE_RSPEC_FOCUS'] == 'true'
|
18
|
+
end
|
12
19
|
|
13
20
|
unless ENV['DISABLE_SIMPLECOV'] == 'true'
|
14
21
|
require 'simplecov'
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dbee-active_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Ruggio
|
8
8
|
- Craig Kattner
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-03-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -37,20 +37,14 @@ dependencies:
|
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
41
|
-
- - ">="
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
version: 2.1.1
|
40
|
+
version: '3'
|
44
41
|
type: :runtime
|
45
42
|
prerelease: false
|
46
43
|
version_requirements: !ruby/object:Gem::Requirement
|
47
44
|
requirements:
|
48
45
|
- - "~>"
|
49
46
|
- !ruby/object:Gem::Version
|
50
|
-
version: '
|
51
|
-
- - ">="
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: 2.1.1
|
47
|
+
version: '3'
|
54
48
|
- !ruby/object:Gem::Dependency
|
55
49
|
name: guard-rspec
|
56
50
|
requirement: !ruby/object:Gem::Requirement
|
@@ -141,14 +135,42 @@ dependencies:
|
|
141
135
|
requirements:
|
142
136
|
- - "~>"
|
143
137
|
- !ruby/object:Gem::Version
|
144
|
-
version:
|
138
|
+
version: '1'
|
145
139
|
type: :development
|
146
140
|
prerelease: false
|
147
141
|
version_requirements: !ruby/object:Gem::Requirement
|
148
142
|
requirements:
|
149
143
|
- - "~>"
|
150
144
|
- !ruby/object:Gem::Version
|
151
|
-
version:
|
145
|
+
version: '1'
|
146
|
+
- !ruby/object:Gem::Dependency
|
147
|
+
name: rubocop-rake
|
148
|
+
requirement: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
type: :development
|
154
|
+
prerelease: false
|
155
|
+
version_requirements: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
- !ruby/object:Gem::Dependency
|
161
|
+
name: rubocop-rspec
|
162
|
+
requirement: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
type: :development
|
168
|
+
prerelease: false
|
169
|
+
version_requirements: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
152
174
|
- !ruby/object:Gem::Dependency
|
153
175
|
name: simplecov
|
154
176
|
requirement: !ruby/object:Gem::Requirement
|
@@ -191,6 +213,20 @@ dependencies:
|
|
191
213
|
- - "~>"
|
192
214
|
- !ruby/object:Gem::Version
|
193
215
|
version: '1'
|
216
|
+
- !ruby/object:Gem::Dependency
|
217
|
+
name: super_diff
|
218
|
+
requirement: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - "~>"
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '0.6'
|
223
|
+
type: :development
|
224
|
+
prerelease: false
|
225
|
+
version_requirements: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - "~>"
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0.6'
|
194
230
|
description: " By default Dbee ships with no underlying SQL generator. This library
|
195
231
|
will plug in ActiveRecord into Dbee and Dbee will use it for SQL generation.\n"
|
196
232
|
email:
|
@@ -256,7 +292,7 @@ metadata:
|
|
256
292
|
documentation_uri: https://www.rubydoc.info/gems/dbee-active_record
|
257
293
|
homepage_uri: https://github.com/bluemarblepayroll/dbee-active_record
|
258
294
|
source_code_uri: https://github.com/bluemarblepayroll/dbee-active_record
|
259
|
-
post_install_message:
|
295
|
+
post_install_message:
|
260
296
|
rdoc_options: []
|
261
297
|
require_paths:
|
262
298
|
- lib
|
@@ -272,7 +308,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
272
308
|
version: '0'
|
273
309
|
requirements: []
|
274
310
|
rubygems_version: 3.0.3
|
275
|
-
signing_key:
|
311
|
+
signing_key:
|
276
312
|
specification_version: 4
|
277
313
|
summary: Plugs in ActiveRecord so Dbee can use Arel for SQL generation.
|
278
314
|
test_files:
|