Class: ActiveRecord::ConnectionAdapters::QueryIntent
- Defined in:
- activerecord/lib/active_record/connection_adapters/query_intent.rb
Overview
:nodoc:
Defined Under Namespace
Classes: EventBuffer
Instance Attribute Summary collapse
-
#adapter ⇒ Object
Returns the value of attribute adapter.
-
#allow_async ⇒ Object
readonly
Returns the value of attribute allow_async.
-
#allow_retry ⇒ Object
readonly
Returns the value of attribute allow_retry.
-
#arel ⇒ Object
readonly
Returns the value of attribute arel.
-
#batch ⇒ Object
readonly
Returns the value of attribute batch.
-
#binds ⇒ Object
Returns the value of attribute binds.
-
#lock_wait ⇒ Object
readonly
Returns the value of attribute lock_wait.
-
#materialize_transactions ⇒ Object
readonly
Returns the value of attribute materialize_transactions.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#notification_payload ⇒ Object
Returns the value of attribute notification_payload.
-
#pool ⇒ Object
readonly
Returns the value of attribute pool.
-
#prepare ⇒ Object
readonly
Returns the value of attribute prepare.
-
#ran_async ⇒ Object
Returns the value of attribute ran_async.
-
#raw_sql ⇒ Object
Returns raw SQL, compiling from arel if needed, memoized.
-
#session ⇒ Object
Returns the value of attribute session.
Instance Method Summary collapse
- #affected_rows ⇒ Object
- #cancel ⇒ Object
-
#canceled? ⇒ Boolean
Was this intent canceled?.
- #cast_result ⇒ Object
-
#ensure_result ⇒ Object
Ensure the result is available, blocking if necessary.
- #execute! ⇒ Object
-
#execute_or_skip ⇒ Object
Called by background thread to execute if not already done.
- #finish ⇒ Object
- #future_result ⇒ Object
- #has_binds? ⇒ Boolean
-
#initialize(adapter:, arel: nil, raw_sql: nil, processed_sql: nil, name: "SQL", binds: [], prepare: false, allow_async: false, allow_retry: false, materialize_transactions: true, batch: false) ⇒ QueryIntent
constructor
A new instance of QueryIntent.
-
#inspect ⇒ Object
Returns a string representation showing key attributes.
-
#pending? ⇒ Boolean
Is this intent still pending (result not yet available)?.
-
#processed_sql ⇒ Object
Returns preprocessed SQL, memoized.
-
#raw_result ⇒ Object
Access the raw result, ensuring it’s available first.
-
#raw_result=(value) ⇒ Object
Internal setter for raw result.
-
#raw_result_available? ⇒ Boolean
Check if result has been populated yet (without blocking).
-
#to_h ⇒ Object
Returns a hash representation of the QueryIntent for debugging/introspection.
- #type_casted_binds ⇒ Object
Constructor Details
#initialize(adapter:, arel: nil, raw_sql: nil, processed_sql: nil, name: "SQL", binds: [], prepare: false, allow_async: false, allow_retry: false, materialize_transactions: true, batch: false) ⇒ QueryIntent
Returns a new instance of QueryIntent.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 37 def initialize(adapter:, arel: nil, raw_sql: nil, processed_sql: nil, name: "SQL", binds: [], prepare: false, allow_async: false, allow_retry: false, materialize_transactions: true, batch: false) if arel.nil? && raw_sql.nil? && processed_sql.nil? raise ArgumentError, "One of arel, raw_sql, or processed_sql must be provided" end @adapter = adapter @arel = arel @raw_sql = raw_sql @name = name @binds = binds @prepare = prepare @allow_async = allow_async @ran_async = nil @allow_retry = allow_retry @materialize_transactions = materialize_transactions @batch = batch @processed_sql = processed_sql @type_casted_binds = nil @notification_payload = nil @raw_result = nil @raw_result_available = false @executed = false @write_query = nil # Deferred execution state @pool = adapter.pool @session = nil @mutex = ActiveSupport::Concurrency::NullLock @error = nil @lock_wait = nil @event_buffer = nil end |
Instance Attribute Details
#adapter ⇒ Object
Returns the value of attribute adapter.
35 36 37 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 35 def adapter @adapter end |
#allow_async ⇒ Object (readonly)
Returns the value of attribute allow_async.
32 33 34 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 32 def allow_async @allow_async end |
#allow_retry ⇒ Object (readonly)
Returns the value of attribute allow_retry.
32 33 34 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 32 def allow_retry @allow_retry end |
#arel ⇒ Object (readonly)
Returns the value of attribute arel.
32 33 34 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 32 def arel @arel end |
#batch ⇒ Object (readonly)
Returns the value of attribute batch.
32 33 34 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 32 def batch @batch end |
#binds ⇒ Object
Returns the value of attribute binds.
35 36 37 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 35 def binds @binds end |
#lock_wait ⇒ Object (readonly)
Returns the value of attribute lock_wait.
32 33 34 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 32 def lock_wait @lock_wait end |
#materialize_transactions ⇒ Object (readonly)
Returns the value of attribute materialize_transactions.
32 33 34 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 32 def materialize_transactions @materialize_transactions end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
32 33 34 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 32 def name @name end |
#notification_payload ⇒ Object
Returns the value of attribute notification_payload.
35 36 37 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 35 def notification_payload @notification_payload end |
#pool ⇒ Object (readonly)
Returns the value of attribute pool.
32 33 34 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 32 def pool @pool end |
#prepare ⇒ Object (readonly)
Returns the value of attribute prepare.
32 33 34 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 32 def prepare @prepare end |
#ran_async ⇒ Object
Returns the value of attribute ran_async.
35 36 37 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 35 def ran_async @ran_async end |
#raw_sql ⇒ Object
Returns raw SQL, compiling from arel if needed, memoized
137 138 139 140 141 142 143 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 137 def raw_sql @raw_sql || begin compile_arel! @raw_sql end end |
#session ⇒ Object
Returns the value of attribute session.
32 33 34 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 32 def session @session end |
Instance Method Details
#affected_rows ⇒ Object
225 226 227 228 229 230 231 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 225 def affected_rows raise "Cannot call affected_rows before query has executed" unless @executed raise "Cannot call affected_rows after cast_result has been called" if defined?(@cast_result) ensure_result @affected_rows ||= adapter.send(:affected_rows, @raw_result) end |
#cancel ⇒ Object
131 132 133 134 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 131 def cancel return unless pending? @error = FutureResult::Canceled.new end |
#canceled? ⇒ Boolean
Was this intent canceled?
127 128 129 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 127 def canceled? @session && !@session.active? end |
#cast_result ⇒ Object
217 218 219 220 221 222 223 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 217 def cast_result raise "Cannot call cast_result before query has executed" unless @executed raise "Cannot call cast_result after affected_rows has been called" if defined?(@affected_rows) ensure_result @cast_result ||= adapter.send(:cast_result, @raw_result) end |
#ensure_result ⇒ Object
Ensure the result is available, blocking if necessary
205 206 207 208 209 210 211 212 213 214 215 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 205 def ensure_result if @session # Async was scheduled: wait for result (sets lock_wait) execute_or_wait end @event_buffer&.flush # Raise any error captured during deferred execution raise @error if @error end |
#execute! ⇒ Object
163 164 165 166 167 168 169 170 171 172 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 163 def execute! if can_run_async? async_schedule!(ActiveRecord::Base.asynchronous_queries_session) else @ran_async = false run_query! end ensure @executed = true end |
#execute_or_skip ⇒ Object
Called by background thread to execute if not already done
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 95 def execute_or_skip return unless pending? @session.synchronize do return unless pending? @pool.with_connection do |connection| return unless @mutex.try_lock begin if pending? @event_buffer = EventBuffer.new(self, ActiveSupport::Notifications.instrumenter) ActiveSupport::IsolatedExecutionState[:active_record_instrumenter] = @event_buffer @adapter = connection @ran_async = true run_query! end rescue => error @error = error ensure @mutex.unlock end end end end |
#finish ⇒ Object
182 183 184 185 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 182 def finish affected_rows # just to consume/close the result nil end |
#future_result ⇒ Object
174 175 176 177 178 179 180 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 174 def future_result if pending? || can_run_async? FutureResult.new(self) else FutureResult.wrap(cast_result) end end |
#has_binds? ⇒ Boolean
158 159 160 161 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 158 def has_binds? compile_arel! binds && !binds.empty? end |
#inspect ⇒ Object
Returns a string representation showing key attributes
90 91 92 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 90 def inspect "#<#{self.class.name} name=#{name.inspect} allow_retry=#{allow_retry} materialize_transactions=#{materialize_transactions}>" end |
#pending? ⇒ Boolean
Is this intent still pending (result not yet available)?
122 123 124 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 122 def pending? !@raw_result_available && @session&.active? end |
#processed_sql ⇒ Object
Returns preprocessed SQL, memoized
146 147 148 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 146 def processed_sql @processed_sql ||= preprocess_query end |
#raw_result ⇒ Object
Access the raw result, ensuring it’s available first
199 200 201 202 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 199 def raw_result ensure_result @raw_result end |
#raw_result=(value) ⇒ Object
Internal setter for raw result
188 189 190 191 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 188 def raw_result=(value) @raw_result = value @raw_result_available = true end |
#raw_result_available? ⇒ Boolean
Check if result has been populated yet (without blocking)
194 195 196 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 194 def raw_result_available? @raw_result_available end |
#to_h ⇒ Object
Returns a hash representation of the QueryIntent for debugging/introspection
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 72 def to_h { arel: arel, raw_sql: raw_sql, processed_sql: processed_sql, name: name, binds: binds, prepare: prepare, allow_async: allow_async, allow_retry: allow_retry, materialize_transactions: materialize_transactions, batch: batch, type_casted_binds: type_casted_binds, notification_payload: notification_payload } end |
#type_casted_binds ⇒ Object
150 151 152 153 154 155 156 |
# File 'activerecord/lib/active_record/connection_adapters/query_intent.rb', line 150 def type_casted_binds @type_casted_binds ||= begin compile_arel! adapter.type_casted_binds(binds) end end |