GitHub Sale: sign up for any paid plan this week and pay nothing until January 1, 2009!  [ hide ]

public
Fork of halorgium/mephisto
Description: A mirror of the mephisto code-base
Homepage: http://mephistoblog.com/
Clone URL: git://github.com/zmack/mephisto.git
svenfuchs (author)
Wed Feb 20 11:11:20 -0800 2008
commit  1ad1b56b4a6c9284534b0afbb9d5d87715ae4312
tree    adc435b61f05728a991fd314188bc3e75cfb6038
parent  2772ec18227b04b3cb618748a2900a7b93b84d94
mephisto / vendor / plugins / engines / lib / engines / rails_extensions / migrations.rb
100644 161 lines (155 sloc) 6.105 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# Contains the enhancements to Rails' migrations system to support the
# Engines::Plugin::Migrator. See Engines::RailsExtensions::Migrations for more
# information.
 
require "engines/plugin/migrator"
 
# = Plugins and Migrations: Background
#
# Rails uses migrations to describe changes to the databases as your application
# evolves. Each change to your application - adding and removing models, most
# commonly - might require tweaks to your schema in the form of new tables, or new
# columns on existing tables, or possibly the removal of tables or columns. Migrations
# can even include arbitrary code to *transform* data as the underlying schema
# changes.
#
# The point is that at any particular stage in your application's development,
# migrations serve to transform the database into a state where it is compatible
# and appropriate at that time.
#
# == What about plugins?
#
# If you want to share models using plugins, chances are that you might also
# want to include the corresponding migrations to create tables for those models.
# With the engines plugin installed, plugins can carry migration data easily:
#
# vendor/
# |
# plugins/
# |
# my_plugin/
# |- init.rb
# |- lib/
# |- db/
# |-migrate/
# |- 001_do_something.rb
# |- 002_and_something_else.rb
# |- ...
#
# When you install a plugin which contains migrations, you are undertaking a
# further step in the development of your application, the same as the addition
# of any other code. With this in mind, you may want to 'roll back' the
# installation of this plugin at some point, and the database should be able
# to migrate back to the point without this plugin in it too.
#
# == An example
#
# For example, our current application is at version 14 (according to the
# +schema_info+ table), when we decide that we want to add a tagging plugin. The
# tagging plugin chosen includes migrations to create the tables it requires
# (say, _tags_ and _taggings_, for instance), along with the models and helpers
# one might expect.
#
# After installing this plugin, these tables should be created in our database.
# Rather than running the migrations directly from the plugin, they should be
# integrated into our main migration stream in order to accurately reflect the
# state of our application's database *at this moment in time*.
#
# $ script/generate plugin_migration
# exists db/migrate
# create db/migrate/015_migrate_tagging_plugin_to_version_3.rb
#
# This migration will take our application to version 15, and contains the following,
# typical migration code:
#
# class MigrateTaggingPluginToVersion3 < ActiveRecord::Migration
# def self.up
# Engines.plugins[:tagging].migrate(3)
# end
# def self.down
# Engines.plugins[:tagging].migrate(0)
# end
# end
#
# When we migrate our application up, using <tt>rake db:migrate</tt> as normal,
# the plugin will be migrated up to its latest version (3 in this example). If we
# ever decide to migrate the application back to the state it was in at version 14,
# the plugin migrations will be taken back down to version 0 (which, typically,
# would remove all tables the plugin migrations define).
#
# == Upgrading plugins
#
# It might happen that later in an application's life, we update to a new version of
# the tagging plugin which requires some changes to our database. The tagging plugin
# provides these changes in the form of its own migrations.
#
# In this case, we just need to re-run the plugin_migration generator to create a
# new migration from the current revision to the newest one:
#
# $ script/generate plugin_migration
# exists db/migrate
# create db/migrate/023_migrate_tagging_plugin_to_version_5.rb
#
# The contents of this migration are:
#
# class MigrateTaggingPluginToVersion3 < ActiveRecord::Migration
# def self.up
# Engines.plugins[:tagging].migrate(5)
# end
# def self.down
# Engines.plugins[:tagging].migrate(3)
# end
# end
#
# Notice that if we were to migrate down to revision 22 or lower, the tagging plugin
# will be migrated back down to version 3 - the version we were previously at.
#
#
# = Creating migrations in plugins
#
# In order to use the plugin migration functionality that engines provides, a plugin
# only needs to provide regular migrations in a <tt>db/migrate</tt> folder within it.
#
# = Explicitly migrating plugins
#
# It's possible to migrate plugins within your own migrations, or any other code.
# Simply get the Plugin instance, and its Plugin#migrate method with the version
# you wish to end up at:
#
# Engines.plugins[:whatever].migrate(version)
#
# ---
#
# The Engines::RailsExtensions::Migrations module defines extensions for Rails'
# migration systems. Specifically:
#
# * Adding a hook to initialize_schema_information to create the plugin schema
# info table.
#
module Engines::RailsExtensions::Migrations
  def self.included(base) # :nodoc:
    base.class_eval { alias_method_chain :initialize_schema_information, :engine_additions }
  end
 
  # Create the schema tables, and ensure that the plugin schema table
  # is also initialized. The plugin schema info table is defined by
  # Engines::Plugin::Migrator.schema_info_table_name.
  def initialize_schema_information_with_engine_additions
    initialize_schema_information_without_engine_additions
 
    # create the plugin schema stuff.
    begin
      execute <<-ESQL
CREATE TABLE #{Engines::Plugin::Migrator.schema_info_table_name}
(plugin_name #{type_to_sql(:string)}, version #{type_to_sql(:integer)})
ESQL
    rescue ActiveRecord::StatementInvalid
      # Schema has been initialized
    end
  end
end
 
module ::ActiveRecord #:nodoc:
  module ConnectionAdapters #:nodoc:
    module SchemaStatements #:nodoc:
      include Engines::RailsExtensions::Migrations
    end
  end
end
 
# Set ActiveRecord to ignore the plugin schema table by default
::ActiveRecord::SchemaDumper.ignore_tables << Engines.schema_info_table