Class | Sequel::Schema::Generator |
In: |
lib/sequel/database/schema_generator.rb
lib/sequel/extensions/schema_dumper.rb |
Parent: | Object |
Schema::Generator is an internal class that the user is not expected to instantiate directly. Instances are created by Database#create_table. It is used to specify table creation parameters. It takes a Database object and a block of column/index/constraint specifications, and gives the Database a table description, which the database uses to create a table.
Schema::Generator has some methods but also includes method_missing, allowing users to specify column type as a method instead of using the column method, which makes for a nicer DSL.
For more information on Sequel‘s support for schema modification, see the "Migrations and Schema Modification" guide.
GENERIC_TYPES | = | [String, Integer, Fixnum, Bignum, Float, Numeric, BigDecimal, Date, DateTime, Time, File, TrueClass, FalseClass] | Classes specifying generic types that Sequel will convert to database-specific types. |
columns | [R] | Return the columns created by this generator |
constraints | [R] | Return the constraints created by this generator |
indexes | [R] | Return the indexes created by this generator |
Add a method for each of the given types that creates a column with that type as a constant. Types given should either already be constants/classes or a capitalized string/symbol with the same name as a constant/class.
# File lib/sequel/database/schema_generator.rb, line 47 47: def self.add_type_method(*types) 48: types.each do |type| 49: class_eval("def #{type}(name, opts={}); column(name, #{type}, opts); end", __FILE__, __LINE__) 50: end 51: end
Set the database in which to create the table, and evaluate the block in the context of this object.
# File lib/sequel/database/schema_generator.rb, line 33 33: def initialize(db, &block) 34: @db = db 35: @columns = [] 36: @indexes = [] 37: @constraints = [] 38: @primary_key = nil 39: instance_eval(&block) if block 40: @columns.unshift(@primary_key) if @primary_key && !has_column?(primary_key_name) 41: end
Add a unnamed constraint to the DDL, specified by the given block or args.
# File lib/sequel/database/schema_generator.rb, line 55 55: def check(*args, &block) 56: constraint(nil, *args, &block) 57: end
Add a column with the given name, type, and opts to the DDL.
You can also create columns via method missing, so the following are equivalent:
column :number, :integer integer :number
The following options are supported:
# File lib/sequel/database/schema_generator.rb, line 93 93: def column(name, type, opts = {}) 94: columns << {:name => name, :type => type}.merge(opts) 95: index(name) if opts[:index] 96: end
Adds a named constraint (or unnamed if name is nil) to the DDL, with the given block or args.
# File lib/sequel/database/schema_generator.rb, line 100 100: def constraint(name, *args, &block) 101: constraints << {:name => name, :type => :check, :check => block || args} 102: end
Dump this generator‘s columns to a string that could be evaled inside another instance to represent the same columns
# File lib/sequel/extensions/schema_dumper.rb, line 192 192: def dump_columns 193: strings = [] 194: cols = columns.dup 195: if pkn = primary_key_name 196: cols.delete_if{|x| x[:name] == pkn} 197: pk = @primary_key.dup 198: pkname = pk.delete(:name) 199: @db.serial_primary_key_options.each{|k,v| pk.delete(k) if v == pk[k]} 200: strings << "primary_key #{pkname.inspect}#{opts_inspect(pk)}" 201: end 202: cols.each do |c| 203: c = c.dup 204: name = c.delete(:name) 205: type = c.delete(:type) 206: opts = opts_inspect(c) 207: strings << if type.is_a?(Class) 208: "#{type.name} #{name.inspect}#{opts}" 209: else 210: "column #{name.inspect}, #{type.inspect}#{opts}" 211: end 212: end 213: strings.join("\n") 214: end
Dump this generator‘s constraints to a string that could be evaled inside another instance to represent the same constraints
# File lib/sequel/extensions/schema_dumper.rb, line 218 218: def dump_constraints 219: cs = constraints.map do |c| 220: c = c.dup 221: type = c.delete(:type) 222: case type 223: when :check 224: raise(Error, "can't dump check/constraint specified with Proc") if c[:check].is_a?(Proc) 225: name = c.delete(:name) 226: if !name and c[:check].length == 1 and c[:check].first.is_a?(Hash) 227: "check #{c[:check].first.inspect[1...-1]}" 228: else 229: "#{name ? "constraint #{name.inspect}," : 'check'} #{c[:check].map{|x| x.inspect}.join(', ')}" 230: end 231: else 232: cols = c.delete(:columns) 233: "#{type} #{cols.inspect}#{opts_inspect(c)}" 234: end 235: end 236: cs.join("\n") 237: end
Dump this generator‘s indexes to a string that could be evaled inside another instance to represent the same indexes. Options:
# File lib/sequel/extensions/schema_dumper.rb, line 246 246: def dump_indexes(options={}) 247: is = indexes.map do |c| 248: c = c.dup 249: cols = c.delete(:columns) 250: if table = options[:add_index] || options[:drop_index] 251: "#{options[:drop_index] ? 'drop' : 'add'}_index #{table.inspect}, #{cols.inspect}#{', :ignore_errors=>true' if options[:ignore_errors]}#{opts_inspect(c)}" 252: else 253: "index #{cols.inspect}#{opts_inspect(c)}" 254: end 255: end 256: is.join("\n") 257: end
Add a foreign key in the table that references another table to the DDL. See column for available options.
# File lib/sequel/database/schema_generator.rb, line 106 106: def foreign_key(name, table=nil, opts = {}) 107: opts = case table 108: when Hash 109: table.merge(opts) 110: when Symbol 111: opts.merge(:table=>table) 112: when NilClass 113: opts 114: else 115: raise(Error, "The second argument to foreign_key should be a Hash, Symbol, or nil") 116: end 117: return composite_foreign_key(name, opts) if name.is_a?(Array) 118: column(name, Integer, opts) 119: end
Add an index on the given column(s) with the given options to the DDL. The available options are:
# File lib/sequel/database/schema_generator.rb, line 137 137: def index(columns, opts = {}) 138: indexes << {:columns => Array(columns)}.merge(opts) 139: end
Add primary key information to the DDL. Takes between one and three arguments. The last one is an options hash as for Generator#column. The first one distinguishes two modes: an array of existing column names adds a composite primary key constraint. A single symbol adds a new column of that name and makes it the primary key. In that case the optional middle argument denotes the type.
Examples:
primary_key(:id) primary_key(:zip_code, :null => false) primary_key([:street_number, :house_number]) primary_key(:id, :string, :auto_increment => false)
# File lib/sequel/database/schema_generator.rb, line 159 159: def primary_key(name, *args) 160: return composite_primary_key(name, *args) if name.is_a?(Array) 161: @primary_key = @db.serial_primary_key_options.merge({:name => name}) 162: 163: if opts = args.pop 164: opts = {:type => opts} unless opts.is_a?(Hash) 165: if type = args.pop 166: opts.merge!(:type => type) 167: end 168: @primary_key.merge!(opts) 169: end 170: @primary_key 171: end
The name of the primary key for this table, if it has a primary key.
# File lib/sequel/database/schema_generator.rb, line 174 174: def primary_key_name 175: @primary_key[:name] if @primary_key 176: end
Add a unique constraint on the given columns to the DDL.
# File lib/sequel/database/schema_generator.rb, line 184 184: def unique(columns, opts = {}) 185: constraints << {:type => :unique, :columns => Array(columns)}.merge(opts) 186: end