migration_comments 0.3.2 → 0.4.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.travis.yml +27 -0
- data/README.rdoc +12 -3
- data/Rakefile +24 -0
- data/docker-compose.yml +12 -0
- data/gemfiles/rails4.gemfile +4 -0
- data/gemfiles/rails5.gemfile +4 -0
- data/lib/migration_comments.rb +12 -40
- data/lib/migration_comments/active_record/connection_adapters/abstract_adapter.rb +1 -10
- data/lib/migration_comments/active_record/connection_adapters/abstract_adapter/schema_creation.rb +22 -25
- data/lib/migration_comments/active_record/connection_adapters/alter_table.rb +5 -10
- data/lib/migration_comments/active_record/connection_adapters/column.rb +1 -5
- data/lib/migration_comments/active_record/connection_adapters/comment_definition.rb +1 -9
- data/lib/migration_comments/active_record/connection_adapters/mysql2_adapter.rb +97 -3
- data/lib/migration_comments/active_record/connection_adapters/postgresql_adapter.rb +19 -22
- data/lib/migration_comments/active_record/connection_adapters/sqlite3_adapter.rb +73 -46
- data/lib/migration_comments/active_record/connection_adapters/table.rb +3 -3
- data/lib/migration_comments/active_record/connection_adapters/table_definition.rb +9 -18
- data/lib/migration_comments/active_record/schema_dumper.rb +6 -10
- data/lib/migration_comments/annotate_models.rb +6 -8
- data/lib/migration_comments/schema_formatter.rb +8 -1
- data/lib/migration_comments/version.rb +1 -1
- data/migration_comments.gemspec +3 -10
- data/test/add_comments_test.rb +43 -2
- data/test/annotate_models_test.rb +6 -4
- data/test/auto_increment_test.rb +39 -9
- data/test/config/database.yml +2 -2
- data/test/primary_uuid_test.rb +27 -0
- data/test/schema_dumper_test.rb +35 -11
- data/test/test_helper.rb +8 -1
- metadata +34 -11
- data/lib/migration_comments/active_record/connection_adapters/abstract_sqlite_adapter.rb +0 -85
- data/lib/migration_comments/active_record/connection_adapters/mysql_adapter.rb +0 -107
- data/lib/migration_comments/active_record/connection_adapters/sqlite_adapter.rb +0 -71
@@ -1,12 +1,5 @@
|
|
1
1
|
module MigrationComments::ActiveRecord::ConnectionAdapters
|
2
2
|
module PostgreSQLAdapter
|
3
|
-
def self.included(base)
|
4
|
-
base.class_eval do
|
5
|
-
alias_method_chain :create_table, :migration_comments
|
6
|
-
alias_method_chain :add_column, :migration_comments
|
7
|
-
alias_method_chain :change_column, :migration_comments
|
8
|
-
end
|
9
|
-
end
|
10
3
|
|
11
4
|
def comments_supported?
|
12
5
|
true
|
@@ -18,48 +11,52 @@ module MigrationComments::ActiveRecord::ConnectionAdapters
|
|
18
11
|
|
19
12
|
# Set a comment on a table
|
20
13
|
def set_table_comment(table_name, comment_text)
|
21
|
-
execute CommentDefinition.new(
|
14
|
+
execute comment_sql(CommentDefinition.new(table_name, nil, comment_text))
|
22
15
|
end
|
23
16
|
|
24
17
|
# Set a comment on a column
|
25
18
|
def set_column_comment(table_name, column_name, comment_text)
|
26
|
-
execute CommentDefinition.new(
|
19
|
+
execute comment_sql(CommentDefinition.new(table_name, column_name, comment_text))
|
20
|
+
end
|
21
|
+
|
22
|
+
if ::ActiveRecord::VERSION::MAJOR >= 5
|
23
|
+
def change_column_comment(table_name, column_name, comment)
|
24
|
+
comment_text = comment.respond_to?(:comment_text) ? comment.comment_text : comment
|
25
|
+
super(table_name, column_name, comment_text)
|
26
|
+
end
|
27
27
|
end
|
28
28
|
|
29
29
|
def retrieve_table_comment(table_name)
|
30
|
-
|
31
|
-
result[0].nil? ? nil : result[0][0]
|
30
|
+
select_value(table_comment_sql(table_name)).presence
|
32
31
|
end
|
33
32
|
|
34
33
|
def retrieve_column_comments(table_name, *column_names)
|
35
34
|
result = select_rows(column_comment_sql(table_name, *column_names))
|
36
|
-
|
37
|
-
return result.inject({}){|m, row| m[row[0].to_sym] = row[1]; m}
|
35
|
+
Hash[result.map{|row| [row[0].to_sym, row[1].presence]}]
|
38
36
|
end
|
39
37
|
|
40
|
-
def
|
38
|
+
def create_table(table_name, options = {})
|
41
39
|
local_table_definition = nil
|
42
|
-
|
40
|
+
super(table_name, options) do |td|
|
43
41
|
local_table_definition = td
|
44
|
-
local_table_definition.
|
45
|
-
local_table_definition.comment options[:comment] if options.has_key?(:comment)
|
42
|
+
local_table_definition.comment = options[:comment] if options.has_key?(:comment)
|
46
43
|
yield td if block_given?
|
47
44
|
end
|
48
45
|
comments = local_table_definition.collect_comments(table_name)
|
49
46
|
comments.each do |comment_definition|
|
50
|
-
execute comment_definition
|
47
|
+
execute comment_sql(comment_definition)
|
51
48
|
end
|
52
49
|
end
|
53
50
|
|
54
|
-
def
|
55
|
-
|
51
|
+
def add_column(table_name, column_name, type, options = {})
|
52
|
+
super(table_name, column_name, type, options)
|
56
53
|
if options[:comment]
|
57
54
|
set_column_comment(table_name, column_name, options[:comment])
|
58
55
|
end
|
59
56
|
end
|
60
57
|
|
61
|
-
def
|
62
|
-
|
58
|
+
def change_column(table_name, column_name, type, options = {})
|
59
|
+
super(table_name, column_name, type, options)
|
63
60
|
if options.keys.include?(:comment)
|
64
61
|
set_column_comment(table_name, column_name, options[:comment])
|
65
62
|
end
|
@@ -1,40 +1,50 @@
|
|
1
1
|
module MigrationComments::ActiveRecord::ConnectionAdapters
|
2
2
|
module SQLite3Adapter
|
3
|
-
include AbstractSQLiteAdapter
|
4
3
|
|
5
|
-
def
|
6
|
-
|
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
|
4
|
+
def comments_supported?
|
5
|
+
true
|
11
6
|
end
|
12
7
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
8
|
+
def inline_comments?
|
9
|
+
true
|
10
|
+
end
|
16
11
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
}
|
12
|
+
def set_table_comment(table_name, comment_text)
|
13
|
+
alter_table(table_name, :comment => comment_text)
|
14
|
+
end
|
21
15
|
|
22
|
-
|
23
|
-
|
24
|
-
|
16
|
+
def set_column_comment(table_name, column_name, comment_text)
|
17
|
+
sql_type = primary_key(table_name) == column_name.to_s ?
|
18
|
+
:primary_key :
|
19
|
+
column_for(table_name, column_name).sql_type
|
20
|
+
change_column table_name, column_name, sql_type, :comment => comment_text
|
21
|
+
end
|
25
22
|
|
26
|
-
|
23
|
+
def retrieve_table_comment(table_name)
|
24
|
+
result = select_value(lookup_comment_sql(table_name))
|
25
|
+
$1 if result =~ /CREATE (?:TEMPORARY )?TABLE #{quote_table_name table_name} [^\(]*\/\*(.*)\*\/ \(/
|
26
|
+
end
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
def retrieve_column_comments(table_name, *column_names)
|
29
|
+
if column_names.empty?
|
30
|
+
return columns(table_name).inject({}) { |m, v| m[v.name.to_sym] = v.comment if v.comment.present?; m }
|
30
31
|
end
|
32
|
+
result = select_value(lookup_comment_sql(table_name))
|
33
|
+
result =~ /^CREATE (?:TEMPORARY )?TABLE "\w*" [^\(]*(?:\/\*.*\*\/ )?\((.*)\)[^\)]*$/
|
34
|
+
col_defs = $1
|
35
|
+
comment_matches = col_defs.scan(/"([^",]+)"[^,]*\/\*(.+?)\*\//)
|
36
|
+
Hash[comment_matches.map{|col_name, comment| [col_name.to_sym, comment.presence] }]
|
37
|
+
end
|
31
38
|
|
32
|
-
|
33
|
-
|
39
|
+
def create_table(table_name, options = {})
|
40
|
+
super(table_name, options) do |td|
|
41
|
+
td.comment = options[:comment] if options.has_key?(:comment)
|
42
|
+
yield td if block_given?
|
43
|
+
end
|
34
44
|
end
|
35
45
|
|
36
|
-
def
|
37
|
-
cols =
|
46
|
+
def columns(table_name)
|
47
|
+
cols = super(table_name)
|
38
48
|
comments = retrieve_column_comments(table_name, *(cols.map(&:name)))
|
39
49
|
cols.each do |col|
|
40
50
|
col.comment = comments[col.name.to_sym] if comments.has_key?(col.name.to_sym)
|
@@ -42,34 +52,51 @@ module MigrationComments::ActiveRecord::ConnectionAdapters
|
|
42
52
|
cols
|
43
53
|
end
|
44
54
|
|
45
|
-
def
|
46
|
-
from_primary_key = primary_key(from)
|
47
|
-
options[:id] = false
|
55
|
+
def copy_table(from, to, options = {}) #:nodoc:
|
48
56
|
unless options.has_key?(:comment)
|
49
57
|
table_comment = retrieve_table_comment(from)
|
50
|
-
options
|
58
|
+
options.merge!(comment: table_comment) if table_comment
|
59
|
+
end
|
60
|
+
super(from, to, options) do |definition|
|
61
|
+
retrieve_column_comments(from).each do |col_name, comment|
|
62
|
+
definition[col_name].comment = CommentDefinition.new(from, col_name, comment)
|
63
|
+
end
|
64
|
+
yield definition if block_given?
|
51
65
|
end
|
52
|
-
|
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
|
66
|
+
end
|
61
67
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
68
|
+
def change_column(table_name, column_name, type, options = {}) #:nodoc:
|
69
|
+
super(table_name, column_name, type, options)
|
70
|
+
if options.has_key?(:comment)
|
71
|
+
alter_table(table_name) do |definition|
|
72
|
+
definition[column_name].comment = CommentDefinition.new(table_name, column_name, options[:comment])
|
66
73
|
end
|
67
|
-
yield @definition if block_given?
|
68
74
|
end
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
75
|
+
end
|
76
|
+
|
77
|
+
def comment_sql(comment_definition)
|
78
|
+
if comment_definition.nil? || comment_definition.comment_text.blank?
|
79
|
+
""
|
80
|
+
else
|
81
|
+
" /*#{escaped_comment(comment_definition.comment_text)}*/"
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
def add_column_options!(sql, options)
|
87
|
+
super(sql, options)
|
88
|
+
if options.keys.include?(:comment)
|
89
|
+
sql << comment_sql(CommentDefinition.new(nil, nil, options[:comment]))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
def escaped_comment(comment)
|
95
|
+
comment.gsub(/\*\//, "*-/")
|
96
|
+
end
|
97
|
+
|
98
|
+
def lookup_comment_sql(table_name)
|
99
|
+
"select sql from (select * from sqlite_master where type='table' union select * from sqlite_temp_master where type='table') where tbl_name = '#{table_name}'"
|
73
100
|
end
|
74
101
|
end
|
75
102
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module MigrationComments::ActiveRecord::ConnectionAdapters
|
2
2
|
module Table
|
3
3
|
def change_comment(column_name, comment_text)
|
4
|
-
@base.set_column_comment(
|
4
|
+
@base.set_column_comment(name, column_name, comment_text)
|
5
5
|
end
|
6
6
|
|
7
7
|
def change_table_comment(comment_text)
|
8
|
-
@base.set_table_comment(
|
8
|
+
@base.set_table_comment(name, comment_text)
|
9
9
|
end
|
10
|
-
|
10
|
+
alias_method :comment, :change_table_comment
|
11
11
|
end
|
12
12
|
end
|
@@ -1,33 +1,24 @@
|
|
1
1
|
module MigrationComments::ActiveRecord::ConnectionAdapters
|
2
2
|
module TableDefinition
|
3
|
+
attr_accessor :comment
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
base.class_eval do
|
7
|
-
alias_method_chain :column, :migration_comments
|
8
|
-
attr_accessor :base
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def comment(text)
|
13
|
-
@table_comment = CommentDefinition.new(base, nil, nil, text)
|
14
|
-
self
|
5
|
+
def comment=(text)
|
6
|
+
@comment = text.respond_to?(:comment_text) ? text : CommentDefinition.new(nil, nil, text)
|
15
7
|
end
|
16
8
|
|
17
|
-
def
|
18
|
-
|
9
|
+
def column(name, type, options = {})
|
10
|
+
super(name, type, options)
|
19
11
|
if options.has_key?(:comment)
|
20
12
|
col = self[name]
|
21
|
-
col.comment = CommentDefinition.new(
|
13
|
+
col.comment = CommentDefinition.new(nil, name, options[:comment])
|
22
14
|
end
|
23
15
|
self
|
24
16
|
end
|
25
17
|
|
26
18
|
def collect_comments(table_name)
|
27
|
-
comments = []
|
28
|
-
comments
|
29
|
-
comments.
|
30
|
-
comments.each{|comment| comment.table = table_name; comment.adapter = base}
|
19
|
+
comments = [comment] + columns.map(&:comment)
|
20
|
+
comments.compact!
|
21
|
+
comments.each{|comment| comment.table_name = table_name }
|
31
22
|
end
|
32
23
|
end
|
33
24
|
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
module MigrationComments::ActiveRecord
|
2
2
|
module SchemaDumper
|
3
3
|
include MigrationComments::SchemaFormatter
|
4
|
-
def self.included(base)
|
5
|
-
base.class_eval do
|
6
|
-
alias_method_chain :table, :migration_comments
|
7
|
-
end
|
8
|
-
end
|
9
4
|
|
10
|
-
def
|
5
|
+
def table(table, stream)
|
6
|
+
return super if ::ActiveRecord::VERSION::MAJOR >= 5 && @connection.class.name !~ /SQLite/
|
11
7
|
tbl_stream = StringIO.new
|
12
|
-
|
8
|
+
super(table, tbl_stream)
|
13
9
|
tbl_stream.rewind
|
14
10
|
commented_stream = append_comments(table, tbl_stream)
|
15
11
|
tbl_stream.close
|
@@ -25,8 +21,8 @@ module MigrationComments::ActiveRecord
|
|
25
21
|
table_line = 0
|
26
22
|
col_names = {}
|
27
23
|
error = false
|
28
|
-
while (
|
29
|
-
content =
|
24
|
+
while (stream_line = stream.gets)
|
25
|
+
content = stream_line.chomp
|
30
26
|
if content =~ /^# Could not dump table "#{table_name}"/
|
31
27
|
error = true
|
32
28
|
elsif content =~ /create_table\s/
|
@@ -43,7 +39,7 @@ module MigrationComments::ActiveRecord
|
|
43
39
|
elsif table_line == index && table_comment.present?
|
44
40
|
block_init = " do |t|"
|
45
41
|
line.chomp!(block_init) << ", " << render_comment(table_comment) << block_init
|
46
|
-
elsif col_names[index]
|
42
|
+
elsif col_names[index] && ::ActiveRecord::VERSION::MAJOR < 5
|
47
43
|
comment = column_comments[col_names[index]]
|
48
44
|
line << ',' << ' ' * (len - line.length) << render_comment(comment) unless comment.blank?
|
49
45
|
end
|
@@ -1,18 +1,16 @@
|
|
1
1
|
module MigrationComments
|
2
2
|
module AnnotateModels
|
3
|
-
def self.
|
4
|
-
base
|
5
|
-
|
6
|
-
include ClassMethods
|
7
|
-
alias_method_chain :get_schema_info, :migration_comments
|
8
|
-
end
|
3
|
+
def self.prepended(base)
|
4
|
+
class << base
|
5
|
+
prepend ClassMethods
|
9
6
|
end
|
10
7
|
end
|
11
8
|
|
12
9
|
module ClassMethods
|
13
|
-
def
|
14
|
-
info = get_schema_info_without_migration_comments(*args)
|
10
|
+
def get_schema_info(*args)
|
15
11
|
klass = args[0]
|
12
|
+
klass.reset_column_information
|
13
|
+
info = super(*args)
|
16
14
|
commented_info(klass, info)
|
17
15
|
end
|
18
16
|
|
@@ -13,7 +13,14 @@ module MigrationComments
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def render_value(value)
|
16
|
-
|
16
|
+
case value
|
17
|
+
when String
|
18
|
+
%Q[#{value}].inspect
|
19
|
+
when Symbol
|
20
|
+
value.inspect
|
21
|
+
else
|
22
|
+
value
|
23
|
+
end
|
17
24
|
end
|
18
25
|
end
|
19
26
|
end
|
data/migration_comments.gemspec
CHANGED
@@ -18,18 +18,11 @@ 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 'activerecord', '>= 2.
|
21
|
+
s.add_runtime_dependency 'activerecord', '>= 4.2.0'
|
22
22
|
|
23
|
-
|
24
|
-
# however, the comments should work with the original 'annotate_models' plugin as well at:
|
25
|
-
# http://repo.pragprog.com/svn/Public/plugins/annotate_models
|
26
|
-
# provided the environment is not loaded until _after_ the AnnotateModels module is declared
|
27
|
-
s.add_development_dependency 'annotate', '~> 2.5.0'
|
28
|
-
|
29
|
-
# add / replace with other adapter(s) as needed
|
23
|
+
s.add_development_dependency 'annotate', '~> 2.7.0'
|
30
24
|
s.add_development_dependency 'pg'
|
31
|
-
# s.add_development_dependency 'postgres-pr'
|
32
|
-
# s.add_development_dependency 'mysql'
|
33
25
|
s.add_development_dependency 'mysql2'
|
34
26
|
s.add_development_dependency 'sqlite3'
|
27
|
+
s.add_development_dependency 'minitest-byebug'
|
35
28
|
end
|
data/test/add_comments_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
2
|
|
3
|
-
class AddCommentsTest < Minitest::
|
3
|
+
class AddCommentsTest < Minitest::Test
|
4
4
|
include TestHelper
|
5
5
|
|
6
6
|
def test_adding_a_table_comment
|
@@ -26,10 +26,51 @@ class AddCommentsTest < Minitest::Unit::TestCase
|
|
26
26
|
assert_nil result_field2
|
27
27
|
end
|
28
28
|
|
29
|
+
def test_adding_a_column_with_a_comment
|
30
|
+
comment_text = "a comment in a new column"
|
31
|
+
result_field1 = nil
|
32
|
+
result_field3 = nil
|
33
|
+
ActiveRecord::Schema.define do
|
34
|
+
add_column :sample, :field3, :string, :comment => comment_text
|
35
|
+
result_field3 = retrieve_column_comment :sample, :field3
|
36
|
+
result_field1 = retrieve_column_comment :sample, :field1
|
37
|
+
end
|
38
|
+
assert_equal comment_text, result_field3
|
39
|
+
assert_nil result_field1
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_changing_a_column_while_adding_a_comment
|
43
|
+
comment_text = "a comment in a changing column"
|
44
|
+
result_field1 = nil
|
45
|
+
ActiveRecord::Schema.define do
|
46
|
+
change_column :sample, :field1, :string, :limit => 25, :comment => comment_text
|
47
|
+
result_field1 = retrieve_column_comment :sample, :field1
|
48
|
+
end
|
49
|
+
assert_equal comment_text, result_field1
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_creating_a_temp_table_with_table_comments_and_no_block
|
53
|
+
ActiveRecord::Schema.define do
|
54
|
+
begin
|
55
|
+
create_table :sample3, temporary: true, comment: "a table comment"
|
56
|
+
ensure
|
57
|
+
drop_table :sample3 rescue nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
29
62
|
def test_creating_a_table_with_table_comments_and_no_block
|
63
|
+
table_comment = "a table comment"
|
64
|
+
result_table_comment = nil
|
30
65
|
ActiveRecord::Schema.define do
|
31
|
-
|
66
|
+
begin
|
67
|
+
create_table :sample3, comment: table_comment
|
68
|
+
result_table_comment = retrieve_table_comment :sample3
|
69
|
+
ensure
|
70
|
+
drop_table :sample3 rescue nil
|
71
|
+
end
|
32
72
|
end
|
73
|
+
assert_equal table_comment, result_table_comment
|
33
74
|
end
|
34
75
|
|
35
76
|
def test_creating_a_table_with_table_and_column_comments
|