activerecord-mysql-comment 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 66410bee5613edcf7002198f103386edd8626c4c
4
+ data.tar.gz: 4598b131bfc608b50b848237ab98e9ccacd368e4
5
+ SHA512:
6
+ metadata.gz: 541dc8a54f913d0b4a713da35220cab3ee62bb042b991f23a3c59d34fd63e4c094bf0b7ea820f04f38cf812b0354329218da8f4609c59a924c2c9659131d5317
7
+ data.tar.gz: 873831e35c5eeb2a8d17ac0734955ae9736dd204c80eb770cff6dada2a96cc9023011c2fa26044a86de5ac2e6faba635a74c028cc73088c062e40c5cb6539d6d
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ debug.log
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1
5
+ - 2.2
6
+ - ruby-head
7
+ env:
8
+ - "AR_VERSION=4.0.13"
9
+ - "AR_VERSION=4.1.9"
10
+ - "AR_VERSION=4.2.0"
11
+ before_install:
12
+ - mysql -e "create database activerecord_unittest;"
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem "activerecord", "~> #{ENV['AR_VERSION']}" if ENV['AR_VERSION']
4
+
5
+ # Specify your gem's dependencies in activerecord-mysql-comment.gemspec
6
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Naoya Murakami
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,75 @@
1
+ # ActiveRecord::Mysql::Comment
2
+
3
+ [![Build Status](https://travis-ci.org/naoa/activerecord-mysql-comment.png?branch=master)](https://travis-ci.org/naoa/activerecord-mysql-comment)
4
+
5
+ Adds column comment and index comment to migrations for ActiveRecord MySQL adapters
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'activerecord-mysql-comment'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install activerecord-mysql-comment
22
+
23
+ ## Usage
24
+
25
+ ```ruby
26
+ bundle exec rails g migration CreatePosts
27
+ ```
28
+
29
+ ```ruby
30
+ class CreatePosts < ActiveRecord::Migration
31
+ def change
32
+ create_table :posts, options: 'ENGINE=Mroonga COMMENT="default_tokenizer=TokenMecab"' do |t|
33
+ t.string :title
34
+ t.text :content, comment: 'flags "COLUMN_SCALAR|COMPRESS_ZLIB"'
35
+ t.timestamps
36
+ end
37
+ add_index :posts, :content, type: 'fulltext', comment: 'parser "TokenBigram", normalizer "NormalizerAuto"'
38
+ end
39
+ end
40
+ ```
41
+
42
+ ```ruby
43
+ bundle exec rake db:migrate
44
+ ```
45
+
46
+ ```ruby
47
+ create_table "posts", force: :cascade, options: "ENGINE=Mroonga DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='default_tokenizer=TokenMecab'" do |t|
48
+ t.string "title", limit: 255
49
+ t.text "content", limit: 65535, comment: "flags \"COLUMN_SCALAR|COMPRESS_ZLIB\""
50
+ t.datetime "created_at"
51
+ t.datetime "updated_at"
52
+ end
53
+
54
+ add_index "posts", ["content"], name: "index_posts_on_content", type: :fulltext, comment: "parser \"TokenBigram\", normalizer \"NormalizerAuto\""
55
+ ```
56
+
57
+ ## Note
58
+
59
+ * Table options need [activerecord-mysql-awesome](https://github.com/kamipo/activerecord-mysql-awesome). If you use ``rake db:reset``, you should install it.
60
+
61
+ * If you use [activerecord-mysql-awesome](https://github.com/kamipo/activerecord-mysql-awesome), please loading it before load activerecord-mysql-comment.
62
+
63
+ ## Contributing
64
+
65
+ 1. Fork it ( https://github.com/naoa/activerecord-mysql-comment/fork )
66
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
67
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
68
+ 4. Push to the branch (`git push origin my-new-feature`)
69
+ 5. Create a new Pull Request
70
+
71
+ ## Thanks
72
+
73
+ * [@kamipo](https://github.com/kamipo)
74
+
75
+ This library is made by referring to [activerecord-mysql-awesome](https://github.com/kamipo/activerecord-mysql-awesome).
@@ -0,0 +1,62 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ require File.expand_path(File.dirname(__FILE__)) + "/test/config"
5
+ require File.expand_path(File.dirname(__FILE__)) + "/test/support/config"
6
+
7
+ desc 'Run mysql2 tests by default'
8
+ task :default => :test
9
+
10
+ desc 'Run mysql2 tests'
11
+ task :test => :test_mysql2
12
+
13
+ desc 'Build MySQL test databases'
14
+ namespace :db do
15
+ task :create => ['db:mysql:build']
16
+ task :drop => ['db:mysql:drop']
17
+ end
18
+
19
+ %w( mysql mysql2 ).each do |adapter|
20
+ namespace :test do
21
+ Rake::TestTask.new(adapter => "#{adapter}:env") { |t|
22
+ t.libs << 'test'
23
+ t.test_files = Dir.glob( "test/cases/**/*_test.rb" ).sort
24
+
25
+ t.warning = true
26
+ t.verbose = true
27
+ }
28
+ end
29
+
30
+ namespace adapter do
31
+ task :test => "test_#{adapter}"
32
+
33
+ # Set the connection environment for the adapter
34
+ task(:env) { ENV['ARCONN'] = adapter }
35
+ end
36
+
37
+ # Make sure the adapter test evaluates the env setting task
38
+ task "test_#{adapter}" => ["#{adapter}:env", "test:#{adapter}"]
39
+ end
40
+
41
+ namespace :db do
42
+ namespace :mysql do
43
+ desc 'Build the MySQL test databases'
44
+ task :build do
45
+ config = ARTest.config['connections']['mysql']
46
+ %x( mysql --user=#{config['arunit']['username']} --password=#{config['arunit']['password']} -e "create DATABASE #{config['arunit']['database']} DEFAULT CHARACTER SET utf8" )
47
+ end
48
+
49
+ desc 'Drop the MySQL test databases'
50
+ task :drop do
51
+ config = ARTest.config['connections']['mysql']
52
+ %x( mysqladmin --user=#{config['arunit']['username']} --password=#{config['arunit']['password']} -f drop #{config['arunit']['database']} )
53
+ end
54
+
55
+ desc 'Rebuild the MySQL test databases'
56
+ task :rebuild => [:drop, :build]
57
+ end
58
+ end
59
+
60
+ task :build_mysql_databases => 'db:mysql:build'
61
+ task :drop_mysql_databases => 'db:mysql:drop'
62
+ task :rebuild_mysql_databases => 'db:mysql:rebuild'
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'activerecord/mysql/comment/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "activerecord-mysql-comment"
8
+ spec.version = ActiveRecord::Mysql::Comment::VERSION
9
+ spec.authors = ["Naoya Murakami"]
10
+ spec.email = ["naoya@createfield.com"]
11
+ spec.summary = %q{Adds column comment and index comment to migrations for ActiveRecord MySQL adapters}
12
+ spec.description = %q{Adds column comment and index comment to migrations for ActiveRecord MySQL adapters}
13
+ spec.homepage = "https://github.com/naoa/activerecord-mysql-comment"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.required_ruby_version = '>= 2.0.0'
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.7"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_runtime_dependency "activesupport", "~> 4.0"
26
+ spec.add_runtime_dependency "activerecord", "~> 4.0"
27
+ spec.add_runtime_dependency "mysql2"
28
+ end
@@ -0,0 +1 @@
1
+ require 'activerecord/mysql/comment'
@@ -0,0 +1,11 @@
1
+ require 'active_record/connection_adapters/abstract/schema_dumper'
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters # :nodoc:
5
+ module ColumnDumper
6
+ def options_for_column_spec(table_name)
7
+ { table_name: table_name }
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,100 @@
1
+ require 'active_record/connection_adapters/abstract_mysql_adapter'
2
+
3
+ module ActiveRecord
4
+ module Mysql
5
+ module Comment
6
+ module SchemaStatements
7
+ def add_index_options(table_name, column_name, options = {})
8
+ if options.key?(:comment)
9
+ comment = options[:comment]
10
+ options.delete(:comment)
11
+ end
12
+
13
+ index_name, index_type, index_columns, index_options, algorithm, using = super
14
+
15
+ if comment.present?
16
+ if index_options
17
+ index_options << " COMMENT '#{comment}'"
18
+ else
19
+ index_options = " COMMENT '#{comment}'"
20
+ end
21
+ end
22
+
23
+ [index_name, index_type, index_columns, index_options, algorithm, using]
24
+ end
25
+ end
26
+
27
+ class ChangeColumnDefinition < Struct.new(:column, :name) #:nodoc:
28
+ end
29
+
30
+ class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition
31
+ attr_accessor :auto_increment, :unsigned, :charset, :collation, :comment
32
+ end
33
+
34
+ class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
35
+ def initialize(types, name, temporary, options, as = nil)
36
+ super(types, name, temporary, options)
37
+ @as = as
38
+ end
39
+
40
+ def new_column_definition(name, type, options) # :nodoc:
41
+ column = super
42
+ column.comment = options[:comment]
43
+ column
44
+ end
45
+
46
+ private
47
+ def create_column_definition(name, type)
48
+ ColumnDefinition.new(name, type)
49
+ end
50
+ end
51
+
52
+ module SchemaCreation
53
+
54
+ private
55
+ def column_options(o)
56
+ column_options = super
57
+ column_options[:comment] = o.comment
58
+ column_options
59
+ end
60
+
61
+ def add_column_options!(sql, options)
62
+ if options[:comment]
63
+ sql << " COMMENT '#{options[:comment]}'"
64
+ end
65
+ super
66
+ end
67
+ end
68
+
69
+ public
70
+ def prepare_column_options(column, options) # :nodoc:
71
+ spec = super
72
+ comment = select_one("SHOW FULL COLUMNS FROM #{options[:table_name]} WHERE Field = '#{column.name}'")["Comment"]
73
+ if comment.present?
74
+ spec[:comment] = comment.inspect
75
+ end
76
+ spec
77
+ end
78
+
79
+ def migration_keys
80
+ super | [:comment]
81
+ end
82
+
83
+ private
84
+ def create_table_definition(name, temporary = false, options = nil, as = nil) # :nodoc:
85
+ TableDefinition.new(native_database_types, name, temporary, options, as)
86
+ end
87
+ end
88
+ end
89
+
90
+ module ConnectionAdapters
91
+ class AbstractMysqlAdapter < AbstractAdapter
92
+ prepend Mysql::Comment
93
+ prepend Mysql::Comment::SchemaStatements
94
+
95
+ class SchemaCreation < AbstractAdapter::SchemaCreation
96
+ prepend Mysql::Comment::SchemaCreation
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,49 @@
1
+ require 'active_record/schema_dumper'
2
+
3
+ module ActiveRecord
4
+ module Mysql
5
+ module Comment
6
+ module SchemaDumper
7
+ private
8
+ def table(table, stream)
9
+ @types = @types.merge(@connection.options_for_column_spec(table))
10
+ super(table, stream)
11
+ ensure
12
+ @types = @connection.native_database_types
13
+ end
14
+
15
+ def indexes(table, stream)
16
+ buf = StringIO.new
17
+ super(table, buf)
18
+ buf = buf.string
19
+ output = add_index_comment(table, buf)
20
+ stream.print output
21
+ stream
22
+ end
23
+
24
+ def add_index_comment(table, buf)
25
+ output = ""
26
+ buf.each_line do |line|
27
+ output << line
28
+ if matched = line.match(/name: \"(?<name>.*)\", /)
29
+ index_name = matched[:name]
30
+ end
31
+ if index_name.present?
32
+ comment = @connection.select_one("SHOW INDEX FROM #{table} WHERE Key_name = '#{index_name}';")["Index_comment"]
33
+ if comment.present?
34
+ output = output.chop
35
+ output << ", comment: #{comment.inspect}\n"
36
+ end
37
+ end
38
+ end
39
+ output
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+
46
+ class SchemaDumper #:nodoc:
47
+ prepend Mysql::Comment::SchemaDumper
48
+ end
49
+ end
@@ -0,0 +1,15 @@
1
+ require 'active_support'
2
+
3
+ begin
4
+ require 'rails'
5
+ rescue LoadError
6
+ # nothing to do! yay!
7
+ end
8
+
9
+ if defined? Rails
10
+ require 'activerecord/mysql/comment/railtie'
11
+ else
12
+ ActiveSupport.on_load :active_record do
13
+ require 'activerecord/mysql/comment/base'
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ if ActiveRecord::VERSION::MAJOR == 4
2
+ require 'activerecord-mysql-comment/active_record/schema_dumper'
3
+ require 'activerecord-mysql-comment/active_record/connection_adapters/abstract/schema_dumper'
4
+ require 'activerecord-mysql-comment/active_record/connection_adapters/abstract_mysql_adapter'
5
+ else
6
+ raise "activerecord-mysql-comment supports activerecord ~> 4.x"
7
+ end
@@ -0,0 +1,13 @@
1
+ module ActiveRecord
2
+ module Mysql
3
+ module Comment
4
+ class Railtie < Rails::Railtie
5
+ initializer 'activerecord-mysql-comment' do
6
+ ActiveSupport.on_load :active_record do
7
+ require 'activerecord/mysql/comment/base'
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ module ActiveRecord
2
+ module Mysql
3
+ module Comment
4
+ VERSION = "0.0.1"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ /config.yml
@@ -0,0 +1,46 @@
1
+ require 'cases/helper'
2
+ require 'support/schema_dumping_helper'
3
+
4
+ class ColumnCommentTest < ActiveRecord::TestCase
5
+ include SchemaDumpingHelper
6
+
7
+ class ColumnComment < ActiveRecord::Base
8
+ end
9
+
10
+ setup do
11
+ @connection = ActiveRecord::Base.connection
12
+ @connection.create_table("column_comments", force: true) do |t|
13
+ t.string "string_non_comment"
14
+ t.string "string_comment", comment: 'string_hoge'
15
+ t.text "text_comment", comment: 'text_hoge'
16
+ end
17
+ end
18
+
19
+ teardown do
20
+ @connection.drop_table "column_comments"
21
+ end
22
+
23
+ def test_add_column
24
+ @connection.add_column 'column_comments', 'title', :string, comment: 'string_hoge'
25
+ comment = @connection.select_one("SHOW FULL COLUMNS FROM column_comments WHERE Field = 'title'")["Comment"]
26
+ assert_equal 'string_hoge', comment
27
+ end
28
+
29
+ def test_change_column
30
+ @connection.add_column 'column_comments', 'description', :string, comment: 'string_comment'
31
+ @connection.change_column 'column_comments', 'description', :text, comment: 'text_comment'
32
+
33
+ comment = @connection.select_one("SHOW FULL COLUMNS FROM column_comments WHERE Field = 'description'")["Comment"]
34
+
35
+ if ActiveRecord::VERSION::STRING >= "4.1.0"
36
+ assert_equal 'text_comment', comment
37
+ end
38
+ end
39
+
40
+ def test_schema_dump_column_collation
41
+ schema = dump_table_schema "column_comments"
42
+ assert_match %r{t.string\s+"string_non_comment"(?:,\s+limit: 255)?$}, schema
43
+ assert_match %r{t.string\s+"string_comment",(?:\s+limit: 255,)?\s+comment: "string_hoge"$}, schema
44
+ assert_match %r{t.text\s+"text_comment",(?:\s+limit: 65535,)?\s+comment: "text_hoge"$}, schema
45
+ end
46
+ end
@@ -0,0 +1,51 @@
1
+ require 'bundler'
2
+ Bundler.setup
3
+
4
+ require 'activerecord-mysql-comment'
5
+ require 'config'
6
+
7
+ require 'active_support/testing/autorun'
8
+ require 'stringio'
9
+
10
+ require 'active_record'
11
+ require 'cases/test_case'
12
+ require 'active_support/dependencies'
13
+ require 'active_support/logger'
14
+ require 'active_support/core_ext/string/strip'
15
+
16
+ require 'support/config'
17
+ require 'support/connection'
18
+
19
+ # TODO: Move all these random hacks into the ARTest namespace and into the support/ dir
20
+
21
+ Thread.abort_on_exception = true
22
+
23
+ # Show backtraces for deprecated behavior for quicker cleanup.
24
+ ActiveSupport::Deprecation.debug = true
25
+
26
+ # Enable raise errors in after_commit and after_rollback.
27
+ ActiveRecord::Base.tap do |klass|
28
+ klass.raise_in_transactional_callbacks = true if klass.respond_to?(:raise_in_transactional_callbacks=)
29
+ end
30
+
31
+ # Connect to the database
32
+ ARTest.connect
33
+
34
+ def current_adapter?(*types)
35
+ types.any? do |type|
36
+ ActiveRecord::ConnectionAdapters.const_defined?(type) &&
37
+ ActiveRecord::Base.connection.is_a?(ActiveRecord::ConnectionAdapters.const_get(type))
38
+ end
39
+ end
40
+
41
+ def mysql_56?
42
+ current_adapter?(:Mysql2Adapter) &&
43
+ ActiveRecord::Base.connection.send(:version).join(".") >= "5.6.0"
44
+ end
45
+
46
+ # FIXME: we have tests that depend on run order, we should fix that and
47
+ # remove this method call.
48
+ require 'active_support/test_case'
49
+ ActiveSupport::TestCase.tap do |klass|
50
+ klass.test_order = :sorted if klass.respond_to?(:test_order=)
51
+ end
@@ -0,0 +1,31 @@
1
+ require 'cases/helper'
2
+ require 'support/schema_dumping_helper'
3
+
4
+ class IndexCommentTest < ActiveRecord::TestCase
5
+ include SchemaDumpingHelper
6
+
7
+ class IndexComment < ActiveRecord::Base
8
+ end
9
+
10
+ setup do
11
+ @connection = ActiveRecord::Base.connection
12
+ @connection.create_table("index_comments", force: true) do |t|
13
+ t.string "string"
14
+ t.text "text"
15
+ end
16
+ @connection.add_index :index_comments, :string, comment: 'no_named_index_comment'
17
+ @connection.add_index :index_comments, :string, name: 'named_column', comment: 'named_index_comment'
18
+ @connection.add_index :index_comments, :string, name: 'no_index_comment'
19
+ end
20
+
21
+ teardown do
22
+ @connection.drop_table "index_comments"
23
+ end
24
+
25
+ def test_schema_dump_index_comment
26
+ schema = dump_table_schema "index_comments"
27
+ assert_match %r{add_index\s+"index_comments",\s+\[\"string\"\],\s+name:\s+\"index_index_comments_on_string\",\s+using:\s+:btree,\s+comment:\s+\"no_named_index_comment\"$}, schema
28
+ assert_match %r{add_index\s+"index_comments",\s+\[\"string\"\],\s+name:\s+\"named_column\",\s+using:\s+:btree,\s+comment:\s+\"named_index_comment\"$}, schema
29
+ assert_match %r{add_index\s+"index_comments",\s+\[\"string\"\],\s+name:\s+\"no_index_comment\",\s+using:\s+:btree$}, schema
30
+ end
31
+ end
@@ -0,0 +1,123 @@
1
+ require 'active_support/test_case'
2
+
3
+ module ActiveRecord
4
+ # = Active Record Test Case
5
+ #
6
+ # Defines some test assertions to test against SQL queries.
7
+ class TestCase < ActiveSupport::TestCase #:nodoc:
8
+ def teardown
9
+ SQLCounter.clear_log
10
+ end
11
+
12
+ def assert_date_from_db(expected, actual, message = nil)
13
+ assert_equal expected.to_s, actual.to_s, message
14
+ end
15
+
16
+ def capture(stream)
17
+ stream = stream.to_s
18
+ captured_stream = Tempfile.new(stream)
19
+ stream_io = eval("$#{stream}")
20
+ origin_stream = stream_io.dup
21
+ stream_io.reopen(captured_stream)
22
+
23
+ yield
24
+
25
+ stream_io.rewind
26
+ return captured_stream.read
27
+ ensure
28
+ captured_stream.close
29
+ captured_stream.unlink
30
+ stream_io.reopen(origin_stream)
31
+ end
32
+
33
+ def capture_sql
34
+ SQLCounter.clear_log
35
+ yield
36
+ SQLCounter.log_all.dup
37
+ end
38
+
39
+ def assert_sql(*patterns_to_match)
40
+ capture_sql { yield }
41
+ ensure
42
+ failed_patterns = []
43
+ patterns_to_match.each do |pattern|
44
+ failed_patterns << pattern unless SQLCounter.log_all.any?{ |sql| pattern === sql }
45
+ end
46
+ assert failed_patterns.empty?, "Query pattern(s) #{failed_patterns.map(&:inspect).join(', ')} not found.#{SQLCounter.log.size == 0 ? '' : "\nQueries:\n#{SQLCounter.log.join("\n")}"}"
47
+ end
48
+
49
+ def assert_queries(num = 1, options = {})
50
+ ignore_none = options.fetch(:ignore_none) { num == :any }
51
+ SQLCounter.clear_log
52
+ x = yield
53
+ the_log = ignore_none ? SQLCounter.log_all : SQLCounter.log
54
+ if num == :any
55
+ assert_operator the_log.size, :>=, 1, "1 or more queries expected, but none were executed."
56
+ else
57
+ mesg = "#{the_log.size} instead of #{num} queries were executed.#{the_log.size == 0 ? '' : "\nQueries:\n#{the_log.join("\n")}"}"
58
+ assert_equal num, the_log.size, mesg
59
+ end
60
+ x
61
+ end
62
+
63
+ def assert_no_queries(options = {}, &block)
64
+ options.reverse_merge! ignore_none: true
65
+ assert_queries(0, options, &block)
66
+ end
67
+
68
+ def assert_column(model, column_name, msg=nil)
69
+ assert has_column?(model, column_name), msg
70
+ end
71
+
72
+ def assert_no_column(model, column_name, msg=nil)
73
+ assert_not has_column?(model, column_name), msg
74
+ end
75
+
76
+ def has_column?(model, column_name)
77
+ model.reset_column_information
78
+ model.column_names.include?(column_name.to_s)
79
+ end
80
+ end
81
+
82
+ class SQLCounter
83
+ class << self
84
+ attr_accessor :ignored_sql, :log, :log_all
85
+ def clear_log; self.log = []; self.log_all = []; end
86
+ end
87
+
88
+ self.clear_log
89
+
90
+ self.ignored_sql = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /^SHOW max_identifier_length/, /^BEGIN/, /^COMMIT/]
91
+
92
+ # FIXME: this needs to be refactored so specific database can add their own
93
+ # ignored SQL, or better yet, use a different notification for the queries
94
+ # instead examining the SQL content.
95
+ oracle_ignored = [/^select .*nextval/i, /^SAVEPOINT/, /^ROLLBACK TO/, /^\s*select .* from all_triggers/im, /^\s*select .* from all_constraints/im, /^\s*select .* from all_tab_cols/im]
96
+ mysql_ignored = [/^SHOW TABLES/i, /^SHOW FULL FIELDS/, /^SHOW CREATE TABLE /i, /^SHOW VARIABLES /]
97
+ postgresql_ignored = [/^\s*select\b.*\bfrom\b.*pg_namespace\b/im, /^\s*select tablename\b.*from pg_tables\b/im, /^\s*select\b.*\battname\b.*\bfrom\b.*\bpg_attribute\b/im, /^SHOW search_path/i]
98
+ sqlite3_ignored = [/^\s*SELECT name\b.*\bFROM sqlite_master/im]
99
+
100
+ [oracle_ignored, mysql_ignored, postgresql_ignored, sqlite3_ignored].each do |db_ignored_sql|
101
+ ignored_sql.concat db_ignored_sql
102
+ end
103
+
104
+ attr_reader :ignore
105
+
106
+ def initialize(ignore = Regexp.union(self.class.ignored_sql))
107
+ @ignore = ignore
108
+ end
109
+
110
+ def call(name, start, finish, message_id, values)
111
+ sql = values[:sql]
112
+
113
+ # FIXME: this seems bad. we should probably have a better way to indicate
114
+ # the query was cached
115
+ return if 'CACHE' == values[:name]
116
+
117
+ self.class.log_all << sql
118
+ self.class.log << sql unless ignore =~ sql
119
+ end
120
+ end
121
+
122
+ ActiveSupport::Notifications.subscribe('sql.active_record', SQLCounter.new)
123
+ end
@@ -0,0 +1,20 @@
1
+ default_connection: 'mysql2'
2
+
3
+ connections:
4
+ mysql:
5
+ arunit:
6
+ username: rails
7
+ encoding: utf8
8
+ collation: utf8_unicode_ci
9
+ arunit2:
10
+ username: rails
11
+ encoding: utf8
12
+
13
+ mysql2:
14
+ arunit:
15
+ username: rails
16
+ encoding: utf8
17
+ collation: utf8_unicode_ci
18
+ arunit2:
19
+ username: rails
20
+ encoding: utf8
@@ -0,0 +1,5 @@
1
+ TEST_ROOT = File.expand_path(File.dirname(__FILE__))
2
+ ASSETS_ROOT = TEST_ROOT + "/assets"
3
+ FIXTURES_ROOT = TEST_ROOT + "/fixtures"
4
+ MIGRATIONS_ROOT = TEST_ROOT + "/migrations"
5
+ SCHEMA_ROOT = TEST_ROOT + "/schema"
@@ -0,0 +1,43 @@
1
+ require 'yaml'
2
+ require 'erb'
3
+ require 'fileutils'
4
+ require 'pathname'
5
+
6
+ module ARTest
7
+ class << self
8
+ def config
9
+ @config ||= read_config
10
+ end
11
+
12
+ private
13
+
14
+ def config_file
15
+ Pathname.new(ENV['ARCONFIG'] || TEST_ROOT + '/config.yml')
16
+ end
17
+
18
+ def read_config
19
+ unless config_file.exist?
20
+ FileUtils.cp TEST_ROOT + '/config.example.yml', config_file
21
+ end
22
+
23
+ erb = ERB.new(config_file.read)
24
+ expand_config(YAML.parse(erb.result(binding)).transform)
25
+ end
26
+
27
+ def expand_config(config)
28
+ config['connections'].each do |adapter, connection|
29
+ dbs = [['arunit', 'activerecord_unittest'], ['arunit2', 'activerecord_unittest2']]
30
+ dbs.each do |name, dbname|
31
+ unless connection[name].is_a?(Hash)
32
+ connection[name] = { 'database' => connection[name] }
33
+ end
34
+
35
+ connection[name]['database'] ||= dbname
36
+ connection[name]['adapter'] ||= adapter
37
+ end
38
+ end
39
+
40
+ config
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,18 @@
1
+ require 'active_support/logger'
2
+
3
+ module ARTest
4
+ def self.connection_name
5
+ ENV['ARCONN'] || config['default_connection']
6
+ end
7
+
8
+ def self.connection_config
9
+ config['connections'][connection_name]
10
+ end
11
+
12
+ def self.connect
13
+ puts "Using #{connection_name}"
14
+ ActiveRecord::Base.logger = ActiveSupport::Logger.new("debug.log", 0, 100 * 1024 * 1024)
15
+ ActiveRecord::Base.configurations = connection_config
16
+ ActiveRecord::Base.establish_connection :arunit
17
+ end
18
+ end
@@ -0,0 +1,8 @@
1
+ module ConnectionHelper
2
+ def run_without_connection
3
+ original_connection = ActiveRecord::Base.remove_connection
4
+ yield original_connection
5
+ ensure
6
+ ActiveRecord::Base.establish_connection(original_connection)
7
+ end
8
+ end
@@ -0,0 +1,20 @@
1
+ module SchemaDumpingHelper
2
+ def dump_table_schema(table, connection = ActiveRecord::Base.connection)
3
+ old_ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
4
+ ActiveRecord::SchemaDumper.ignore_tables = connection.tables - [table]
5
+ stream = StringIO.new
6
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
7
+ stream.string
8
+ ensure
9
+ ActiveRecord::SchemaDumper.ignore_tables = old_ignore_tables
10
+ end
11
+
12
+ def dump_all_table_schema(ignore_tables)
13
+ old_ignore_tables, ActiveRecord::SchemaDumper.ignore_tables = ActiveRecord::SchemaDumper.ignore_tables, ignore_tables
14
+ stream = StringIO.new
15
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
16
+ stream.string
17
+ ensure
18
+ ActiveRecord::SchemaDumper.ignore_tables = old_ignore_tables
19
+ end
20
+ end
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-mysql-comment
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Naoya Murakami
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '4.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activerecord
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '4.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '4.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mysql2
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Adds column comment and index comment to migrations for ActiveRecord
84
+ MySQL adapters
85
+ email:
86
+ - naoya@createfield.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".travis.yml"
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.md
96
+ - Rakefile
97
+ - activerecord-mysql-comment.gemspec
98
+ - lib/activerecord-mysql-comment.rb
99
+ - lib/activerecord-mysql-comment/active_record/connection_adapters/abstract/schema_dumper.rb
100
+ - lib/activerecord-mysql-comment/active_record/connection_adapters/abstract_mysql_adapter.rb
101
+ - lib/activerecord-mysql-comment/active_record/schema_dumper.rb
102
+ - lib/activerecord/mysql/comment.rb
103
+ - lib/activerecord/mysql/comment/base.rb
104
+ - lib/activerecord/mysql/comment/railtie.rb
105
+ - lib/activerecord/mysql/comment/version.rb
106
+ - test/.gitignore
107
+ - test/cases/column_comment_test.rb
108
+ - test/cases/helper.rb
109
+ - test/cases/index_comment_test.rb
110
+ - test/cases/test_case.rb
111
+ - test/config.example.yml
112
+ - test/config.rb
113
+ - test/support/config.rb
114
+ - test/support/connection.rb
115
+ - test/support/connection_helper.rb
116
+ - test/support/schema_dumping_helper.rb
117
+ homepage: https://github.com/naoa/activerecord-mysql-comment
118
+ licenses:
119
+ - MIT
120
+ metadata: {}
121
+ post_install_message:
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: 2.0.0
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ requirements: []
136
+ rubyforge_project:
137
+ rubygems_version: 2.2.2
138
+ signing_key:
139
+ specification_version: 4
140
+ summary: Adds column comment and index comment to migrations for ActiveRecord MySQL
141
+ adapters
142
+ test_files:
143
+ - test/.gitignore
144
+ - test/cases/column_comment_test.rb
145
+ - test/cases/helper.rb
146
+ - test/cases/index_comment_test.rb
147
+ - test/cases/test_case.rb
148
+ - test/config.example.yml
149
+ - test/config.rb
150
+ - test/support/config.rb
151
+ - test/support/connection.rb
152
+ - test/support/connection_helper.rb
153
+ - test/support/schema_dumping_helper.rb