dbee-active_record 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f116ae2834ca7c1bb8401f58d6eb0a45464f44eb6d972267e9c8d66374c825c1
4
- data.tar.gz: 8b4b89ed376d95c61cfb093ee6966bd958a53afacbfaf385011f6dfa6cfddcae
3
+ metadata.gz: a19e2929826b2291f8309610e4740340a887deead5ad1a19a9a54b49d5e1fb12
4
+ data.tar.gz: aa96b0004e4a7d7c11c161088d6edaafe9d21099df94d20beed8df0dc0676b84
5
5
  SHA512:
6
- metadata.gz: 63c5e3440f06afab714dd1591a00d1da4ee42df659d35edf96f927528d9413ac1773414ba61973bb20c489e75491e6bc5bbd378fc3e2972b6b9843ae2087663a
7
- data.tar.gz: b60502a160fe716ab7b32fcf3e474ae56a7552772a0fc7e54105139ded1128c6a334e81fa90ea12d71f9d6af63736b620705c78ccc5b1542382f47ac31eb8556
6
+ metadata.gz: 87eaf4667b57c442f8f08923c96f2ba9428acff018b6e4f5f44becfe7e4fca41031f93a19f35935a46fc2277bbc0484f48807bf483a06c5fcd06d7616009f165
7
+ data.tar.gz: 67838d5d7d683ce91bfbebbed17dce20d50cd640af580c0f816a8e5989bd2cc46fa4eff356226bc84af66a689200c9c63790693c465727fde3abea3f919ab3ed
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ # 1.2.0 (August 29th, 2019)
2
+
3
+ * Add support for Dbee partitioners
4
+ * Only support Dbee version 1.2.0 and above
5
+
1
6
  # 1.1.0 (August 27th, 2019)
2
7
 
3
8
  * Only support Dbee version 1.1.0 and above
@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
34
34
  end
35
35
 
36
36
  s.add_dependency('activerecord', activerecord_version)
37
- s.add_dependency('dbee', '~>1', '>=1.1.0')
37
+ s.add_dependency('dbee', '~>1', '>=1.2.0')
38
38
 
39
39
  s.add_development_dependency('guard-rspec', '~>4.7')
40
40
  s.add_development_dependency('mysql2', '~>0.5')
@@ -13,6 +13,8 @@ module Dbee
13
13
  class ExpressionBuilder
14
14
  # Can derive constraints for Arel table JOIN statements.
15
15
  class ConstraintMaker
16
+ include Singleton
17
+
16
18
  CONCAT_METHOD = lambda do |on, arel_column, value|
17
19
  on ? on.and(arel_column.eq(value)) : arel_column.eq(value)
18
20
  end
@@ -13,6 +13,8 @@ module Dbee
13
13
  class ExpressionBuilder
14
14
  # Derives Arel#order predicates.
15
15
  class OrderMaker
16
+ include Singleton
17
+
16
18
  SORTER_EVALUATORS = {
17
19
  Query::Sorters::Ascending => ->(column) { column },
18
20
  Query::Sorters::Descending => ->(column) { column.desc }
@@ -13,6 +13,8 @@ module Dbee
13
13
  class ExpressionBuilder
14
14
  # Derives Arel#project predicates.
15
15
  class SelectMaker
16
+ include Singleton
17
+
16
18
  def make(column, arel_column, alias_maker)
17
19
  column_alias = quote(alias_maker.make(column.display))
18
20
 
@@ -13,6 +13,8 @@ module Dbee
13
13
  class ExpressionBuilder
14
14
  # Derives Arel#where predicates.
15
15
  class WhereMaker
16
+ include Singleton
17
+
16
18
  FILTER_EVALUATORS = {
17
19
  Query::Filters::Contains => ->(column, val) { column.matches("%#{val}%") },
18
20
  Query::Filters::Equals => ->(column, val) { column.eq(val) },
@@ -28,10 +28,15 @@ module Dbee
28
28
  @table_alias_maker = table_alias_maker
29
29
  @column_alias_maker = column_alias_maker
30
30
 
31
- @base_table = Arel::Table.new(model.table)
32
- @base_table.table_alias = table_alias_maker.make(model.name)
31
+ clear
32
+ end
33
+
34
+ def clear
35
+ @base_table = make_table(model.table, model.name)
33
36
 
34
- @statement = base_table
37
+ build(base_table)
38
+
39
+ add_partitioners(base_table, model.partitioners)
35
40
  end
36
41
 
37
42
  def add(query)
@@ -60,31 +65,14 @@ module Dbee
60
65
  @key_paths_to_arel_columns ||= {}
61
66
  end
62
67
 
63
- def where_maker
64
- @where_maker ||= WhereMaker.new
65
- end
66
-
67
- def order_maker
68
- @order_maker ||= OrderMaker.new
69
- end
70
-
71
- def select_maker
72
- @select_maker ||= SelectMaker.new
73
- end
74
-
75
- def constraint_maker
76
- @constraint_maker ||= ConstraintMaker.new
77
- end
78
-
79
68
  def add_filter(filter)
80
69
  add_key_path(filter.key_path)
81
70
 
82
71
  key_path = filter.key_path
83
72
  arel_column = key_paths_to_arel_columns[key_path]
73
+ predicate = WhereMaker.instance.make(filter, arel_column)
84
74
 
85
- predicate = where_maker.make(filter, arel_column)
86
-
87
- @statement = statement.where(predicate)
75
+ build(statement.where(predicate))
88
76
 
89
77
  self
90
78
  end
@@ -92,12 +80,11 @@ module Dbee
92
80
  def add_sorter(sorter)
93
81
  add_key_path(sorter.key_path)
94
82
 
95
- key_path = sorter.key_path
83
+ key_path = sorter.key_path
96
84
  arel_column = key_paths_to_arel_columns[key_path]
85
+ predicate = OrderMaker.instance.make(sorter, arel_column)
97
86
 
98
- predicate = order_maker.make(sorter, arel_column)
99
-
100
- @statement = statement.order(predicate)
87
+ build(statement.order(predicate))
101
88
 
102
89
  self
103
90
  end
@@ -105,34 +92,45 @@ module Dbee
105
92
  def add_field(field)
106
93
  add_key_path(field.key_path)
107
94
 
108
- key_path = field.key_path
95
+ key_path = field.key_path
109
96
  arel_column = key_paths_to_arel_columns[key_path]
97
+ predicate = SelectMaker.instance.make(field, arel_column, column_alias_maker)
110
98
 
111
- predicate = select_maker.make(field, arel_column, column_alias_maker)
112
-
113
- @statement = statement.project(predicate)
99
+ build(statement.project(predicate))
114
100
 
115
101
  self
116
102
  end
117
103
 
118
104
  def add_limit(limit)
119
- @limit = limit ? limit.to_i : nil
105
+ limit = limit ? limit.to_i : nil
106
+
107
+ build(statement.take(limit))
120
108
 
121
- @statement = @statement.take(limit) if limit
109
+ self
110
+ end
111
+
112
+ def add_partitioners(table, partitioners)
113
+ partitioners.each do |partitioner|
114
+ arel_column = table[partitioner.name]
115
+ predicate = arel_column.eq(partitioner.value)
116
+
117
+ build(statement.where(predicate))
118
+ end
122
119
 
123
120
  self
124
121
  end
125
122
 
126
123
  def table(name, model, previous_table)
127
- table = Arel::Table.new(model.table)
128
- table.table_alias = table_alias_maker.make(name)
124
+ table = make_table(model.table, name)
129
125
 
130
- on = constraint_maker.make(model.constraints, table, previous_table)
126
+ on = ConstraintMaker.instance.make(model.constraints, table, previous_table)
131
127
 
132
128
  raise MissingConstraintError, "for: #{name}" unless on
133
129
 
134
- @statement = statement.join(table, ::Arel::Nodes::OuterJoin)
135
- @statement = statement.on(on)
130
+ build(statement.join(table, ::Arel::Nodes::OuterJoin))
131
+ build(statement.on(on))
132
+
133
+ add_partitioners(table, model.partitioners)
136
134
 
137
135
  tables[name] = table
138
136
  end
@@ -146,7 +144,7 @@ module Dbee
146
144
  def add_key_path(key_path)
147
145
  return if key_paths_to_arel_columns.key?(key_path)
148
146
 
149
- ancestors = model.ancestors(key_path.ancestor_names)
147
+ ancestors = model.ancestors!(key_path.ancestor_names)
150
148
 
151
149
  table = traverse_ancestors(ancestors)
152
150
 
@@ -155,6 +153,16 @@ module Dbee
155
153
 
156
154
  self
157
155
  end
156
+
157
+ def build(new_expression)
158
+ @statement = new_expression
159
+ end
160
+
161
+ def make_table(table_name, alias_name)
162
+ Arel::Table.new(table_name).tap do |table|
163
+ table.table_alias = table_alias_maker.make(alias_name)
164
+ end
165
+ end
158
166
  end
159
167
  end
160
168
  end
@@ -12,8 +12,10 @@ module Dbee
12
12
  class ActiveRecordProvider
13
13
  # This class can be used when readable alias names are expected.
14
14
  class SafeAliasMaker
15
- def make(name)
16
- name.to_s.tr('.', '_')
15
+ def make(*parts)
16
+ parts.flatten
17
+ .join('_')
18
+ .tr('.', '_')
17
19
  end
18
20
  end
19
21
  end
@@ -10,7 +10,7 @@
10
10
  module Dbee
11
11
  module Providers
12
12
  class ActiveRecordProvider
13
- VERSION = '1.1.0'
13
+ VERSION = '1.2.0'
14
14
  end
15
15
  end
16
16
  end
data/spec/db_helper.rb CHANGED
@@ -53,10 +53,17 @@ def load_schema
53
53
  t.timestamps
54
54
  end
55
55
 
56
+ create_table :owners do |t|
57
+ t.column :name, :string
58
+ t.timestamps
59
+ end
60
+
56
61
  create_table :animals do |t|
62
+ t.column :owner_id, :integer
57
63
  t.column :toy_id, :integer
58
64
  t.column :type, :string
59
65
  t.column :name, :string
66
+ t.column :deleted, :boolean
60
67
  t.timestamps
61
68
  end
62
69
 
@@ -0,0 +1,27 @@
1
+ model_name: Partitioner Example 1
2
+ query:
3
+ fields:
4
+ - key_path: id
5
+ sqlite_readable: |+
6
+ SELECT "dogs"."id" AS 'id'
7
+ FROM "animals" "dogs"
8
+ WHERE "dogs"."type" = 'Dog' AND
9
+ "dogs"."deleted" = 'f'
10
+ sqlite_not_readable: |+
11
+ SELECT
12
+ "t0"."id" AS 'c0'
13
+ FROM "animals" "t0"
14
+ WHERE "t0"."type" = 'Dog' AND
15
+ "t0"."deleted" = 'f'
16
+ mysql_readable: |+
17
+ SELECT
18
+ `dogs`.`id` AS 'id'
19
+ FROM `animals` `dogs`
20
+ WHERE `dogs`.`type` = 'Dog' AND
21
+ `dogs`.`deleted` = FALSE
22
+ mysql_not_readable: |+
23
+ SELECT
24
+ `t0`.`id` AS 'c0'
25
+ FROM `animals` `t0`
26
+ WHERE `t0`.`type` = 'Dog' AND
27
+ `t0`.`deleted` = FALSE
@@ -0,0 +1,37 @@
1
+ model_name: Partitioner Example 2
2
+ query:
3
+ fields:
4
+ - key_path: id
5
+ - key_path: dogs.id
6
+ sqlite_readable: |+
7
+ SELECT
8
+ "owners"."id" AS 'id',
9
+ "dogs"."id" AS 'dogs_id'
10
+ FROM "owners" "owners"
11
+ LEFT OUTER JOIN "animals" "dogs" ON "dogs"."owner_id" = "owners"."id"
12
+ WHERE "dogs"."type" = 'Dog' AND
13
+ "dogs"."deleted" = 'f'
14
+ sqlite_not_readable: |+
15
+ SELECT
16
+ "t0"."id" AS 'c0',
17
+ "t1"."id" AS 'c1'
18
+ FROM "owners" "t0"
19
+ LEFT OUTER JOIN "animals" "t1" ON "t1"."owner_id" = "t0"."id"
20
+ WHERE "t1"."type" = 'Dog' AND
21
+ "t1"."deleted" = 'f'
22
+ mysql_readable: |+
23
+ SELECT
24
+ `owners`.`id` AS 'id',
25
+ `dogs`.`id` AS 'dogs_id'
26
+ FROM `owners` `owners`
27
+ LEFT OUTER JOIN `animals` `dogs` ON `dogs`.`owner_id` = `owners`.`id`
28
+ WHERE `dogs`.`type` = 'Dog' AND
29
+ `dogs`.`deleted` = FALSE
30
+ mysql_not_readable: |+
31
+ SELECT
32
+ `t0`.`id` AS 'c0',
33
+ `t1`.`id` AS 'c1'
34
+ FROM `owners` `t0`
35
+ LEFT OUTER JOIN `animals` `t1` ON `t1`.`owner_id` = `t0`.`id`
36
+ WHERE `t1`.`type` = 'Dog' AND
37
+ `t1`.`deleted` = FALSE
@@ -80,3 +80,26 @@ Reverse Polymorphic Example:
80
80
  - type: static
81
81
  parent: type
82
82
  value: Cat
83
+
84
+ Partitioner Example 1:
85
+ name: dogs
86
+ table: animals
87
+ partitioners:
88
+ - name: type
89
+ value: Dog
90
+ - name: deleted
91
+ value: false
92
+
93
+ Partitioner Example 2:
94
+ name: owners
95
+ models:
96
+ - name: dogs
97
+ table: animals
98
+ constraints:
99
+ - name: owner_id
100
+ parent: id
101
+ partitioners:
102
+ - name: type
103
+ value: Dog
104
+ - name: deleted
105
+ value: false
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbee-active_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Ruggio
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-28 00:00:00.000000000 Z
11
+ date: 2019-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -39,7 +39,7 @@ dependencies:
39
39
  version: '1'
40
40
  - - ">="
41
41
  - !ruby/object:Gem::Version
42
- version: 1.1.0
42
+ version: 1.2.0
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
@@ -49,7 +49,7 @@ dependencies:
49
49
  version: '1'
50
50
  - - ">="
51
51
  - !ruby/object:Gem::Version
52
- version: 1.1.0
52
+ version: 1.2.0
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: guard-rspec
55
55
  requirement: !ruby/object:Gem::Requirement
@@ -219,6 +219,8 @@ files:
219
219
  - spec/fixtures/active_record_snapshots/one_table_query_with_filters.yaml
220
220
  - spec/fixtures/active_record_snapshots/one_table_query_with_limit.yaml
221
221
  - spec/fixtures/active_record_snapshots/one_table_query_with_multiple_sorts.yaml
222
+ - spec/fixtures/active_record_snapshots/partitioner_example_1_query.yaml
223
+ - spec/fixtures/active_record_snapshots/partitioner_example_2_query.yaml
222
224
  - spec/fixtures/active_record_snapshots/reverse_polymorphic_query.yaml
223
225
  - spec/fixtures/active_record_snapshots/two_table_query.yaml
224
226
  - spec/fixtures/models.yaml
@@ -258,6 +260,8 @@ test_files:
258
260
  - spec/fixtures/active_record_snapshots/one_table_query_with_filters.yaml
259
261
  - spec/fixtures/active_record_snapshots/one_table_query_with_limit.yaml
260
262
  - spec/fixtures/active_record_snapshots/one_table_query_with_multiple_sorts.yaml
263
+ - spec/fixtures/active_record_snapshots/partitioner_example_1_query.yaml
264
+ - spec/fixtures/active_record_snapshots/partitioner_example_2_query.yaml
261
265
  - spec/fixtures/active_record_snapshots/reverse_polymorphic_query.yaml
262
266
  - spec/fixtures/active_record_snapshots/two_table_query.yaml
263
267
  - spec/fixtures/models.yaml