Module: ActiveRecord::ConnectionAdapters::SchemaStatements
- Included in:
- AbstractAdapter
- Defined in:
- lib/active_record/connection_adapters/abstract/schema_statements.rb
Instance Method Summary collapse
-
#add_column(table_name, column_name, type, options = {}) ⇒ Object
Adds a new column to the named table.
-
#add_column_options!(sql, options) ⇒ Object
:nodoc:.
-
#add_index(table_name, column_name, options = {}) ⇒ Object
Adds a new index to the table.
-
#add_order_by_for_association_limiting!(sql, options) ⇒ Object
ORDER BY clause for the passed order option.
-
#change_column(table_name, column_name, type, options = {}) ⇒ Object
Changes the column’s definition according to the new options.
-
#change_column_default(table_name, column_name, default) ⇒ Object
Sets a new default value for a column.
-
#columns(table_name, name = nil) ⇒ Object
Returns an array of Column objects for the table specified by
table_name
. -
#create_table(name, options = {}) {|table_definition| ... } ⇒ Object
Creates a new table There are two ways to work with #create_table.
-
#distinct(columns, order_by) ⇒ Object
SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
-
#drop_table(name, options = {}) ⇒ Object
Drops a table from the database.
-
#dump_schema_information ⇒ Object
:nodoc:.
-
#index_name(table_name, options) ⇒ Object
:nodoc:.
-
#initialize_schema_information ⇒ Object
Should not be called normally, but this operation is non-destructive.
-
#native_database_types ⇒ Object
Returns a Hash of mappings from the abstract data types to the native database types.
-
#remove_column(table_name, column_name) ⇒ Object
Removes the column from the table definition.
-
#remove_index(table_name, options = {}) ⇒ Object
Remove the given index from the table.
-
#rename_column(table_name, column_name, new_column_name) ⇒ Object
Renames a column.
-
#rename_table(name, new_name) ⇒ Object
Renames a table.
-
#structure_dump ⇒ Object
Returns a string of
CREATE TABLE
SQL statement(s) for recreating the entire structure of the database. -
#table_alias_for(table_name) ⇒ Object
Truncates a table alias according to the limits of the current adapter.
-
#table_alias_length ⇒ Object
This is the maximum length a table alias can be.
-
#type_to_sql(type, limit = nil, precision = nil, scale = nil) ⇒ Object
:nodoc:.
Instance Method Details
#add_column(table_name, column_name, type, options = {}) ⇒ Object
Adds a new column to the named table. See TableDefinition#column for details of the options you can use.
121 122 123 124 125 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 121 def add_column(table_name, column_name, type, = {}) add_column_sql = "ALTER TABLE #{table_name} ADD #{quote_column_name(column_name)} #{type_to_sql(type, [:limit], [:precision], [:scale])}" (add_column_sql, ) execute(add_column_sql) end |
#add_column_options!(sql, options) ⇒ Object
:nodoc:
278 279 280 281 282 283 284 285 286 287 288 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 278 def (sql, ) #:nodoc: sql << " DEFAULT #{quote([:default], [:column])}" if () # must explcitly check for :null to allow change_column to work on migrations if .has_key? :null if [:null] == false sql << " NOT NULL" else sql << " NULL" end end end |
#add_index(table_name, column_name, options = {}) ⇒ Object
Adds a new index to the table. column_name
can be a single Symbol, or an Array of Symbols.
The index will be named after the table and the first column names, unless you pass :name
as an option.
When creating an index on multiple columns, the first column is used as a name for the index. For example, when you specify an index on two columns [:first
, :last
], the DBMS creates an index for both columns as well as an index for the first colum :first
. Using just the first name for this index makes sense, because you will never have to create a singular index with this name.
Examples
Creating a simple index
add_index(:suppliers, :name)
generates
CREATE INDEX suppliers_name_index ON suppliers(name)
Creating a unique index
add_index(:accounts, [:branch_id, :party_id], :unique => true)
generates
CREATE UNIQUE INDEX accounts_branch_id_party_id_index ON accounts(branch_id, party_id)
Creating a named index
add_index(:accounts, [:branch_id, :party_id], :unique => true, :name => 'by_branch_party')
generates
CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id)
186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 186 def add_index(table_name, column_name, = {}) 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] || index_name else index_type = end quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ") execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{table_name} (#{quoted_column_names})" end |
#add_order_by_for_association_limiting!(sql, options) ⇒ Object
ORDER BY clause for the passed order option. PostgreSQL overrides this due to its stricter standards compliance.
300 301 302 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 300 def add_order_by_for_association_limiting!(sql, ) sql << "ORDER BY #{[:order]}" end |
#change_column(table_name, column_name, type, options = {}) ⇒ Object
Changes the column’s definition according to the new options. See TableDefinition#column for details of the options you can use.
Examples
change_column(:suppliers, :name, :string, :limit => 80)
change_column(:accounts, :description, :text)
139 140 141 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 139 def change_column(table_name, column_name, type, = {}) raise NotImplementedError, "change_column is not implemented" end |
#change_column_default(table_name, column_name, default) ⇒ Object
Sets a new default value for a column. If you want to set the default value to NULL
, you are out of luck. You need to DatabaseStatements#execute the apppropriate SQL statement yourself.
Examples
change_column_default(:suppliers, :qualification, 'new')
change_column_default(:accounts, :authorized, 1)
149 150 151 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 149 def change_column_default(table_name, column_name, default) raise NotImplementedError, "change_column_default is not implemented" end |
#columns(table_name, name = nil) ⇒ Object
Returns an array of Column objects for the table specified by table_name
. See the concrete implementation for details on the expected parameter values.
28 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 28 def columns(table_name, name = nil) end |
#create_table(name, options = {}) {|table_definition| ... } ⇒ Object
Creates a new table There are two ways to work with #create_table. You can use the block form or the regular form, like this:
Block form
# create_table() yields a TableDefinition instance
create_table(:suppliers) do |t|
t.column :name, :string, :limit => 60
# Other fields here
end
Regular form
create_table(:suppliers)
add_column(:suppliers, :name, :string, {:limit => 60})
The options
hash can include the following keys:
:id
-
Whether to automatically add a primary key column. Defaults to true. Join tables for has_and_belongs_to_many should set :id => false.
:primary_key
-
The name of the primary key, if one is to be added automatically. Defaults to
id
. :options
-
Any extra options you want appended to the table definition.
:temporary
-
Make a temporary table.
:force
-
Set to true or false to drop the table before creating it. Defaults to false.
Examples
Add a backend specific option to the generated SQL (MySQL)
create_table(:suppliers, :options => 'ENGINE=InnoDB DEFAULT CHARSET=utf8')
generates:
CREATE TABLE suppliers (
id int(11) DEFAULT NULL auto_increment PRIMARY KEY
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Rename the primary key column
create_table(:objects, :primary_key => 'guid') do |t|
t.column :name, :string, :limit => 80
end
generates:
CREATE TABLE objects (
guid int(11) DEFAULT NULL auto_increment PRIMARY KEY,
name varchar(80)
)
Do not add a primary key column
create_table(:categories_suppliers, :id => false) do |t|
t.column :category_id, :integer
t.column :supplier_id, :integer
end
generates:
CREATE TABLE categories_suppliers_join (
category_id int,
supplier_id int
)
See also TableDefinition#column for details on how to create columns.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 90 def create_table(name, = {}) table_definition = TableDefinition.new(self) table_definition.primary_key([:primary_key] || "id") unless [:id] == false yield table_definition if [:force] drop_table(name, ) rescue nil end create_sql = "CREATE#{' TEMPORARY' if [:temporary]} TABLE " create_sql << "#{name} (" create_sql << table_definition.to_sql create_sql << ") #{[:options]}" execute create_sql end |
#distinct(columns, order_by) ⇒ Object
SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause. Both PostgreSQL and Oracle overrides this for custom DISTINCT syntax.
distinct("posts.id", "posts.created_at desc")
294 295 296 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 294 def distinct(columns, order_by) "DISTINCT #{columns}" end |
#drop_table(name, options = {}) ⇒ Object
Drops a table from the database.
115 116 117 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 115 def drop_table(name, = {}) execute "DROP TABLE #{name}" end |
#dump_schema_information ⇒ Object
:nodoc:
244 245 246 247 248 249 250 251 252 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 244 def dump_schema_information #:nodoc: begin if (current_schema = ActiveRecord::Migrator.current_version) > 0 return "INSERT INTO #{ActiveRecord::Migrator.schema_info_table_name} (version) VALUES (#{current_schema})" end rescue ActiveRecord::StatementInvalid # No Schema Info end end |
#index_name(table_name, options) ⇒ Object
:nodoc:
214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 214 def index_name(table_name, ) #:nodoc: if Hash === # legacy support if [:column] "index_#{table_name}_on_#{Array([:column]) * '_and_'}" elsif [:name] [:name] else raise ArgumentError, "You must specify the index name" end else index_name(table_name, :column => ) end end |
#initialize_schema_information ⇒ Object
Should not be called normally, but this operation is non-destructive. The migrations module handles this automatically.
235 236 237 238 239 240 241 242 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 235 def initialize_schema_information begin execute "CREATE TABLE #{ActiveRecord::Migrator.schema_info_table_name} (version #{type_to_sql(:integer)})" execute "INSERT INTO #{ActiveRecord::Migrator.schema_info_table_name} (version) VALUES(0)" rescue ActiveRecord::StatementInvalid # Schema has been intialized end end |
#native_database_types ⇒ Object
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.
7 8 9 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 7 def native_database_types {} end |
#remove_column(table_name, column_name) ⇒ Object
Removes the column from the table definition.
Examples
remove_column(:suppliers, :qualification)
130 131 132 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 130 def remove_column(table_name, column_name) execute "ALTER TABLE #{table_name} DROP #{quote_column_name(column_name)}" end |
#remove_index(table_name, options = {}) ⇒ Object
Remove the given index from the table.
Remove the suppliers_name_index in the suppliers table.
remove_index :suppliers, :name
Remove the index named accounts_branch_id_index in the accounts table.
remove_index :accounts, :column => :branch_id
Remove the index named accounts_branch_id_party_id_index in the accounts table.
remove_index :accounts, :column => [:branch_id, :party_id]
Remove the index named by_branch_party in the accounts table.
remove_index :accounts, :name => :by_branch_party
210 211 212 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 210 def remove_index(table_name, = {}) execute "DROP INDEX #{quote_column_name(index_name(table_name, ))} ON #{table_name}" end |
#rename_column(table_name, column_name, new_column_name) ⇒ Object
Renames a column.
Example
rename_column(:suppliers, :description, :name)
156 157 158 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 156 def rename_column(table_name, column_name, new_column_name) raise NotImplementedError, "rename_column is not implemented" end |
#rename_table(name, new_name) ⇒ Object
Renames a table.
Example
rename_table('octopuses', 'octopi')
110 111 112 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 110 def rename_table(name, new_name) raise NotImplementedError, "rename_table is not implemented" end |
#structure_dump ⇒ Object
Returns a string of CREATE TABLE
SQL statement(s) for recreating the entire structure of the database.
230 231 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 230 def structure_dump end |
#table_alias_for(table_name) ⇒ Object
Truncates a table alias according to the limits of the current adapter.
17 18 19 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 17 def table_alias_for(table_name) table_name[0..table_alias_length-1].gsub(/\./, '_') end |
#table_alias_length ⇒ Object
This is the maximum length a table alias can be
12 13 14 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 12 def table_alias_length 255 end |
#type_to_sql(type, limit = nil, precision = nil, scale = nil) ⇒ Object
:nodoc:
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/active_record/connection_adapters/abstract/schema_statements.rb', line 255 def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc: native = native_database_types[type] column_type_sql = native.is_a?(Hash) ? native[:name] : native if type == :decimal # ignore limit, use precison and scale precision ||= native[:precision] scale ||= native[:scale] if precision if scale column_type_sql << "(#{precision},#{scale})" else column_type_sql << "(#{precision})" end else raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale if specified" if scale end column_type_sql else limit ||= native[:limit] column_type_sql << "(#{limit})" if limit column_type_sql end end |