torque-postgresql 0.1.2 → 0.1.3

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
  SHA1:
3
- metadata.gz: 8300758ebf9ca8fe37a55561168b82ac794d2668
4
- data.tar.gz: c84621b0e59fe409bf130bce2a08863355f6bbdc
3
+ metadata.gz: 014c4d68ffa9d1de4f02d8f047353181a77c9b1f
4
+ data.tar.gz: acf4391b79a96c8a62aa69e0f6040f76ae43f8fa
5
5
  SHA512:
6
- metadata.gz: 083ad94ce20f01f59b2b7380e1bc615eb715f36c9f638a635dd43708ad5ca07d55247eece6676470f00079e4f0410ec2847884e9bf3915a3f11390c8c2588f8c
7
- data.tar.gz: 0da07cbc82ce422e8ef8d703ac9fb0818e160bb4cdabac782fb9a77f9d0cace067bb58f6e9d8881cdad73ed7e6649cfadedd5a90cae8f5ba955ffefb540228ad
6
+ metadata.gz: b98efaf4fb140e2d14bcae43cdbcbbbd2439bf70e770e4001a2ba547000bc6e3f15bca4b7ceab4daa845e581c983026f318ac6befa0517ff39c6f90a9e12bcfb
7
+ data.tar.gz: 0a5fa71f9f8809fb405eae0ea15fc5943f7eb0b627301002157b6b5dac886e1443d5f4e793f69799411d4271db9c6f0d52f6df5baf71aa049b6d33526d9d2a6a
@@ -18,3 +18,8 @@ require 'torque/postgresql/base'
18
18
  require 'torque/postgresql/migration'
19
19
  require 'torque/postgresql/relation'
20
20
  require 'torque/postgresql/schema_dumper'
21
+
22
+ gdep = Gem::Dependency.new('arel', '~> 9.0.0')
23
+ unless gdep.matching_specs.sort_by(&:version).last
24
+ require 'torque/postgresql/arel/visitors'
25
+ end
@@ -0,0 +1,14 @@
1
+ module Torque
2
+ module PostgreSQL
3
+ module Arel
4
+ module Visitors
5
+ def visit_Arel_SelectManager o, collector
6
+ collector << '('
7
+ visit(o.ast, collector) << ')'
8
+ end
9
+ end
10
+
11
+ ::Arel::Visitors::ToSql.prepend Visitors
12
+ end
13
+ end
14
+ end
@@ -60,7 +60,7 @@ module Torque
60
60
 
61
61
  # Get the arel version of the statement table
62
62
  def table
63
- @table ||= Arel::Table.new(table_name)
63
+ @table ||= ::Arel::Table.new(table_name)
64
64
  end
65
65
 
66
66
  # Get the name of the table of the configurated statement
@@ -80,9 +80,11 @@ module Torque
80
80
 
81
81
  # Project a column on a given table, or use the column table
82
82
  def project(column, arel_table = nil)
83
- if column.to_s.include?('.')
83
+ if column.respond_to?(:as)
84
+ return column
85
+ elsif column.to_s.include?('.')
84
86
  table_name, column = column.to_s.split('.')
85
- arel_table = Arel::Table.new(table_name)
87
+ arel_table = ::Arel::Table.new(table_name)
86
88
  end
87
89
 
88
90
  arel_table ||= table
@@ -102,45 +104,8 @@ module Torque
102
104
 
103
105
  # Setup the class
104
106
  def setup!
105
- # attributes key:
106
- # Provides a map of attributes to be exposed to the main query.
107
- #
108
- # For instace, if the statement query has an 'id' column that you
109
- # want it to be accessed on the main query as 'item_id',
110
- # you can use:
111
- # attributes id: :item_id
112
- #
113
- # If its statement has more tables, and you want to expose those
114
- # fields, then:
115
- # attributes 'table.name': :item_name
116
- #
117
- # join_type key:
118
- # Changes the type of the join and set the constraints
119
- #
120
- # The left side of the hash is the source table column, the right
121
- # side is the statement table column, now it's only accepting '='
122
- # constraints
123
- # join id: :user_id
124
- # join id: :'user.id'
125
- # join 'post.id': :'user.last_post_id'
126
- #
127
- # It's possible to change the default type of join
128
- # join :left, id: :user_id
129
- #
130
- # join key:
131
- # Changes the type of the join
132
- #
133
- # query key:
134
- # Save the query command to be performand
135
- #
136
- # requires key:
137
- # Indicates dependencies with another statements
138
- #
139
- # polymorphic key:
140
- # Indicates a polymorphic relationship, with will affect the way the
141
- # auto join works, by giving a polymorphic connection
142
107
  settings = Settings.new(self)
143
- @config.call(settings)
108
+ settings.instance_exec(settings, &@config)
144
109
 
145
110
  @join_type = settings.join_type || :inner
146
111
  @requires = Array[settings.requires].flatten.compact
@@ -232,24 +197,28 @@ module Torque
232
197
 
233
198
  # Build the statement on the given arel and return the WITH statement
234
199
  def build_arel(arel, base)
235
- list = []
236
-
237
- # Process dependencies
238
- if requires.present?
239
- requires.each do |dependent|
240
- next if base.auxiliary_statements.key?(dependent)
241
-
242
- instance = AuxiliaryStatement.instantiate(dependent, base)
243
- base.auxiliary_statements[dependent] = instance
244
- list << instance.build_arel(arel, base)
245
- end
246
- end
247
-
248
200
  # Build the join for this statement
249
201
  arel.join(table, arel_join).on(*join_columns)
250
202
 
251
203
  # Return the subquery for this statement
252
- list << Arel::Nodes::As.new(table, mount_query)
204
+ ::Arel::Nodes::As.new(table, mount_query)
205
+ end
206
+
207
+ # Get the bound attributes from statement qeury
208
+ def bound_attributes
209
+ return [] unless relation_query?(self.class.query)
210
+ self.class.query.send(:bound_attributes)
211
+ end
212
+
213
+ # Ensure that all the dependencies are loaded in the base relation
214
+ def ensure_dependencies!(base)
215
+ requires.each do |dependent|
216
+ next if base.auxiliary_statements.key?(dependent)
217
+
218
+ instance = AuxiliaryStatement.instantiate(dependent, base)
219
+ instance.ensure_dependencies!(base)
220
+ base.auxiliary_statements[dependent] = instance
221
+ end
253
222
  end
254
223
 
255
224
  private
@@ -257,10 +226,10 @@ module Torque
257
226
  # Get the class of the join on arel
258
227
  def arel_join
259
228
  case @join_type
260
- when :inner then Arel::Nodes::InnerJoin
261
- when :left then Arel::Nodes::OuterJoin
262
- when :right then Arel::Nodes::RightOuterJoin
263
- when :full then Arel::Nodes::FullOuterJoin
229
+ when :inner then ::Arel::Nodes::InnerJoin
230
+ when :left then ::Arel::Nodes::OuterJoin
231
+ when :right then ::Arel::Nodes::RightOuterJoin
232
+ when :full then ::Arel::Nodes::FullOuterJoin
264
233
  else
265
234
  raise ArgumentError, <<-MSG.strip
266
235
  The '#{@join_type}' is not implemented as a join type.
@@ -272,7 +241,7 @@ module Torque
272
241
  def mount_query
273
242
  klass = self.class
274
243
  query = klass.query
275
- uses = @uses.map(&klass.parent.connection.method(:quote))
244
+ uses = @uses
276
245
 
277
246
  # Call a proc to get the query
278
247
  if query.respond_to?(:call)
@@ -282,9 +251,10 @@ module Torque
282
251
 
283
252
  # Prepare the query depending on its type
284
253
  if query.is_a?(String)
285
- Arel::Nodes::SqlLiteral.new("(#{query})" % uses)
254
+ uses.map!(&klass.parent.connection.method(:quote))
255
+ ::Arel::Nodes::SqlLiteral.new("(#{query})" % uses)
286
256
  elsif relation_query?(query)
287
- query.select(*select_columns).send(:build_arel)
257
+ query.select(*select_columns).arel
288
258
  else
289
259
  raise ArgumentError, <<-MSG.strip
290
260
  Only String and ActiveRecord::Base objects are accepted as query objects,
@@ -21,8 +21,20 @@ module Torque
21
21
  @query_table
22
22
  end
23
23
 
24
+ # Grant an easy access to arel table columns
25
+ def col(name)
26
+ query_table[name.to_s]
27
+ end
28
+
29
+ alias column col
30
+
31
+ # Grant an easy access to arel sql literal
32
+ def sql(string)
33
+ ::Arel::Nodes::SqlLiteral.new(string)
34
+ end
35
+
24
36
  # There are two ways of setting the query:
25
- # - A simple relation based on a modle
37
+ # - A simple relation based on a Model
26
38
  # - A string or a proc that requires the table name as first argument
27
39
  def query(value = nil, command = nil)
28
40
  return @query if value.nil?
@@ -39,7 +51,7 @@ module Torque
39
51
  MSG
40
52
 
41
53
  @query = command
42
- @query_table = Arel::Table.new(value)
54
+ @query_table = ::Arel::Table.new(value)
43
55
  end
44
56
 
45
57
  end
@@ -14,6 +14,44 @@ module Torque
14
14
  protected
15
15
 
16
16
  # Creates a new auxiliary statement (CTE) under the base class
17
+ # attributes key:
18
+ # Provides a map of attributes to be exposed to the main query.
19
+ #
20
+ # For instace, if the statement query has an 'id' column that you
21
+ # want it to be accessed on the main query as 'item_id',
22
+ # you can use:
23
+ # attributes id: :item_id, 'MAX(id)' => :max_id,
24
+ # col(:id).minimum => :min_id
25
+ #
26
+ # If its statement has more tables, and you want to expose those
27
+ # fields, then:
28
+ # attributes 'table.name': :item_name
29
+ #
30
+ # join_type key:
31
+ # Changes the type of the join and set the constraints
32
+ #
33
+ # The left side of the hash is the source table column, the right
34
+ # side is the statement table column, now it's only accepting '='
35
+ # constraints
36
+ # join id: :user_id
37
+ # join id: :'user.id'
38
+ # join 'post.id': :'user.last_post_id'
39
+ #
40
+ # It's possible to change the default type of join
41
+ # join :left, id: :user_id
42
+ #
43
+ # join key:
44
+ # Changes the type of the join
45
+ #
46
+ # query key:
47
+ # Save the query command to be performand
48
+ #
49
+ # requires key:
50
+ # Indicates dependencies with another statements
51
+ #
52
+ # polymorphic key:
53
+ # Indicates a polymorphic relationship, with will affect the way the
54
+ # auto join works, by giving a polymorphic connection
17
55
  def auxiliary_statement(table, &block)
18
56
  klass = AuxiliaryStatement.lookup(table, self)
19
57
  auxiliary_statements_list[table.to_sym] = klass
@@ -26,7 +26,7 @@ module Torque
26
26
  list.map do |item|
27
27
  case item
28
28
  when String
29
- Arel::Nodes::SqlLiteral.new(klass.send(:sanitize_sql, item.to_s))
29
+ ::Arel::Nodes::SqlLiteral.new(klass.send(:sanitize_sql, item.to_s))
30
30
  when Symbol
31
31
  base ? base.arel_attribute(item) : klass.arel_attribute(item)
32
32
  when Array
@@ -15,12 +15,22 @@ module Torque
15
15
  options = args.extract_options!
16
16
  self.auxiliary_statements ||= {}
17
17
  args.each do |table|
18
- self.auxiliary_statements[table] = instantiate(table, self, options)
18
+ instance = instantiate(table, self, options)
19
+ instance.ensure_dependencies!(self)
20
+ self.auxiliary_statements[table] = instance
19
21
  end
20
22
 
21
23
  self
22
24
  end
23
25
 
26
+ # Get all auxiliary statements bound attributes and the base bound
27
+ # attributes as well
28
+ def bound_attributes
29
+ return super unless self.auxiliary_statements.present?
30
+ bindings = self.auxiliary_statements.values.map(&:bound_attributes)
31
+ (bindings + super).flatten
32
+ end
33
+
24
34
  private
25
35
  delegate :instantiate, to: PostgreSQL::AuxiliaryStatement
26
36
 
@@ -37,7 +47,7 @@ module Torque
37
47
 
38
48
  arel.with(subqueries.flatten)
39
49
  if select_values.empty? && columns.any?
40
- columns.unshift table[Arel.sql('*')]
50
+ columns.unshift table[::Arel.star]
41
51
  arel.projections = columns
42
52
  end
43
53
  end
@@ -1,5 +1,5 @@
1
1
  module Torque
2
2
  module PostgreSQL
3
- VERSION = '0.1.2'
3
+ VERSION = '0.1.3'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: torque-postgresql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carlos Silva
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-28 00:00:00.000000000 Z
11
+ date: 2018-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -191,6 +191,7 @@ files:
191
191
  - lib/torque/postgresql/adapter/schema_definitions.rb
192
192
  - lib/torque/postgresql/adapter/schema_dumper.rb
193
193
  - lib/torque/postgresql/adapter/schema_statements.rb
194
+ - lib/torque/postgresql/arel/visitors.rb
194
195
  - lib/torque/postgresql/attributes.rb
195
196
  - lib/torque/postgresql/attributes/builder.rb
196
197
  - lib/torque/postgresql/attributes/builder/enum.rb
@@ -230,7 +231,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
230
231
  version: 1.8.11
231
232
  requirements: []
232
233
  rubyforge_project:
233
- rubygems_version: 2.5.1
234
+ rubygems_version: 2.6.14
234
235
  signing_key:
235
236
  specification_version: 4
236
237
  summary: ActiveRecord extension to access PostgreSQL advanced resources