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:



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

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)


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

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

#adapter_nameObject

:nodoc:



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

def adapter_name #:nodoc:
  'Advantage'
end

#add_column_options!(sql, options) ⇒ Object

Add column options



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

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:



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

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

#begin_db_transactionObject

Begin a transaction



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

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



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

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.



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

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



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

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



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

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



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

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.



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

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

#disconnect!Object

:nodoc:



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

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



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

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



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

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



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

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



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

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



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

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?



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

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



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

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)


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

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



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

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



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

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:



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

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

#quote_column_name(name) ⇒ Object

Applies quotations around column names in generated queries



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

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

#quoted_falseObject

:nodoc:



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

def quoted_false #:nodoc:
  '0'
end

#quoted_trueObject

:nodoc:



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

def quoted_true #:nodoc:
  '1'
end

#reconnect!Object

:nodoc:



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

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

#remove_column(table_name, column_name) ⇒ Object

Drop a column from a table



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

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



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

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



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

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?



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

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)


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

def requires_reloading? #:nodoc:
  true
end

#rollback_db_transactionObject

Rollback the transaction



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

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)


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

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.



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

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

#supports_autoincrement?Boolean

:nodoc:

Returns:

  • (Boolean)


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

def supports_autoincrement? #:nodoc:
  true
end

#supports_count_distinct?Boolean

:nodoc:

Returns:

  • (Boolean)


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

def supports_count_distinct? #:nodoc:
  true
end

#supports_migrations?Boolean

:nodoc:

Returns:

  • (Boolean)


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

def supports_migrations? #:nodoc:
  true
end

#tables(name = nil) ⇒ Object

Retrieve a list of Tables



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

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



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

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).



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

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.



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

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