mack-data_mapper 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. data/README +3 -0
  2. data/lib/helpers/orm_helpers.rb +47 -0
  3. data/lib/mack-data_mapper.rb +45 -0
  4. data/lib/mack-data_mapper_tasks.rb +3 -0
  5. data/lib/migration_generator/migration_generator.rb +41 -0
  6. data/lib/migration_generator/templates/db/migrations/%=@migration_name%.rb.template +31 -0
  7. data/lib/model_generator/manifest.yml +11 -0
  8. data/lib/model_generator/model_generator.rb +54 -0
  9. data/lib/model_generator/templates/model.rb.template +11 -0
  10. data/lib/model_generator/templates/test.rb.template +9 -0
  11. data/lib/scaffold_generator/manifest.yml +24 -0
  12. data/lib/scaffold_generator/scaffold_generator.rb +41 -0
  13. data/lib/scaffold_generator/templates/app/controllers/controller.rb.template +50 -0
  14. data/lib/scaffold_generator/templates/app/views/edit.html.erb.template +19 -0
  15. data/lib/scaffold_generator/templates/app/views/index.html.erb.template +41 -0
  16. data/lib/scaffold_generator/templates/app/views/new.html.erb.template +19 -0
  17. data/lib/scaffold_generator/templates/app/views/show.html.erb.template +12 -0
  18. data/lib/scaffold_generator/templates/test.rb.template +9 -0
  19. data/lib/tasks/db_create_drop_tasks.rake +76 -0
  20. data/lib/tasks/db_migration_tasks.rake +83 -0
  21. data/test/database.yml +3 -0
  22. data/test/fixtures/add_users_migration.rb.fixture +9 -0
  23. data/test/fixtures/album.rb.fixture +4 -0
  24. data/test/fixtures/album_unit_test.rb.fixture +9 -0
  25. data/test/fixtures/album_with_cols.rb.fixture +7 -0
  26. data/test/fixtures/create_users_migration.rb.fixture +12 -0
  27. data/test/fixtures/routes.rb.fixture +3 -0
  28. data/test/fixtures/zoo_no_cols/edit.html.erb.fixture +11 -0
  29. data/test/fixtures/zoo_no_cols/index.html.erb.fixture +20 -0
  30. data/test/fixtures/zoo_no_cols/new.html.erb.fixture +11 -0
  31. data/test/fixtures/zoo_no_cols/show.html.erb.fixture +6 -0
  32. data/test/fixtures/zoo_with_cols/edit.html.erb.fixture +19 -0
  33. data/test/fixtures/zoo_with_cols/index.html.erb.fixture +26 -0
  34. data/test/fixtures/zoo_with_cols/new.html.erb.fixture +19 -0
  35. data/test/fixtures/zoo_with_cols/show.html.erb.fixture +22 -0
  36. data/test/fixtures/zoo_with_cols/zoo.rb.fixture +4 -0
  37. data/test/fixtures/zoo_with_cols/zoos_controller.rb.fixture +50 -0
  38. data/test/generators/migration_generator_test.rb +71 -0
  39. data/test/generators/model_generator_test.rb +37 -0
  40. data/test/generators/scaffold_generator_test.rb +61 -0
  41. data/test/lib/user.rb +6 -0
  42. data/test/tasks/db_migration_tasks_test.rb +57 -0
  43. data/test/test_helper.rb +76 -0
  44. metadata +117 -0
data/README ADDED
@@ -0,0 +1,3 @@
1
+ README
2
+ ========================================================================
3
+ mack-data_mapper was developed by: markbates
@@ -0,0 +1,47 @@
1
+ module Mack
2
+ module ViewHelpers
3
+ module OrmHelpers
4
+ DEFAULT_PARTIAL = %{
5
+ <div>
6
+ <div class="errorExplanation" id="errorExplanation">
7
+ <h2><%= pluralize_word(errors.size, "error") %> occured.</h2>
8
+ <ul>
9
+ <% for error in errors %>
10
+ <li><%= error %></li>
11
+ <% end %>
12
+ </ul>
13
+ </div>
14
+ </div>
15
+ }
16
+
17
+ def error_messages_for(object_names = [], view_partial = nil)
18
+ object_names = [object_names].flatten
19
+ app_errors = []
20
+ object_names.each do |name|
21
+ object = instance_variable_get("@#{name}")
22
+ if object
23
+ if object.is_a?(DataMapper::Persistence)
24
+ app_errors << object.errors.full_messages
25
+ end
26
+ end
27
+ end
28
+ app_errors.flatten!
29
+ File.join(Mack::Configuration.views_directory, "application", "_error_messages.html.erb")
30
+ unless app_errors.empty?
31
+ if view_partial.nil?
32
+ if File.exist?(File.join(Mack::Configuration.views_directory, "application", "_error_messages.html.erb"))
33
+ render :partial => "application/error_messages", :locals => {:errors => app_errors}
34
+ else
35
+ render :text => DEFAULT_PARTIAL, :locals => {:errors => app_errors}
36
+ end
37
+ else
38
+ render :partial => view_partial, :locals => {:errors => app_errors}
39
+ end
40
+ else
41
+ ""
42
+ end
43
+ end
44
+ # self.include_safely_into(Mack::ViewBinder)
45
+ end # OrmHelpers
46
+ end # ViewHelpers
47
+ end # Mack
@@ -0,0 +1,45 @@
1
+ require 'rubygems'
2
+ require 'genosaurus'
3
+ require 'erubis'
4
+ begin
5
+ require 'mack-orm_common'
6
+ rescue Exception => e
7
+ end
8
+
9
+ gem("datamapper", "0.3.2")
10
+ require 'data_mapper'
11
+
12
+ module Mack
13
+ module Configuration
14
+
15
+ def self.load_database_configurations(env = Mack::Configuration.env)
16
+ dbs = Mack::Configuration.database_configurations
17
+ unless dbs.nil?
18
+ settings = dbs[env]
19
+ settings.symbolize_keys!
20
+ if settings[:default]
21
+ settings.each do |k,v|
22
+ DataMapper::Database.setup(k, v.symbolize_keys)
23
+ end
24
+ else
25
+ DataMapper::Database.setup(settings)
26
+ end
27
+ end
28
+ end # load_database_configurations
29
+
30
+ end # Configuration
31
+ end # Mack
32
+
33
+
34
+ Mack::Configuration.load_database_configurations
35
+
36
+ class SchemaInfo # :nodoc:
37
+ include DataMapper::Persistence
38
+
39
+ property :version, :integer, :default => 0
40
+ end
41
+
42
+ [:helpers, :migration_generator, :model_generator, :scaffold_generator].each do |folder|
43
+ Dir.glob(File.join(File.dirname(__FILE__), folder.to_s, "**/*.rb")).each {|f| require f}
44
+ end
45
+ # Dir.glob(File.join(File.dirname(__FILE__), "tasks", "**/*.rake")).each {|f| load f}
@@ -0,0 +1,3 @@
1
+ Dir.glob(File.join(File.dirname(__FILE__), "tasks", "*.rake")).each do |f|
2
+ load(f)
3
+ end
@@ -0,0 +1,41 @@
1
+ # This will generate a migration for your application.
2
+ #
3
+ # Example without columns:
4
+ # rake generate:migration name=create_users
5
+ #
6
+ # db/migrations/<number>_create_users.rb:
7
+ # class CreateUsers < DataMapper::Migration
8
+ # self.up
9
+ # end
10
+ #
11
+ # self.down
12
+ # end
13
+ # end
14
+ #
15
+ # Example with columns:
16
+ # rake generate:migration name=create_users cols=username:string,email_address:string,created_at:datetime,updated_at:datetime
17
+ #
18
+ # db/migrations/<number>_create_users.rb:
19
+ # class CreateUsers < DataMapper::Migration
20
+ # self.up
21
+ # create_table :users do |t|
22
+ # t.column :username, :string
23
+ # t.column :email_address, :string
24
+ # t.column :created_at, :datetime
25
+ # t.column :updated_at, :datetime
26
+ # end
27
+ #
28
+ # self.down
29
+ # drop_table :users
30
+ # end
31
+ # end
32
+ class MigrationGenerator < Genosaurus
33
+
34
+ require_param :name
35
+
36
+ def setup
37
+ @table_name = param(:name).underscore.plural.gsub("create_", "")
38
+ @migration_name = "#{next_migration_number}_#{param(:name).underscore}"
39
+ end
40
+
41
+ end
@@ -0,0 +1,31 @@
1
+ class <%= param(:name).camelcase %> < DataMapper::Migration
2
+
3
+ def self.up
4
+ <%
5
+ unless columns.empty?
6
+ -%>
7
+ create_table :<%= @table_name %> do |t|
8
+ <%
9
+ for column in columns
10
+ -%>
11
+ t.column :<%= column.column_name %>, :<%= column.column_type %>
12
+ <%
13
+ end
14
+ -%>
15
+ end
16
+ <%
17
+ end
18
+ -%>
19
+ end
20
+
21
+ def self.down
22
+ <%
23
+ unless columns.empty?
24
+ -%>
25
+ drop_table :<%= @table_name %>
26
+ <%
27
+ end
28
+ -%>
29
+ end
30
+
31
+ end
@@ -0,0 +1,11 @@
1
+ models_directory:
2
+ type: directory
3
+ output_path: <%= File.join("app", "models") %>
4
+ model_template:
5
+ type: file
6
+ template_path: <%= File.join(templates_directory_path, "model.rb.template") %>
7
+ output_path: <%= File.join("app", "models", "#{param(:name).singular.underscore}.rb") %>
8
+ test_template:
9
+ type: file
10
+ template_path: <%= File.join(templates_directory_path, "test.rb.template") %>
11
+ output_path: <%= File.join("test", "unit", "#{param(:name).singular.underscore}_test.rb") %>
@@ -0,0 +1,54 @@
1
+ # This will generate an ORM 'model' for your application based on the specified ORM you're using.
2
+ #
3
+ # Example without columns:
4
+ # rake generate:model name=user
5
+ #
6
+ # app/models/user.rb:
7
+ # class User
8
+ # include DataMapper::Persistence
9
+ #
10
+ # end
11
+ # db/migrations/<number>_create_users.rb:
12
+ # class CreateUsers < DataMapper::Migration
13
+ # self.up
14
+ # end
15
+ #
16
+ # self.down
17
+ # end
18
+ # end
19
+ #
20
+ # Example with columns:
21
+ # rake generate:model name=user cols=username:string,email_address:string,created_at:datetime,updated_at:datetime
22
+ #
23
+ # app/models/user.rb:
24
+ # class User
25
+ # include DataMapper::Persistence
26
+ #
27
+ # property :username, :string
28
+ # property :email_address, :string
29
+ # property :created_at, :datetime
30
+ # property :updated_at, :datetime
31
+ # end
32
+ # db/migrations/<number>_create_users.rb:
33
+ # class CreateUsers < DataMapper::Migration
34
+ # self.up
35
+ # create_table :users do |t|
36
+ # t.column :username, :string
37
+ # t.column :email_address, :string
38
+ # t.column :created_at, :datetime
39
+ # t.column :updated_at, :datetime
40
+ # end
41
+ #
42
+ # self.down
43
+ # drop_table :users
44
+ # end
45
+ # end
46
+ class ModelGenerator < Genosaurus
47
+
48
+ require_param :name
49
+
50
+ def after_generate
51
+ MigrationGenerator.run(@options.merge({"name" => "create_#{param(:name).plural}"}))
52
+ end
53
+
54
+ end
@@ -0,0 +1,11 @@
1
+ class <%= param(:name).singular.camelcase %>
2
+ include DataMapper::Persistence
3
+
4
+ <%
5
+ for column in columns
6
+ -%>
7
+ property :<%= column.column_name %>, :<%= column.column_type %>
8
+ <%
9
+ end
10
+ -%>
11
+ end
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ class <%= param(:name).singular.camelcase %>Test < Test::Unit::TestCase
4
+
5
+ def test_truth
6
+ assert true
7
+ end
8
+
9
+ end
@@ -0,0 +1,24 @@
1
+ controller_template:
2
+ type: file
3
+ template_path: <%= File.join(templates_directory_path, "app", "controllers", "controller.rb.template") %>
4
+ output_path: <%= File.join("app", "controllers", "#{@name_plural}_controller.rb") %>
5
+ edit_template:
6
+ type: file
7
+ template_path: <%= File.join(templates_directory_path, "app", "views", "edit.html.erb.template") %>
8
+ output_path: <%= File.join("app", "views", @name_plural, "edit.html.erb") %>
9
+ index_template:
10
+ type: file
11
+ template_path: <%= File.join(templates_directory_path, "app", "views", "index.html.erb.template") %>
12
+ output_path: <%= File.join("app", "views", @name_plural, "index.html.erb") %>
13
+ new_template:
14
+ type: file
15
+ template_path: <%= File.join(templates_directory_path, "app", "views", "new.html.erb.template") %>
16
+ output_path: <%= File.join("app", "views", @name_plural, "new.html.erb") %>
17
+ show_template:
18
+ type: file
19
+ template_path: <%= File.join(templates_directory_path, "app", "views", "show.html.erb.template") %>
20
+ output_path: <%= File.join("app", "views", @name_plural, "show.html.erb") %>
21
+ functional_teat_template:
22
+ type: file
23
+ template_path: <%= File.join(templates_directory_path, "test.rb.template") %>
24
+ output_path: <%= File.join("test", "functional", "#{@name_plural}_controller_test.rb") %>
@@ -0,0 +1,41 @@
1
+ # Generates scaffold for Mack applications.
2
+ #
3
+ # Example:
4
+ # rake generate:scaffold name=post
5
+ class ScaffoldGenerator < Genosaurus
6
+
7
+ require_param :name
8
+
9
+ def setup
10
+ @name_singular = param(:name).singular.underscore
11
+ @name_plural = param(:name).plural.underscore
12
+ @name_singular_camel = @name_singular.camelcase
13
+ @name_plural_camel = @name_plural.camelcase
14
+ end
15
+
16
+ def after_generate
17
+ ModelGenerator.run(@options)
18
+ update_routes_file
19
+ end
20
+
21
+ def update_routes_file
22
+ # update routes.rb
23
+ routes = File.join(Mack::Configuration.config_directory, "routes.rb")
24
+ rf = File.open(routes).read
25
+ unless rf.match(".resource :#{@name_plural}")
26
+ puts "Updating routes.rb"
27
+ nrf = ""
28
+ rf.each do |line|
29
+ if line.match("Mack::Routes.build")
30
+ x = line.match(/\|(.+)\|/).captures
31
+ line << "\n #{x}.resource :#{@name_plural} # Added by rake generate:scaffold name=#{param(:name)}\n"
32
+ end
33
+ nrf << line
34
+ end
35
+ File.open(routes, "w") do |f|
36
+ f.puts nrf
37
+ end
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,50 @@
1
+ class <%= @name_plural_camel %>Controller < Mack::Controller::Base
2
+
3
+ # GET /<%= @name_plural %>
4
+ def index
5
+ @<%= @name_plural %> = <%= @name_singular_camel %>.find(:all)
6
+ end
7
+
8
+ # GET /<%= @name_plural %>/1
9
+ def show
10
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
11
+ end
12
+
13
+ # GET /<%= @name_plural %>/new
14
+ def new
15
+ @<%= @name_singular %> = <%= @name_singular_camel %>.new
16
+ end
17
+
18
+ # GET /<%= @name_plural %>/1/edit
19
+ def edit
20
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
21
+ end
22
+
23
+ # POST /<%= @name_plural %>
24
+ def create
25
+ @<%= @name_singular %> = <%= @name_singular_camel %>.new(params(:<%= @name_singular %>))
26
+ if @<%= @name_singular %>.save
27
+ redirect_to(<%= @name_plural %>_show_url(:id => @<%= @name_singular %>.id))
28
+ else
29
+ render(:action => "new")
30
+ end
31
+ end
32
+
33
+ # PUT /<%= @name_plural %>/1
34
+ def update
35
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
36
+ if @<%= @name_singular %>.update_attributes(params(:<%= @name_singular %>))
37
+ redirect_to(<%= @name_plural %>_show_url(:id => @<%= @name_singular %>.id))
38
+ else
39
+ render(:action => "edit")
40
+ end
41
+ end
42
+
43
+ # DELETE /<%= @name_plural %>/1
44
+ def delete
45
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
46
+ @<%= @name_singular %>.destroy!
47
+ redirect_to(<%= @name_plural %>_index_url)
48
+ end
49
+
50
+ end
@@ -0,0 +1,19 @@
1
+ <h1>Edit <%= @name_singular_camel %></h1>
2
+
3
+ <%%= error_messages_for :<%= @name_singular %> %>
4
+
5
+ <%% form(<%= @name_singular %>s_update_url(:id => @<%= @name_singular %>.id), :class => "edit_<%= @name_singular %>", :id => "edit_<%= @name_singular %>", :method => :put) do %>
6
+ <% for column in columns -%>
7
+ <% unless column.column_name == "created_at" || column.column_name == "updated_at" -%>
8
+ <p>
9
+ <b><%= column.column_name.singular.camelcase %></b><br />
10
+ <%= column.form_field %>
11
+ </p>
12
+ <% end -%>
13
+ <% end -%>
14
+ <p>
15
+ <input id="<%= @name_singular %>_submit" name="commit" type="submit" value="Update" />
16
+ </p>
17
+ <%% end %>
18
+
19
+ <%%= link_to("Back", <%= @name_singular %>s_index_url) %>
@@ -0,0 +1,41 @@
1
+ <h1>Listing <%= @name_plural_camel %></h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <%
6
+ unless columns.empty?
7
+ columns.each do |col|
8
+ -%>
9
+ <th><%= col.column_name.camelcase %></th>
10
+ <%
11
+ end
12
+ else
13
+ -%>
14
+ <th>&nbsp;</th>
15
+ <%
16
+ end
17
+ -%>
18
+ </tr>
19
+
20
+ <%% for <%= @name_singular %> in @<%= @name_plural %> %>
21
+ <tr>
22
+ <%
23
+ unless columns.empty?
24
+ columns.each do |col| -%>
25
+ <td><%%= <%= @name_singular %>.<%= col.column_name %> %></td>
26
+ <%
27
+ end
28
+ else
29
+ -%>
30
+ <td>&nbsp;</td>
31
+ <% end -%>
32
+ <td><%%= link_to("Show", <%= @name_plural %>_show_url(:id => <%= @name_singular %>.id)) %></td>
33
+ <td><%%= link_to("Edit", <%= @name_plural %>_edit_url(:id => <%= @name_singular %>.id)) %></td>
34
+ <td><%%= link_to("Delete", <%= @name_plural %>_delete_url(:id => <%= @name_singular %>.id), :method => :delete, :confirm => "Are you sure?") %></td>
35
+ </tr>
36
+ <%% end %>
37
+ </table>
38
+
39
+ <br />
40
+
41
+ <%%= link_to("New <%= @name_singular_camel %>", <%= @name_plural %>_new_url) %>
@@ -0,0 +1,19 @@
1
+ <h1>New <%= @name_singular_camel %></h1>
2
+
3
+ <%%= error_messages_for :<%= @name_singular %> %>
4
+
5
+ <%% form(<%= @name_singular %>s_create_url, :class => "new_<%= @name_singular %>", :id => "new_<%= @name_singular %>") do %>
6
+ <% for column in columns -%>
7
+ <% unless column.column_name == "created_at" || column.column_name == "updated_at" -%>
8
+ <p>
9
+ <b><%= column.column_name.singular.camelcase %></b><br />
10
+ <%= column.form_field %>
11
+ </p>
12
+ <% end -%>
13
+ <% end -%>
14
+ <p>
15
+ <input id="<%= @name_singular %>_submit" name="commit" type="submit" value="Create" />
16
+ </p>
17
+ <%% end %>
18
+
19
+ <%%= link_to("Back", <%= @name_singular %>s_index_url) %>
@@ -0,0 +1,12 @@
1
+ <p>
2
+ <h1><%= @name_singular_camel %></h1>
3
+ </p>
4
+ <% for column in columns -%>
5
+ <p>
6
+ <b><%= column.column_name.singular.camelcase %></b><br />
7
+ <%%= @<%= @name_singular %>.<%= column.column_name %> %>
8
+ </p>
9
+ <% end -%>
10
+
11
+ <%%= link_to("Edit", <%= @name_plural %>_edit_url(:id => @<%= @name_singular %>.id)) %> |
12
+ <%%= link_to("Back", <%= @name_plural %>_index_url) %>
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ class <%= @name_plural_camel %>ControllerTest < Test::Unit::TestCase
4
+
5
+ def test_truth
6
+ assert true
7
+ end
8
+
9
+ end
@@ -0,0 +1,76 @@
1
+ require 'rake'
2
+ namespace :db do
3
+
4
+ desc "Create the database for your environment."
5
+ task :create => :environment do
6
+ Mack::Configuration.load_database_configurations(Mack::Configuration.env)
7
+ database(:default) do
8
+ drop_create_database
9
+ end
10
+ end
11
+
12
+ namespace :create do
13
+
14
+ desc "Creates your Full environment. Does NOT create your production database!"
15
+ task :all => :environment do
16
+ Mack::Configuration.load_database_configurations("test")
17
+ database(:default) do
18
+ drop_create_database
19
+ end
20
+ Mack::Configuration.load_database_configurations("development")
21
+ database(:default) do
22
+ drop_create_database
23
+ end
24
+ Rake::Task["db:migrate"].invoke
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ private
32
+ def drop_create_database
33
+ configuration = database.adapter.instance_variable_get('@configuration')
34
+ case database.adapter.class.name
35
+ when "DataMapper::Adapters::MysqlAdapter"
36
+ DataMapper::Database.setup(:tmp, {
37
+ :adapter => "mysql",
38
+ :host => "localhost",
39
+ :database => "mysql",
40
+ :username => ENV["DB_USERNAME"] || "root",
41
+ :password => ENV["DB_PASSWORD"] || ""
42
+ })
43
+ database(:tmp) do
44
+ puts "Dropping (MySQL): #{configuration.database}"
45
+ database.execute "DROP DATABASE IF EXISTS `#{configuration.database}`"
46
+ puts "Creating (MySQL): #{configuration.database}"
47
+ database.execute "CREATE DATABASE `#{configuration.database}` DEFAULT CHARACTER SET `utf8`"
48
+ begin
49
+ database.adapter.flush_connections!
50
+ rescue Exception => e
51
+ end
52
+ end
53
+ when "DataMapper::Adapters::PostgresqlAdapter"
54
+ ENV['PGHOST'] = configuration.host if configuration.host
55
+ ENV['PGPORT'] = configuration.port.to_s if configuration.port
56
+ ENV['PGPASSWORD'] = configuration.password.to_s if configuration.password
57
+
58
+ database.adapter.flush_connections!
59
+ begin
60
+ puts "Dropping (PostgreSQL): #{configuration.database}"
61
+ `dropdb -U "#{configuration.username}" #{configuration.database}`
62
+ rescue Exception => e
63
+ end
64
+
65
+ begin
66
+ puts "Creating (PostgreSQL): #{configuration.database}"
67
+ `createdb -U "#{configuration.username}" #{configuration.database}`
68
+ rescue Exception => e
69
+ end
70
+ when 'DataMapper::Adapters::Sqlite3Adapter'
71
+ puts "Dropping (SQLite3): #{configuration.database}"
72
+ FileUtils.rm_rf(configuration.database)
73
+ else
74
+ raise "Task not supported for '#{database.adapter}'"
75
+ end
76
+ end
@@ -0,0 +1,83 @@
1
+ require 'rake'
2
+ namespace :db do
3
+
4
+ desc "Migrate the database through scripts in db/migrations"
5
+ task :migrate => "db:schema:create" do
6
+ migration_files.each do |migration|
7
+ require migration
8
+ migration = File.basename(migration, ".rb")
9
+ m_number = migration_number(migration)
10
+ if m_number > @schema_info.version
11
+ migration_name(migration).camelcase.constantize.up
12
+ @schema_info.version += 1
13
+ @schema_info.save
14
+ end
15
+ end # each
16
+ end # migrate
17
+
18
+ desc "Rolls the schema back to the previous version. Specify the number of steps with STEP=n"
19
+ task :rollback => ["db:schema:create", "db:abort_if_pending_migrations"] do
20
+ migrations = migration_files.reverse
21
+ (ENV["STEP"] || 1).to_i.times do |step|
22
+ migration = migrations[step]
23
+ require migration
24
+ migration = File.basename(migration, ".rb")
25
+ m_number = migration_number(migration)
26
+ if m_number == @schema_info.version
27
+ migration_name(migration).camelcase.constantize.down
28
+ @schema_info.version -= 1
29
+ @schema_info.save
30
+ end
31
+ end
32
+
33
+ end # rollback
34
+
35
+ desc "Raises an error if there are pending migrations"
36
+ task :abort_if_pending_migrations do
37
+ migrations = migration_files.reverse
38
+ return if migrations.empty?
39
+ migration = migrations.first
40
+ migration = File.basename(migration, ".rb")
41
+ m_number = migration_number(migration)
42
+ if m_number > @schema_info.version
43
+ raise Mack::Errors::UnrunMigrations.new(m_number - @schema_info.version)
44
+ end
45
+ end
46
+
47
+ desc "Displays the current schema version of your database"
48
+ task :version => "db:schema:create" do
49
+ puts "\nYour database is currently at version: #{@schema_info.version}\n"
50
+ end
51
+
52
+ private
53
+ namespace :schema do
54
+
55
+ task :create => "mack:environment" do
56
+ require 'data_mapper/migration'
57
+ unless SchemaInfo.table.exists?
58
+ class SchemaInfo
59
+ include DataMapper::Persistence
60
+ property :version, :integer
61
+ end
62
+ SchemaInfo.auto_migrate!
63
+ SchemaInfo.create(:version => 0, :id => 1)
64
+ end
65
+ @schema_info = SchemaInfo.first
66
+ end # create
67
+
68
+ end # schema
69
+
70
+
71
+ def migration_files
72
+ Dir.glob(File.join(Mack::Configuration.root, "db", "migrations", "*.rb"))
73
+ end
74
+
75
+ def migration_number(migration)
76
+ migration.match(/(^\d+)/).captures.last.to_i
77
+ end
78
+
79
+ def migration_name(migration)
80
+ migration.match(/^\d+_(.+)/).captures.last
81
+ end
82
+
83
+ end # db
data/test/database.yml ADDED
@@ -0,0 +1,3 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: <%= File.join(Mack::Configuration.root, "mack-data_mapper_test.db") %>
@@ -0,0 +1,9 @@
1
+ class AddUsers < DataMapper::Migration
2
+ def self.up
3
+ User.create(:username => "markbates", :email => "mark@mackframework.com")
4
+ end
5
+
6
+ def self.down
7
+ User.delete_all
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ class Album
2
+ include DataMapper::Persistence
3
+
4
+ end