Class: ActiveRecord::ConnectionAdapters::AdvantageAdapter

Inherits:
AbstractAdapter
  • Object
show all
Defined in:
lib/active_record/connection_adapters/advantage_adapter.rb

Instance Method Summary collapse

Constructor Details

#initialize(connection, logger, connection_string = "") ⇒ AdvantageAdapter

:nodoc:



112
113
114
115
116
117
118
119
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 112

def initialize( connection, logger, connection_string = "") #:nodoc:
  super(connection, logger)
  @auto_commit = true
  @affected_rows = 0
  @connection_string = connection_string
  @visitor = Arel::Visitors::Advantage.new self
  connect!
end

Instance Method Details

#active?Boolean

:nodoc:

Returns:

  • (Boolean)


133
134
135
136
137
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 133

def active? #:nodoc:
  ADS.instance.api.ads_execute_immediate(@connection, "SELECT 1 FROM SYSTEM.IOTA") == 1
rescue
  false
end

#adapter_nameObject

:nodoc:



121
122
123
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 121

def adapter_name #:nodoc:
  'Advantage'
end

#add_column_options!(sql, options) ⇒ Object

Add column options



419
420
421
422
423
424
425
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 419

def add_column_options!(sql, options) #:nodoc:
  sql << " DEFAULT #{quote(options[:default], options[:column])}" if options_include_default?(options)
  # must explicitly check for :null to allow change_column to work on migrations
  if options[:null] == false
    sql << " CONSTRAINT NOT NULL"
  end
end

#add_lock!(sql, options) ⇒ Object

:nodoc:



310
311
312
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 310

def add_lock!(sql, options) #:nodoc:
  sql
end

#begin_db_transactionObject

Begin a transaction



293
294
295
296
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 293

def begin_db_transaction #:nodoc:
  ADS.instance.api.AdsBeginTransaction(@connection)
  @auto_commit = false;
end

#change_column(table_name, column_name, type, options = {}) ⇒ Object

Alter a column



412
413
414
415
416
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 412

def change_column(table_name, column_name, type, options = {}) #:nodoc:
  add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{type_to_sql(type, type_options[:limit], type_options[:precision], type_options[:scale])}"
  add_column_options!(add_column_sql, options)
  execute(add_column_sql)
end

#change_column_default(table_name, column_name, default) ⇒ Object

Change a columns defaults.



399
400
401
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 399

def change_column_default(table_name, column_name, default) #:nodoc:
  execute "ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{get_column_type(table_name, column_name)} DEFAULT #{quote(default)}"
end

#change_column_null(table_name, column_name, null, default = nil) ⇒ Object

Change a columns nullability



404
405
406
407
408
409
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 404

def change_column_null(table_name, column_name, null, default = nil) #:nodoc:
  unless null || default.nil?
      execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
  end
      execute("ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{get_column_type(table_name, column_name)} CONSTRAINT #{null ? '' : 'NOT'} NULL")
end

#columns(table_name, name = nil) ⇒ Object

Return a list of columns



336
337
338
339
340
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 336

def columns(table_name, name = nil) #:nodoc:
  table_structure(table_name).map do |field|
    AdvantageColumn.new(strip_or_self(field['COLUMN_NAME']), field['COLUMN_DEF'], strip_or_self(field['TYPE_NAME']), field['NULLABLE'])
  end
end

#commit_db_transactionObject

Commit the transaction



299
300
301
302
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 299

def commit_db_transaction #:nodoc:
  ADS.instance.api.ads_commit(@connection)
  @auto_commit = true;
end

#delete_sql(sql, name = nil) ⇒ Object

The database delete function.



235
236
237
238
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 235

def delete_sql(sql, name = nil) #:nodoc:
  execute( sql, name )
  return @affected_rows
end

#disconnect!Object

:nodoc:



139
140
141
142
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 139

def disconnect! #:nodoc:
  result = ADS.instance.api.ads_disconnect( @connection )
  super
end

#exec_delete(sql, name = nil, binds = []) ⇒ Object

The Database delete function as part of the rails changes



261
262
263
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 261

def exec_delete(sql, name = nil, binds = []) #:nodoc:
  log(sql, "delete", binds) { query(sql, binds) }
end

#exec_insert(sql, name = nil, binds = []) ⇒ Object

The Database insert function as part of the rails changes



251
252
253
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 251

def exec_insert(sql, name = nil, binds = [])  #:nodoc:
  log(sql, "insert", binds) { query(sql, binds) }
end

#exec_update(sql, name = nil, binds = []) ⇒ Object

The Database update function as part of the rails changes



256
257
258
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 256

def exec_update(sql, name = nil, binds = [])  #:nodoc:
  log(sql, "update", binds) { query(sql, binds) }
end

#execute(sql, name = nil, binds = []) ⇒ Object

The database execution function



200
201
202
203
204
205
206
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 200

def execute(sql, name = nil, binds = []) #:nodoc:
  if name == :skip_logging
      query(sql, binds)
  else
      log(sql, name, binds) { query(sql, binds) }
  end
end

#get_column_type(table_name, column_name) ⇒ Object

Helper function to retrieve the columns current type



377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 377

def get_column_type(table_name, column_name) #:nodoc:
    sql = <<-SQL
SELECT
    CASE
    WHEN type_name = 'VARCHAR' or type_name = 'CHAR' or type_name = 'CICHAR' or
   type_name = 'NVARCHAR' or type_name = 'NCHAR' or type_name = 'VARBINARY'
   THEN CAST(TRIM(type_name) + '(' + TRIM(CAST(column_size AS SQL_CHAR)) + ')' AS SQL_CHAR)
    WHEN type_name = 'NUMERIC' or type_name = 'DOUBLE' or type_name = 'CURDOUBLE'
   THEN CAST(TRIM(type_name) + '(' + TRIM(CAST(column_size AS SQL_CHAR)) + ',' + TRIM(CAST(decimal_digits AS SQL_CHAR)) + ')' AS SQL_CHAR)
    ELSE
   TRIM(type_name COLLATE ads_default_cs)
    END  AS "domain"
from (EXECUTE PROCEDURE sp_GetColumns( NULL, NULL, '#{table_name}', NULL)) as spgc
WHERE COLUMN_NAME = '#{column_name}'
SQL
   rs = select(sql)
   if !rs.nil? and !rs[0].nil?
       rs[0]['domain']
   end
end

#indexes(table_name, name = nil) ⇒ Object

Return a list of indexes EJS - Is there a way to get info without DD?



344
345
346
347
348
349
350
351
352
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 344

def indexes(table_name, name = nil) #:nodoc:
  sql = "SELECT name, INDEX_OPTIONS & 1 AS [unique], index_expression FROM SYSTEM.INDEXES WHERE parent = '#{table_name}'"
  select(sql, name).map do |row|
    index = IndexDefinition.new(table_name, row['name'])
    index.unique = row['unique'] == 1
    index.columns = row['index_expression']
    index
  end
end

#insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) ⇒ Object

The database insert function. ActiveRecord requires that insert_sql returns the primary key of the row just inserted. In most cases, this can be accomplished by immediatly querying the @@identity property. If the @@identity property is 0, then passed id_value is used



243
244
245
246
247
248
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 243

def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
  execute(sql, name)
  identity = last_inserted_id(nil)
  retval = id_value if retval == 0
  return retval
end

#last_inserted_id(result) ⇒ Object

Retrieve the last AutoInc ID

Raises:

  • (ActiveRecord::StatementInvalid)


266
267
268
269
270
271
272
273
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 266

def last_inserted_id(result) #:nodoc:
  rs = ADS.instance.api.ads_execute_direct(@connection, 'SELECT LASTAUTOINC( CONNECTION ) FROM SYSTEM.IOTA')
  raise ActiveRecord::StatementInvalid.new("#{ADS.instance.api.ads_error(@connection)}:#{sql}") if rs.nil?
  ADS.instance.api.ads_fetch_next(rs)
  retval, identity = ADS.instance.api.ads_get_column(rs, 0)
  ADS.instance.api.ads_free_stmt(rs)
  identity
end

#native_database_typesObject

Maps native ActiveRecord/Ruby types into ADS types



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 165

def native_database_types #:nodoc:
  {
    :primary_key => 'AUTOINC PRIMARY KEY CONSTRAINT NOT NULL',
    :string      => { :name => "varchar", :limit => 255 },
    :text        => { :name => "memo" },
    :integer     => { :name => "integer" },
    :float       => { :name => "float" },
    :decimal     => { :name => "numeric" },
    :datetime    => { :name => "timestamp" },
    :timestamp   => { :name => "timestamp" },
    :time        => { :name => "time" },
    :date        => { :name => "date" },
    :binary      => { :name => "blob" },
    :boolean     => { :name => "logical"}
  }
end

#primary_key(table_name) ⇒ Object

Return the primary key



355
356
357
358
359
360
361
362
363
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 355

def primary_key(table_name) #:nodoc:
  sql = "SELECT COLUMN_NAME FROM (EXECUTE PROCEDURE sp_GetBestRowIdentifier( NULL, NULL, '#{table_name}', NULL, FALSE)) as gbri"
  rs = select(sql)
  if !rs.nil? and !rs[0].nil?
    strip_or_self(rs[0]['COLUMN_NAME'])
  else
    nil
  end
end

#quote(value, column = nil) ⇒ Object

:nodoc:



187
188
189
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 187

def quote(value, column = nil)  #:nodoc:
  super(value, column)
end

#quote_column_name(name) ⇒ Object

Applies quotations around column names in generated queries



183
184
185
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 183

def quote_column_name(name) #:nodoc:
  %Q("#{name}")
end

#quoted_falseObject

:nodoc:



195
196
197
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 195

def quoted_false #:nodoc:
  '0'
end

#quoted_trueObject

:nodoc:



191
192
193
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 191

def quoted_true #:nodoc:
  '1'
end

#reconnect!Object

:nodoc:



144
145
146
147
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 144

def reconnect! #:nodoc:
  disconnect!
  connect!
end

#remove_column(table_name, column_name) ⇒ Object

Drop a column from a table



433
434
435
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 433

def remove_column(table_name, column_name) #:nodoc:
  execute "ALTER TABLE #{quote_table_name(table_name)} DROP #{quote_column_name(column_name)}"
end

#remove_index(table_name, options = {}) ⇒ Object

Drop an index



366
367
368
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 366

def remove_index(table_name, options={}) #:nodoc:
  execute "DROP INDEX #{quote_table_name(table_name)}.#{quote_column_name(index_name(table_name, options))}"
end

#rename_column(table_name, column_name, new_column_name) ⇒ Object

Rename a column



428
429
430
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 428

def rename_column(table_name, column_name, new_column_name) #:nodoc:
  execute "ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{type_to_sql(type, type_options[:limit], type_options[:precision], type_options[:scale])}"
end

#rename_table(name, new_name) ⇒ Object

Rename a table EJS - can be done without dd?



372
373
374
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 372

def rename_table(name, new_name) #:nodoc:
  execute "EXECUTE PROCEDURE sp_RenameDDObject(#{quote_table_name(name)} , #{quote_table_name(new_name)}, 1 /* ADS_DD_TABLE_OBJECT */, 0 /* Rename File */)"
end

#requires_reloading?Boolean

:nodoc:

Returns:

  • (Boolean)


129
130
131
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 129

def requires_reloading? #:nodoc:
  true
end

#rollback_db_transactionObject

Rollback the transaction



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

def rollback_db_transaction #:nodoc:
  ADS.instance.api.ads_rollback(@connection)
  @auto_commit = true;
end

#select_rows(sql, name = nil) ⇒ Object

Returns a query as an array of arrays

Raises:

  • (ActiveRecord::StatementInvalid)


276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 276

def select_rows(sql, name = nil)
  rs = ADS.instance.api.ads_execute_direct(@connection, sql)
  raise ActiveRecord::StatementInvalid.new("#{ADS.instance.api.ads_error(@connection)}:#{sql}") if rs.nil?
  record = []
  while ADS.instance.api.ads_fetch_next(rs) == 1
    max_cols = ADS.instance.api.ads_num_cols(rs)
    result = Array.new(max_cols)
    max_cols.times do |cols|
      result[cols] = ADS.instance.api.ads_get_column(rs, cols)[1]
    end
    record << result
  end
  ADS.instance.api.ads_free_stmt(rs)
  return record
end

#strip_or_self(str) ⇒ Object

Used from StackOverflow question 1000688 Stip alone will return NIL if the string is not altered. In that case, still return the string.



160
161
162
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 160

def strip_or_self(str)  #:nodoc:
    str.strip! || str if str
end

#supports_autoincrement?Boolean

:nodoc:

Returns:

  • (Boolean)


153
154
155
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 153

def supports_autoincrement? #:nodoc:
  true
end

#supports_count_distinct?Boolean

:nodoc:

Returns:

  • (Boolean)


149
150
151
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 149

def supports_count_distinct? #:nodoc:
  true
end

#supports_migrations?Boolean

:nodoc:

Returns:

  • (Boolean)


125
126
127
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 125

def supports_migrations? #:nodoc:
  true
end

#tables(name = nil) ⇒ Object

Retrieve a list of Tables



330
331
332
333
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 330

def tables(name = nil) #:nodoc:
    sql = "EXECUTE PROCEDURE sp_GetTables( NULL, NULL, NULL, 'TABLE' );"
    select(sql, name).map { |row| strip_or_self(row["TABLE_NAME"]) }
end

#translate_exception(exception, message) ⇒ Object

Translate the exception if possible



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 209

def translate_exception(exception, message)  #:nodoc:
  return super unless exception.respond_to?(:errno)
  case exception.errno
    when 2121
      if exception.sql !~ /^SELECT/i then
    raise ActiveRecord::ActiveRecordError.new(message)
      else
        super
      end
    when 7076
      raise InvalidForeignKey.new(message, exception)
    when 7057
      raise RecordNotUnique.new(message, exception)
    else
      super
  end
  super
end

#type_to_sql(type, limit = nil, precision = nil, scale = nil) ⇒ Object

Advantage does not support sizing of integers based on the sytax INTEGER(size).



315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 315

def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
  if native = native_database_types[type]
    if type == :integer
      column_type_sql = 'integer'
    elsif type == :string and !limit.nil?
      "varchar (#{limit})"
    else
      super(type, limit, precision, scale)
    end
  else
    super(type, limit, precision, scale)
  end
end

#update_sql(sql, name = nil) ⇒ Object

The database update function.



229
230
231
232
# File 'lib/active_record/connection_adapters/advantage_adapter.rb', line 229

def update_sql(sql, name = nil)  #:nodoc:
  execute( sql, name )
  return @affected_rows
end