ardm-migrations 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +35 -0
  3. data/.travis.yml +11 -0
  4. data/Gemfile +53 -0
  5. data/LICENSE +20 -0
  6. data/README.rdoc +39 -0
  7. data/Rakefile +4 -0
  8. data/ardm-migrations.gemspec +27 -0
  9. data/db/migrations/1_create_people_table.rb +12 -0
  10. data/db/migrations/2_add_dob_to_people.rb +13 -0
  11. data/db/migrations/config.rb +4 -0
  12. data/examples/Rakefile +144 -0
  13. data/examples/sample_migration.rb +58 -0
  14. data/examples/sample_migration_spec.rb +50 -0
  15. data/lib/ardm-migrations.rb +1 -0
  16. data/lib/dm-migrations/adapters/dm-do-adapter.rb +295 -0
  17. data/lib/dm-migrations/adapters/dm-mysql-adapter.rb +299 -0
  18. data/lib/dm-migrations/adapters/dm-oracle-adapter.rb +332 -0
  19. data/lib/dm-migrations/adapters/dm-postgres-adapter.rb +159 -0
  20. data/lib/dm-migrations/adapters/dm-sqlite-adapter.rb +96 -0
  21. data/lib/dm-migrations/adapters/dm-sqlserver-adapter.rb +177 -0
  22. data/lib/dm-migrations/adapters/dm-yaml-adapter.rb +23 -0
  23. data/lib/dm-migrations/auto_migration.rb +239 -0
  24. data/lib/dm-migrations/exceptions/duplicate_migration.rb +6 -0
  25. data/lib/dm-migrations/migration.rb +300 -0
  26. data/lib/dm-migrations/migration_runner.rb +85 -0
  27. data/lib/dm-migrations/sql/column.rb +5 -0
  28. data/lib/dm-migrations/sql/mysql.rb +61 -0
  29. data/lib/dm-migrations/sql/postgres.rb +82 -0
  30. data/lib/dm-migrations/sql/sqlite.rb +51 -0
  31. data/lib/dm-migrations/sql/table.rb +15 -0
  32. data/lib/dm-migrations/sql/table_creator.rb +109 -0
  33. data/lib/dm-migrations/sql/table_modifier.rb +57 -0
  34. data/lib/dm-migrations/sql.rb +5 -0
  35. data/lib/dm-migrations/version.rb +5 -0
  36. data/lib/dm-migrations.rb +3 -0
  37. data/lib/spec/example/migration_example_group.rb +73 -0
  38. data/lib/spec/matchers/migration_matchers.rb +106 -0
  39. data/spec/integration/auto_migration_spec.rb +553 -0
  40. data/spec/integration/auto_upgrade_spec.rb +40 -0
  41. data/spec/integration/migration_runner_spec.rb +89 -0
  42. data/spec/integration/migration_spec.rb +157 -0
  43. data/spec/integration/sql_spec.rb +250 -0
  44. data/spec/isolated/require_after_setup_spec.rb +30 -0
  45. data/spec/isolated/require_before_setup_spec.rb +30 -0
  46. data/spec/isolated/require_spec.rb +25 -0
  47. data/spec/rcov.opts +6 -0
  48. data/spec/spec.opts +4 -0
  49. data/spec/spec_helper.rb +18 -0
  50. data/spec/unit/migration_spec.rb +453 -0
  51. data/spec/unit/sql/column_spec.rb +14 -0
  52. data/spec/unit/sql/postgres_spec.rb +97 -0
  53. data/spec/unit/sql/sqlite_extensions_spec.rb +108 -0
  54. data/spec/unit/sql/table_creator_spec.rb +94 -0
  55. data/spec/unit/sql/table_modifier_spec.rb +49 -0
  56. data/spec/unit/sql/table_spec.rb +28 -0
  57. data/spec/unit/sql_spec.rb +7 -0
  58. data/tasks/spec.rake +38 -0
  59. data/tasks/yard.rake +9 -0
  60. data/tasks/yardstick.rake +19 -0
  61. metadata +150 -0
@@ -0,0 +1,57 @@
1
+ module SQL
2
+ class TableModifier
3
+ extend DataMapper::Property::Lookup
4
+
5
+ attr_accessor :table_name, :opts, :statements, :adapter
6
+
7
+ def initialize(adapter, table_name, opts = {}, &block)
8
+ @adapter = adapter
9
+ @table_name = table_name.to_s
10
+ @opts = (opts)
11
+
12
+ @statements = []
13
+
14
+ self.instance_eval &block
15
+ end
16
+
17
+ def add_column(name, type, opts = {})
18
+ column = SQL::TableCreator::Column.new(@adapter, name, type, opts)
19
+ @statements << "ALTER TABLE #{quoted_table_name} ADD COLUMN #{column.to_sql}"
20
+ end
21
+
22
+ def drop_column(name)
23
+ # raise NotImplemented for SQLite3. Can't ALTER TABLE, need to copy table.
24
+ # We'd have to inspect it, and we can't, since we aren't executing any queries yet.
25
+ # TODO instead of building the SQL queries when executing the block, create AddColumn,
26
+ # AlterColumn and DropColumn objects that get #to_sql'd
27
+ if name.is_a?(Array)
28
+ name.each{ |n| drop_column(n) }
29
+ else
30
+ @statements << "ALTER TABLE #{quoted_table_name} DROP COLUMN #{quote_column_name(name)}"
31
+ end
32
+ end
33
+ alias_method :drop_columns, :drop_column
34
+
35
+ def rename_column(name, new_name, opts = {})
36
+ # raise NotImplemented for SQLite3
37
+ @statements << "ALTER TABLE #{quoted_table_name} RENAME COLUMN #{quote_column_name(name)} TO #{quote_column_name(new_name)}"
38
+ end
39
+
40
+ def change_column(name, type, opts = {})
41
+ column = SQL::TableCreator::Column.new(@adapter, name, type, opts)
42
+ @statements << @adapter.change_column_type_statement(table_name, column)
43
+ end
44
+
45
+ def quote_column_name(name)
46
+ @adapter.send(:quote_name, name.to_s)
47
+ end
48
+
49
+ def quoted_table_name
50
+ @adapter.send(:quote_name, table_name)
51
+ end
52
+
53
+ def to_sql
54
+ @statements.join(';')
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,5 @@
1
+ require 'dm-migrations/sql/table_creator'
2
+ require 'dm-migrations/sql/table_modifier'
3
+ require 'dm-migrations/sql/sqlite'
4
+ require 'dm-migrations/sql/mysql'
5
+ require 'dm-migrations/sql/postgres'
@@ -0,0 +1,5 @@
1
+ module DataMapper
2
+ module Migrations
3
+ VERSION = '1.2.0'
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ require 'dm-core'
2
+ require 'dm-migrations/migration'
3
+ require 'dm-migrations/auto_migration'
@@ -0,0 +1,73 @@
1
+ require 'spec/matchers/migration_matchers'
2
+
3
+ require 'spec'
4
+
5
+ module Spec
6
+ module Example
7
+ class MigrationExampleGroup < Spec::Example::ExampleGroup
8
+ include Spec::Matchers::Migration
9
+
10
+ before(:all) do
11
+ if this_migration.adapter.supports_schema_transactions?
12
+ run_prereq_migrations
13
+ end
14
+ end
15
+
16
+ before(:each) do
17
+ if ! this_migration.adapter.supports_schema_transactions?
18
+ run_prereq_migrations
19
+ else
20
+ this_migration.adapter.begin_transaction
21
+ end
22
+ end
23
+
24
+ after(:each) do
25
+ if this_migration.adapter.supports_schema_transactions?
26
+ this_migration.adapter.rollback_transaction
27
+ end
28
+ end
29
+
30
+ after(:all) do
31
+ this_migration.adapter.recreate_database
32
+ end
33
+
34
+ def run_prereq_migrations
35
+ "running n-1 migrations"
36
+ all_databases.each do |db|
37
+ db.adapter.recreate_database
38
+ end
39
+ @@migrations.sort.each do |migration|
40
+ break if migration.name.to_s == migration_name.to_s
41
+ migration.perform_up
42
+ end
43
+ end
44
+
45
+ def run_migration
46
+ this_migration.perform_up
47
+ end
48
+
49
+ def migration_name
50
+ @migration_name ||= self.class.instance_variable_get("@description_text").to_s
51
+ end
52
+
53
+ def all_databases
54
+ @@migrations.map { |m| m.database }.uniq
55
+ end
56
+
57
+ def this_migration
58
+ @@migrations.select { |m| m.name.to_s == migration_name }.first
59
+ end
60
+
61
+ def select(sql)
62
+ this_migration.adapter.select(sql)
63
+ end
64
+
65
+ def table(table_name)
66
+ this_migration.adapter.table(table_name)
67
+ end
68
+
69
+ Spec::Example::ExampleGroupFactory.register(:migration, self)
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,106 @@
1
+ module Spec
2
+ module Matchers
3
+ module Migration
4
+
5
+ def have_table(table_name)
6
+ HaveTableMatcher.new(table_name)
7
+ end
8
+
9
+ def have_column(column_name)
10
+ HaveColumnMatcher.new(column_name)
11
+ end
12
+
13
+ def permit_null
14
+ NullableColumnMatcher.new
15
+ end
16
+
17
+ def be_primary_key
18
+ PrimaryKeyMatcher.new
19
+ end
20
+
21
+ class HaveTableMatcher
22
+
23
+ attr_accessor :table_name, :repository
24
+
25
+ def initialize(table_name)
26
+ @table_name = table_name
27
+ end
28
+
29
+ def matches?(repository)
30
+ repository.adapter.storage_exists?(table_name)
31
+ end
32
+
33
+ def failure_message
34
+ %(expected #{repository} to have table '#{table_name}')
35
+ end
36
+
37
+ def negative_failure_message
38
+ %(expected #{repository} to not have table '#{table_name}')
39
+ end
40
+
41
+ end
42
+
43
+ class HaveColumnMatcher
44
+
45
+ attr_accessor :table, :column_name
46
+
47
+ def initialize(column_name)
48
+ @column_name = column_name
49
+ end
50
+
51
+ def matches?(table)
52
+ @table = table
53
+ table.columns.map { |c| c.name }.include?(column_name.to_s)
54
+ end
55
+
56
+ def failure_message
57
+ %(expected #{table} to have column '#{column_name}')
58
+ end
59
+
60
+ def negative_failure_message
61
+ %(expected #{table} to not have column '#{column_name}')
62
+ end
63
+
64
+ end
65
+
66
+ class NullableColumnMatcher
67
+
68
+ attr_accessor :column
69
+
70
+ def matches?(column)
71
+ @column = column
72
+ ! column.not_null
73
+ end
74
+
75
+ def failure_message
76
+ %(expected #{column.name} to permit NULL)
77
+ end
78
+
79
+ def negative_failure_message
80
+ %(expected #{column.name} to be NOT NULL)
81
+ end
82
+
83
+ end
84
+
85
+ class PrimaryKeyMatcher
86
+
87
+ attr_accessor :column
88
+
89
+ def matches?(column)
90
+ @column = column
91
+ column.primary_key
92
+ end
93
+
94
+ def failure_message
95
+ %(expected #{column.name} to be PRIMARY KEY)
96
+ end
97
+
98
+ def negative_failure_message
99
+ %(expected #{column.name} to not be PRIMARY KEY)
100
+ end
101
+
102
+ end
103
+
104
+ end
105
+ end
106
+ end