module ActiveRecord::ConnectionAdapters::OracleEnhanced::SchemaStatements

Public Instance Methods

add_reference(table_name, ref_name, **options) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 413
def add_reference(table_name, ref_name, **options)
  OracleEnhanced::ReferenceDefinition.new(ref_name, **options).add_to(update_table_definition(table_name, self))
end
add_synonym(name, table_name, options = {}) click to toggle source

Add synonym to existing table or view or sequence. Can be used to create local synonym to remote table in other schema or in other database Examples:

add_synonym :posts, "blog.posts"
add_synonym :posts_seq, "blog.posts_seq"
add_synonym :employees, "hr.employees", :force => true
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 395
def add_synonym(name, table_name, options = {})
  sql = +"CREATE"
  if options[:force] == true
    sql << " OR REPLACE"
  end
  sql << " SYNONYM #{quote_table_name(name)} FOR #{quote_table_name(table_name)}"
  execute sql
end
aliased_types(name, fallback) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 430
def aliased_types(name, fallback)
  fallback
end
change_column_comment(table_name, column_name, comment_or_changes) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 506
def change_column_comment(table_name, column_name, comment_or_changes)
  clear_cache!
  comment = extract_new_comment_value(comment_or_changes)
  execute "COMMENT ON COLUMN #{quote_table_name(table_name)}.#{quote_column_name(column_name)} IS '#{comment}'"
end
change_table_comment(table_name, comment_or_changes) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 496
def change_table_comment(table_name, comment_or_changes)
  clear_cache!
  comment = extract_new_comment_value(comment_or_changes)
  if comment.nil?
    execute "COMMENT ON TABLE #{quote_table_name(table_name)} IS ''"
  else
    execute "COMMENT ON TABLE #{quote_table_name(table_name)} IS #{quote(comment)}"
  end
end
columns(table_name) click to toggle source
Calls superclass method
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 163
def columns(table_name)
  table_name = table_name.to_s
  if @columns_cache[table_name]
    @columns_cache[table_name]
  else
    @columns_cache[table_name] = super(table_name)
  end
end
create_alter_table(name) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 621
def create_alter_table(name)
  OracleEnhanced::AlterTable.new create_table_definition(name)
end
create_schema_dumper(options) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 629
def create_schema_dumper(options)
  OracleEnhanced::SchemaDumper.create(self, options)
end
create_table(table_name, id: :primary_key, primary_key: nil, force: nil, **options) { |td| ... } click to toggle source

Additional options for create_table method in migration files.

You can specify individual starting value in table creation migration file, e.g.:

create_table :users, :sequence_start_value => 100 do |t|
  # ...
end

You can also specify other sequence definition additional parameters, e.g.:

create_table :users, :sequence_start_value => “100 NOCACHE INCREMENT BY 10” do |t|
  # ...
end

Create primary key trigger (so that you can skip primary key value in INSERT statement). By default trigger name will be “table_name_pkt”, you can override the name with :trigger_name option (but it is not recommended to override it as then this trigger will not be detected by ActiveRecord model and it will still do prefetching of sequence value). Example:

create_table :users, :primary_key_trigger => true do |t|
  # ...
end

It is possible to add table and column comments in table creation migration files:

create_table :employees, :comment => “Employees and contractors” do |t|
  t.string      :first_name, :comment => “Given name”
  t.string      :last_name, :comment => “Surname”
end
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 202
def create_table(table_name, id: :primary_key, primary_key: nil, force: nil, **options)
  create_sequence = id != false
  td = create_table_definition(
    table_name, **options.extract!(:temporary, :options, :as, :comment, :tablespace, :organization)
  )

  if id && !td.as
    pk = primary_key || Base.get_primary_key(table_name.to_s.singularize)

    if pk.is_a?(Array)
      td.primary_keys pk
    else
      td.primary_key pk, id, **options
    end
  end

  # store that primary key was defined in create_table block
  unless create_sequence
    class << td
      attr_accessor :create_sequence
      def primary_key(*args)
        self.create_sequence = true
        super(*args)
      end
    end
  end

  yield td if block_given?
  create_sequence = create_sequence || td.create_sequence

  if force && data_source_exists?(table_name)
    drop_table(table_name, force: force, if_exists: true)
  else
    schema_cache.clear_data_source_cache!(table_name.to_s)
  end

  execute schema_creation.accept td

  create_sequence_and_trigger(table_name, options) if create_sequence

  if supports_comments? && !supports_comments_in_create?
    if table_comment = td.comment.presence
      change_table_comment(table_name, table_comment)
    end
    td.columns.each do |column|
      change_column_comment(table_name, column.name, column.comment) if column.comment.present?
    end
  end
  td.indexes.each { |c, o| add_index table_name, c, **o }

  rebuild_primary_key_index_to_default_tablespace(table_name, options)
end
data_source_exists?(table_name) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 55
def data_source_exists?(table_name)
  (_owner, _table_name) = @connection.describe(table_name)
  true
rescue
  false
end
data_sources() click to toggle source
Calls superclass method
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 27
def data_sources
  super | synonyms.map(&:name)
end
index_name_exists?(table_name, index_name) click to toggle source

Verify the existence of an index with a given name.

The default argument is returned if the underlying implementation does not define the indexes method, as there’s no way to determine the correct answer in that case.

Will always query database and not index cache.

# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 370
        def index_name_exists?(table_name, index_name)
          (_owner, table_name) = @connection.describe(table_name)
          result = select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name), bind_string("index_name", index_name.to_s.upcase)])
            SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ 1 FROM all_indexes i
            WHERE i.owner = SYS_CONTEXT('userenv', 'current_schema')
               AND i.table_owner = SYS_CONTEXT('userenv', 'current_schema')
               AND i.table_name = :table_name
               AND i.index_name = :index_name
          SQL
          result == 1
        end
remove_synonym(name) click to toggle source

Remove existing synonym to table or view or sequence Example:

remove_synonym :posts, "blog.posts"
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 409
def remove_synonym(name)
  execute "DROP SYNONYM #{quote_table_name(name)}"
end
synonyms() click to toggle source

get synonyms for schema dump

# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 77
        def synonyms
          result = select_all(<<~SQL.squish, "SCHEMA")
            SELECT synonym_name, table_owner, table_name
            FROM all_synonyms where owner = SYS_CONTEXT('userenv', 'current_schema')
          SQL

          result.collect do |row|
             OracleEnhanced::SynonymDefinition.new(oracle_downcase(row["synonym_name"]),
             oracle_downcase(row["table_owner"]), oracle_downcase(row["table_name"]))
           end
        end
table_exists?(table_name) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 31
        def table_exists?(table_name)
          table_name = table_name.to_s
          if table_name.include?("@")
            # db link is not table
            false
          else
            default_owner = current_schema
          end
          real_name = OracleEnhanced::Quoting.valid_table_name?(table_name) ?
            table_name.upcase : table_name
          if real_name.include?(".")
            table_owner, table_name = real_name.split(".")
          else
            table_owner, table_name = default_owner, real_name
          end

          select_values(<<~SQL.squish, "SCHEMA", [bind_string("owner", table_owner), bind_string("table_name", table_name)]).any?
            SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ owner, table_name
            FROM all_tables
            WHERE owner = :owner
            AND table_name = :table_name
          SQL
        end
tablespace(table_name) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 547
        def tablespace(table_name)
          select_value(<<~SQL.squish, "SCHEMA")
            SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ tablespace_name
            FROM all_tables
            WHERE table_name='#{table_name.to_s.upcase}'
            AND owner = SYS_CONTEXT('userenv', 'current_schema')
          SQL
        end
update_table_definition(table_name, base) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 625
def update_table_definition(table_name, base)
  OracleEnhanced::Table.new(table_name, base)
end

Private Instance Methods

column_for(table_name, column_name) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 697
def column_for(table_name, column_name)
  unless column = columns(table_name).find { |c| c.name == column_name.to_s }
    raise "No such column: #{table_name}.#{column_name}"
  end
  column
end
create_sequence_and_trigger(table_name, options) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 704
def create_sequence_and_trigger(table_name, options)
  # TODO: Needs rename since no triggers created
  # This method will be removed since sequence will not be created separately
  seq_name = options[:sequence_name] || default_sequence_name(table_name)
  seq_start_value = options[:sequence_start_value] || default_sequence_start_value
  execute "CREATE SEQUENCE #{quote_table_name(seq_name)} START WITH #{seq_start_value}"
end
create_table_definition(name, **options) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 638
def create_table_definition(name, **options)
  OracleEnhanced::TableDefinition.new(self, name, **options)
end
default_tablespace_for(type) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 693
def default_tablespace_for(type)
  (default_tablespaces[type] || default_tablespaces[native_database_types[type][:name]]) rescue nil
end
fetch_type_metadata(sql_type, virtual = nil) click to toggle source
Calls superclass method
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 677
def fetch_type_metadata(sql_type, virtual = nil)
  OracleEnhanced::TypeMetadata.new(super(sql_type), virtual: virtual)
end
new_column_from_field(table_name, field) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 642
def new_column_from_field(table_name, field)
  limit, scale = field["limit"], field["scale"]
  if limit || scale
    field["sql_type"] += "(#{(limit || 38).to_i}" + ((scale = scale.to_i) > 0 ? ",#{scale})" : ")")
  end

  if field["sql_type_owner"]
    field["sql_type"] = field["sql_type_owner"] + "." + field["sql_type"]
  end

  is_virtual = field["virtual_column"] == "YES"

  # clean up odd default spacing from Oracle
  if field["data_default"] && !is_virtual
    field["data_default"].sub!(/^(.*?)\s*$/, '\1')

    # If a default contains a newline these cleanup regexes need to
    # match newlines.
    field["data_default"].sub!(/^'(.*)'$/m, '\1')
    field["data_default"] = nil if /^(null|empty_[bc]lob\(\))$/i.match?(field["data_default"])
    # TODO: Needs better fix to fallback "N" to false
    field["data_default"] = false if field["data_default"] == "N" && OracleEnhancedAdapter.emulate_booleans_from_strings
  end

  type_metadata = fetch_type_metadata(field["sql_type"], is_virtual)
  default_value = extract_value_from_default(field["data_default"])
  default_value = nil if is_virtual
  OracleEnhanced::Column.new(oracle_downcase(field["name"]),
                   default_value,
                   type_metadata,
                   field["nullable"] == "Y",
                   comment: field["column_comment"]
  )
end
rebuild_primary_key_index_to_default_tablespace(table_name, options) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 712
          def rebuild_primary_key_index_to_default_tablespace(table_name, options)
            tablespace = default_tablespace_for(:index)

            return unless tablespace

            index_name = select_value(<<~SQL.squish, "Index name for primary key",  [bind_string("table_name", table_name.upcase)])
              SELECT /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.2') */ index_name FROM all_constraints
                  WHERE table_name = :table_name
                  AND constraint_type = 'P'
                  AND owner = SYS_CONTEXT('userenv', 'current_schema')
            SQL

            return unless index_name

            execute("ALTER INDEX #{quote_column_name(index_name)} REBUILD TABLESPACE #{tablespace}")
          end
schema_creation() click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 634
def schema_creation
  OracleEnhanced::SchemaCreation.new self
end
tablespace_for(obj_type, tablespace_option, table_name = nil, column_name = nil) click to toggle source
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 681
def tablespace_for(obj_type, tablespace_option, table_name = nil, column_name = nil)
  tablespace_sql = +""
  if tablespace = (tablespace_option || default_tablespace_for(obj_type))
    if [:blob, :clob, :nclob].include?(obj_type.to_sym)
      tablespace_sql << " LOB (#{quote_column_name(column_name)}) STORE AS #{column_name.to_s[0..10]}_#{table_name.to_s[0..14]}_ls (TABLESPACE #{tablespace})"
    else
      tablespace_sql << " TABLESPACE #{tablespace}"
    end
  end
  tablespace_sql
end