module ActiveRecord::ConnectionAdapters::OracleEnhanced::SchemaStatements
Public Instance Methods
# 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 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
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 430 def aliased_types(name, fallback) fallback end
# 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
# 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
# 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
# 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
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 629 def create_schema_dumper(options) OracleEnhanced::SchemaDumper.create(self, options) end
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
# 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
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 27 def data_sources super | synonyms.map(&:name) end
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 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
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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# File lib/active_record/connection_adapters/oracle_enhanced/schema_statements.rb, line 634 def schema_creation OracleEnhanced::SchemaCreation.new self end
# 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