Class: DataMapper::Migration

Included Modules

SQL

Attributes

Instance Attributes

adapter [RW] public

Sets the attribute adapter.

database [RW] public

Sets the attribute database.

name [RW] public

Sets the attribute name.

position [RW] public

Sets the attribute position.

Constructor Summary

public initialize( position, name, opts = {}, &block )
[View source]


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'dm-more/dm-migrations/lib/migration.rb', line 19

def initialize( position, name, opts = {}, &block )
  @position, @name = position, name
  @options = opts

  @database = DataMapper.repository(@options[:database] || :default)
  @adapter = @database.adapter

  case @adapter.class.to_s



  when /Sqlite3/  then @adapter.extend(SQL::Sqlite3)
  when /Mysql/    then @adapter.extend(SQL::Mysql)
  when /Postgres/ then @adapter.extend(SQL::Postgresql)
  else
    raise "Unsupported Migration Adapter #{@adapter.class}"
  end

  @verbose = @options.has_key?(:verbose) ? @options[:verbose] : true

  @up_action   = lambda {}
  @down_action = lambda {}

  instance_eval &block
end

Public Visibility

Public Instance Method Summary

#<=> other

Orders migrations by position, so we know what order to run them in.

#create_table(table_name, opts = {}, &block)
#down(&block)

define the actions that should be performed on a down migration.

#drop_table(table_name, opts = {})
#execute(sql)

execute raw SQL.

#modify_table(table_name, opts = {}, &block)
#perform_down

un-do the migration by running the code in the #down block.

#perform_up

perform the migration by running the code in the #up block.

#say(message, indent = 4)

Output some text.

#say_with_time(message, indent = 2)

Time how long the block takes to run, and output it with the message.

#up(&block)

define the actions that should be performed on an up migration.

#write(text="")

output the given text, but only if verbose mode is on.

Public Instance Methods Inherited from Object

validatable?

Public Instance Method Details

<=

public <=> other

Orders migrations by position, so we know what order to run them in. First order by postition, then by name, so at least the order is predictable.

[View source]


103
104
105
106
107
108
109
110
111
112
113
114
# File 'dm-more/dm-migrations/lib/migration.rb', line 103

def <=> other


  if self.position == other.position



    self.name.to_s <=> other.name.to_s
  else
    self.position <=> other.position
  end
end

create_table

public create_table(table_name, opts = {}, &block)
[View source]


87
88
89
# File 'dm-more/dm-migrations/lib/migration.rb', line 87

def create_table(table_name, opts = {}, &block)
  execute TableCreator.new(@adapter, table_name, opts, &block).to_sql
end

down

public down(&block)

define the actions that should be performed on a down migration

[View source]


48
49
50
# File 'dm-more/dm-migrations/lib/migration.rb', line 48

def down(&block)
  @down_action = block
end

drop_table

public drop_table(table_name, opts = {})
[View source]


91
92
93
# File 'dm-more/dm-migrations/lib/migration.rb', line 91

def drop_table(table_name, opts = {})
  execute "DROP TABLE #{@adapter.send(:quote_table_name, table_name.to_s)}"
end

execute

public execute(sql)

execute raw SQL

[View source]


81
82
83
84
85
# File 'dm-more/dm-migrations/lib/migration.rb', line 81

def execute(sql)
  say_with_time(sql) do
    @adapter.execute(sql)
  end
end

modify_table

public modify_table(table_name, opts = {}, &block)
[View source]


95
96
97
98
99
# File 'dm-more/dm-migrations/lib/migration.rb', line 95

def modify_table(table_name, opts = {}, &block)
  TableModifier.new(@adapter, table_name, opts, &block).statements.each do |sql|
    execute(sql)
  end
end

perform_down

public perform_down

un-do the migration by running the code in the #down block

[View source]


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'dm-more/dm-migrations/lib/migration.rb', line 67

def perform_down


  res = nil
  if needs_down?



    # DataMapper.database.adapter.transaction do
    say_with_time "== Performing Down Migration ##{position}: #{name}", 0 do
      res = @down_action.call
    end
    update_migration_info(:down)
    # end
  end
  res
end

perform_up

public perform_up

perform the migration by running the code in the #up block

[View source]


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'dm-more/dm-migrations/lib/migration.rb', line 53

def perform_up


  res = nil
  if needs_up?



    # DataMapper.database.adapter.transaction do
    say_with_time "== Performing Up Migration ##{position}: #{name}", 0 do
      res = @up_action.call
    end
    update_migration_info(:up)
    # end
  end
  res
end

say

public say(message, indent = 4)

Output some text. Optional indent level

[View source]


112
113
114
# File 'dm-more/dm-migrations/lib/migration.rb', line 112

def say(message, indent = 4)
  write "#{" " * indent} #{message}"
end

say_with_time

public say_with_time(message, indent = 2)

Time how long the block takes to run, and output it with the message.

[View source]


117
118
119
120
121
122
123
# File 'dm-more/dm-migrations/lib/migration.rb', line 117

def say_with_time(message, indent = 2)
  say(message, indent)
  result = nil
  time = Benchmark.measure { result = yield }
  say("-> %.4fs" % time.real, indent)
  result
end

up

public up(&block)

define the actions that should be performed on an up migration

[View source]


43
44
45
# File 'dm-more/dm-migrations/lib/migration.rb', line 43

def up(&block)
  @up_action = block
end

write

public write(text="")

output the given text, but only if verbose mode is on

[View source]


126
127
128
# File 'dm-more/dm-migrations/lib/migration.rb', line 126

def write(text="")
  puts text if @verbose
end

Protected Visibility

Protected Instance Method Summary

#create_migration_info_table_if_needed
#migration_info_table

Quoted table name, for the adapter.

#migration_info_table_exists?
#migration_name_column

Quoted `migration_name` column, for the adapter.

#migration_record

Fetch the record for this migration out of the migration_info table.

#needs_down?

True if the migration has already been run.

#needs_up?

True if the migration needs to be run.

#quoted_name

Quote the name of the migration for use in SQL.

#update_migration_info(direction)

Inserts or removes a row into the `migration_info` table, so we can mark this migration as run, or un-done.

Protected Instance Method Details

create_migration_info_table_if_needed

protected create_migration_info_table_if_needed
[View source]


146
147
148
149
150
151
152
153
154
155
156
157
# File 'dm-more/dm-migrations/lib/migration.rb', line 146

def create_migration_info_table_if_needed


  save, @verbose = @verbose, true # false
  unless migration_info_table_exists?



    execute("CREATE TABLE #{migration_info_table} (#{migration_name_column} VARCHAR(255) UNIQUE)")
  end
  @verbose = save
end

migration_info_table

protected migration_info_table

Quoted table name, for the adapter

[View source]


182
183
184
185
186
# File 'dm-more/dm-migrations/lib/migration.rb', line 182

def migration_info_table


  @migration_info_table ||= @adapter.send(:quote_table_name, 'migration_info')
end

migration_info_table_exists?

protected migration_info_table_exists?
[View source]


159
160
161
162
163
# File 'dm-more/dm-migrations/lib/migration.rb', line 159

def migration_info_table_exists?


  adapter.exists?('migration_info')
end

migration_name_column

protected migration_name_column

Quoted `migration_name` column, for the adapter

[View source]


187
188
189
190
191
# File 'dm-more/dm-migrations/lib/migration.rb', line 187

def migration_name_column


  @migration_name_column ||= @adapter.send(:quote_column_name, 'migration_name')
end

migration_record

protected migration_record

Fetch the record for this migration out of the migration_info table

[View source]


164
165
166
167
168
169
# File 'dm-more/dm-migrations/lib/migration.rb', line 164

def migration_record


  return [] unless migration_info_table_exists?
  @adapter.query("SELECT #{migration_name_column} FROM #{migration_info_table} WHERE #{migration_name_column} = #{quoted_name}")
end

needs_down?

protected needs_down?

True if the migration has already been run

[View source]


176
177
178
179
180
181
# File 'dm-more/dm-migrations/lib/migration.rb', line 176

def needs_down?


  create_migration_info_table_if_needed
  ! migration_record.empty?
end

needs_up?

protected needs_up?

True if the migration needs to be run

[View source]


170
171
172
173
174
175
# File 'dm-more/dm-migrations/lib/migration.rb', line 170

def needs_up?


  create_migration_info_table_if_needed
  migration_record.empty?
end

quoted_name

protected quoted_name

Quote the name of the migration for use in SQL

[View source]


155
156
157
158
159
# File 'dm-more/dm-migrations/lib/migration.rb', line 155

def quoted_name


  "'#{name}'"
end

update_migration_info

protected update_migration_info(direction)

Inserts or removes a row into the `migration_info` table, so we can mark this migration as run, or un-done

[View source]


133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'dm-more/dm-migrations/lib/migration.rb', line 133

def update_migration_info(direction)
  save, @verbose = @verbose, false

  create_migration_info_table_if_needed

  if direction.to_sym == :up



    execute("INSERT INTO #{migration_info_table} (#{migration_name_column}) VALUES (#{quoted_name})")
  elsif direction.to_sym == :down
    execute("DELETE FROM #{migration_info_table} WHERE #{migration_name_column} = #{quoted_name}")
  end
  @verbose = save
end