Module: ActiveRecord::ConnectionAdapters::OracleEnhancedSchemaStatements
- Defined in:
- lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb
Instance Method Summary collapse
-
#add_column(table_name, column_name, type, options = {}) ⇒ Object
:nodoc:.
-
#add_comment(table_name, column_name, comment) ⇒ Object
:nodoc:.
-
#add_index(table_name, column_name, options = {}) ⇒ Object
clear cached indexes when adding new index.
-
#add_table_comment(table_name, comment) ⇒ Object
:nodoc:.
-
#change_column(table_name, column_name, type, options = {}) ⇒ Object
:nodoc:.
-
#change_column_default(table_name, column_name, default) ⇒ Object
:nodoc:.
-
#change_column_null(table_name, column_name, null, default = nil) ⇒ Object
:nodoc:.
-
#column_comment(table_name, column_name) ⇒ Object
:nodoc:.
-
#create_table(name, options = {}, &block) ⇒ Object
Additional options for
create_table
method in migration files. -
#drop_table(name, options = {}) ⇒ Object
:nodoc:.
-
#index_name(table_name, options) ⇒ Object
returned shortened index name if default is too large.
-
#index_name_exists?(table_name, index_name, default) ⇒ Boolean
Verify the existence of an index with a given name.
- #initialize_schema_migrations_table ⇒ Object
-
#remove_column(table_name, *column_names) ⇒ Object
:nodoc:.
-
#remove_index(table_name, options = {}) ⇒ Object
Remove the given index from the table.
-
#remove_index!(table_name, index_name) ⇒ Object
clear cached indexes when removing index.
-
#rename_column(table_name, column_name, new_column_name) ⇒ Object
:nodoc:.
-
#rename_index(table_name, index_name, new_index_name) ⇒ Object
:nodoc:.
-
#rename_table(name, new_name) ⇒ Object
:nodoc:.
-
#table_comment(table_name) ⇒ Object
:nodoc:.
- #tablespace(table_name) ⇒ Object
-
#type_to_sql(type, limit = nil, precision = nil, scale = nil) ⇒ Object
Maps logical Rails types to Oracle-specific data types.
Instance Method Details
#add_column(table_name, column_name, type, options = {}) ⇒ Object
:nodoc:
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 241 def add_column(table_name, column_name, type, = {}) #:nodoc: if type.to_sym == :virtual type = [:type] end add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} " add_column_sql << type_to_sql(type, [:limit], [:precision], [:scale]) if type (add_column_sql, .merge(:type=>type, :column_name=>column_name, :table_name=>table_name)) add_column_sql << tablespace_for((type_to_sql(type).downcase.to_sym), nil, table_name, column_name) if type execute(add_column_sql) ensure clear_table_columns_cache(table_name) end |
#add_comment(table_name, column_name, comment) ⇒ Object
:nodoc:
321 322 323 324 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 321 def add_comment(table_name, column_name, comment) #:nodoc: return if comment.blank? execute "COMMENT ON COLUMN #{quote_table_name(table_name)}.#{column_name} IS '#{comment}'" end |
#add_index(table_name, column_name, options = {}) ⇒ Object
clear cached indexes when adding new index
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 149 def add_index(table_name, column_name, = {}) #:nodoc: column_names = Array(column_name) index_name = index_name(table_name, :column => column_names) if Hash === # legacy support, since this param was a string index_type = [:unique] ? "UNIQUE" : "" index_name = [:name].to_s if .key?(:name) tablespace = tablespace_for(:index, [:tablespace]) else index_type = end if index_name.to_s.length > index_name_length raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{index_name_length} characters" end if index_name_exists?(table_name, index_name, false) raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists" end quoted_column_names = column_names.map { |e| quote_column_name_or_expression(e) }.join(", ") execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})#{tablespace} #{[:options]}" ensure self.all_schema_indexes = nil end |
#add_table_comment(table_name, comment) ⇒ Object
:nodoc:
326 327 328 329 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 326 def add_table_comment(table_name, comment) #:nodoc: return if comment.blank? execute "COMMENT ON TABLE #{quote_table_name(table_name)} IS '#{comment}'" end |
#change_column(table_name, column_name, type, options = {}) ⇒ Object
:nodoc:
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 273 def change_column(table_name, column_name, type, = {}) #:nodoc: column = column_for(table_name, column_name) # remove :null option if its value is the same as current column definition # otherwise Oracle will raise error if .has_key?(:null) && [:null] == column.null [:null] = nil end if type.to_sym == :virtual type = [:type] end change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} MODIFY #{quote_column_name(column_name)} " change_column_sql << "#{type_to_sql(type, [:limit], [:precision], [:scale])}" if type (change_column_sql, .merge(:type=>type, :column_name=>column_name, :table_name=>table_name)) change_column_sql << tablespace_for((type_to_sql(type).downcase.to_sym), nil, [:table_name], [:column_name]) if type execute(change_column_sql) ensure clear_table_columns_cache(table_name) end |
#change_column_default(table_name, column_name, default) ⇒ Object
:nodoc:
257 258 259 260 261 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 257 def change_column_default(table_name, column_name, default) #:nodoc: execute "ALTER TABLE #{quote_table_name(table_name)} MODIFY #{quote_column_name(column_name)} DEFAULT #{quote(default)}" ensure clear_table_columns_cache(table_name) end |
#change_column_null(table_name, column_name, null, default = nil) ⇒ Object
:nodoc:
263 264 265 266 267 268 269 270 271 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 263 def change_column_null(table_name, column_name, null, default = nil) #:nodoc: column = column_for(table_name, column_name) 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 change_column table_name, column_name, column.sql_type, :null => null end |
#column_comment(table_name, column_name) ⇒ Object
:nodoc:
340 341 342 343 344 345 346 347 348 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 340 def column_comment(table_name, column_name) #:nodoc: (owner, table_name, db_link) = @connection.describe(table_name) select_value <<-SQL SELECT comments FROM all_col_comments#{db_link} WHERE owner = '#{owner}' AND table_name = '#{table_name}' AND column_name = '#{column_name.upcase}' SQL end |
#create_table(name, options = {}, &block) ⇒ Object
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
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 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 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 41 def create_table(name, = {}, &block) create_sequence = [:id] != false column_comments = {} table_definition = TableDefinition.new(self) table_definition.primary_key([:primary_key] || Base.get_primary_key(name.to_s.singularize)) unless [:id] == false # store that primary key was defined in create_table block unless create_sequence class << table_definition attr_accessor :create_sequence def primary_key(*args) self.create_sequence = true super(*args) end end end # store column comments class << table_definition attr_accessor :column_comments def column(name, type, = {}) if [:comment] self.column_comments ||= {} self.column_comments[name] = [:comment] end super(name, type, ) end end result = block.call(table_definition) if block create_sequence = create_sequence || table_definition.create_sequence column_comments = table_definition.column_comments if table_definition.column_comments tablespace = tablespace_for(:table, [:tablespace]) if [:force] && table_exists?(name) drop_table(name, ) end create_sql = "CREATE#{' GLOBAL TEMPORARY' if [:temporary]} TABLE " create_sql << quote_table_name(name) create_sql << " (#{table_definition.to_sql})" unless [:temporary] create_sql << " ORGANIZATION #{[:organization]}" if [:organization] create_sql << tablespace table_definition.lob_columns.each{|cd| create_sql << tablespace_for(cd.sql_type.downcase.to_sym, nil, name, cd.name)} end create_sql << " #{[:options]}" execute create_sql create_sequence_and_trigger(name, ) if create_sequence add_table_comment name, [:comment] column_comments.each do |column_name, comment| add_comment name, column_name, comment end end |
#drop_table(name, options = {}) ⇒ Object
:nodoc:
111 112 113 114 115 116 117 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 111 def drop_table(name, = {}) #:nodoc: super(name) seq_name = [:sequence_name] || default_sequence_name(name) execute "DROP SEQUENCE #{quote_table_name(seq_name)}" rescue nil ensure clear_table_columns_cache(name) end |
#index_name(table_name, options) ⇒ Object
returned shortened index name if default is too large
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 192 def index_name(table_name, ) #:nodoc: default_name = super(table_name, ).to_s # sometimes options can be String or Array with column names = {} unless .is_a?(Hash) identifier_max_length = [:identifier_max_length] || index_name_length return default_name if default_name.length <= identifier_max_length # remove 'index', 'on' and 'and' keywords shortened_name = "i_#{table_name}_#{Array([:column]) * '_'}" # leave just first three letters from each word if shortened_name.length > identifier_max_length shortened_name = shortened_name.split('_').map{|w| w[0,3]}.join('_') end # generate unique name using hash function if shortened_name.length > identifier_max_length shortened_name = 'i'+Digest::SHA1.hexdigest(default_name)[0,identifier_max_length-1] end @logger.warn "#{adapter_name} shortened default index name #{default_name} to #{shortened_name}" if @logger shortened_name end |
#index_name_exists?(table_name, index_name, default) ⇒ Boolean
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.
220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 220 def index_name_exists?(table_name, index_name, default) (owner, table_name, db_link) = @connection.describe(table_name) result = select_value(<<-SQL) SELECT 1 FROM all_indexes#{db_link} i WHERE i.owner = '#{owner}' AND i.table_owner = '#{owner}' AND i.table_name = '#{table_name}' AND i.index_name = '#{index_name.to_s.upcase}' SQL result == 1 end |
#initialize_schema_migrations_table ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 119 def initialize_schema_migrations_table sm_table = ActiveRecord::Migrator.schema_migrations_table_name unless table_exists?(sm_table) index_name = "#{Base.table_name_prefix}unique_schema_migrations#{Base.table_name_suffix}" if index_name.length > index_name_length truncate_to = index_name_length - index_name.to_s.length - 1 truncated_name = "unique_schema_migrations"[0..truncate_to] index_name = "#{Base.table_name_prefix}#{truncated_name}#{Base.table_name_suffix}" end create_table(sm_table, :id => false) do |schema_migrations_table| schema_migrations_table.column :version, :string, :null => false end add_index sm_table, :version, :unique => true, :name => index_name # Backwards-compatibility: if we find schema_info, assume we've # migrated up to that point: si_table = Base.table_name_prefix + 'schema_info' + Base.table_name_suffix if table_exists?(si_table) ActiveSupport::Deprecation.warn "Usage of the schema table `#{si_table}` is deprecated. Please switch to using `schema_migrations` table" old_version = select_value("SELECT version FROM #{quote_table_name(si_table)}").to_i assume_migrated_upto_version(old_version) drop_table(si_table) end end end |
#remove_column(table_name, *column_names) ⇒ Object
:nodoc:
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 302 def remove_column(table_name, *column_names) #:nodoc: raise ArgumentError.new("You must specify at least one column name. Example: remove_column(:people, :first_name)") if column_names.empty? major, minor = ActiveRecord::VERSION::MAJOR, ActiveRecord::VERSION::MINOR is_deprecated = (major == 3 and minor >= 2) or major > 3 if column_names.flatten! and is_deprecated = 'Passing array to remove_columns is deprecated, please use ' + 'multiple arguments, like: `remove_columns(:posts, :foo, :bar)`' ActiveSupport::Deprecation.warn , caller end column_names.each do |column_name| execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)}" end ensure clear_table_columns_cache(table_name) end |
#remove_index(table_name, options = {}) ⇒ Object
Remove the given index from the table. Gives warning if index does not exist
176 177 178 179 180 181 182 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 176 def remove_index(table_name, = {}) #:nodoc: index_name = index_name(table_name, ) unless index_name_exists?(table_name, index_name, true) raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist" end remove_index!(table_name, index_name) end |
#remove_index!(table_name, index_name) ⇒ Object
clear cached indexes when removing index
185 186 187 188 189 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 185 def remove_index!(table_name, index_name) #:nodoc: execute "DROP INDEX #{quote_column_name(index_name)}" ensure self.all_schema_indexes = nil end |
#rename_column(table_name, column_name, new_column_name) ⇒ Object
:nodoc:
296 297 298 299 300 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 296 def rename_column(table_name, column_name, new_column_name) #:nodoc: execute "ALTER TABLE #{quote_table_name(table_name)} RENAME COLUMN #{quote_column_name(column_name)} to #{quote_column_name(new_column_name)}" ensure clear_table_columns_cache(table_name) end |
#rename_index(table_name, index_name, new_index_name) ⇒ Object
:nodoc:
232 233 234 235 236 237 238 239 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 232 def rename_index(table_name, index_name, new_index_name) #:nodoc: unless index_name_exists?(table_name, index_name, true) raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist" end execute "ALTER INDEX #{quote_column_name(index_name)} rename to #{quote_column_name(new_index_name)}" ensure self.all_schema_indexes = nil end |
#rename_table(name, new_name) ⇒ Object
:nodoc:
100 101 102 103 104 105 106 107 108 109 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 100 def rename_table(name, new_name) #:nodoc: if new_name.to_s.length > table_name_length raise ArgumentError, "New table name '#{new_name}' is too long; the limit is #{table_name_length} characters" end if "#{new_name}_seq".to_s.length > sequence_name_length raise ArgumentError, "New sequence name '#{new_name}_seq' is too long; the limit is #{sequence_name_length} characters" end execute "RENAME #{quote_table_name(name)} TO #{quote_table_name(new_name)}" execute "RENAME #{quote_table_name("#{name}_seq")} TO #{quote_table_name("#{new_name}_seq")}" end |
#table_comment(table_name) ⇒ Object
:nodoc:
331 332 333 334 335 336 337 338 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 331 def table_comment(table_name) #:nodoc: (owner, table_name, db_link) = @connection.describe(table_name) select_value <<-SQL SELECT comments FROM all_tab_comments#{db_link} WHERE owner = '#{owner}' AND table_name = '#{table_name}' SQL end |
#tablespace(table_name) ⇒ Object
358 359 360 361 362 363 364 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 358 def tablespace(table_name) select_value <<-SQL SELECT tablespace_name FROM user_tables WHERE table_name='#{table_name.to_s.upcase}' SQL end |
#type_to_sql(type, limit = nil, precision = nil, scale = nil) ⇒ Object
Maps logical Rails types to Oracle-specific data types.
351 352 353 354 355 356 |
# File 'lib/active_record/connection_adapters/oracle_enhanced_schema_statements.rb', line 351 def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc: # Ignore options for :text and :binary columns return super(type, nil, nil, nil) if ['text', 'binary'].include?(type.to_s) super end |