Search code examples
ruby-on-railsadvantage-database-server

Automatically select hidden ROWID Column by default


To start, the database is set up for an existing application. It's on the Advantage Database Server, and I can't change the table structure.

Some of the tables have the "Primary Key" set up as the pseudo-column ROWID, which always exists on all tables, but is never selected by default.

I've convinced the adapter so that it always announces the presence of ROWID in the columns, so that I can run an annotate, and a rake db:schema:dump happily now, but it is still causing problems for my models as ROWID is not included in the select * of the standard select:

Worksheet.last
 => #<Worksheet ROWID: nil, FILENAME: "2130002", CREATED: "2021-03-04", ANALYST: "CJH", WKSTATUS: "PURGED", DETS: "02535", FIRSTSAMP: 0.106499e6, CHECKDATE: nil, CHECKTIME: "", CHECKEDBY: "", EXCEL: false>

Worksheet.last.ROWID
 => nil

Worksheet.select("ROWID, WKSHEET.*").last
 => #<Worksheet ROWID: "CFTquNBaHrvwAAAAAF", FILENAME: "2130002", CREATED: "2021-03-04", ANALYST: "CJH", WKSTATUS: "PURGED", DETS: "02535", FIRSTSAMP: 0.106499e6, CHECKDATE: nil, CHECKTIME: "", CHECKEDBY: "", EXCEL: false>

Worksheet.select("ROWID, WKSHEET.*").last.ROWID
 => "CFTquNBaHrvwAAAAAF"

is there a way of setting the "default scope" or similar so that the table automatically includes the ROWID column (at least on the specific tables that use this as the "Primary Key")? ... preferably without using the table name, as this isn't always logical

cut down model for completeness:

class Worksheet < ApplicationRecord
  self.table_name = 'WKSHEET'
  self.sequence_name = :autogenerated
  self.primary_key = 'ROWID'
end

for anyone who enjoys light reading of database internals, there is this link that explains the ADS ROWID Pseudo-column


Solution

  • It really was as simple as adding in a default_scope with a select:

    class Worksheet < ApplicationRecord
      self.table_name = 'WKSHEET'
      self.sequence_name = :autogenerated
      self.primary_key = 'ROWID'
    
      default_scope { select("#{table_name}.ROWID, #{table_name}.*") }
    end
    

    output:

    Worksheet.last
     => #<Worksheet ROWID: "CFTquNBaHrvwAAAAAF", FILENAME: "2130002", CREATED: "2021-03-04", ANALYST: "CJH", WKSTATUS: "PURGED", DETS: "02535", FIRSTSAMP: 0.106499e6, CHECKDATE: nil, CHECKTIME: "", CHECKEDBY: "", EXCEL: false>
    
    Worksheet.last.ROWID
     => "CFTquNBaHrvwAAAAAF"
    

    even better, by using the #{table_name} I can copy and paste that line to all the models that use the ROWID as their primary key.