dbee-active_record 1.0.0.pre.alpha

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 +7 -0
  2. data/.editorconfig +8 -0
  3. data/.gitignore +7 -0
  4. data/.rubocop.yml +27 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +30 -0
  7. data/CHANGELOG.md +7 -0
  8. data/CODE_OF_CONDUCT.md +74 -0
  9. data/Gemfile +5 -0
  10. data/Guardfile +16 -0
  11. data/LICENSE +7 -0
  12. data/README.md +75 -0
  13. data/Rakefile +15 -0
  14. data/bin/console +18 -0
  15. data/dbee-active_record.gemspec +36 -0
  16. data/lib/dbee/providers/active_record_provider/expression_builder/constraint_maker.rb +50 -0
  17. data/lib/dbee/providers/active_record_provider/expression_builder/order_maker.rb +23 -0
  18. data/lib/dbee/providers/active_record_provider/expression_builder/select_maker.rb +31 -0
  19. data/lib/dbee/providers/active_record_provider/expression_builder/where_maker.rb +54 -0
  20. data/lib/dbee/providers/active_record_provider/expression_builder.rb +169 -0
  21. data/lib/dbee/providers/active_record_provider/obfuscated_alias_maker.rb +40 -0
  22. data/lib/dbee/providers/active_record_provider/safe_alias_maker.rb +21 -0
  23. data/lib/dbee/providers/active_record_provider/version.rb +16 -0
  24. data/lib/dbee/providers/active_record_provider.rb +51 -0
  25. data/spec/config/database.yaml.ci +9 -0
  26. data/spec/db_helper.rb +56 -0
  27. data/spec/dbee/providers/active_record_provider_spec.rb +79 -0
  28. data/spec/fixtures/active_record_snapshots/five_table_query.yaml +77 -0
  29. data/spec/fixtures/active_record_snapshots/multiple_same_table_query_with_static_constraints.yaml +104 -0
  30. data/spec/fixtures/active_record_snapshots/one_table_query.yaml +26 -0
  31. data/spec/fixtures/active_record_snapshots/one_table_query_with_ascending_sort.yaml +31 -0
  32. data/spec/fixtures/active_record_snapshots/one_table_query_with_descending_sort.yaml +32 -0
  33. data/spec/fixtures/active_record_snapshots/one_table_query_with_filters.yaml +170 -0
  34. data/spec/fixtures/active_record_snapshots/one_table_query_with_limit.yaml +30 -0
  35. data/spec/fixtures/active_record_snapshots/one_table_query_with_multiple_sorts.yaml +33 -0
  36. data/spec/fixtures/active_record_snapshots/two_table_query.yaml +44 -0
  37. data/spec/fixtures/models.yaml +66 -0
  38. data/spec/spec_helper.rb +52 -0
  39. metadata +256 -0
@@ -0,0 +1,40 @@
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
+ module Dbee
11
+ module Providers
12
+ class ActiveRecordProvider
13
+ # Derives new alias names and keeps count of ones already generated in order to avoid
14
+ # collision.
15
+ class ObfuscatedAliasMaker
16
+ attr_reader :prefix
17
+
18
+ def initialize(prefix = '')
19
+ @counter = -1
20
+ @prefix = prefix
21
+ end
22
+
23
+ def make(_name)
24
+ increment
25
+ current
26
+ end
27
+
28
+ private
29
+
30
+ def current
31
+ "#{prefix}#{@counter}"
32
+ end
33
+
34
+ def increment
35
+ @counter += 1
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,21 @@
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
+ module Dbee
11
+ module Providers
12
+ class ActiveRecordProvider
13
+ # This class can be used when readable alias names are expected.
14
+ class SafeAliasMaker
15
+ def make(name)
16
+ name.to_s.tr('.', '_')
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,16 @@
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
+ module Dbee
11
+ module Providers
12
+ class ActiveRecordProvider
13
+ VERSION = '1.0.0-alpha'
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,51 @@
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 'dbee'
11
+ require 'active_record'
12
+
13
+ require_relative 'active_record_provider/expression_builder'
14
+ require_relative 'active_record_provider/obfuscated_alias_maker'
15
+ require_relative 'active_record_provider/safe_alias_maker'
16
+
17
+ module Dbee
18
+ module Providers
19
+ # Provider which leverages ActiveRecord and Arel for generating SQL.
20
+ class ActiveRecordProvider
21
+ DEFAULT_TABLE_PREFIX = 't'
22
+ DEFAULT_COLUMN_PREFIX = 'c'
23
+
24
+ attr_reader :readable, :table_alias_maker, :column_alias_maker
25
+
26
+ def initialize(
27
+ readable: true,
28
+ table_prefix: DEFAULT_TABLE_PREFIX,
29
+ column_prefix: DEFAULT_COLUMN_PREFIX
30
+ )
31
+ @readable = readable
32
+ @table_alias_maker = alias_maker(table_prefix)
33
+ @column_alias_maker = alias_maker(column_prefix)
34
+ end
35
+
36
+ def sql(model, query)
37
+ ExpressionBuilder.new(
38
+ model,
39
+ table_alias_maker,
40
+ column_alias_maker
41
+ ).add(query).to_sql
42
+ end
43
+
44
+ private
45
+
46
+ def alias_maker(prefix)
47
+ readable ? SafeAliasMaker.new : ObfuscatedAliasMaker.new(prefix)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,9 @@
1
+ sqlite:
2
+ adapter: sqlite3
3
+ database: ':memory:'
4
+ mysql:
5
+ adapter: mysql2
6
+ database: dbee_test
7
+ username: root
8
+ host: 127.0.0.1
9
+ port: 3306
data/spec/db_helper.rb ADDED
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2018-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
+ # Enable logging using something like:
11
+ # ActiveRecord::Base.logger = Logger.new(STDERR)
12
+
13
+ def connect_to_db(name)
14
+ config = yaml_file_read('spec', 'config', 'database.yaml')[name.to_s]
15
+ ActiveRecord::Base.establish_connection(config)
16
+ end
17
+
18
+ def load_schema
19
+ ActiveRecord::Schema.define do
20
+ create_table :theaters do |t|
21
+ t.column :name, :string
22
+ t.column :partition, :string
23
+ t.column :active, :boolean
24
+ t.column :inspected, :boolean
25
+ t.timestamps
26
+ end
27
+
28
+ create_table :members do |t|
29
+ t.column :tid, :integer
30
+ t.column :account_number, :string
31
+ t.column :partition, :string
32
+ t.timestamps
33
+ end
34
+
35
+ create_table :demographics do |t|
36
+ t.column :member_id, :integer
37
+ t.column :name, :string
38
+ t.timestamps
39
+ end
40
+
41
+ create_table :phone_numbers do |t|
42
+ t.column :demographic_id, :integer
43
+ t.column :phone_type, :string
44
+ t.column :phone_number, :string
45
+ t.timestamps
46
+ end
47
+
48
+ create_table :movies do |t|
49
+ t.column :member_id, :integer
50
+ t.column :name, :string
51
+ t.column :genre, :string
52
+ t.column :favorite, :boolean, default: false, null: false
53
+ t.timestamps
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,79 @@
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 do
14
+ let(:models) { yaml_fixture('models.yaml') }
15
+
16
+ describe 'Snapshot' do
17
+ context 'Generating SQL' do
18
+ %w[sqlite mysql].each do |dbms|
19
+ context dbms do
20
+ before(:all) do
21
+ connect_to_db(dbms)
22
+ end
23
+
24
+ { readable: true, not_readable: false }.each_pair do |type, readable|
25
+ context type.to_s do
26
+ let(:key) { "#{dbms}_#{type}" }
27
+
28
+ yaml_fixture_files('active_record_snapshots').each_pair do |filename, snapshot|
29
+ specify File.basename(filename) do
30
+ model_name = snapshot['model_name']
31
+ query = Dbee::Query.make(snapshot['query'])
32
+ model = Dbee::Model.make(models[model_name])
33
+ expected_sql = snapshot[key].to_s.chomp.tr("\n", ' ')
34
+ actual_sql = described_class.new(readable: readable).sql(model, query)
35
+
36
+ error_msg = <<~ERROR_MSG
37
+ Expected: #{expected_sql}
38
+ Actual: #{actual_sql}
39
+ ERROR_MSG
40
+
41
+ expect(actual_sql).to eq(expected_sql), error_msg
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ context 'Executing SQL' do
51
+ %w[sqlite].each do |dbms|
52
+ context dbms do
53
+ before(:all) do
54
+ connect_to_db(dbms)
55
+ load_schema
56
+ end
57
+
58
+ { readable: true, not_readable: false }.each_pair do |type, readable|
59
+ context type.to_s do
60
+ let(:key) { "#{dbms}_#{type}" }
61
+
62
+ yaml_fixture_files('active_record_snapshots').each_pair do |filename, snapshot|
63
+ specify File.basename(filename) do
64
+ model_name = snapshot['model_name']
65
+ query = Dbee::Query.make(snapshot['query'])
66
+ model = Dbee::Model.make(models[model_name])
67
+
68
+ sql = described_class.new(readable: readable).sql(model, query)
69
+
70
+ expect { ActiveRecord::Base.connection.execute(sql) }.to_not raise_error
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,77 @@
1
+ model_name: Theaters, Members, and Movies
2
+ query:
3
+ fields:
4
+ - key_path: members.demos.phone_numbers.phone_number
5
+ display: PHONE NUMBER
6
+ - key_path: members.demos.name
7
+ - key_path: id
8
+ - key_path: name
9
+ - key_path: members.movies.id
10
+ - key_path: members.id
11
+ - key_path: members.account_number
12
+ - key_path: members.demos.phone_numbers.phone_type
13
+ - key_path: members.movies.name
14
+ sqlite_readable: |+
15
+ SELECT
16
+ "members_demos_phone_numbers"."phone_number" AS 'PHONE NUMBER',
17
+ "members_demos"."name" AS 'members_demos_name',
18
+ "theaters"."id" AS 'id',
19
+ "theaters"."name" AS 'name',
20
+ "members_movies"."id" AS 'members_movies_id',
21
+ "members"."id" AS 'members_id',
22
+ "members"."account_number" AS 'members_account_number',
23
+ "members_demos_phone_numbers"."phone_type" AS 'members_demos_phone_numbers_phone_type',
24
+ "members_movies"."name" AS 'members_movies_name'
25
+ FROM "theaters" "theaters"
26
+ LEFT OUTER JOIN "members" "members" ON "members"."tid" = "theaters"."id" AND "members"."partition" = "theaters"."partition"
27
+ LEFT OUTER JOIN "demographics" "members_demos" ON "members_demos"."member_id" = "members"."id"
28
+ LEFT OUTER JOIN "phone_numbers" "members_demos_phone_numbers" ON "members_demos_phone_numbers"."demographic_id" = "members_demos"."id"
29
+ LEFT OUTER JOIN "movies" "members_movies" ON "members_movies"."member_id" = "members"."id"
30
+ sqlite_not_readable: |+
31
+ SELECT
32
+ "t3"."phone_number" AS 'c0',
33
+ "t2"."name" AS 'c1',
34
+ "t0"."id" AS 'c2',
35
+ "t0"."name" AS 'c3',
36
+ "t4"."id" AS 'c4',
37
+ "t1"."id" AS 'c5',
38
+ "t1"."account_number" AS 'c6',
39
+ "t3"."phone_type" AS 'c7',
40
+ "t4"."name" AS 'c8'
41
+ FROM "theaters" "t0"
42
+ LEFT OUTER JOIN "members" "t1" ON "t1"."tid" = "t0"."id" AND "t1"."partition" = "t0"."partition"
43
+ LEFT OUTER JOIN "demographics" "t2" ON "t2"."member_id" = "t1"."id"
44
+ LEFT OUTER JOIN "phone_numbers" "t3" ON "t3"."demographic_id" = "t2"."id"
45
+ LEFT OUTER JOIN "movies" "t4" ON "t4"."member_id" = "t1"."id"
46
+ mysql_readable: |+
47
+ SELECT
48
+ `members_demos_phone_numbers`.`phone_number` AS 'PHONE NUMBER',
49
+ `members_demos`.`name` AS 'members_demos_name',
50
+ `theaters`.`id` AS 'id',
51
+ `theaters`.`name` AS 'name',
52
+ `members_movies`.`id` AS 'members_movies_id',
53
+ `members`.`id` AS 'members_id',
54
+ `members`.`account_number` AS 'members_account_number',
55
+ `members_demos_phone_numbers`.`phone_type` AS 'members_demos_phone_numbers_phone_type',
56
+ `members_movies`.`name` AS 'members_movies_name'
57
+ FROM `theaters` `theaters`
58
+ LEFT OUTER JOIN `members` `members` ON `members`.`tid` = `theaters`.`id` AND `members`.`partition` = `theaters`.`partition`
59
+ LEFT OUTER JOIN `demographics` `members_demos` ON `members_demos`.`member_id` = `members`.`id`
60
+ LEFT OUTER JOIN `phone_numbers` `members_demos_phone_numbers` ON `members_demos_phone_numbers`.`demographic_id` = `members_demos`.`id`
61
+ LEFT OUTER JOIN `movies` `members_movies` ON `members_movies`.`member_id` = `members`.`id`
62
+ mysql_not_readable: |+
63
+ SELECT
64
+ `t3`.`phone_number` AS 'c0',
65
+ `t2`.`name` AS 'c1',
66
+ `t0`.`id` AS 'c2',
67
+ `t0`.`name` AS 'c3',
68
+ `t4`.`id` AS 'c4',
69
+ `t1`.`id` AS 'c5',
70
+ `t1`.`account_number` AS 'c6',
71
+ `t3`.`phone_type` AS 'c7',
72
+ `t4`.`name` AS 'c8'
73
+ FROM `theaters` `t0`
74
+ LEFT OUTER JOIN `members` `t1` ON `t1`.`tid` = `t0`.`id` AND `t1`.`partition` = `t0`.`partition`
75
+ LEFT OUTER JOIN `demographics` `t2` ON `t2`.`member_id` = `t1`.`id`
76
+ LEFT OUTER JOIN `phone_numbers` `t3` ON `t3`.`demographic_id` = `t2`.`id`
77
+ LEFT OUTER JOIN `movies` `t4` ON `t4`.`member_id` = `t1`.`id`
@@ -0,0 +1,104 @@
1
+ model_name: Theaters, Members, and Movies
2
+ query:
3
+ fields:
4
+ - key_path: id
5
+ - key_path: name
6
+ - key_path: members.id
7
+ - key_path: members.account_number
8
+ - key_path: members.movies.id
9
+ - key_path: members.movies.name
10
+ display: 'Movie Name'
11
+ - key_path: members.movies.genre
12
+ - key_path: members.favorite_comic_movies.id
13
+ - key_path: members.favorite_comic_movies.name
14
+ display: 'Favorite Comic Movie Name'
15
+ - key_path: members.favorite_comic_movies.genre
16
+ - key_path: members.favorite_mystery_movies.id
17
+ - key_path: members.favorite_mystery_movies.name
18
+ display: 'Favorite Mystery Movie Name'
19
+ - key_path: members.favorite_mystery_movies.genre
20
+ limit: 12
21
+ sqlite_readable: |+
22
+ SELECT
23
+ "theaters"."id" AS 'id',
24
+ "theaters"."name" AS 'name',
25
+ "members"."id" AS 'members_id',
26
+ "members"."account_number" AS 'members_account_number',
27
+ "members_movies"."id" AS 'members_movies_id',
28
+ "members_movies"."name" AS 'Movie Name',
29
+ "members_movies"."genre" AS 'members_movies_genre',
30
+ "members_favorite_comic_movies"."id" AS 'members_favorite_comic_movies_id',
31
+ "members_favorite_comic_movies"."name" AS 'Favorite Comic Movie Name',
32
+ "members_favorite_comic_movies"."genre" AS 'members_favorite_comic_movies_genre',
33
+ "members_favorite_mystery_movies"."id" AS 'members_favorite_mystery_movies_id',
34
+ "members_favorite_mystery_movies"."name" AS 'Favorite Mystery Movie Name',
35
+ "members_favorite_mystery_movies"."genre" AS 'members_favorite_mystery_movies_genre'
36
+ FROM "theaters" "theaters"
37
+ LEFT OUTER JOIN "members" "members" ON "members"."tid" = "theaters"."id" AND "members"."partition" = "theaters"."partition"
38
+ LEFT OUTER JOIN "movies" "members_movies" ON "members_movies"."member_id" = "members"."id"
39
+ LEFT OUTER JOIN "movies" "members_favorite_comic_movies" ON "members_favorite_comic_movies"."member_id" = "members"."id" AND "members_favorite_comic_movies"."genre" = 'comic'
40
+ LEFT OUTER JOIN "movies" "members_favorite_mystery_movies" ON "members_favorite_mystery_movies"."member_id" = "members"."id" AND "members_favorite_mystery_movies"."genre" = 'mystery'
41
+ LIMIT 12
42
+ sqlite_not_readable: |+
43
+ SELECT
44
+ "t0"."id" AS 'c0',
45
+ "t0"."name" AS 'c1',
46
+ "t1"."id" AS 'c2',
47
+ "t1"."account_number" AS 'c3',
48
+ "t2"."id" AS 'c4',
49
+ "t2"."name" AS 'c5',
50
+ "t2"."genre" AS 'c6',
51
+ "t3"."id" AS 'c7',
52
+ "t3"."name" AS 'c8',
53
+ "t3"."genre" AS 'c9',
54
+ "t4"."id" AS 'c10',
55
+ "t4"."name" AS 'c11',
56
+ "t4"."genre" AS 'c12'
57
+ FROM "theaters" "t0"
58
+ LEFT OUTER JOIN "members" "t1" ON "t1"."tid" = "t0"."id" AND "t1"."partition" = "t0"."partition"
59
+ LEFT OUTER JOIN "movies" "t2" ON "t2"."member_id" = "t1"."id"
60
+ LEFT OUTER JOIN "movies" "t3" ON "t3"."member_id" = "t1"."id" AND "t3"."genre" = 'comic'
61
+ LEFT OUTER JOIN "movies" "t4" ON "t4"."member_id" = "t1"."id" AND "t4"."genre" = 'mystery'
62
+ LIMIT 12
63
+ mysql_readable: |+
64
+ SELECT
65
+ `theaters`.`id` AS 'id',
66
+ `theaters`.`name` AS 'name',
67
+ `members`.`id` AS 'members_id',
68
+ `members`.`account_number` AS 'members_account_number',
69
+ `members_movies`.`id` AS 'members_movies_id',
70
+ `members_movies`.`name` AS 'Movie Name',
71
+ `members_movies`.`genre` AS 'members_movies_genre',
72
+ `members_favorite_comic_movies`.`id` AS 'members_favorite_comic_movies_id',
73
+ `members_favorite_comic_movies`.`name` AS 'Favorite Comic Movie Name',
74
+ `members_favorite_comic_movies`.`genre` AS 'members_favorite_comic_movies_genre',
75
+ `members_favorite_mystery_movies`.`id` AS 'members_favorite_mystery_movies_id',
76
+ `members_favorite_mystery_movies`.`name` AS 'Favorite Mystery Movie Name',
77
+ `members_favorite_mystery_movies`.`genre` AS 'members_favorite_mystery_movies_genre'
78
+ FROM `theaters` `theaters`
79
+ LEFT OUTER JOIN `members` `members` ON `members`.`tid` = `theaters`.`id` AND `members`.`partition` = `theaters`.`partition`
80
+ LEFT OUTER JOIN `movies` `members_movies` ON `members_movies`.`member_id` = `members`.`id`
81
+ LEFT OUTER JOIN `movies` `members_favorite_comic_movies` ON `members_favorite_comic_movies`.`member_id` = `members`.`id` AND `members_favorite_comic_movies`.`genre` = 'comic'
82
+ LEFT OUTER JOIN `movies` `members_favorite_mystery_movies` ON `members_favorite_mystery_movies`.`member_id` = `members`.`id` AND `members_favorite_mystery_movies`.`genre` = 'mystery'
83
+ LIMIT 12
84
+ mysql_not_readable: |+
85
+ SELECT
86
+ `t0`.`id` AS 'c0',
87
+ `t0`.`name` AS 'c1',
88
+ `t1`.`id` AS 'c2',
89
+ `t1`.`account_number` AS 'c3',
90
+ `t2`.`id` AS 'c4',
91
+ `t2`.`name` AS 'c5',
92
+ `t2`.`genre` AS 'c6',
93
+ `t3`.`id` AS 'c7',
94
+ `t3`.`name` AS 'c8',
95
+ `t3`.`genre` AS 'c9',
96
+ `t4`.`id` AS 'c10',
97
+ `t4`.`name` AS 'c11',
98
+ `t4`.`genre` AS 'c12'
99
+ FROM `theaters` `t0`
100
+ LEFT OUTER JOIN `members` `t1` ON `t1`.`tid` = `t0`.`id` AND `t1`.`partition` = `t0`.`partition`
101
+ LEFT OUTER JOIN `movies` `t2` ON `t2`.`member_id` = `t1`.`id`
102
+ LEFT OUTER JOIN `movies` `t3` ON `t3`.`member_id` = `t1`.`id` AND `t3`.`genre` = 'comic'
103
+ LEFT OUTER JOIN `movies` `t4` ON `t4`.`member_id` = `t1`.`id` AND `t4`.`genre` = 'mystery'
104
+ LIMIT 12
@@ -0,0 +1,26 @@
1
+ model_name: Theaters, Members, and Movies
2
+ query:
3
+ fields:
4
+ - key_path: id
5
+ display: 'ID #'
6
+ - key_path: name
7
+ sqlite_not_readable: |+
8
+ SELECT
9
+ "t0"."id" AS 'c0',
10
+ "t0"."name" AS 'c1'
11
+ FROM "theaters" "t0"
12
+ sqlite_readable: |+
13
+ SELECT
14
+ "theaters"."id" AS 'ID #',
15
+ "theaters"."name" AS 'name'
16
+ FROM "theaters" "theaters"
17
+ mysql_not_readable: |+
18
+ SELECT
19
+ `t0`.`id` AS 'c0',
20
+ `t0`.`name` AS 'c1'
21
+ FROM `theaters` `t0`
22
+ mysql_readable: |+
23
+ SELECT
24
+ `theaters`.`id` AS 'ID #',
25
+ `theaters`.`name` AS 'name'
26
+ FROM `theaters` `theaters`
@@ -0,0 +1,31 @@
1
+ model_name: Theaters, Members, and Movies
2
+ query:
3
+ fields:
4
+ - key_path: id
5
+ - key_path: name
6
+ sorters:
7
+ - key_path: created_at
8
+ sqlite_readable: |+
9
+ SELECT
10
+ "theaters"."id" AS 'id',
11
+ "theaters"."name" AS 'name'
12
+ FROM "theaters" "theaters"
13
+ ORDER BY "theaters"."created_at"
14
+ sqlite_not_readable: |+
15
+ SELECT
16
+ "t0"."id" AS 'c0',
17
+ "t0"."name" AS 'c1'
18
+ FROM "theaters" "t0"
19
+ ORDER BY "t0"."created_at"
20
+ mysql_readable: |+
21
+ SELECT
22
+ `theaters`.`id` AS 'id',
23
+ `theaters`.`name` AS 'name'
24
+ FROM `theaters` `theaters`
25
+ ORDER BY `theaters`.`created_at`
26
+ mysql_not_readable: |+
27
+ SELECT
28
+ `t0`.`id` AS 'c0',
29
+ `t0`.`name` AS 'c1'
30
+ FROM `theaters` `t0`
31
+ ORDER BY `t0`.`created_at`
@@ -0,0 +1,32 @@
1
+ model_name: Theaters, Members, and Movies
2
+ query:
3
+ fields:
4
+ - key_path: id
5
+ - key_path: name
6
+ sorters:
7
+ - key_path: created_at
8
+ direction: descending
9
+ sqlite_readable: |+
10
+ SELECT
11
+ "theaters"."id" AS 'id',
12
+ "theaters"."name" AS 'name'
13
+ FROM "theaters" "theaters"
14
+ ORDER BY "theaters"."created_at" DESC
15
+ sqlite_not_readable: |+
16
+ SELECT
17
+ "t0"."id" AS 'c0',
18
+ "t0"."name" AS 'c1'
19
+ FROM "theaters" "t0"
20
+ ORDER BY "t0"."created_at" DESC
21
+ mysql_readable: |+
22
+ SELECT
23
+ `theaters`.`id` AS 'id',
24
+ `theaters`.`name` AS 'name'
25
+ FROM `theaters` `theaters`
26
+ ORDER BY `theaters`.`created_at` DESC
27
+ mysql_not_readable: |+
28
+ SELECT
29
+ `t0`.`id` AS 'c0',
30
+ `t0`.`name` AS 'c1'
31
+ FROM `theaters` `t0`
32
+ ORDER BY `t0`.`created_at` DESC