ardm-migrations 1.2.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 (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