dm-migrations 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,38 @@
1
+ History.txt
2
+ LICENSE
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ TODO
7
+ db/migrations/1_create_people_table.rb
8
+ db/migrations/2_add_dob_to_people.rb
9
+ db/migrations/config.rb
10
+ examples/sample_migration.rb
11
+ examples/sample_migration_spec.rb
12
+ lib/dm-migrations.rb
13
+ lib/dm-migrations/version.rb
14
+ lib/migration.rb
15
+ lib/migration_runner.rb
16
+ lib/spec/example/migration_example_group.rb
17
+ lib/spec/matchers/migration_matchers.rb
18
+ lib/sql.rb
19
+ lib/sql/column.rb
20
+ lib/sql/mysql.rb
21
+ lib/sql/postgresql.rb
22
+ lib/sql/sqlite3.rb
23
+ lib/sql/table.rb
24
+ lib/sql/table_creator.rb
25
+ lib/sql/table_modifier.rb
26
+ spec/integration/migration_runner_spec.rb
27
+ spec/integration/migration_spec.rb
28
+ spec/integration/sql_spec.rb
29
+ spec/spec.opts
30
+ spec/spec_helper.rb
31
+ spec/unit/migration_spec.rb
32
+ spec/unit/sql/column_spec.rb
33
+ spec/unit/sql/postgresql_spec.rb
34
+ spec/unit/sql/sqlite3_extensions_spec.rb
35
+ spec/unit/sql/table_creator_spec.rb
36
+ spec/unit/sql/table_modifier_spec.rb
37
+ spec/unit/sql/table_spec.rb
38
+ spec/unit/sql_spec.rb
@@ -1,4 +1,3 @@
1
- dm-migrations
2
- =============
1
+ = dm-migrations
3
2
 
4
3
  DataMapper plugin for writing and specing migrations.
data/Rakefile CHANGED
@@ -1,51 +1,44 @@
1
1
  require 'rubygems'
2
2
  require 'spec'
3
- require 'rake/clean'
4
- require 'rake/gempackagetask'
5
3
  require 'spec/rake/spectask'
6
4
  require 'pathname'
7
5
 
8
- CLEAN.include '{log,pkg}/'
9
-
10
- spec = Gem::Specification.new do |s|
11
- s.name = 'dm-migrations'
12
- s.version = '0.9.2'
13
- s.platform = Gem::Platform::RUBY
14
- s.has_rdoc = true
15
- s.extra_rdoc_files = %w[ README LICENSE TODO ]
16
- s.summary = 'DataMapper plugin for writing and specing migrations'
17
- s.description = s.summary
18
- s.author = 'Paul Sadauskas'
19
- s.email = 'psadauskas@gmail.com'
20
- s.homepage = 'http://github.com/sam/dm-more/tree/master/dm-migrations'
21
- s.require_path = 'lib'
22
- s.files = FileList[ '{lib,spec}/**/*.rb', 'spec/spec.opts', 'Rakefile', *s.extra_rdoc_files ]
23
- s.add_dependency('dm-core', "=#{s.version}")
24
- end
6
+ ROOT = Pathname(__FILE__).dirname.expand_path
7
+ require ROOT + 'lib/dm-migrations/version'
8
+
9
+ AUTHOR = "Paul Sadauskas"
10
+ EMAIL = "psadauskas@gmail.com"
11
+ GEM_NAME = "dm-migrations"
12
+ GEM_VERSION = DataMapper::Migration::VERSION
13
+ GEM_DEPENDENCIES = [["dm-core", GEM_VERSION]]
14
+ GEM_CLEAN = ["log", "pkg"]
15
+ GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.txt LICENSE TODO ] }
16
+
17
+ PROJECT_NAME = "datamapper"
18
+ PROJECT_URL = "http://github.com/sam/dm-more/tree/master/dm-migrations"
19
+ PROJECT_DESCRIPTION = PROJECT_SUMMARY = "DataMapper plugin for writing and speccing migrations"
20
+
21
+ require ROOT.parent + 'tasks/hoe'
25
22
 
26
23
  task :default => [ :spec ]
27
24
 
28
25
  WIN32 = (RUBY_PLATFORM =~ /win32|mingw|cygwin/) rescue nil
29
26
  SUDO = WIN32 ? '' : ('sudo' unless ENV['SUDOLESS'])
30
27
 
31
- Rake::GemPackageTask.new(spec) do |pkg|
32
- pkg.gem_spec = spec
33
- end
34
-
35
- desc "Install #{spec.name} #{spec.version} (default ruby)"
28
+ desc "Install #{GEM_NAME} #{GEM_VERSION} (default ruby)"
36
29
  task :install => [ :package ] do
37
- sh "#{SUDO} gem install --local pkg/#{spec.name}-#{spec.version} --no-update-sources", :verbose => false
30
+ sh "#{SUDO} gem install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources", :verbose => false
38
31
  end
39
32
 
40
- desc "Uninstall #{spec.name} #{spec.version} (default ruby)"
33
+ desc "Uninstall #{GEM_NAME} #{GEM_VERSION} (default ruby)"
41
34
  task :uninstall => [ :clobber ] do
42
- sh "#{SUDO} gem uninstall #{spec.name} -v#{spec.version} -I -x", :verbose => false
35
+ sh "#{SUDO} gem uninstall #{GEM_NAME} -v#{GEM_VERSION} -I -x", :verbose => false
43
36
  end
44
37
 
45
38
  namespace :jruby do
46
- desc "Install #{spec.name} #{spec.version} with JRuby"
39
+ desc "Install #{GEM_NAME} #{GEM_VERSION} with JRuby"
47
40
  task :install => [ :package ] do
48
- sh %{#{SUDO} jruby -S gem install --local pkg/#{spec.name}-#{spec.version} --no-update-sources}, :verbose => false
41
+ sh %{#{SUDO} jruby -S gem install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources}, :verbose => false
49
42
  end
50
43
  end
51
44
 
@@ -0,0 +1,12 @@
1
+ migration 1, :create_people_table do
2
+ up do
3
+ create_table :people do
4
+ column :id, Integer, :serial => true
5
+ column :name, String, :size => 50
6
+ column :age, Integer
7
+ end
8
+ end
9
+ down do
10
+ drop_table :people
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ migration 2, :add_dob_to_people do
2
+ up do
3
+ modify_table :people do
4
+ add_column :dob, DateTime, :nullable? => true
5
+ end
6
+ end
7
+
8
+ down do
9
+ modify_table :people do
10
+ drop_column :dob
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ DataMapper::Logger.new(STDOUT, :debug)
2
+ DataMapper.logger.debug( "Starting Migration" )
3
+
4
+ DataMapper.setup(:default, 'postgres://postgres@localhost/dm_core_test')
@@ -0,0 +1,61 @@
1
+ require File.dirname(__FILE__) + '/../lib/migration_runner'
2
+ require 'fileutils'
3
+ FileUtils.touch(File.join(Dir.pwd, "migration_test.db"))
4
+ # DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/migration_test.db")
5
+ DataMapper.setup(:default, "postgres://localhost/migration_test")
6
+ # DataMapper.setup(:default, "mysql://localhost/migration_test")
7
+
8
+ DataMapper::Logger.new(STDOUT, :debug)
9
+ DataMapper.logger.debug( "Starting Migration" )
10
+
11
+ migration 1, :create_people_table do
12
+ up do
13
+ create_table :people do
14
+ column :id, Integer, :serial => true
15
+ column :name, String, :size => 50
16
+ column :age, Integer
17
+ end
18
+ end
19
+ down do
20
+ drop_table :people
21
+ end
22
+ end
23
+
24
+ migration 2, :add_dob_to_people do
25
+ up do
26
+ modify_table :people do
27
+ add_column :dob, DateTime, :nullable? => true
28
+ end
29
+ end
30
+
31
+ down do
32
+ modify_table :people do
33
+ drop_column :dob
34
+ end
35
+ end
36
+ end
37
+
38
+ # migrate_down!
39
+ # migrate_up!
40
+ #
41
+ # class Person
42
+ # include DataMapper::Resource
43
+ #
44
+ # property :id, Integer, :serial => true
45
+ # property :name, String, :size => 50
46
+ # property :age, Integer
47
+ # property :dob, DateTime, :default => Time.now
48
+ #
49
+ # end
50
+ #
51
+ # Person.create(:name => "Mark Bates", :age => 31)
52
+ # puts Person.first.inspect
53
+ # puts Person.all.inspect
54
+
55
+ if $0 == __FILE__
56
+ if $*.first == "down"
57
+ migrate_down!
58
+ else
59
+ migrate_up!
60
+ end
61
+ end
@@ -0,0 +1,46 @@
1
+ require File.dirname(__FILE__) + '/sample_migration'
2
+ require File.dirname(__FILE__) + '/../lib/spec/example/migration_example_group'
3
+
4
+ describe :create_people_table, :type => :migration do
5
+
6
+ before do
7
+ run_migration
8
+ end
9
+
10
+ it 'should create a people table' do
11
+ repository(:default).should have_table(:people)
12
+ end
13
+
14
+ it 'should have an id column as the primary key' do
15
+ table(:people).should have_column(:id)
16
+ table(:people).column(:id).type.should == 'integer'
17
+ #table(:people).column(:id).should be_primary_key
18
+ end
19
+
20
+ it 'should have a name column as a string' do
21
+ table(:people).should have_column(:name)
22
+ table(:people).column(:name).type.should == 'character varying'
23
+ table(:people).column(:name).should permit_null
24
+ end
25
+
26
+ it 'should have a nullable age column as a int' do
27
+ table(:people).should have_column(:age)
28
+ table(:people).column(:age).type.should == 'integer'
29
+ table(:people).column(:age).should permit_null
30
+ end
31
+
32
+ end
33
+
34
+ describe :add_dob_to_people, :type => :migration do
35
+
36
+ before do
37
+ run_migration
38
+ end
39
+
40
+ it 'should add a dob column as a timestamp' do
41
+ table(:people).should have_column(:dob)
42
+ table(:people).column(:dob).type.should == 'timestamp without time zone'
43
+ table(:people).column(:dob).should permit_null
44
+ end
45
+
46
+ end
@@ -0,0 +1,5 @@
1
+ module DataMapper
2
+ class Migration
3
+ VERSION = "0.9.3"
4
+ end
5
+ end
@@ -1,5 +1,5 @@
1
1
  require 'rubygems'
2
- gem 'dm-core', '=0.9.2'
2
+ gem 'dm-core', '=0.9.3'
3
3
  require 'dm-core'
4
4
  require 'benchmark'
5
5
  require File.dirname(__FILE__) + '/sql'
@@ -51,30 +51,30 @@ module DataMapper
51
51
 
52
52
  # perform the migration by running the code in the #up block
53
53
  def perform_up
54
- res = nil
54
+ result = nil
55
55
  if needs_up?
56
56
  # DataMapper.database.adapter.transaction do
57
57
  say_with_time "== Performing Up Migration ##{position}: #{name}", 0 do
58
- res = @up_action.call
58
+ result = @up_action.call
59
59
  end
60
60
  update_migration_info(:up)
61
61
  # end
62
62
  end
63
- res
63
+ result
64
64
  end
65
65
 
66
66
  # un-do the migration by running the code in the #down block
67
67
  def perform_down
68
- res = nil
68
+ result = nil
69
69
  if needs_down?
70
70
  # DataMapper.database.adapter.transaction do
71
71
  say_with_time "== Performing Down Migration ##{position}: #{name}", 0 do
72
- res = @down_action.call
72
+ result = @down_action.call
73
73
  end
74
74
  update_migration_info(:down)
75
75
  # end
76
76
  end
77
- res
77
+ result
78
78
  end
79
79
 
80
80
  # execute raw SQL
@@ -127,8 +127,6 @@ module DataMapper
127
127
  puts text if @verbose
128
128
  end
129
129
 
130
- protected
131
-
132
130
  # Inserts or removes a row into the `migration_info` table, so we can mark this migration as run, or un-done
133
131
  def update_migration_info(direction)
134
132
  save, @verbose = @verbose, false
@@ -144,7 +142,7 @@ module DataMapper
144
142
  end
145
143
 
146
144
  def create_migration_info_table_if_needed
147
- save, @verbose = @verbose, true # false
145
+ save, @verbose = @verbose, false
148
146
  unless migration_info_table_exists?
149
147
  execute("CREATE TABLE #{migration_info_table} (#{migration_name_column} VARCHAR(255) UNIQUE)")
150
148
  end
@@ -168,13 +166,13 @@ module DataMapper
168
166
 
169
167
  # True if the migration needs to be run
170
168
  def needs_up?
171
- create_migration_info_table_if_needed
169
+ return true unless migration_info_table_exists?
172
170
  migration_record.empty?
173
171
  end
174
172
 
175
173
  # True if the migration has already been run
176
174
  def needs_down?
177
- create_migration_info_table_if_needed
175
+ return false unless migration_info_table_exists?
178
176
  ! migration_record.empty?
179
177
  end
180
178
 
data/lib/sql.rb CHANGED
@@ -1,110 +1,10 @@
1
+ require File.dirname(__FILE__) + '/sql/table_creator'
2
+ require File.dirname(__FILE__) + '/sql/table_modifier'
3
+
1
4
  require File.dirname(__FILE__) + '/sql/sqlite3'
2
5
  require File.dirname(__FILE__) + '/sql/mysql'
3
6
  require File.dirname(__FILE__) + '/sql/postgresql'
4
7
 
5
8
  module SQL
6
9
 
7
- class TableCreator
8
- attr_accessor :table_name, :opts
9
-
10
- def initialize(adapter, table_name, opts = {}, &block)
11
- @adapter = adapter
12
- @table_name = table_name.to_s
13
- @opts = opts
14
-
15
- @columns = []
16
-
17
- self.instance_eval &block
18
- end
19
-
20
- def quoted_table_name
21
- @adapter.send(:quote_table_name, table_name)
22
- end
23
-
24
- def column(name, type, opts = {})
25
- @columns << Column.new(@adapter, name, type, opts)
26
- end
27
-
28
- def to_sql
29
- "CREATE TABLE #{quoted_table_name} (#{@columns.map{ |c| c.to_sql }.join(', ')})"
30
- end
31
-
32
- class Column
33
- attr_accessor :name, :type
34
-
35
- def initialize(adapter, name, type, opts = {})
36
- @adapter = adapter
37
- @name = name.to_s
38
- @opts = (opts ||= {})
39
- @type = build_type(type)
40
- end
41
-
42
- def build_type(type_class)
43
- schema = {:name => @name, :quote_column_name => quoted_name}.merge(@opts)
44
- schema.merge!(@adapter.class.type_map[type_class])
45
- @adapter.property_schema_statement(schema)
46
- end
47
-
48
- def to_sql
49
- type
50
- end
51
-
52
- def quoted_name
53
- @adapter.send(:quote_column_name, name)
54
- end
55
- end
56
-
57
- end
58
-
59
- class TableModifier
60
- attr_accessor :table_name, :opts, :statements, :adapter
61
-
62
- def initialize(adapter, table_name, opts = {}, &block)
63
- @adapter = adapter
64
- @table_name = table_name.to_s
65
- @opts = (opts ||= {})
66
-
67
- @statements = []
68
-
69
- self.instance_eval &block
70
- end
71
-
72
- def add_column(name, type, opts = {})
73
- column = SQL::TableCreator::Column.new(@adapter, name, type, opts)
74
- @statements << "ALTER TABLE #{quoted_table_name} ADD COLUMN #{column.to_sql}"
75
- end
76
-
77
- def drop_column(name)
78
- # raise NotImplemented for SQLite3. Can't ALTER TABLE, need to copy table.
79
- # We'd have to inspect it, and we can't, since we aren't executing any queries yet.
80
- # Just write the sql yourself.
81
- if name.is_a?(Array)
82
- name.each{ |n| drop_column(n) }
83
- else
84
- @statements << "ALTER TABLE #{quoted_table_name} DROP COLUMN #{quote_column_name(name)}"
85
- end
86
- end
87
- alias drop_columns drop_column
88
-
89
- def rename_column(name, new_name, opts = {})
90
- # raise NotImplemented for SQLite3
91
- @statements << "ALTER TABLE #{quoted_table_name} RENAME COLUMN #{quote_column_name(name)} TO #{quote_column_name(new_name)}"
92
- end
93
-
94
- def change_column(name, type, opts = {})
95
- # raise NotImplemented for SQLite3
96
- @statements << "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(name)} TYPE #{type}"
97
- end
98
-
99
- def quote_column_name(name)
100
- @adapter.send(:quote_column_name, name.to_s)
101
- end
102
-
103
- def quoted_table_name
104
- @adapter.send(:quote_table_name, table_name)
105
- end
106
-
107
- end
108
-
109
-
110
10
  end