dbee-active_record 2.1.0.pre.alpha.1 → 2.3.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +84 -0
  3. data/.rubocop.yml +4 -18
  4. data/.tool-versions +1 -0
  5. data/CHANGELOG.md +19 -1
  6. data/Guardfile +2 -1
  7. data/README.md +4 -4
  8. data/dbee-active_record.gemspec +11 -13
  9. data/lib/dbee/providers/active_record_provider/expression_builder.rb +81 -59
  10. data/lib/dbee/providers/active_record_provider/maker.rb +37 -0
  11. data/lib/dbee/providers/active_record_provider/{expression_builder → makers}/constraint.rb +1 -1
  12. data/lib/dbee/providers/active_record_provider/{expression_builder → makers}/order.rb +1 -1
  13. data/lib/dbee/providers/active_record_provider/{expression_builder → makers}/select.rb +13 -3
  14. data/lib/dbee/providers/active_record_provider/{expression_builder → makers}/where.rb +27 -7
  15. data/lib/dbee/providers/active_record_provider/version.rb +1 -1
  16. data/lib/dbee/providers/active_record_provider.rb +3 -3
  17. data/spec/db_helper.rb +7 -3
  18. data/spec/dbee/providers/active_record_provider/expression_builder_spec.rb +90 -0
  19. data/spec/dbee/providers/active_record_provider/makers/where_spec.rb +260 -0
  20. data/spec/dbee/providers/active_record_provider_spec.rb +15 -18
  21. data/spec/fixtures/active_record_snapshots/five_table_query.yaml +1 -0
  22. data/spec/fixtures/active_record_snapshots/multiple_same_table_query_with_static_constraints.yaml +1 -0
  23. data/spec/fixtures/active_record_snapshots/one_table_empty_query.yaml +11 -0
  24. data/spec/fixtures/active_record_snapshots/one_table_query.yaml +1 -0
  25. data/spec/fixtures/active_record_snapshots/one_table_query_with_ascending_sort.yaml +1 -0
  26. data/spec/fixtures/active_record_snapshots/one_table_query_with_descending_sort.yaml +1 -0
  27. data/spec/fixtures/active_record_snapshots/one_table_query_with_filters.yaml +1 -0
  28. data/spec/fixtures/active_record_snapshots/one_table_query_with_limit.yaml +1 -0
  29. data/spec/fixtures/active_record_snapshots/one_table_query_with_multiple_sorts.yaml +1 -0
  30. data/spec/fixtures/active_record_snapshots/partitioner_example_1_query.yaml +1 -0
  31. data/spec/fixtures/active_record_snapshots/partitioner_example_2_query.yaml +1 -0
  32. data/spec/fixtures/active_record_snapshots/reverse_polymorphic_query.yaml +1 -0
  33. data/spec/fixtures/active_record_snapshots/two_table_query.yaml +6 -0
  34. data/spec/fixtures/active_record_snapshots/two_table_query_with_aggregation.yaml +1 -0
  35. data/spec/fixtures/active_record_snapshots/two_table_query_with_pivoting.yaml +1 -0
  36. data/spec/fixtures/models.yaml +110 -102
  37. data/spec/spec_helper.rb +13 -2
  38. metadata +108 -27
  39. data/.travis.yml +0 -31
data/spec/db_helper.rb CHANGED
@@ -106,6 +106,8 @@ def load_schema
106
106
  t.timestamps
107
107
  end
108
108
 
109
+ add_index :fields, %i[section key], unique: true
110
+
109
111
  create_table :patients do |t|
110
112
  t.column :first, :string
111
113
  t.column :middle, :string
@@ -114,14 +116,16 @@ def load_schema
114
116
  end
115
117
 
116
118
  create_table :patient_field_values do |t|
117
- t.column :patient_id, :integer
118
- t.column :field_id, :integer
119
+ t.column :patient_id, :integer, foreign_key: true
120
+ t.column :field_id, :integer, foreign_key: true
119
121
  t.column :value, :string
120
122
  t.timestamps
121
123
  end
122
124
 
125
+ add_index :patient_field_values, %i[patient_id field_id], unique: true
126
+
123
127
  create_table :patient_payments do |t|
124
- t.column :patient_id, :integer
128
+ t.column :patient_id, :integer, foreign_key: true
125
129
  t.column :amount, :decimal
126
130
  t.timestamps
127
131
  end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'spec_helper'
11
+ require 'db_helper'
12
+
13
+ describe Dbee::Providers::ActiveRecordProvider::ExpressionBuilder do
14
+ let(:schema) { Dbee::Schema.new(models['Patients']) }
15
+ let(:alias_maker) { Dbee::Providers::ActiveRecordProvider::SafeAliasMaker.new }
16
+
17
+ let(:empty_query) { Dbee::Query.make(from: :patients) }
18
+
19
+ let(:id_and_average_query) do
20
+ Dbee::Query.make(
21
+ from: :patients,
22
+ fields: [
23
+ {
24
+ key_path: :id,
25
+ display: 'ID #'
26
+ },
27
+ {
28
+ key_path: 'patient_payments.amount',
29
+ display: 'Ave Payment',
30
+ aggregator: :ave
31
+ }
32
+ ],
33
+ sorters: [
34
+ {
35
+ key_path: :id
36
+ }
37
+ ],
38
+ filters: [
39
+ {
40
+ key_path: :id,
41
+ value: 123
42
+ }
43
+ ]
44
+ )
45
+ end
46
+
47
+ let(:first_and_count_query) do
48
+ Dbee::Query.make(
49
+ from: :patients,
50
+ fields: [
51
+ {
52
+ key_path: :first,
53
+ display: 'First Name'
54
+ },
55
+ {
56
+ key_path: 'patient_payments.amount',
57
+ display: 'Number of Payments',
58
+ aggregator: :count
59
+ }
60
+ ]
61
+ )
62
+ end
63
+
64
+ subject { described_class.new(schema, alias_maker, alias_maker) }
65
+
66
+ before(:all) do
67
+ connect_to_db(:sqlite)
68
+ end
69
+
70
+ describe '#to_sql' do
71
+ specify 'when called with no fields, then called with fields removes star select' do
72
+ expect(subject.to_sql(empty_query)).to include('*')
73
+ expect(subject.to_sql(id_and_average_query)).not_to include('*')
74
+ end
75
+
76
+ context 'with aggregation' do
77
+ it 'generates the same sql when called multiple times' do
78
+ first_sql = subject.to_sql(id_and_average_query)
79
+ second_sql = subject.to_sql(id_and_average_query)
80
+
81
+ expect(first_sql).to eq(second_sql)
82
+
83
+ third_sql = subject.to_sql(first_and_count_query)
84
+ fourth_sql = subject.to_sql(first_and_count_query)
85
+
86
+ expect(third_sql).to eq(fourth_sql)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,260 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2020-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'spec_helper'
11
+ require 'db_helper'
12
+
13
+ # rubocop:disable Layout/LineLength
14
+ # Disable the line length cop beause there are some lengthy 'expected' SQL strings in spec which
15
+ # cannot be shortened.
16
+ describe Dbee::Providers::ActiveRecordProvider::Makers::Where do
17
+ before(:all) { connect_to_db(:sqlite) }
18
+
19
+ let(:subject) { described_class.instance }
20
+ let(:column) { Arel::Table.new(:test)[:foo] }
21
+
22
+ describe 'equals' do
23
+ specify 'a string value' do
24
+ filter = Dbee::Query::Filters::Equals.new(key_path: :foo, value: 'bar')
25
+ expect(subject.make(filter, column).to_sql).to eq %q("test"."foo" = 'bar')
26
+ end
27
+
28
+ specify 'a null value' do
29
+ filter = Dbee::Query::Filters::Equals.new(key_path: :foo, value: nil)
30
+ expect(subject.make(filter, column).to_sql).to eq '"test"."foo" IS NULL'
31
+ end
32
+
33
+ specify 'a set with a null value' do
34
+ filter = Dbee::Query::Filters::Equals.new(key_path: :foo, value: ['a', nil, 'c'])
35
+ expected = %q[("test"."foo" IS NULL OR "test"."foo" IN ('a', 'c'))]
36
+ expect(subject.make(filter, column).to_sql).to eq expected
37
+ end
38
+
39
+ specify 'a set without a null value' do
40
+ filter = Dbee::Query::Filters::Equals.new(key_path: :foo, value: %w[a b c])
41
+ expect(subject.make(filter, column).to_sql).to eq %q["test"."foo" IN ('a', 'b', 'c')]
42
+ end
43
+ end
44
+
45
+ describe 'not equals' do
46
+ specify 'a string value' do
47
+ filter = Dbee::Query::Filters::NotEquals.new(key_path: :foo, value: 'bar')
48
+ expect(subject.make(filter, column).to_sql).to eq %q("test"."foo" != 'bar')
49
+ end
50
+
51
+ specify 'a null value' do
52
+ filter = Dbee::Query::Filters::NotEquals.new(key_path: :foo, value: nil)
53
+ expect(subject.make(filter, column).to_sql).to eq '"test"."foo" IS NOT NULL'
54
+ end
55
+
56
+ specify 'a set with a null value' do
57
+ filter = Dbee::Query::Filters::NotEquals.new(key_path: :foo, value: ['a', nil, 'c'])
58
+ expected = %q[("test"."foo" IS NOT NULL OR "test"."foo" NOT IN ('a', 'c'))]
59
+ expect(subject.make(filter, column).to_sql).to eq expected
60
+ end
61
+
62
+ specify 'a set without a null value' do
63
+ filter = Dbee::Query::Filters::NotEquals.new(key_path: :foo, value: %w[a b c])
64
+ expect(subject.make(filter, column).to_sql).to eq %q["test"."foo" NOT IN ('a', 'b', 'c')]
65
+ end
66
+ end
67
+
68
+ describe 'contains' do
69
+ specify 'a string value' do
70
+ filter = Dbee::Query::Filters::Contains.new(key_path: :foo, value: 'bar')
71
+ expect(subject.make(filter, column).to_sql).to eq %q("test"."foo" LIKE '%bar%')
72
+ end
73
+
74
+ specify 'a null value' do
75
+ filter = Dbee::Query::Filters::Contains.new(key_path: :foo, value: nil)
76
+ expect(subject.make(filter, column).to_sql).to eq '"test"."foo" IS NULL'
77
+ end
78
+
79
+ specify 'a set with a null value' do
80
+ filter = Dbee::Query::Filters::Contains.new(key_path: :foo, value: ['a', nil, 'c'])
81
+ expected = %q[(("test"."foo" IS NULL OR "test"."foo" LIKE '%a%') OR "test"."foo" LIKE '%c%')]
82
+ expect(subject.make(filter, column).to_sql).to eq expected
83
+ end
84
+
85
+ specify 'a set without a null value' do
86
+ filter = Dbee::Query::Filters::Contains.new(key_path: :foo, value: %w[a b c])
87
+ expected = %q[(("test"."foo" LIKE '%a%' OR "test"."foo" LIKE '%b%') OR "test"."foo" LIKE '%c%')]
88
+ expect(subject.make(filter, column).to_sql).to eq expected
89
+ end
90
+ end
91
+
92
+ describe 'not contains' do
93
+ specify 'a string value' do
94
+ filter = Dbee::Query::Filters::NotContain.new(key_path: :foo, value: 'bar')
95
+ expect(subject.make(filter, column).to_sql).to eq %q("test"."foo" NOT LIKE '%bar%')
96
+ end
97
+
98
+ specify 'a null value' do
99
+ filter = Dbee::Query::Filters::NotContain.new(key_path: :foo, value: nil)
100
+ expect(subject.make(filter, column).to_sql).to eq '"test"."foo" IS NOT NULL'
101
+ end
102
+
103
+ specify 'a set with a null value' do
104
+ filter = Dbee::Query::Filters::NotContain.new(key_path: :foo, value: ['a', nil, 'c'])
105
+ expected = %q[(("test"."foo" IS NOT NULL OR "test"."foo" NOT LIKE '%a%') OR "test"."foo" NOT LIKE '%c%')]
106
+ expect(subject.make(filter, column).to_sql).to eq expected
107
+ end
108
+
109
+ specify 'a set without a null value' do
110
+ filter = Dbee::Query::Filters::NotContain.new(key_path: :foo, value: %w[a b c])
111
+ expected = %q[(("test"."foo" NOT LIKE '%a%' OR "test"."foo" NOT LIKE '%b%') OR "test"."foo" NOT LIKE '%c%')]
112
+ expect(subject.make(filter, column).to_sql).to eq expected
113
+ end
114
+ end
115
+
116
+ describe 'starts with' do
117
+ specify 'a string value' do
118
+ filter = Dbee::Query::Filters::StartsWith.new(key_path: :foo, value: 'bar')
119
+ expect(subject.make(filter, column).to_sql).to eq %q("test"."foo" LIKE 'bar%')
120
+ end
121
+
122
+ specify 'a null value' do
123
+ filter = Dbee::Query::Filters::StartsWith.new(key_path: :foo, value: nil)
124
+ expect(subject.make(filter, column).to_sql).to eq '"test"."foo" IS NULL'
125
+ end
126
+
127
+ specify 'a set with a null value' do
128
+ filter = Dbee::Query::Filters::StartsWith.new(key_path: :foo, value: ['a', nil, 'c'])
129
+ expected = %q[(("test"."foo" IS NULL OR "test"."foo" LIKE 'a%') OR "test"."foo" LIKE 'c%')]
130
+ expect(subject.make(filter, column).to_sql).to eq expected
131
+ end
132
+
133
+ specify 'a set without a null value' do
134
+ filter = Dbee::Query::Filters::StartsWith.new(key_path: :foo, value: %w[a b c])
135
+ expected = %q[(("test"."foo" LIKE 'a%' OR "test"."foo" LIKE 'b%') OR "test"."foo" LIKE 'c%')]
136
+ expect(subject.make(filter, column).to_sql).to eq expected
137
+ end
138
+ end
139
+
140
+ describe 'not start with' do
141
+ specify 'a string value' do
142
+ filter = Dbee::Query::Filters::NotStartWith.new(key_path: :foo, value: 'bar')
143
+ expect(subject.make(filter, column).to_sql).to eq %q("test"."foo" NOT LIKE 'bar%')
144
+ end
145
+
146
+ specify 'a null value' do
147
+ filter = Dbee::Query::Filters::NotStartWith.new(key_path: :foo, value: nil)
148
+ expect(subject.make(filter, column).to_sql).to eq '"test"."foo" IS NOT NULL'
149
+ end
150
+
151
+ specify 'a set with a null value' do
152
+ filter = Dbee::Query::Filters::NotStartWith.new(key_path: :foo, value: ['a', nil, 'c'])
153
+ expected = %q[(("test"."foo" IS NOT NULL OR "test"."foo" NOT LIKE 'a%') OR "test"."foo" NOT LIKE 'c%')]
154
+ expect(subject.make(filter, column).to_sql).to eq expected
155
+ end
156
+
157
+ specify 'a set without a null value' do
158
+ filter = Dbee::Query::Filters::NotStartWith.new(key_path: :foo, value: %w[a b c])
159
+ expected = %q[(("test"."foo" NOT LIKE 'a%' OR "test"."foo" NOT LIKE 'b%') OR "test"."foo" NOT LIKE 'c%')]
160
+ expect(subject.make(filter, column).to_sql).to eq expected
161
+ end
162
+ end
163
+
164
+ describe 'greater than' do
165
+ specify 'a string value' do
166
+ filter = Dbee::Query::Filters::GreaterThan.new(key_path: :foo, value: 'bar')
167
+ expect(subject.make(filter, column).to_sql).to eq %q("test"."foo" > 'bar')
168
+ end
169
+
170
+ specify 'a null value' do
171
+ filter = Dbee::Query::Filters::GreaterThan.new(key_path: :foo, value: nil)
172
+ expect(subject.make(filter, column).to_sql).to eq '"test"."foo" IS NULL'
173
+ end
174
+
175
+ specify 'a set with a null value' do
176
+ filter = Dbee::Query::Filters::GreaterThan.new(key_path: :foo, value: ['a', nil, 'c'])
177
+ expected = %q[(("test"."foo" IS NULL OR "test"."foo" > 'a') OR "test"."foo" > 'c')]
178
+ expect(subject.make(filter, column).to_sql).to eq expected
179
+ end
180
+
181
+ specify 'a set without a null value' do
182
+ filter = Dbee::Query::Filters::GreaterThan.new(key_path: :foo, value: %w[a b c])
183
+ expected = %q[(("test"."foo" > 'a' OR "test"."foo" > 'b') OR "test"."foo" > 'c')]
184
+ expect(subject.make(filter, column).to_sql).to eq expected
185
+ end
186
+ end
187
+
188
+ describe 'greater than or equal to' do
189
+ specify 'a string value' do
190
+ filter = Dbee::Query::Filters::GreaterThanOrEqualTo.new(key_path: :foo, value: 'bar')
191
+ expect(subject.make(filter, column).to_sql).to eq %q("test"."foo" >= 'bar')
192
+ end
193
+
194
+ specify 'a null value' do
195
+ filter = Dbee::Query::Filters::GreaterThanOrEqualTo.new(key_path: :foo, value: nil)
196
+ expect(subject.make(filter, column).to_sql).to eq '"test"."foo" IS NULL'
197
+ end
198
+
199
+ specify 'a set with a null value' do
200
+ filter = Dbee::Query::Filters::GreaterThanOrEqualTo.new(key_path: :foo, value: ['a', nil, 'c'])
201
+ expected = %q[(("test"."foo" IS NULL OR "test"."foo" >= 'a') OR "test"."foo" >= 'c')]
202
+ expect(subject.make(filter, column).to_sql).to eq expected
203
+ end
204
+
205
+ specify 'a set without a null value' do
206
+ filter = Dbee::Query::Filters::GreaterThanOrEqualTo.new(key_path: :foo, value: %w[a b c])
207
+ expected = %q[(("test"."foo" >= 'a' OR "test"."foo" >= 'b') OR "test"."foo" >= 'c')]
208
+ expect(subject.make(filter, column).to_sql).to eq expected
209
+ end
210
+ end
211
+
212
+ describe 'less than' do
213
+ specify 'a string value' do
214
+ filter = Dbee::Query::Filters::LessThan.new(key_path: :foo, value: 'bar')
215
+ expect(subject.make(filter, column).to_sql).to eq %q("test"."foo" < 'bar')
216
+ end
217
+
218
+ specify 'a null value' do
219
+ filter = Dbee::Query::Filters::LessThan.new(key_path: :foo, value: nil)
220
+ expect(subject.make(filter, column).to_sql).to eq '"test"."foo" IS NULL'
221
+ end
222
+
223
+ specify 'a set with a null value' do
224
+ filter = Dbee::Query::Filters::LessThan.new(key_path: :foo, value: ['a', nil, 'c'])
225
+ expected = %q[(("test"."foo" IS NULL OR "test"."foo" < 'a') OR "test"."foo" < 'c')]
226
+ expect(subject.make(filter, column).to_sql).to eq expected
227
+ end
228
+
229
+ specify 'a set without a null value' do
230
+ filter = Dbee::Query::Filters::LessThan.new(key_path: :foo, value: %w[a b c])
231
+ expected = %q[(("test"."foo" < 'a' OR "test"."foo" < 'b') OR "test"."foo" < 'c')]
232
+ expect(subject.make(filter, column).to_sql).to eq expected
233
+ end
234
+ end
235
+
236
+ describe 'less than or equal to' do
237
+ specify 'a string value' do
238
+ filter = Dbee::Query::Filters::LessThanOrEqualTo.new(key_path: :foo, value: 'bar')
239
+ expect(subject.make(filter, column).to_sql).to eq %q("test"."foo" <= 'bar')
240
+ end
241
+
242
+ specify 'a null value' do
243
+ filter = Dbee::Query::Filters::LessThanOrEqualTo.new(key_path: :foo, value: nil)
244
+ expect(subject.make(filter, column).to_sql).to eq '"test"."foo" IS NULL'
245
+ end
246
+
247
+ specify 'a set with a null value' do
248
+ filter = Dbee::Query::Filters::LessThanOrEqualTo.new(key_path: :foo, value: ['a', nil, 'c'])
249
+ expected = %q[(("test"."foo" IS NULL OR "test"."foo" <= 'a') OR "test"."foo" <= 'c')]
250
+ expect(subject.make(filter, column).to_sql).to eq expected
251
+ end
252
+
253
+ specify 'a set without a null value' do
254
+ filter = Dbee::Query::Filters::LessThanOrEqualTo.new(key_path: :foo, value: %w[a b c])
255
+ expected = %q[(("test"."foo" <= 'a' OR "test"."foo" <= 'b') OR "test"."foo" <= 'c')]
256
+ expect(subject.make(filter, column).to_sql).to eq expected
257
+ end
258
+ end
259
+ end
260
+ # rubocop:enable Layout/LineLength
@@ -11,22 +11,19 @@ require 'spec_helper'
11
11
  require 'db_helper'
12
12
 
13
13
  describe Dbee::Providers::ActiveRecordProvider do
14
- let(:models) { yaml_fixture('models.yaml') }
15
-
16
14
  describe '#sql' do
17
15
  before(:all) do
18
16
  connect_to_db(:sqlite)
19
17
  end
20
18
 
21
19
  it 'errors when joining tables with no constraints' do
22
- model_hash = {
23
- name: :users,
24
- models: [
25
- { name: :logins }
26
- ]
20
+ schema_hash = {
21
+ users: { relationships: { logins: nil } },
22
+ logins: nil
27
23
  }
28
24
 
29
25
  query_hash = {
26
+ from: :users,
30
27
  fields: [
31
28
  { key_path: 'id' },
32
29
  { key_path: 'logins.id' }
@@ -34,11 +31,11 @@ describe Dbee::Providers::ActiveRecordProvider do
34
31
  }
35
32
 
36
33
  query = Dbee::Query.make(query_hash)
37
- model = Dbee::Model.make(model_hash)
34
+ schema = Dbee::Schema.new(schema_hash)
38
35
 
39
36
  error_class = Dbee::Providers::ActiveRecordProvider::ExpressionBuilder::MissingConstraintError
40
37
 
41
- expect { described_class.new.sql(model, query) }.to raise_error(error_class)
38
+ expect { described_class.new.sql(schema, query) }.to raise_error(error_class)
42
39
  end
43
40
  end
44
41
 
@@ -57,12 +54,13 @@ describe Dbee::Providers::ActiveRecordProvider do
57
54
  yaml_fixture_files('active_record_snapshots').each_pair do |filename, snapshot|
58
55
  specify File.basename(filename) do
59
56
  model_name = snapshot['model_name']
57
+
60
58
  query = Dbee::Query.make(snapshot['query'])
61
- model = Dbee::Model.make(models[model_name])
59
+ schema = Dbee::Schema.new(models[model_name])
62
60
 
63
61
  expected_5_sql = snapshot[key].to_s.chomp.tr("\n", ' ')
64
62
  expected_6_sql = expected_5_sql.gsub(' ', ' ').gsub("'t'", '1').gsub("'f'", '0')
65
- actual_sql = described_class.new(readable: readable).sql(model, query)
63
+ actual_sql = described_class.new(readable: readable).sql(schema, query)
66
64
 
67
65
  error_msg = <<~ERROR_MSG
68
66
  Expected 5 SQL: #{expected_5_sql}
@@ -95,9 +93,9 @@ describe Dbee::Providers::ActiveRecordProvider do
95
93
  specify File.basename(filename) do
96
94
  model_name = snapshot['model_name']
97
95
  query = Dbee::Query.make(snapshot['query'])
98
- model = Dbee::Model.make(models[model_name])
96
+ schema = Dbee::Schema.new(models[model_name])
99
97
 
100
- sql = described_class.new(readable: readable).sql(model, query)
98
+ sql = described_class.new(readable: readable).sql(schema, query)
101
99
 
102
100
  expect { ActiveRecord::Base.connection.execute(sql) }.to_not raise_error
103
101
  end
@@ -128,10 +126,10 @@ describe Dbee::Providers::ActiveRecordProvider do
128
126
 
129
127
  let(:snapshot) { yaml_file_read(*snapshot_path) }
130
128
  let(:query) { Dbee::Query.make(snapshot['query']) }
131
- let(:model) { Dbee::Model.make(models['Patients']) }
129
+ let(:schema) { Dbee::Schema.new(models['Patients']) }
132
130
 
133
131
  it 'pivots table rows into columns' do
134
- sql = described_class.new.sql(model, query)
132
+ sql = described_class.new.sql(schema, query)
135
133
 
136
134
  results = ActiveRecord::Base.connection.execute(sql)
137
135
 
@@ -173,11 +171,10 @@ describe Dbee::Providers::ActiveRecordProvider do
173
171
 
174
172
  let(:snapshot) { yaml_file_read(*snapshot_path) }
175
173
  let(:query) { Dbee::Query.make(snapshot['query']) }
176
- let(:model) { Dbee::Model.make(models['Patients']) }
174
+ let(:schema) { Dbee::Schema.new(models['Patients']) }
177
175
 
178
176
  it 'executes correct SQL aggregate functions' do
179
- sql = described_class.new.sql(model, query)
180
-
177
+ sql = described_class.new.sql(schema, query)
181
178
  results = ActiveRecord::Base.connection.execute(sql)
182
179
 
183
180
  expect(results[0]).to include(
@@ -1,5 +1,6 @@
1
1
  model_name: Theaters, Members, and Movies
2
2
  query:
3
+ from: theaters
3
4
  fields:
4
5
  - key_path: members.demos.phone_numbers.phone_number
5
6
  display: PHONE NUMBER
@@ -1,5 +1,6 @@
1
1
  model_name: Theaters, Members, and Movies
2
2
  query:
3
+ from: theaters
3
4
  fields:
4
5
  - key_path: id
5
6
  - key_path: name
@@ -0,0 +1,11 @@
1
+ model_name: Patients
2
+ query:
3
+ from: patients
4
+ sqlite_readable: |+
5
+ SELECT "patients".* FROM "patients" "patients"
6
+ sqlite_not_readable: |+
7
+ SELECT "t0".* FROM "patients" "t0"
8
+ mysql_readable: |+
9
+ SELECT `patients`.* FROM `patients` `patients`
10
+ mysql_not_readable: |+
11
+ SELECT `t0`.* FROM `patients` `t0`
@@ -1,5 +1,6 @@
1
1
  model_name: Theaters, Members, and Movies
2
2
  query:
3
+ from: theaters
3
4
  fields:
4
5
  - key_path: id
5
6
  display: 'ID #'
@@ -1,5 +1,6 @@
1
1
  model_name: Theaters, Members, and Movies
2
2
  query:
3
+ from: theaters
3
4
  fields:
4
5
  - key_path: id
5
6
  - key_path: name
@@ -1,5 +1,6 @@
1
1
  model_name: Theaters, Members, and Movies
2
2
  query:
3
+ from: theaters
3
4
  fields:
4
5
  - key_path: id
5
6
  - key_path: name
@@ -1,5 +1,6 @@
1
1
  model_name: Theaters, Members, and Movies
2
2
  query:
3
+ from: theaters
3
4
  fields:
4
5
  - key_path: id
5
6
  display: 'ID #'
@@ -1,5 +1,6 @@
1
1
  model_name: Theaters, Members, and Movies
2
2
  query:
3
+ from: theaters
3
4
  fields:
4
5
  - key_path: id
5
6
  - key_path: name
@@ -1,5 +1,6 @@
1
1
  model_name: Theaters, Members, and Movies
2
2
  query:
3
+ from: theaters
3
4
  fields:
4
5
  - key_path: id
5
6
  - key_path: name
@@ -1,5 +1,6 @@
1
1
  model_name: Partitioner Example 1
2
2
  query:
3
+ from: dogs
3
4
  fields:
4
5
  - key_path: id
5
6
  sqlite_readable: |+
@@ -1,5 +1,6 @@
1
1
  model_name: Partitioner Example 2
2
2
  query:
3
+ from: owners
3
4
  fields:
4
5
  - key_path: id
5
6
  - key_path: dogs.id
@@ -1,5 +1,6 @@
1
1
  model_name: Reverse Polymorphic Example
2
2
  query:
3
+ from: animals
3
4
  fields:
4
5
  - key_path: id
5
6
  - key_path: type
@@ -1,11 +1,13 @@
1
1
  model_name: Theaters, Members, and Movies
2
2
  query:
3
+ from: theaters
3
4
  fields:
4
5
  - key_path: id
5
6
  - key_path: name
6
7
  - key_path: members.id
7
8
  - key_path: members.account_number
8
9
  limit: 12
10
+ offset: 25
9
11
  sqlite_readable: |+
10
12
  SELECT
11
13
  "theaters"."id" AS 'id',
@@ -15,6 +17,7 @@ sqlite_readable: |+
15
17
  FROM "theaters" "theaters"
16
18
  LEFT OUTER JOIN "members" "members" ON "members"."tid" = "theaters"."id" AND "members"."partition" = "theaters"."partition"
17
19
  LIMIT 12
20
+ OFFSET 25
18
21
  sqlite_not_readable: |+
19
22
  SELECT
20
23
  "t0"."id" AS 'c0',
@@ -24,6 +27,7 @@ sqlite_not_readable: |+
24
27
  FROM "theaters" "t0"
25
28
  LEFT OUTER JOIN "members" "t1" ON "t1"."tid" = "t0"."id" AND "t1"."partition" = "t0"."partition"
26
29
  LIMIT 12
30
+ OFFSET 25
27
31
  mysql_readable: |+
28
32
  SELECT
29
33
  `theaters`.`id` AS 'id',
@@ -33,6 +37,7 @@ mysql_readable: |+
33
37
  FROM `theaters` `theaters`
34
38
  LEFT OUTER JOIN `members` `members` ON `members`.`tid` = `theaters`.`id` AND `members`.`partition` = `theaters`.`partition`
35
39
  LIMIT 12
40
+ OFFSET 25
36
41
  mysql_not_readable: |+
37
42
  SELECT
38
43
  `t0`.`id` AS 'c0',
@@ -42,3 +47,4 @@ mysql_not_readable: |+
42
47
  FROM `theaters` `t0`
43
48
  LEFT OUTER JOIN `members` `t1` ON `t1`.`tid` = `t0`.`id` AND `t1`.`partition` = `t0`.`partition`
44
49
  LIMIT 12
50
+ OFFSET 25
@@ -1,5 +1,6 @@
1
1
  model_name: Patients
2
2
  query:
3
+ from: patients
3
4
  fields:
4
5
  - key_path: id
5
6
  display: 'ID #'
@@ -1,5 +1,6 @@
1
1
  model_name: Patients
2
2
  query:
3
+ from: patients
3
4
  fields:
4
5
  - key_path: id
5
6
  display: 'ID #'