migration_comments 0.2.1 → 0.3.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.
data/README.rdoc CHANGED
@@ -4,8 +4,9 @@ Comments for your migrations
4
4
 
5
5
  Tested on:
6
6
 
7
- * Ruby 1.8.7/1.9.x using Rails 3.x
8
- * Ruby 1.8.6/1.8.7 using Rails 2.3.x.
7
+ Rails 4.x:: using Ruby 1.9.3 / 2.0
8
+ Rails 3.x:: using Ruby 1.8.7 / 1.9.x / 2.0
9
+ Rails 2.3.x (deprecated):: using 1.8.6 / 1.8.7
9
10
 
10
11
  == Why?
11
12
 
data/Rakefile CHANGED
@@ -1 +1,8 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.test_files = FileList['test/*_test.rb']
7
+ t.verbose = true
8
+ end
@@ -1,4 +1,5 @@
1
1
  require "migration_comments/version"
2
+ require "migration_comments/schema_formatter"
2
3
 
3
4
  require 'migration_comments/active_record/schema_dumper'
4
5
  require 'migration_comments/active_record/connection_adapters/comment_definition'
@@ -6,16 +7,24 @@ require 'migration_comments/active_record/connection_adapters/column_definition'
6
7
  require 'migration_comments/active_record/connection_adapters/column'
7
8
  require 'migration_comments/active_record/connection_adapters/table'
8
9
  require 'migration_comments/active_record/connection_adapters/table_definition'
10
+ require 'migration_comments/active_record/connection_adapters/alter_table'
9
11
  require 'migration_comments/active_record/connection_adapters/abstract_adapter'
12
+ require 'migration_comments/active_record/connection_adapters/abstract_adapter/schema_creation'
10
13
  require 'migration_comments/active_record/connection_adapters/mysql_adapter'
11
14
  require 'migration_comments/active_record/connection_adapters/mysql2_adapter'
12
15
  require 'migration_comments/active_record/connection_adapters/postgresql_adapter'
16
+ require 'migration_comments/active_record/connection_adapters/abstract_sqlite_adapter'
13
17
  require 'migration_comments/active_record/connection_adapters/sqlite_adapter'
18
+ require 'migration_comments/active_record/connection_adapters/sqlite3_adapter'
14
19
 
15
20
  require 'active_record/connection_adapters/abstract_adapter'
16
21
 
17
22
  module MigrationComments
18
23
  def self.setup
24
+ if ::ActiveRecord::VERSION::MAJOR == 2
25
+ warn "[DEPRECATION] MigrationComments support for ActiveRecord v2.3 is deprecated and will be removed in a future version."
26
+ end
27
+
19
28
  base_names = %w(SchemaDumper) +
20
29
  %w(ColumnDefinition Column Table TableDefinition AbstractAdapter).map{|name| "ConnectionAdapters::#{name}"}
21
30
 
@@ -27,10 +36,27 @@ module MigrationComments
27
36
  end
28
37
  end
29
38
 
30
- %w(PostgreSQL Mysql Mysql2 SQLite).each do |adapter|
39
+ # Rails 4 introduces some new models that were not previously present
40
+ optimistic_models = []
41
+ optimistic_models << "ActiveRecord::ConnectionAdapters::AbstractAdapter::SchemaCreation"
42
+ optimistic_models << "ActiveRecord::ConnectionAdapters::AlterTable"
43
+ optimistic_models.each do |model_name|
44
+ begin
45
+ model = model_name.constantize
46
+ mc_class = "MigrationComments::#{model_name}".constantize
47
+ model.module_eval do
48
+ model.send(:include, mc_class)
49
+ end
50
+ rescue Exception => ex
51
+ end
52
+ end
53
+
54
+ adapters = %w(PostgreSQL Mysql Mysql2)
55
+ adapters << (::ActiveRecord::VERSION::MAJOR <= 3 ? "SQLite" : "SQLite3")
56
+ adapters.each do |adapter|
31
57
  begin
32
58
  require("active_record/connection_adapters/#{adapter.downcase}_adapter")
33
- adapter_class = ('ActiveRecord::ConnectionAdapters::' << "#{adapter}Adapter").constantize
59
+ adapter_class = ('::ActiveRecord::ConnectionAdapters::' << "#{adapter}Adapter").constantize
34
60
  mc_class = ('MigrationComments::ActiveRecord::ConnectionAdapters::' << "#{adapter}Adapter").constantize
35
61
  adapter_class.module_eval do
36
62
  adapter_class.__send__(:include, mc_class)
@@ -19,6 +19,10 @@ module MigrationComments::ActiveRecord::ConnectionAdapters
19
19
  false
20
20
  end
21
21
 
22
+ def inline_comments?
23
+ false
24
+ end
25
+
22
26
  # Remove a comment on a table (if set)
23
27
  def remove_table_comment(table_name)
24
28
  set_table_comment(table_name, nil)
@@ -0,0 +1,40 @@
1
+ module MigrationComments::ActiveRecord::ConnectionAdapters::AbstractAdapter
2
+ module SchemaCreation
3
+ def self.included(base)
4
+ base.class_eval do
5
+ alias_method_chain :column_options, :migration_comments
6
+ alias_method_chain :visit_TableDefinition, :migration_comments
7
+ alias_method_chain :visit_ColumnDefinition, :migration_comments
8
+ end
9
+ end
10
+
11
+ def column_options_with_migration_comments(o)
12
+ column_options = o.primary_key? ? {} : column_options_without_migration_comments(o)
13
+ column_options[:comment] = o.comment.comment_text if o.comment
14
+ column_options
15
+ end
16
+
17
+ def visit_TableDefinition_with_migration_comments(o)
18
+ if @conn.inline_comments?
19
+ create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE "
20
+ create_sql << "#{quote_table_name(o.name)}#{o.table_comment} ("
21
+ create_sql << o.columns.map { |c| accept c }.join(', ')
22
+ create_sql << ") #{o.options}"
23
+ create_sql
24
+ else
25
+ visit_TableDefinition_without_migration_comments(o)
26
+ end
27
+ end
28
+
29
+ def visit_ColumnDefinition_with_migration_comments(o)
30
+ if @conn.inline_comments?
31
+ sql_type = type_to_sql(o.type.to_sym, o.limit, o.precision, o.scale)
32
+ column_sql = "#{quote_column_name(o.name)} #{sql_type}"
33
+ add_column_options!(column_sql, column_options(o))
34
+ column_sql
35
+ else
36
+ visit_ColumnDefinition_without_migration_comments(o)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,85 @@
1
+ module MigrationComments::ActiveRecord::ConnectionAdapters
2
+ module AbstractSQLiteAdapter
3
+ def comments_supported?
4
+ true
5
+ end
6
+
7
+ def inline_comments?
8
+ true
9
+ end
10
+
11
+ def set_table_comment(table_name, comment_text)
12
+ alter_table(table_name, :comment => comment_text)
13
+ end
14
+
15
+ def set_column_comment(table_name, column_name, comment_text)
16
+ sql_type = primary_key(table_name) == column_name.to_s ?
17
+ :primary_key :
18
+ column_for(table_name, column_name).sql_type
19
+ change_column table_name, column_name, sql_type, :comment => comment_text
20
+ end
21
+
22
+ def retrieve_table_comment(table_name)
23
+ result = select_rows(lookup_comment_sql(table_name))
24
+ if result[0][0] =~ /CREATE (?:TEMPORARY )?TABLE #{quote_table_name table_name} [^\(]*\/\*(.*)\*\/ \(/
25
+ $1
26
+ end
27
+ end
28
+
29
+ def retrieve_column_comments(table_name, *column_names)
30
+ if column_names.empty?
31
+ return columns(table_name).inject({}) { |m, v| m[v.name.to_sym] = v.comment if v.comment.present?; m }
32
+ end
33
+ result = select_rows(lookup_comment_sql(table_name))
34
+ result[0][0] =~ /^CREATE (?:TEMPORARY )?TABLE "\w*" [^\(]*(?:\/\*.*\*\/ )?\((.*)\)[^\)]*$/
35
+ col_defs = $1
36
+ comment_matches = col_defs.scan(/"([^",]+)"[^,]*\/\*(.+?)\*\//)
37
+ comment_matches.inject({}){|m, row| m[row.first.to_sym] = row.last; m}
38
+ end
39
+
40
+ def change_column_with_migration_comments(table_name, column_name, type, options = {}) #:nodoc:
41
+ adapter = self
42
+ alter_table(table_name) do |definition|
43
+ include_default = options_include_default?(options)
44
+ definition[column_name].instance_eval do
45
+ self.type = type
46
+ self.limit = options[:limit] if options.include?(:limit)
47
+ self.default = options[:default] if include_default
48
+ self.null = options[:null] if options.include?(:null)
49
+ self.precision = options[:precision] if options.include?(:precision)
50
+ self.scale = options[:scale] if options.include?(:scale)
51
+ self.comment = CommentDefinition.new(adapter, table_name, column_name, options[:comment]) if options.include?(:comment)
52
+ end
53
+ end
54
+ end
55
+
56
+ def column_for(table_name, column_name)
57
+ columns(table_name).detect{|col| col.name == column_name.to_s}
58
+ end
59
+
60
+ def comment_sql(comment_definition)
61
+ if comment_definition.nil? || comment_definition.comment_text.blank?
62
+ ""
63
+ else
64
+ " /*#{escaped_comment(comment_definition.comment_text)}*/"
65
+ end
66
+
67
+ end
68
+
69
+ def add_column_options!(sql, options)
70
+ super(sql, options)
71
+ if options.keys.include?(:comment)
72
+ sql << CommentDefinition.new(self, nil, nil, options[:comment]).to_sql
73
+ end
74
+ end
75
+
76
+ private
77
+ def escaped_comment(comment)
78
+ comment.gsub(/\*\//, "*-/")
79
+ end
80
+
81
+ def lookup_comment_sql(table_name)
82
+ "select sql from (select * from sqlite_master where type='table' union select * from sqlite_temp_master where type='table') where tbl_name = '#{table_name}'"
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,17 @@
1
+ module MigrationComments::ActiveRecord::ConnectionAdapters
2
+ module AlterTable
3
+ def self.included(base)
4
+ base.class_eval do
5
+ alias_method_chain :add_column, :migration_comments
6
+ end
7
+ end
8
+
9
+ def add_column_with_migration_comments(name, type, options)
10
+ add_column_without_migration_comments(name, type, options)
11
+ if options.keys.include?(:comment)
12
+ column = @adds.last
13
+ column.comment = CommentDefinition.new(nil, @td, name, options[:comment])
14
+ end
15
+ end
16
+ end
17
+ end
@@ -2,12 +2,15 @@ module MigrationComments::ActiveRecord::ConnectionAdapters
2
2
  module MysqlAdapter
3
3
  def self.included(base)
4
4
  base.class_eval do
5
- attr_accessor :database_name
6
5
  alias_method_chain :create_table, :migration_comments
7
6
  alias_method_chain :change_column, :migration_comments
8
7
  end
9
8
  end
10
9
 
10
+ def comments_supported?
11
+ true
12
+ end
13
+
11
14
  def set_table_comment(table_name, comment_text)
12
15
  execute "ALTER TABLE #{quote_table_name table_name} COMMENT #{escaped_comment(comment_text)}"
13
16
  end
@@ -31,14 +34,14 @@ module MigrationComments::ActiveRecord::ConnectionAdapters
31
34
  def retrieve_column_comments(table_name, *column_names)
32
35
  result = select_rows(column_comment_sql(table_name, *column_names))
33
36
  return {} if result.nil?
34
- found = result.inject({}){|m, row| m[row[0].to_sym] = (row[1].blank? ? nil : row[1]); m}
35
-
37
+ result.inject({}){|m, row| m[row[0].to_sym] = (row[1].blank? ? nil : row[1]); m}
36
38
  end
37
39
 
38
40
  def create_table_with_migration_comments(table_name, options={}, &block)
39
41
  local_table_definition = nil
40
42
  create_table_without_migration_comments(table_name, options) do |td|
41
43
  local_table_definition = td
44
+ local_table_definition.base = self
42
45
  local_table_definition.comment options[:comment] if options.has_key?(:comment)
43
46
  block.call(td)
44
47
  end
@@ -76,7 +79,6 @@ module MigrationComments::ActiveRecord::ConnectionAdapters
76
79
  end
77
80
 
78
81
  def table_comment_sql(table_name)
79
- ensure_database_name
80
82
  <<SQL
81
83
  SELECT table_comment FROM INFORMATION_SCHEMA.TABLES
82
84
  WHERE table_schema = '#{database_name}'
@@ -85,7 +87,6 @@ SQL
85
87
  end
86
88
 
87
89
  def column_comment_sql(table_name, *column_names)
88
- ensure_database_name
89
90
  col_matcher_sql = column_names.empty? ? "" : " AND column_name IN (#{column_names.map{|c_name| "'#{c_name}'"}.join(',')})"
90
91
  <<SQL
91
92
  SELECT column_name, column_comment FROM INFORMATION_SCHEMA.COLUMNS
@@ -94,10 +95,8 @@ SELECT column_name, column_comment FROM INFORMATION_SCHEMA.COLUMNS
94
95
  SQL
95
96
  end
96
97
 
97
- def ensure_database_name
98
- return if database_name
99
- info = YAML::load(IO.read('config/database.yml'))
100
- @database_name = info[ENV['DB'] || Rails.env.to_s]["database"]
98
+ def database_name
99
+ @database_name ||= select_rows("SELECT DATABASE()")[0][0]
101
100
  end
102
101
 
103
102
  end
@@ -37,6 +37,7 @@ module MigrationComments::ActiveRecord::ConnectionAdapters
37
37
  local_table_definition = nil
38
38
  create_table_without_migration_comments(table_name, options) do |td|
39
39
  local_table_definition = td
40
+ local_table_definition.base = self
40
41
  local_table_definition.comment options[:comment] if options.has_key?(:comment)
41
42
  block.call(td)
42
43
  end
@@ -0,0 +1,75 @@
1
+ module MigrationComments::ActiveRecord::ConnectionAdapters
2
+ module SQLite3Adapter
3
+ include AbstractSQLiteAdapter
4
+
5
+ def self.included(base)
6
+ base.class_eval do
7
+ alias_method_chain :columns, :migration_comments
8
+ alias_method_chain :copy_table, :migration_comments
9
+ alias_method_chain :change_column, :migration_comments
10
+ end
11
+ end
12
+
13
+ def create_table(table_name, options = {})
14
+ td = create_table_definition table_name, options[:temporary], options[:options]
15
+ td.base = self
16
+
17
+ unless options[:id] == false
18
+ pk = options.fetch(:primary_key) {
19
+ ActiveRecord::Base.get_primary_key table_name.to_s.singularize
20
+ }
21
+
22
+ td.primary_key pk, options.fetch(:id, :primary_key), options
23
+ end
24
+ td.comment options[:comment] if options.has_key?(:comment)
25
+
26
+ yield td if block_given?
27
+
28
+ if options[:force] && table_exists?(table_name)
29
+ drop_table(table_name, options)
30
+ end
31
+
32
+ execute schema_creation.accept td
33
+ td.indexes.each_pair { |c,o| add_index table_name, c, o }
34
+ end
35
+
36
+ def columns_with_migration_comments(table_name)
37
+ cols = columns_without_migration_comments(table_name)
38
+ comments = retrieve_column_comments(table_name, *(cols.map(&:name)))
39
+ cols.each do |col|
40
+ col.comment = comments[col.name.to_sym] if comments.has_key?(col.name.to_sym)
41
+ end
42
+ cols
43
+ end
44
+
45
+ def copy_table_with_migration_comments(from, to, options = {}) #:nodoc:
46
+ from_primary_key = primary_key(from)
47
+ options[:id] = false
48
+ unless options.has_key?(:comment)
49
+ table_comment = retrieve_table_comment(from)
50
+ options = options.merge(:comment => table_comment) if table_comment
51
+ end
52
+ create_table(to, options) do |definition|
53
+ @definition = definition
54
+ @definition.primary_key(from_primary_key) if from_primary_key.present?
55
+ columns(from).each do |column|
56
+ column_name = options[:rename] ?
57
+ (options[:rename][column.name] ||
58
+ options[:rename][column.name.to_sym] ||
59
+ column.name) : column.name
60
+ next if column_name == from_primary_key
61
+
62
+ @definition.column(column_name, column.type,
63
+ :limit => column.limit, :default => column.default,
64
+ :precision => column.precision, :scale => column.scale,
65
+ :null => column.null, :comment => column.comment)
66
+ end
67
+ yield @definition if block_given?
68
+ end
69
+ copy_table_indexes(from, to, options[:rename] || {})
70
+ copy_table_contents(from, to,
71
+ @definition.columns.map {|column| column.name},
72
+ options[:rename] || {})
73
+ end
74
+ end
75
+ end
@@ -1,46 +1,20 @@
1
1
  module MigrationComments::ActiveRecord::ConnectionAdapters
2
2
  module SQLiteAdapter
3
+ include AbstractSQLiteAdapter
4
+
3
5
  def self.included(base)
4
- base.class_eval do
6
+ base.module_eval do
5
7
  alias_method_chain :columns, :migration_comments
6
8
  alias_method_chain :copy_table, :migration_comments
7
9
  alias_method_chain :change_column, :migration_comments
8
10
  end
9
11
  end
10
12
 
11
- def set_table_comment(table_name, comment_text)
12
- alter_table(table_name, :comment => comment_text)
13
- end
14
-
15
- def set_column_comment(table_name, column_name, comment_text)
16
- sql_type = primary_key(table_name) == column_name.to_s ?
17
- :primary_key :
18
- column_for(table_name, column_name).sql_type
19
- change_column table_name, column_name, sql_type, :comment => comment_text
20
- end
21
-
22
- def retrieve_table_comment(table_name)
23
- result = select_rows(lookup_comment_sql(table_name))
24
- if result[0][0] =~ /CREATE (?:TEMPORARY )?TABLE #{quote_table_name table_name} [^\(]*\/\*(.*)\*\/ \(/
25
- $1
26
- end
27
- end
28
-
29
- def retrieve_column_comments(table_name, *column_names)
30
- if column_names.empty?
31
- return columns(table_name).inject({}) { |m, v| m[v.name.to_sym] = v.comment if v.comment.present?; m }
32
- end
33
- result = select_rows(lookup_comment_sql(table_name))
34
- result[0][0] =~ /^CREATE (?:TEMPORARY )?TABLE "\w*" [^\(]*(?:\/\*.*\*\/ )?\((.*)\)[^\)]*$/
35
- col_defs = $1
36
- comment_matches = col_defs.scan(/"([^",]+)"[^,]*\/\*(.+?)\*\//)
37
- comment_matches.inject({}){|m, row| m[row.first.to_sym] = row.last; m}
38
- end
39
-
40
13
  def create_table(table_name, options = {})
41
- td = table_definition
14
+ td = ActiveRecord::ConnectionAdapters::TableDefinition.new(self)
42
15
  td.primary_key(options[:primary_key] || ActiveRecord::Base.get_primary_key(table_name.to_s.singularize)) unless options[:id] == false
43
16
  td.comment options[:comment] if options.has_key?(:comment)
17
+ td.base = self
44
18
 
45
19
  yield td if block_given?
46
20
 
@@ -57,22 +31,6 @@ module MigrationComments::ActiveRecord::ConnectionAdapters
57
31
  execute create_sql
58
32
  end
59
33
 
60
- def change_column_with_migration_comments(table_name, column_name, type, options = {}) #:nodoc:
61
- adapter = self
62
- alter_table(table_name) do |definition|
63
- include_default = options_include_default?(options)
64
- definition[column_name].instance_eval do
65
- self.type = type
66
- self.limit = options[:limit] if options.include?(:limit)
67
- self.default = options[:default] if include_default
68
- self.null = options[:null] if options.include?(:null)
69
- self.precision = options[:precision] if options.include?(:precision)
70
- self.scale = options[:scale] if options.include?(:scale)
71
- self.comment = CommentDefinition.new(adapter, table_name, column_name, options[:comment]) if options.include?(:comment)
72
- end
73
- end
74
- end
75
-
76
34
  def columns_with_migration_comments(table_name, name = nil)
77
35
  cols = columns_without_migration_comments(table_name, name)
78
36
  comments = retrieve_column_comments(table_name, *(cols.map(&:name)))
@@ -82,19 +40,6 @@ module MigrationComments::ActiveRecord::ConnectionAdapters
82
40
  cols
83
41
  end
84
42
 
85
- def column_for(table_name, column_name)
86
- columns(table_name).detect{|col| col.name == column_name.to_s}
87
- end
88
-
89
- def comment_sql(comment_definition)
90
- if comment_definition.nil? || comment_definition.comment_text.blank?
91
- ""
92
- else
93
- " /*#{escaped_comment(comment_definition.comment_text)}*/"
94
- end
95
-
96
- end
97
-
98
43
  def copy_table_with_migration_comments(from, to, options = {}) #:nodoc:
99
44
  options = options.merge(:id => (!columns(from).detect{|c| c.name == 'id'}.nil? && 'id' == primary_key(from).to_s))
100
45
  unless options.has_key?(:comment)
@@ -122,21 +67,5 @@ module MigrationComments::ActiveRecord::ConnectionAdapters
122
67
  @definition.columns.map {|column| column.name},
123
68
  options[:rename] || {})
124
69
  end
125
-
126
- def add_column_options!(sql, options)
127
- super(sql, options)
128
- if options.keys.include?(:comment)
129
- sql << CommentDefinition.new(self, nil, nil, options[:comment]).to_sql
130
- end
131
- end
132
-
133
- private
134
- def escaped_comment(comment)
135
- comment.gsub(/\*\//, "*-/")
136
- end
137
-
138
- def lookup_comment_sql(table_name)
139
- "select sql from (select * from sqlite_master where type='table' union select * from sqlite_temp_master where type='table') where tbl_name = '#{table_name}'"
140
- end
141
70
  end
142
71
  end
@@ -5,11 +5,12 @@ module MigrationComments::ActiveRecord::ConnectionAdapters
5
5
  def self.included(base)
6
6
  base.class_eval do
7
7
  alias_method_chain :column, :migration_comments
8
+ attr_accessor :base
8
9
  end
9
10
  end
10
11
 
11
12
  def comment(text)
12
- @table_comment = CommentDefinition.new(@base, nil, nil, text)
13
+ @table_comment = CommentDefinition.new(base, nil, nil, text)
13
14
  self
14
15
  end
15
16
 
@@ -17,16 +18,16 @@ module MigrationComments::ActiveRecord::ConnectionAdapters
17
18
  column_without_migration_comments(name, type, options)
18
19
  if options.has_key?(:comment)
19
20
  col = self[name]
20
- col.comment = CommentDefinition.new(@base, nil, name, options[:comment])
21
+ col.comment = CommentDefinition.new(base, nil, name, options[:comment])
21
22
  end
22
23
  self
23
24
  end
24
25
 
25
26
  def collect_comments(table_name)
26
27
  comments = []
27
- comments << @table_comment << @columns.map(&:comment)
28
+ comments << @table_comment << columns.map(&:comment)
28
29
  comments.flatten!.compact!
29
- comments.each{|comment| comment.table = table_name}
30
+ comments.each{|comment| comment.table = table_name; comment.adapter = base}
30
31
  end
31
32
  end
32
33
  end
@@ -1,5 +1,6 @@
1
1
  module MigrationComments::ActiveRecord
2
2
  module SchemaDumper
3
+ include MigrationComments::SchemaFormatter
3
4
  def self.included(base)
4
5
  base.class_eval do
5
6
  alias_method_chain :table, :migration_comments
@@ -23,9 +24,12 @@ module MigrationComments::ActiveRecord
23
24
  lines = []
24
25
  table_line = 0
25
26
  col_names = {}
27
+ error = false
26
28
  while (line = stream.gets)
27
29
  content = line.chomp
28
- if content =~ /create_table\s/
30
+ if content =~ /^# Could not dump table "#{table_name}"/
31
+ error = true
32
+ elsif content =~ /create_table\s/
29
33
  table_line = lines.size
30
34
  elsif content =~ /t\.\w+\s+"(\w+)"/
31
35
  col_names[lines.size] = $1.to_sym
@@ -34,7 +38,9 @@ module MigrationComments::ActiveRecord
34
38
  end
35
39
  len = col_names.keys.map{|index| lines[index]}.map(&:length).max + 2 unless col_names.empty?
36
40
  lines.each_with_index do |line, index|
37
- if table_line == index && table_comment.present?
41
+ if error
42
+ # do nothing
43
+ elsif table_line == index && table_comment.present?
38
44
  block_init = " do |t|"
39
45
  line.chomp!(block_init) << ", " << render_comment(table_comment) << block_init
40
46
  elsif col_names[index]
@@ -46,9 +52,5 @@ module MigrationComments::ActiveRecord
46
52
  comment_stream.rewind
47
53
  comment_stream
48
54
  end
49
-
50
- def render_comment(comment)
51
- ":comment => \"#{comment}\""
52
- end
53
55
  end
54
56
  end
@@ -0,0 +1,19 @@
1
+ module MigrationComments
2
+ module SchemaFormatter
3
+ def render_comment(comment)
4
+ render_kv_pair(:comment, comment)
5
+ end
6
+
7
+ def render_kv_pair(key, value)
8
+ if ::ActiveRecord::VERSION::MAJOR <= 3
9
+ ":#{key} => #{render_value(value)}"
10
+ else
11
+ "#{key}: #{render_value(value)}"
12
+ end
13
+ end
14
+
15
+ def render_value(value)
16
+ value.is_a?(String) ? "\"#{value}\"" : value
17
+ end
18
+ end
19
+ end
@@ -1,3 +1,3 @@
1
1
  module MigrationComments
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
6
6
  s.name = "migration_comments"
7
7
  s.version = MigrationComments::VERSION
8
8
  s.authors = ["Pinny"]
9
- s.email = ["pinny@medwiztech.com"]
9
+ s.email = ["pinny@mwitz.com"]
10
10
  s.homepage = "https://github.com/pinnymz/migration_comments"
11
11
  s.summary = %q{Comments for your migrations}
12
12
  s.description = %q{Add schema comments in your migrations, see them in model annotations and db/schema.rb dump}
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
20
 
21
- s.add_runtime_dependency 'rails', '>= 2.3.2'
21
+ s.add_runtime_dependency 'activerecord', '>= 2.3.2'
22
22
 
23
23
  # for development, we are testing against the 'annotate' gem
24
24
  # however, the comments should work with the original 'annotate_models' plugin as well at:
@@ -26,9 +26,10 @@ Gem::Specification.new do |s|
26
26
  # provided the environment is not loaded until _after_ the AnnotateModels module is declared
27
27
  s.add_development_dependency 'annotate', '~> 2.5.0'
28
28
 
29
- s.add_development_dependency 'pg' # replace with other adapter as needed
29
+ # add / replace with other adapter(s) as needed
30
+ s.add_development_dependency 'pg'
30
31
  # s.add_development_dependency 'postgres-pr'
31
32
  # s.add_development_dependency 'mysql'
32
- # s.add_development_dependency 'mysql2'
33
- # s.add_development_dependency 'sqlite3'
33
+ s.add_development_dependency 'mysql2'
34
+ s.add_development_dependency 'sqlite3'
34
35
  end
@@ -1,4 +1,4 @@
1
- require './test_helper'
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
2
 
3
3
  class AddCommentsTest < Test::Unit::TestCase
4
4
  include TestHelper
@@ -40,7 +40,7 @@ class AddCommentsTest < Test::Unit::TestCase
40
40
  result_table_comment = retrieve_table_comment :sample2
41
41
  result_column_comments = retrieve_column_comments :sample2
42
42
  ensure
43
- drop_table :sample2
43
+ drop_table :sample2 rescue nil
44
44
  end
45
45
  end
46
46
  assert_equal table_comment, result_table_comment
@@ -1,4 +1,4 @@
1
- require './test_helper'
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
2
  gem 'annotate'
3
3
  require 'annotate/annotate_models'
4
4
 
@@ -1,4 +1,4 @@
1
- require './test_helper'
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
2
 
3
3
  class Sample < ActiveRecord::Base
4
4
  self.table_name = 'sample'
@@ -6,13 +6,13 @@ postgres:
6
6
  password: postgres
7
7
 
8
8
  mysql:
9
- adapter: mysql # mysql2
9
+ adapter: mysql2
10
10
  database: migration_comments_test
11
11
  user: root
12
12
  password: password
13
13
 
14
14
  sqlite:
15
15
  adapter: sqlite3
16
- database: db/migration_comments_test
16
+ database: test/db/migration_comments_test
17
17
  pool: 5
18
18
  timeout: 5000
@@ -1,7 +1,8 @@
1
- require './test_helper'
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
2
 
3
3
  class SchemaDumperTest < Test::Unit::TestCase
4
4
  include TestHelper
5
+ include MigrationComments::SchemaFormatter
5
6
 
6
7
  def test_dump
7
8
  ActiveRecord::Schema.define do
@@ -14,23 +15,23 @@ class SchemaDumperTest < Test::Unit::TestCase
14
15
  dest.rewind
15
16
  result = dest.read
16
17
  expected = <<EOS
17
- ActiveRecord::Schema.define(:version => 1) do
18
+ ActiveRecord::Schema.define(#{render_kv_pair(:version, 1)}) do
18
19
 
19
- create_table "sample", :force => true, :comment => "a table comment" do |t|
20
- t.string "field1", :comment => "a \"comment\" \\ that ' needs; escaping''"
20
+ create_table "sample", #{render_kv_pair(:force, true)}, #{render_kv_pair(:comment, "a table comment")} do |t|
21
+ t.string "field1", __SPACES__#{render_kv_pair(:comment, %{a \"comment\" \\ that ' needs; escaping''})}
21
22
  t.integer "field2"
22
- t.string "field3", :default => "", :null => false, :comment => "third column comment"
23
+ t.string "field3", #{render_kv_pair(:default, "")}, #{render_kv_pair(:null, false)}, #{render_kv_pair(:comment, "third column comment")}
23
24
  end
24
25
 
25
26
  end
26
27
  EOS
27
-
28
- assert_match /#{Regexp.escape expected}/, result
28
+ assert_match /#{Regexp.escape(expected).gsub(/__SPACES__/, " +")}/, result
29
29
  end
30
30
 
31
31
  def test_dump_with_no_columns
32
32
  ActiveRecord::Schema.define do
33
- remove_column :sample, :field1, :field2
33
+ remove_column :sample, :field1
34
+ remove_column :sample, :field2
34
35
  set_table_comment :sample, "a table comment"
35
36
  end
36
37
  dest = StringIO.new
@@ -38,11 +39,38 @@ EOS
38
39
  dest.rewind
39
40
  result = dest.read
40
41
  expected = <<EOS
41
- ActiveRecord::Schema.define(:version => 1) do
42
+ ActiveRecord::Schema.define(#{render_kv_pair(:version, 1)}) do
42
43
 
43
- create_table "sample", :force => true, :comment => "a table comment" do |t|
44
+ create_table "sample", #{render_kv_pair(:force, true)}, #{render_kv_pair(:comment, "a table comment")} do |t|
44
45
  end
45
46
 
47
+ end
48
+ EOS
49
+
50
+ assert_match /#{Regexp.escape expected}/, result
51
+ end
52
+
53
+ def test_schema_dump_with_custom_type_error_for_pg
54
+ return unless ENV['DB'] == 'postgres'
55
+ ActiveRecord::Base.connection.execute "DROP TYPE IF EXISTS my_custom_type; CREATE TYPE my_custom_type AS ENUM('thing1', 'thing2');"
56
+ ActiveRecord::Base.connection.execute "ALTER TABLE sample ALTER COLUMN field2 TYPE my_custom_type USING 'thing1';"
57
+
58
+ ActiveRecord::Schema.define do
59
+ set_table_comment :sample, "a table comment"
60
+ set_column_comment :sample, :field1, "column comment"
61
+ end
62
+
63
+ dest = StringIO.new
64
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, dest)
65
+ dest.rewind
66
+ result = dest.read
67
+
68
+ expected = <<EOS
69
+ ActiveRecord::Schema.define(#{render_kv_pair(:version, 1)}) do
70
+
71
+ # Could not dump table "sample" because of following StandardError
72
+ # Unknown type 'my_custom_type' for column 'field2'
73
+
46
74
  end
47
75
  EOS
48
76
 
data/test/test_helper.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  require 'test/unit'
2
2
 
3
3
  require 'rubygems'
4
- gem 'rails', '>= 2.3.2'
4
+ gem 'activerecord', '>= 2.3.2'
5
5
  require 'active_record'
6
6
  require 'yaml'
7
7
 
8
- CONFIGURATIONS = YAML::load(IO.read('config/database.yml'))
8
+ CONFIGURATIONS = YAML::load(IO.read(File.join(File.dirname(__FILE__), 'config/database.yml')))
9
9
 
10
10
  ENV['DB'] ||= 'postgres' # override as needed
11
11
 
metadata CHANGED
@@ -1,79 +1,104 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: migration_comments
3
- version: !ruby/object:Gem::Version
4
- hash: 21
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 2
9
- - 1
10
- version: 0.2.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Pinny
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-12-31 00:00:00 -05:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- name: rails
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
12
+ date: 2013-07-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 7
30
- segments:
31
- - 2
32
- - 3
33
- - 2
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
34
21
  version: 2.3.2
35
22
  type: :runtime
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: annotate
39
23
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 2.3.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: annotate
32
+ requirement: !ruby/object:Gem::Requirement
41
33
  none: false
42
- requirements:
34
+ requirements:
43
35
  - - ~>
44
- - !ruby/object:Gem::Version
45
- hash: 27
46
- segments:
47
- - 2
48
- - 5
49
- - 0
36
+ - !ruby/object:Gem::Version
50
37
  version: 2.5.0
51
38
  type: :development
52
- version_requirements: *id002
53
- - !ruby/object:Gem::Dependency
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.5.0
46
+ - !ruby/object:Gem::Dependency
54
47
  name: pg
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
55
  prerelease: false
56
- requirement: &id003 !ruby/object:Gem::Requirement
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: mysql2
64
+ requirement: !ruby/object:Gem::Requirement
57
65
  none: false
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- hash: 3
62
- segments:
63
- - 0
64
- version: "0"
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
65
70
  type: :development
66
- version_requirements: *id003
67
- description: Add schema comments in your migrations, see them in model annotations and db/schema.rb dump
68
- email:
69
- - pinny@medwiztech.com
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: sqlite3
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description: Add schema comments in your migrations, see them in model annotations
95
+ and db/schema.rb dump
96
+ email:
97
+ - pinny@mwitz.com
70
98
  executables: []
71
-
72
99
  extensions: []
73
-
74
100
  extra_rdoc_files: []
75
-
76
- files:
101
+ files:
77
102
  - .gitignore
78
103
  - Gemfile
79
104
  - MIT-LICENSE
@@ -81,17 +106,22 @@ files:
81
106
  - Rakefile
82
107
  - lib/migration_comments.rb
83
108
  - lib/migration_comments/active_record/connection_adapters/abstract_adapter.rb
109
+ - lib/migration_comments/active_record/connection_adapters/abstract_adapter/schema_creation.rb
110
+ - lib/migration_comments/active_record/connection_adapters/abstract_sqlite_adapter.rb
111
+ - lib/migration_comments/active_record/connection_adapters/alter_table.rb
84
112
  - lib/migration_comments/active_record/connection_adapters/column.rb
85
113
  - lib/migration_comments/active_record/connection_adapters/column_definition.rb
86
114
  - lib/migration_comments/active_record/connection_adapters/comment_definition.rb
87
115
  - lib/migration_comments/active_record/connection_adapters/mysql2_adapter.rb
88
116
  - lib/migration_comments/active_record/connection_adapters/mysql_adapter.rb
89
117
  - lib/migration_comments/active_record/connection_adapters/postgresql_adapter.rb
118
+ - lib/migration_comments/active_record/connection_adapters/sqlite3_adapter.rb
90
119
  - lib/migration_comments/active_record/connection_adapters/sqlite_adapter.rb
91
120
  - lib/migration_comments/active_record/connection_adapters/table.rb
92
121
  - lib/migration_comments/active_record/connection_adapters/table_definition.rb
93
122
  - lib/migration_comments/active_record/schema_dumper.rb
94
123
  - lib/migration_comments/annotate_models.rb
124
+ - lib/migration_comments/schema_formatter.rb
95
125
  - lib/migration_comments/version.rb
96
126
  - migration_comments.gemspec
97
127
  - test/add_comments_test.rb
@@ -100,39 +130,34 @@ files:
100
130
  - test/config/database.yml
101
131
  - test/schema_dumper_test.rb
102
132
  - test/test_helper.rb
103
- has_rdoc: true
104
133
  homepage: https://github.com/pinnymz/migration_comments
105
134
  licenses: []
106
-
107
135
  post_install_message:
108
136
  rdoc_options: []
109
-
110
- require_paths:
137
+ require_paths:
111
138
  - lib
112
- required_ruby_version: !ruby/object:Gem::Requirement
139
+ required_ruby_version: !ruby/object:Gem::Requirement
113
140
  none: false
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- hash: 3
118
- segments:
141
+ requirements:
142
+ - - ! '>='
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ segments:
119
146
  - 0
120
- version: "0"
121
- required_rubygems_version: !ruby/object:Gem::Requirement
147
+ hash: 1998391628422785254
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
149
  none: false
123
- requirements:
124
- - - ">="
125
- - !ruby/object:Gem::Version
126
- hash: 3
127
- segments:
150
+ requirements:
151
+ - - ! '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ segments:
128
155
  - 0
129
- version: "0"
156
+ hash: 1998391628422785254
130
157
  requirements: []
131
-
132
158
  rubyforge_project: migration_comments
133
- rubygems_version: 1.3.7
159
+ rubygems_version: 1.8.25
134
160
  signing_key:
135
161
  specification_version: 3
136
162
  summary: Comments for your migrations
137
163
  test_files: []
138
-