Class: ActiveRecord::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/active_record/connection_adapters/ibm_db_pstmt.rb,
lib/active_record/connection_adapters/ibm_db_adapter.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.add_conditions!(sql, conditions, scope = :auto) ⇒ Object

Adds a sanitized version of conditions to the sql string. Note that the passed-in sql string is changed. The optional scope argument is for the current :find scope.



575
576
577
578
579
580
581
582
583
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 575

def add_conditions!(sql, conditions, scope = :auto)
  scope = scope(:find) if :auto == scope
  conditions = [conditions]
  conditions << scope[:conditions] if scope
  conditions << type_condition if finder_needs_type_condition?
  merged_conditions = merge_conditions(*conditions)
  sql << "WHERE #{merged_conditions["sqlSegment"]} " unless merged_conditions["sqlSegment"].blank?
  merged_conditions["paramArray"]
end

.add_group!(sql, group, having, scope = :auto) ⇒ Object



343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 343

def add_group!(sql, group, having, scope = :auto)
  param_array = []
  if group
    sql << " GROUP BY #{group}"
    if having
      sql_param_hash = sanitize_sql_for_conditions(having)
      sql << " HAVING #{sql_param_hash["sqlSegment"]}"
      param_array = param_array + sql_param_hash["paramArray"] unless sql_param_hash["paramArray"].nil?
    end
  else
    scope = scope(:find) if :auto == scope
    if scope && (scoped_group = scope[:group])
      sql << " GROUP BY #{scoped_group}"
      if scope[:having]
        sql_param_hash = sanitize_sql_for_conditions(scope[:having])
        sql << " HAVING #{sql_param_hash["sqlSegment"]}"
        param_array = param_array + sql_param_hash["paramArray"] unless sql_param_hash["paramArray"].nil?
      end
    end
  end
  param_array
end

.add_joins!(sql, joins, scope = :auto) ⇒ Object

The optional scope argument is for the current :find scope.



367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 367

def add_joins!(sql, joins, scope = :auto)
  param_array = []
  scope = scope(:find) if :auto == scope

  if joins.is_a?(Hash) && joins.has_key?("pstmt_hook")
    param_array = joins["pstmt_hook"]["paramArray"]
    joins = joins["pstmt_hook"]["sqlSegment"]
  end

  merged_joins = if scope && scope[:joins] && joins 
                   join_merge_hash = merge_joins(scope[:joins], joins)
                   param_array = param_array + join_merge_hash["pstmt_hook"]["paramArray"]
                   join_merge_hash["pstmt_hook"]["sqlSegment"]
                 else
                   if(scope && scope[:joins].is_a?(Hash) && scope[:joins].has_key?("pstmt_hook"))
                     param_array = scope[:joins]["pstmt_hook"]["paramArray"]
                     (joins || scope[:joins]["pstmt_hook"]["sqlSegment"])
                   else
                     (joins || scope && scope[:joins])
                   end
                 end

  case merged_joins
  when Symbol, Hash, Array
    if array_of_strings?(merged_joins)
      sql << merged_joins.join(' ') + " "
    else
      join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, merged_joins, nil)
      sql << " #{join_dependency.join_associations.collect { |assoc| 
                    sql_param_hash = assoc.association_join 
                    param_array = param_array + sql_param_hash["paramArray"] unless sql_param_hash["paramArray"].nil?
                    sql_param_hash["sqlSegment"]
                  }.join} "
    end
  when String
    sql << " #{merged_joins} "
  end
  param_array
end

.attribute_condition(quoted_column_name, argument) ⇒ Object



598
599
600
601
602
603
604
605
606
607
608
609
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 598

def attribute_condition(quoted_column_name, argument)
  case argument
    when nil   then "#{quoted_column_name} IS NULL"
    when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope then "#{quoted_column_name} IN (?)"
    when Range then if argument.exclude_end?
                      "#{quoted_column_name} >= ? AND #{quoted_column_name} < ?"
                    else
                      "#{quoted_column_name} BETWEEN ? AND ?"
                    end
    else            "#{quoted_column_name} = ?"
  end
end

.construct_finder_sql(options) ⇒ Object



318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 318

def construct_finder_sql(options)
  param_array = []
  scope = scope(:find)
  sql  = "SELECT #{options[:select] || (scope && scope[:select]) || default_select(options[:joins] || (scope && scope[:joins]))} "
  sql << "FROM #{options[:from]  || (scope && scope[:from]) || quoted_table_name} "

  param_array = add_joins!(sql, options[:joins], scope)

  param_array = param_array + add_conditions!(sql, options[:conditions], scope)

  param_array = param_array + add_group!(sql, options[:group], options[:having], scope)

  add_order!(sql, options[:order], scope)

  temp_options = options.dup # Ensure that the necessary parameters are received in the duplicate, so that the original hash is intact
  temp_options[:paramArray] = [] # To receive the values for limit and offset.
  add_limit!(sql, temp_options, scope)

  param_array = param_array + temp_options[:paramArray]

  add_lock!(sql, options, scope)

  [sql] + param_array
end

.count_by_sql(sql) ⇒ Object



471
472
473
474
475
476
477
478
479
480
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 471

def count_by_sql(sql)
  sql_param_hash = sanitize_conditions(sql)
  result = connection.prepared_select(sql_param_hash, "#{name} Count").first
  #result will be of type Hash.
  if result
    return result.values.first.to_i  #Retrieve the first value from hash
  else
    return 0
  end
end

.delete_all(conditions = nil) ⇒ Object



542
543
544
545
546
547
548
549
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 542

def delete_all(conditions = nil)
  sql = "DELETE FROM #{quoted_table_name} "
  param_array = add_conditions!(sql, conditions, scope(:find))
  # Prepare the sql for deleting the rows
  pstmt = connection.prepare(sql, "#{name} Delete all")
  # Execute the prepared Statement
  connection.prepared_delete(pstmt, param_array)
end

.expand_id_conditions(id_or_conditions) ⇒ Object

Interpret Array and Hash as conditions and anything else as an id.



311
312
313
314
315
316
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 311

def expand_id_conditions(id_or_conditions)
  case id_or_conditions
    when Array, Hash then id_or_conditions
    else {primary_key => id_or_conditions}
  end
end

.find_by_sql(sql) ⇒ Object



305
306
307
308
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 305

def find_by_sql(sql)
  sql_param_hash = sanitize_sql(sql)
  connection.prepared_select(sql_param_hash, "#{name} Load").collect! { |record| instantiate(record) }
end

.find_one(id, options) ⇒ Object



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 192

def find_one(id, options)
  param_array = [quote_value(id,columns_hash[primary_key])]
  if options[:conditions]
    sql_param_hash = sanitize_sql(options[:conditions])
    conditions = " AND (#{sql_param_hash["sqlSegment"]})"
    param_array = param_array + sql_param_hash["paramArray"] unless sql_param_hash["paramArray"].nil?
  end

  options.update :conditions => ["#{quoted_table_name}.#{connection.quote_column_name(primary_key)} = ?#{conditions}"] + param_array

  # Use find_every(options).first since the primary key condition
  # already ensures we have a single record. Using find_initial adds
  # a superfluous :limit => 1.
  if result = find_every(options).first
    result
  else
    raise RecordNotFound, "Couldn't find #{name} with ID=#{id}#{conditions} with parameters #{param_array.last(param_array.size-1)}"
  end
end

.find_some(ids, options) ⇒ Object



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 212

def find_some(ids, options)
  param_array = []
  ids_array = ids.map { |id| quote_value(id,columns_hash[primary_key]) }
  if options[:conditions]
    sql_param_hash = sanitize_sql(options[:conditions])
    conditions = " AND (#{sql_param_hash["sqlSegment"]})"
    param_array = param_array + sql_param_hash["paramArray"] unless sql_param_hash["paramArray"].nil?
  end

  options.update :conditions => ["#{quoted_table_name}.#{connection.quote_column_name(primary_key)} IN (?)#{conditions}"] + [ids_array] + param_array

  result = find_every(options)

  # Determine expected size from limit and offset, not just ids.size.
  expected_size =
    if options[:limit] && ids.size > options[:limit]
      options[:limit]
    else
      ids.size
    end

  # 11 ids with limit 3, offset 9 should give 2 results.
  if options[:offset] && (ids.size - options[:offset] < expected_size)
    expected_size = ids.size - options[:offset]
  end

  if result.size == expected_size
    result
  else
    raise RecordNotFound, "Couldn't find all #{name.pluralize} with IDs (#{ids.join(', ')})#{conditions} with parameter(s) #{param_array.join(', ')} (found #{result.size} results, but was looking for #{expected_size})"
  end
end

.ibm_db_connection(config) ⇒ Object

Establishes a connection to a specified database using the credentials provided with the config argument. All the ActiveRecord objects will use this connection



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/active_record/connection_adapters/ibm_db_adapter.rb', line 101

def self.ibm_db_connection(config)
  # Attempts to load the Ruby driver IBM databases
  # while not already loaded or raises LoadError in case of failure.
  begin
    require 'ibm_db' unless defined? IBM_DB
  rescue LoadError
    raise LoadError, "Failed to load IBM_DB Ruby driver."
  end

  if( config.has_key?(:parameterized) && config[:parameterized] == true )
    require 'active_record/connection_adapters/ibm_db_pstmt'
  end

  # Converts all +config+ keys to symbols
  config = config.symbolize_keys

  # Flag to decide if quoted literal replcement should take place. By default it is ON. Set it to OFF if using Pstmt
  set_quoted_literal_replacement = IBM_DB::QUOTED_LITERAL_REPLACEMENT_ON

  # Retrieves the database alias (local catalog name) or remote name
  # (for remote TCP/IP connections) from the +config+ hash
  # or raises ArgumentError in case of failure.
  if config.has_key?(:database)
    database = config[:database].to_s
  else
    raise ArgumentError, "Missing argument: a database name needs to be specified."
  end

  # Retrieves database user credentials from the +config+ hash
  # or raises ArgumentError in case of failure.
  if !config.has_key?(:username) || !config.has_key?(:password)
    raise ArgumentError, "Missing argument(s): Username/Password for #{config[:database]} is not specified"
  else
    username = config[:username].to_s
    password = config[:password].to_s
  end

  # Providing default schema (username) when not specified
  config[:schema] = config.has_key?(:schema) ? config[:schema].to_s : config[:username].to_s

  if(config.has_key?(:parameterized) && config[:parameterized] == true )
    set_quoted_literal_replacement = IBM_DB::QUOTED_LITERAL_REPLACEMENT_OFF
  end

  # Extract connection options from the database configuration
  # (in support to formatting, audit and billing purposes):
  # Retrieve database objects fields in lowercase
  conn_options = {IBM_DB::ATTR_CASE => IBM_DB::CASE_LOWER}
  config.each do |key, value|
    if !value.nil?
      case key
        when :app_user        # Set connection's user info
          conn_options[IBM_DB::SQL_ATTR_INFO_USERID]     = value
        when :account         # Set connection's account info
          conn_options[IBM_DB::SQL_ATTR_INFO_ACCTSTR]    = value
        when :application     # Set connection's application info
          conn_options[IBM_DB::SQL_ATTR_INFO_APPLNAME]   = value
        when :workstation     # Set connection's workstation info
          conn_options[IBM_DB::SQL_ATTR_INFO_WRKSTNNAME] = value
      end    
    end
  end

  begin
    # Checks if a host name or address has been specified. If so, this implies a TCP/IP connection
    # Returns IBM_DB.Connection object upon succesful DB connection to the database
    # If otherwise the connection fails, +false+ is returned
    if config.has_key?(:host)
      # Retrieves the host address/name
      host = config[:host]
      # A net address connection requires a port. If no port has been specified, 50000 is used by default
      port = config[:port] || 50000
      # Connects to the database specified using the hostname, port, authentication type, username and password info
      # Starting with DB2 9.1FP5 secure connections using SSL are supported. 
      # On the client side using CLI this is supported from CLI version V95FP2 and onwards.
      # This feature is set by specifying SECURITY=SSL in the connection string.
      # Below connection string is constructed and SECURITY parameter is appended if the user has specified the :security option
      conn_string = "DRIVER={IBM DB2 ODBC DRIVER};\
                     DATABASE=#{database};\
                     HOSTNAME=#{host};\
                     PORT=#{port};\
                     PROTOCOL=TCPIP;\
                     UID=#{username};\
                     PWD=#{password};"
      conn_string << "SECURITY=#{config[:security]};" if config.has_key?(:security)
      conn_string << "AUTHENTICATION=#{config[:authentication]};" if config.has_key?(:authentication)
      conn_string << "CONNECTTIMEOUT=#{config[:timeout]};" if config.has_key?(:timeout)
    
      connection = IBM_DB.connect( conn_string, '', '', conn_options, set_quoted_literal_replacement )
    else
      # No host implies a local catalog-based connection: +database+ represents catalog alias
      connection = IBM_DB.connect( database, username, password, conn_options,  set_quoted_literal_replacement )
    end
  rescue StandardError => connect_err
    raise "Failed to connect to [#{database}] due to: #{connect_err}"
  end
  # Verifies that the connection was successful
  if connection
    # Creates an instance of *IBM_DBAdapter* based on the +connection+
    # and credentials provided in +config+
    ConnectionAdapters::IBM_DBAdapter.new(connection, logger, config, conn_options)
  else
    # If the connection failure was not caught previoulsy, it raises a Runtime error
    raise "An unexpected error occured during connect attempt to [#{database}]"
  end
end

.merge_conditions(*conditions) ⇒ Object

Merges conditions so that the result is a valid condition



552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 552

def merge_conditions(*conditions)
  segments = []
  return_hash = {}
  return_hash["paramArray"] = []
  conditions.each do |condition|
    unless condition.blank?
      sql_param_hash = sanitize_sql(condition)
      unless sql_param_hash["sqlSegment"].blank?
        segments << sql_param_hash["sqlSegment"]
        if !sql_param_hash["paramArray"].nil? && !sql_param_hash["paramArray"].empty?
          return_hash["paramArray"] = return_hash["paramArray"] + 
                                      sql_param_hash["paramArray"]
        end
      end
    end
  end

  return_hash["sqlSegment"] = "(#{segments.join(') AND (')})" unless segments.empty?
  return_hash
end

.merge_joins(*joins) ⇒ Object



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 245

def merge_joins(*joins)
  sql_param_hash = {}
  param_array = []
  if joins.any?{|j| j.is_a?(String) || array_of_strings?(j) || (j.is_a?(Hash) && j.has_key?("pstmt_hook"))}
    joins_array = []
    joins_compare_array = []

    joins.each do |join|
      get_join_associations = true
      if join.is_a?(String)
        unless joins_compare_array.include?(join)
          joins_array << join
          joins_compare_array << join
        end
        get_join_associations = false
      elsif (join.is_a?(Hash) && join.has_key?("pstmt_hook"))
        if(join["pstmt_hook"]["sqlSegment"].is_a?(Array))
          compare_string = join["pstmt_hook"]["sqlSegment"].join(" ") + join["pstmt_hook"]["paramArray"].join(" ")
        else
          compare_string = join["pstmt_hook"]["sqlSegment"] + join["pstmt_hook"]["paramArray"].join(" ")
        end
        unless joins_compare_array.include?(compare_string)
          param_array = param_array + join["pstmt_hook"]["paramArray"] unless join["pstmt_hook"]["paramArray"].nil?
          joins_array << join["pstmt_hook"]["sqlSegment"]
          joins_compare_array << compare_string
        end
        get_join_associations = false
      end
      unless array_of_strings?(join)
        if get_join_associations
          join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, join, nil)
          join_dependency.join_associations.each do |assoc| 
            sql_param_hash = assoc.association_join
            compare_string = nil
            compare_string = sql_param_hash["sqlSegment"] + sql_param_hash["paramArray"].join(" ") unless sql_param_hash.nil?
            unless compare_string.nil? || joins_array.include?(compare_string)
              param_array = param_array + sql_param_hash["paramArray"] unless sql_param_hash["paramArray"].nil?
              joins_array << sql_param_hash["sqlSegment"]
              joins_compare_array << compare_string
            end
          end
        end
      else
        if get_join_associations
          joins_array = joins_array + join.flatten.map{|j| j.strip }.uniq
        end
      end
    end
    sql_param_hash["sqlSegment"] = joins_array.flatten.map{|j| j.strip }.uniq
    sql_param_hash["paramArray"] = param_array
    {"pstmt_hook" => sql_param_hash}
  else
    sql_param_hash["sqlSegment"] = joins.collect{|j| safe_to_array(j)}.flatten.uniq
    sql_param_hash["paramArray"] = param_array
    {"pstmt_hook" => sql_param_hash}
  end
end

.quote_bound_value(value) ⇒ Object

Returns an array of parameter values, with the values respectively quoted if of type date time or is nil



769
770
771
772
773
774
775
776
777
778
779
780
781
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 769

def quote_bound_value(value) #:nodoc:
  if value.respond_to?(:map) && !value.acts_like?(:string)
    if (value.respond_to?(:empty?) && value.empty?) || value.nil?
      [nil]
    else
      value.map { |v| 
          connection.quote_value_for_pstmt(v)
      }
    end
  else
    [connection.quote_value_for_pstmt(value)]
  end
end

.quote_value(value, column = nil) ⇒ Object

:nodoc:



482
483
484
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 482

def quote_value(value, column = nil) #:nodoc:
  connection.quote_value_for_pstmt(value,column)
end

.replace_bind_variables(statement, values) ⇒ Object

Check delete_all method, which passes a ? and array of params, as an example. This method replace_bind_variables replaces those ? with a string of the values. For Eg:- if said Wood.delete(), delete all sends the condition as [“id in (?)”, [1,2,3,4]] This method sends the condition part back as string, “id in (1,2,3,4)” originally Now this method is modified to send out a hash containing the parameter array and the sql to be prepared



716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 716

def replace_bind_variables(statement, values)
  raise_if_bind_arity_mismatch(statement, statement.count('?'), values.size)
  bound = values.dup
  return_hash = {}
  return_hash["paramArray"] = []
  return_hash["sqlSegment"] = ''

  return_hash["sqlSegment"] = 
     statement.gsub('?') {
        str_seg = ''
        param_array = quote_bound_value(bound.shift)
        if param_array && param_array.size > 1
          for index in 0...param_array.size-1
            str_seg << '?,'
          end
        end
        str_seg << '?'
        return_hash["paramArray"] = return_hash["paramArray"] + param_array unless param_array.nil?
        str_seg
      }
  return_hash
end

.replace_named_bind_variables(statement, bind_vars) ⇒ Object

Replaces the named parameters with ‘?’ and pass a hash containing the sql’s condition clause segment and the parameters array



740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 740

def replace_named_bind_variables(statement, bind_vars) #:nodoc:
  return_hash = {}
  return_hash["paramArray"] = []
  return_hash["sqlSegment"] = ''

  return_hash["sqlSegment"] =
    statement.gsub(/(:?):([a-zA-Z]\w*)/) {

      if $1 == ':' # skip postgresql casts
        $& # return the whole match
      elsif bind_vars.include?(match = $2.to_sym)
        str_seg = ''
        param_array = quote_bound_value(bind_vars[match])
        if param_array.size > 1
          for index in 0...param_array.size-1
            str_seg << '?,'
          end
        end
        str_seg << '?'
        return_hash["paramArray"] = return_hash["paramArray"] + param_array
        str_seg
      else
        raise PreparedStatementInvalid, "missing value for :#{match} in #{statement}"
      end
    }
  return_hash
end

.sanitize_sql_array(ary) ⇒ Object

Accepts an array of conditions. The array has each value sanitized and interpolated into the SQL statement.



661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 661

def sanitize_sql_array(ary)
  statement, *values = ary
  return_hash = {}

  if values.first.is_a?(Hash) and statement =~ /:\w+/
    replace_named_bind_variables(statement, values.first)
  elsif statement && statement.include?('?')
    replace_bind_variables(statement, values)
  else
    if !values.nil? && values.size > 0
      return_hash["sqlSegment"] = statement % values.collect { |value| connection.quote_string(value.to_s) }
    else
      return_hash["sqlSegment"] = statement
    end
    return_hash["paramArray"] = []
    return_hash
  end
end

.sanitize_sql_for_assignment(assignments) ⇒ Object

Accepts an array, hash, or string of SQL conditions and sanitizes them into a valid SQL fragment for a SET clause.

{ :name => nil, :group_id => 4 }  returns "name = NULL , group_id='4'"


630
631
632
633
634
635
636
637
638
639
640
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 630

def sanitize_sql_for_assignment(assignments)
  return_hash = {}
  case assignments
    when Array; sanitize_sql_array(assignments)
    when Hash;  sanitize_sql_hash_for_assignment(assignments)
    else        
      return_hash["sqlSegment"] = assignments
      return_hash["paramArray"] = nil
      return_hash
  end
end

.sanitize_sql_for_conditions(condition, table_name = quoted_table_name) ⇒ Object Also known as: sanitize_sql, sanitize_conditions



642
643
644
645
646
647
648
649
650
651
652
653
654
655
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 642

def sanitize_sql_for_conditions(condition, table_name = quoted_table_name)
  return nil if condition.blank?

  return_hash = {}

  case condition
    when Array; sanitize_sql_array(condition)
    when Hash;  sanitize_sql_hash_for_conditions(condition, table_name)
    else
      return_hash["sqlSegment"] = condition
      return_hash["paramArray"] = nil
      return_hash
  end
end

.sanitize_sql_hash_for_assignment(attrs) ⇒ Object

Sanitizes a hash of attribute/value pairs into SQL conditions for a SET clause.

{ :status => nil, :group_id => 1 }
  # => "status = NULL , group_id = 1"


616
617
618
619
620
621
622
623
624
625
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 616

def sanitize_sql_hash_for_assignment(attrs)
  return_hash = {}
  return_hash["paramArray"] = []

  return_hash["sqlSegment"] = attrs.map do |attr, value|
    return_hash["paramArray"] += quote_bound_value(value)
    "#{connection.quote_column_name(attr)} = ?"
  end.join(', ')
  return_hash
end

.sanitize_sql_hash_for_conditions(attrs, table_name = quoted_table_name) ⇒ Object Also known as: sanitize_sql_hash



680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 680

def sanitize_sql_hash_for_conditions(attrs, table_name = quoted_table_name)
  attrs = expand_hash_conditions_for_aggregates(attrs)
  temp_table_name = table_name

  param_array = []

  conditions = attrs.map do |attr, value|
    unless value.is_a?(Hash)
      attr = attr.to_s

      # Extract table name from qualified attribute names.
      if attr.include?('.')
        table_name, attr = attr.split('.', 2)
        table_name = connection.quote_table_name(table_name)
      else
        table_name = temp_table_name
      end

      param_array << value unless value.nil?
      attribute_condition("#{table_name}.#{connection.quote_column_name(attr)}", value)
    else
      sql_param_hash = sanitize_sql_hash_for_conditions(value, connection.quote_table_name(attr.to_s))
      param_array = param_array + sql_param_hash["paramArray"] unless sql_param_hash["paramArray"].empty?
      sql_param_hash["sqlSegment"]
    end
  end.join(' AND ')

  replace_bind_variables(conditions, expand_range_bind_variables(param_array))
end

.type_condition(table_alias = nil) ⇒ Object



585
586
587
588
589
590
591
592
593
594
595
596
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 585

def type_condition(table_alias=nil)
  param_array = []
  quoted_table_alias = self.connection.quote_table_name(table_alias || table_name)
  quoted_inheritance_column = connection.quote_column_name(inheritance_column)
  param_array << self.connection.quote_value_for_pstmt(sti_name)
  type_condition = subclasses.inject("#{quoted_table_alias}.#{quoted_inheritance_column} = ? ") do |condition, subclass|
    param_array << self.connection.quote_value_for_pstmt(subclass.sti_name)
    condition << "OR #{quoted_table_alias}.#{quoted_inheritance_column} = ? "
  end

  [" (#{type_condition}) "] + param_array
end

.update_all(updates, conditions = nil, options = {}) ⇒ Object



486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 486

def update_all(updates, conditions = nil, options = {})
  sql_values_hash = sanitize_sql_for_assignment(updates)
  param_array = sql_values_hash["paramArray"]

  sql  = "UPDATE #{quoted_table_name} SET #{sql_values_hash["sqlSegment"]} "

  scope = scope(:find)

  select_sql = ""
  temp_param_array = add_conditions!(select_sql, conditions, scope)

  if !param_array.nil? && !param_array.empty?
    param_array += temp_param_array
  else
    param_array = temp_param_array
  end

  if options.has_key?(:limit) || (scope && scope[:limit])
    # Only take order from scope if limit is also provided by scope, this
    # is useful for updating a has_many association with a limit.
    add_order!(select_sql, options[:order], scope)

    temp_options = options.dup # Ensure that the necessary parameters are received in the duplicate, so that the original hash is intact
    temp_options[:paramArray] = [] # To receive the values for limit and offset.
    add_limit!(select_sql, temp_options, scope)
    param_array = param_array + temp_options[:paramArray]

    sql.concat(connection.limited_update_conditions(select_sql, quoted_table_name, connection.quote_column_name(primary_key)))
  else
    add_order!(select_sql, options[:order], nil)
    sql.concat(select_sql)
  end

  pstmt = connection.prepare(sql, "#{name} Update")
  connection.prepared_update(pstmt, param_array)
end

.update_counters_without_lock(id, counters) ⇒ Object



523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 523

def update_counters_without_lock(id, counters)
  updates = counters.inject([]) { |list, (counter_name, increment)|
    sign = increment < 0 ? "-" : "+"
    list << "#{connection.quote_column_name(counter_name)} = COALESCE(#{connection.quote_column_name(counter_name)}, 0) #{sign} #{increment.abs}"
  }.join(", ")

  if id.is_a?(Array)
    ids_list = id.map {|i|
      connection.quote_value_for_pstmt(i)
    }
    condition = ["#{connection.quote_column_name(primary_key)} IN  (?)", ids_list]
  else
    param_value = connection.quote_value_for_pstmt(id)
    condition = ["#{connection.quote_column_name(primary_key)} = ?", param_value]
  end

  update_all(updates, condition)
end

.with_scope(method_scoping = {}, action = :merge, &block) ⇒ Object



408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 408

def with_scope(method_scoping = {}, action = :merge, &block)
  method_scoping = method_scoping.method_scoping if method_scoping.respond_to?(:method_scoping)

  # Dup first and second level of hash (method and params).
  method_scoping = method_scoping.inject({}) do |hash, (method, params)|
    hash[method] = (params == true) ? params : params.dup
    hash
  end

  method_scoping.assert_valid_keys([ :find, :create ])

  if f = method_scoping[:find]
    f.assert_valid_keys(VALID_FIND_OPTIONS)
    set_readonly_option! f
  end

  # Merge scopings
  if [:merge, :reverse_merge].include?(action) && current_scoped_methods
    method_scoping = current_scoped_methods.inject(method_scoping) do |hash, (method, params)|
      case hash[method]
        when Hash
          if method == :find
            (hash[method].keys + params.keys).uniq.each do |key|
              merge = hash[method][key] && params[key] # merge if both scopes have the same key
              if key == :conditions && merge
                if params[key].is_a?(Hash) && hash[method][key].is_a?(Hash)
                  sql_param_hash    = merge_conditions(hash[method][key].deep_merge(params[key]))
                  hash[method][key] = [sql_param_hash["sqlSegment"]] + sql_param_hash["paramArray"]
                else
                  sql_param_hash    = merge_conditions(params[key], hash[method][key])
                  hash[method][key] = [sql_param_hash["sqlSegment"]] + sql_param_hash["paramArray"]
                end
              elsif key == :include && merge
                hash[method][key] = merge_includes(hash[method][key], params[key]).uniq
              elsif key == :joins && merge
                hash[method][key] = merge_joins(params[key], hash[method][key])
              else
                hash[method][key] = hash[method][key] || params[key]
              end
            end
          else
            if action == :reverse_merge
              hash[method] = hash[method].merge(params)
            else
              hash[method] = params.merge(hash[method])
            end
          end
        else
          hash[method] = params
      end
      hash
    end
  end

  self.scoped_methods << method_scoping
  begin
    yield
  ensure
    self.scoped_methods.pop
  end
end

Instance Method Details

#destroy_without_lockObject

Deletes the record in the database and freezes this instance to reflect that no changes should be made (since they can’t be persisted).



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 36

def destroy_without_lock
  unless new_record?
    # Prepare the sql for deleting a row
    pstmt = connection.prepare(
              "DELETE FROM #{self.class.quoted_table_name} " +
              "WHERE #{connection.quote_column_name(self.class.primary_key)} = ?",
              "#{self.class.name} Destroy"
            )
    # Execute the prepared Statement
    connection.prepared_delete(pstmt, [connection.quote_value_for_pstmt(quoted_id)])
  end

  @destroyed = true
  freeze
end

#quote_value(value, column = nil) ⇒ Object

:nodoc:



30
31
32
# File 'lib/active_record/connection_adapters/ibm_db_pstmt.rb', line 30

def quote_value(value, column = nil) #:nodoc:
  connection.quote_value_for_pstmt(value,column)
end