Class: Sequel::Schema::Generator

Inherits:
Object
  • Object
show all
Defined in:
lib/sequel_core/schema/generator.rb

Overview

Schema::Generator is used to create tables. It takes a Database object and a block of column/index/constraint specifications, and creates a table in the database based on the specifications.

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.

See Database#create_table.

Instance Method Summary collapse

Constructor Details

#initialize(db, &block) ⇒ Generator

Set the database in which to create the table, and evaluate the block in the context of this object.



17
18
19
20
21
22
23
# File 'lib/sequel_core/schema/generator.rb', line 17

def initialize(db, &block)
  @db = db
  @columns = []
  @indexes = []
  @primary_key = nil
  instance_eval(&block) if block
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(type, name = nil, opts = {}) ⇒ Object

Add a column with the given type, name, and opts to the DDL. See column for available options.



113
114
115
# File 'lib/sequel_core/schema/generator.rb', line 113

def method_missing(type, name = nil, opts = {})
  name ? column(name, type, opts) : super
end

Instance Method Details

#check(*args, &block) ⇒ Object

Add a unnamed constraint to the DDL, specified by the given block or args.



27
28
29
# File 'lib/sequel_core/schema/generator.rb', line 27

def check(*args, &block)
  constraint(nil, *args, &block)
end

#column(name, type, opts = {}) ⇒ Object

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:

  • :default - The default value for the column.

  • :index - Create an index on this column.

  • :key - For foreign key columns, the column in the associated table that this column references. Unnecessary if this column references the primary key of the associated table.

  • :null - Mark the column as allowing NULL values (if true), or not allowing NULL values (if false). If unspecified, will default to whatever the database default is.

  • :on_delete - Specify the behavior of this column when being deleted. See Schema::SQL#on_delete_clause for options.

  • :size - The size of the column, generally used with string columns to specify the maximum number of characters the column will hold.

  • :unique - Mark the column is unique, generally has the same effect as creating a unique index on the column.

  • :unsigned - Make the column type unsigned, only useful for integer columns.



57
58
59
60
# File 'lib/sequel_core/schema/generator.rb', line 57

def column(name, type, opts = {})
  @columns << {:name => name, :type => type}.merge(opts)
  index(name) if opts[:index]
end

#constraint(name, *args, &block) ⇒ Object

Adds a named constraint (or unnamed if name is nil) to the DDL, with the given block or args.



64
65
66
# File 'lib/sequel_core/schema/generator.rb', line 64

def constraint(name, *args, &block)
  @columns << {:name => name, :type => :check, :check => block || args}
end

#create_infoObject

Return the DDL created by the generator as a array of two elements, the first being the columns and the second being the indexes.



70
71
72
73
# File 'lib/sequel_core/schema/generator.rb', line 70

def create_info
  @columns.unshift(@primary_key) if @primary_key && !has_column?(primary_key_name)
  [@columns, @indexes]
end

#foreign_key(name, table = nil, opts = {}) ⇒ Object

Add a foreign key in the table that references another table to the DDL. See column for available options.



77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/sequel_core/schema/generator.rb', line 77

def foreign_key(name, table=nil, opts = {})
  opts = case table
  when Hash
    table.merge(opts)
  when Symbol
    opts.merge(:table=>table)
  when NilClass
    opts
  else
    raise(Error, "The seconds argument to foreign_key should be a Hash, Symbol, or nil")
  end
  column(name, :integer, opts)
end

#full_text_index(columns, opts = {}) ⇒ Object

Add a full text index on the given columns to the DDL.



92
93
94
# File 'lib/sequel_core/schema/generator.rb', line 92

def full_text_index(columns, opts = {})
  index(columns, opts.merge(:type => :full_text))
end

#has_column?(name) ⇒ Boolean

True if the DDL includes the creation of a column with the given name.

Returns:

  • (Boolean)


97
98
99
# File 'lib/sequel_core/schema/generator.rb', line 97

def has_column?(name)
  @columns.any?{|c| c[:name] == name}
end

#index(columns, opts = {}) ⇒ Object

Add an index on the given column(s) with the given options to the DDL. The available options are:

  • :type - The type of index to use (only supported by some databases)

  • :unique - Make the index unique, so duplicate values are not allowed.

  • :where - Create a partial index (only supported by some databases)



107
108
109
# File 'lib/sequel_core/schema/generator.rb', line 107

def index(columns, opts = {})
  @indexes << {:columns => Array(columns)}.merge(opts)
end

#primary_key(name, *args) ⇒ Object

Add a column with the given name and primary key options to the DDL. You can optionally provide a type argument and/or an options hash argument to change the primary key options. See column for available options.



120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/sequel_core/schema/generator.rb', line 120

def primary_key(name, *args)
  @primary_key = @db.serial_primary_key_options.merge({:name => name})
  
  if opts = args.pop
    opts = {:type => opts} unless opts.is_a?(Hash)
    if type = args.pop
      opts.merge!(:type => type)
    end
    @primary_key.merge!(opts)
  end
  @primary_key
end

#primary_key_nameObject

The name of the primary key for this table, if it has a primary key.



134
135
136
# File 'lib/sequel_core/schema/generator.rb', line 134

def primary_key_name
  @primary_key[:name] if @primary_key
end

#spatial_index(columns, opts = {}) ⇒ Object

Add a spatial index on the given columns to the DDL.



139
140
141
# File 'lib/sequel_core/schema/generator.rb', line 139

def spatial_index(columns, opts = {})
  index(columns, opts.merge(:type => :spatial))
end

#unique(columns, opts = {}) ⇒ Object

Add a unique index on the given columns to the DDL.



144
145
146
# File 'lib/sequel_core/schema/generator.rb', line 144

def unique(columns, opts = {})
  index(columns, opts.merge(:unique => true))
end