Module: ODBCAdapter::SchemaStatements

Included in:
ActiveRecord::ConnectionAdapters::ODBCAdapter
Defined in:
lib/odbc_adapter/schema_statements.rb

Instance Method Summary collapse

Instance Method Details

#columns(table_name, _name = nil) ⇒ Object

Returns an array of Column objects for the table specified by table_name.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/odbc_adapter/schema_statements.rb', line 61

def columns(table_name, _name = nil)
  stmt   = @connection.columns(native_case(table_name.to_s))
  result = stmt.fetch_all || []
  stmt.drop

  result.each_with_object([]) do |col, cols|
    col_name        = col[3]  # SQLColumns: COLUMN_NAME
    col_default     = col[12] # SQLColumns: COLUMN_DEF
    col_sql_type    = col[4]  # SQLColumns: DATA_TYPE
    col_native_type = col[5]  # SQLColumns: TYPE_NAME
    col_limit       = col[6]  # SQLColumns: COLUMN_SIZE
    col_scale       = col[8]  # SQLColumns: DECIMAL_DIGITS

    # SQLColumns: IS_NULLABLE, SQLColumns: NULLABLE
    col_nullable = nullability(col_name, col[17], col[10])

    args = { sql_type: col_sql_type, type: col_sql_type, limit: col_limit }
    args[:sql_type] = 'boolean' if col_native_type == self.class::BOOLEAN_TYPE

    if [ODBC::SQL_DECIMAL, ODBC::SQL_NUMERIC].include?(col_sql_type)
      args[:scale]     = col_scale || 0
      args[:precision] = col_limit
    end
     = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(**args)

    cols << new_column(format_case(col_name), col_default, , col_nullable, table_name, col_native_type)
  end
end

#current_databaseObject



126
127
128
# File 'lib/odbc_adapter/schema_statements.rb', line 126

def current_database
  .database_name.strip
end

#foreign_keys(table_name) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/odbc_adapter/schema_statements.rb', line 98

def foreign_keys(table_name)
  stmt   = @connection.foreign_keys(native_case(table_name.to_s))
  result = stmt.fetch_all || []
  stmt.drop unless stmt.nil?

  result.map do |key|
    fk_from_table      = key[2]  # PKTABLE_NAME
    fk_to_table        = key[6]  # FKTABLE_NAME

    ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(
      fk_from_table,
      fk_to_table,
      name:        key[11], # FK_NAME
      column:      key[3],  # PKCOLUMN_NAME
      primary_key: key[7],  # FKCOLUMN_NAME
      on_delete:   key[10], # DELETE_RULE
      on_update:   key[9]   # UPDATE_RULE
    )
  end
end

#index_name(table_name, options) ⇒ Object

Ensure it’s shorter than the maximum identifier length for the current dbms



121
122
123
124
# File 'lib/odbc_adapter/schema_statements.rb', line 121

def index_name(table_name, options)
  maximum = .max_identifier_len || 255
  super(table_name, options)[0...maximum]
end

#indexes(table_name, _name = nil) ⇒ Object

Returns an array of indexes for the given table.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/odbc_adapter/schema_statements.rb', line 30

def indexes(table_name, _name = nil)
  stmt   = @connection.indexes(native_case(table_name.to_s))
  result = stmt.fetch_all || []
  stmt.drop unless stmt.nil?

  index_cols = []
  index_name = nil
  unique     = nil

  result.each_with_object([]).with_index do |(row, indices), row_idx|
    # Skip table statistics
    next if row[6].zero? # SQLStatistics: TYPE

    if row[7] == 1 # SQLStatistics: ORDINAL_POSITION
      # Start of column descriptor block for next index
      index_cols = []
      unique     = row[3].zero? # SQLStatistics: NON_UNIQUE
      index_name = String.new(row[5]) # SQLStatistics: INDEX_NAME
    end

    index_cols << format_case(row[8]) # SQLStatistics: COLUMN_NAME
    next_row = result[row_idx + 1]

    if (row_idx == result.length - 1) || (next_row[6].zero? || next_row[7] == 1)
      indices << ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, format_case(index_name), unique, index_cols)
    end
  end
end

#native_database_typesObject

Returns a Hash of mappings from the abstract data types to the native database types. See TableDefinition#column for details on the recognized abstract data types.



6
7
8
# File 'lib/odbc_adapter/schema_statements.rb', line 6

def native_database_types
  @native_database_types ||= ColumnMetadata.new(self).native_database_types
end

#primary_key(table_name) ⇒ Object

Returns just a table’s primary key



91
92
93
94
95
96
# File 'lib/odbc_adapter/schema_statements.rb', line 91

def primary_key(table_name)
  stmt   = @connection.primary_keys(native_case(table_name.to_s))
  result = stmt.fetch_all || []
  stmt.drop unless stmt.nil?
  result[0] && result[0][3]
end

#tables(_name = nil) ⇒ Object

Returns an array of table names, for database tables visible on the current connection.



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/odbc_adapter/schema_statements.rb', line 12

def tables(_name = nil)
  stmt   = @connection.tables
  result = stmt.fetch_all || []
  stmt.drop

  result.each_with_object([]) do |row, table_names|
    schema_name, table_name, table_type = row[1..3]
    next if respond_to?(:table_filtered?) && table_filtered?(schema_name, table_type)
    table_names << format_case(table_name)
  end
end

#viewsObject

Returns an array of view names defined in the database.



25
26
27
# File 'lib/odbc_adapter/schema_statements.rb', line 25

def views
  []
end