activerecord-mysql-awesome 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: acaf5232085a194cd6be165d88c391949371c823
4
- data.tar.gz: 7454e2e8c349fa58074f9dfee87b40dc7e06f656
3
+ metadata.gz: 5c4fa2c015cdf2511abc7e277b57491d4dcbbd28
4
+ data.tar.gz: 37e2778cd1ed6cd57748d255753aba1741371b4f
5
5
  SHA512:
6
- metadata.gz: 867ae8b90d562e056db29aa6d0f0a5f77b69d479661df53f3aa1f92760c4fb4fff72d903b79620ac5223cd08bc9ab1771dde9ac14dee549be71dfbd86bf5284d
7
- data.tar.gz: 7e592e3d399b3c2421fafa289707caf3f986967e2254c25ce44fbdde87d8c0662173eddec3ebc9c792989f20ac3bea57367494e60f2e04e8831217be04fcecc5
6
+ metadata.gz: 55f18e15f1694fcb7365e3716d0394e2181bc11248d38a1b5de2c08b10794b597d490f047b88467afb93bf45d9a6f72726d08955b04d838dc0f23eaf8786ac1a
7
+ data.tar.gz: b039c7d9c91e43d1a8e8d575cc0363bd5b8daf8fcd9e30766af98b8470314ef7f59148244d071ae249630c756db0f0579ae01f94e17b3ad97143c4182410281d
data/.gitignore CHANGED
@@ -12,3 +12,4 @@
12
12
  *.o
13
13
  *.a
14
14
  mkmf.log
15
+ debug.log
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1
5
+ - ruby-head
6
+ env:
7
+ - "AR_VERSION=4.0.12"
8
+ - "AR_VERSION=4.1.8"
9
+ - "AR_VERSION=4.2.0.rc3"
10
+ before_install:
11
+ - mysql -e "create database activerecord_unittest;"
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Build Status](https://travis-ci.org/kamipo/activerecord-mysql-awesome.png?branch=master)](https://travis-ci.org/kamipo/activerecord-mysql-awesome)
4
4
 
5
- Awecome patches backported for ActiveRecord MySQL adapters.
5
+ Awesome patches backported for ActiveRecord MySQL adapters.
6
6
 
7
7
  ## Installation
8
8
 
data/Rakefile CHANGED
@@ -1,2 +1,62 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rake/testtask'
2
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']} -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']} -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'
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = ActiveRecord::Mysql::Awesome::VERSION
9
9
  spec.authors = ["Ryuta Kamizono"]
10
10
  spec.email = ["kamipo@gmail.com"]
11
- spec.summary = %q{Awecome patches backported for ActiveRecord MySQL adapters}
12
- spec.description = %q{Awecome patches backported for ActiveRecord MySQL adapters}
11
+ spec.summary = %q{Awesome patches backported for ActiveRecord MySQL adapters}
12
+ spec.description = %q{Awesome patches backported for ActiveRecord MySQL adapters}
13
13
  spec.homepage = "https://github.com/kamipo/activerecord-mysql-awesome"
14
14
  spec.license = "MIT"
15
15
 
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.required_ruby_version = '>= 2.0.0'
22
+
21
23
  spec.add_development_dependency "bundler", "~> 1.7"
22
24
  spec.add_development_dependency "rake", "~> 10.0"
23
25
  spec.add_runtime_dependency "activesupport", "~> 4.0"
@@ -1,8 +1,138 @@
1
1
  require 'active_record/connection_adapters/abstract_mysql_adapter'
2
2
 
3
3
  module ActiveRecord
4
+ module Mysql
5
+ module Awesome
6
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = false)
7
+ case type.to_s
8
+ when 'integer'
9
+ case limit
10
+ when nil, 4, 11; 'int' # compatibility with MySQL default
11
+ else
12
+ super(type, limit, precision, scale)
13
+ end.tap do |sql_type|
14
+ sql_type << ' unsigned' if unsigned
15
+ end
16
+ when 'float', 'decimal'
17
+ super(type, limit, precision, scale).tap do |sql_type|
18
+ sql_type << ' unsigned' if unsigned
19
+ end
20
+ when 'primary_key'
21
+ "#{type_to_sql(:integer, limit, precision, scale, unsigned)} auto_increment PRIMARY KEY"
22
+ when 'datetime', 'time'
23
+ return super(type, limit, precision, scale) unless precision
24
+
25
+ native_type = native_database_types[type.to_sym][:name]
26
+ case precision
27
+ when 0..6; "#{native_type}(#{precision})"
28
+ else raise(ActiveRecordError, "No #{native_type} type has precision of #{precision}. The allowed range of precision is from 0 to 6")
29
+ end
30
+ else
31
+ super(type, limit, precision, scale)
32
+ end
33
+ end
34
+
35
+ module Column
36
+ def unsigned?
37
+ sql_type =~ /unsigned/i
38
+ end
39
+ end
40
+
41
+ if ActiveRecord::VERSION::STRING < "4.2.0"
42
+ def quote(value, column = nil) #:nodoc:
43
+ return super unless column && column.type
44
+
45
+ case column.type
46
+ when :datetime, :time
47
+ if value.acts_like?(:time) && value.respond_to?(:usec)
48
+ zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
49
+ result = value.send(zone_conversion_method).to_s(:db)
50
+ precision = column.precision
51
+ case precision
52
+ when 1..6
53
+ "'#{result}.#{sprintf("%0#{precision}d", value.usec / 10**(6 - precision))}'"
54
+ when 0, nil
55
+ "'#{result}'"
56
+ end
57
+ else
58
+ super
59
+ end
60
+ else
61
+ super
62
+ end
63
+ end
64
+
65
+ module Column
66
+ def extract_limit(sql_type)
67
+ case sql_type
68
+ when /^(?:date)?time/i; nil
69
+ else
70
+ super
71
+ end
72
+ end
73
+
74
+ def extract_precision(sql_type)
75
+ case sql_type
76
+ when /^(?:date)?time/i
77
+ $1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/
78
+ else
79
+ super
80
+ end
81
+ end
82
+ end
83
+ else
84
+ protected
85
+
86
+ def initialize_type_map(m) # :nodoc:
87
+ super
88
+ register_class_with_precision m, %r(time)i, MysqlTime
89
+ register_class_with_precision m, %r(datetime)i, MysqlDateTime
90
+ end
91
+
92
+ def register_class_with_precision(mapping, key, klass) # :nodoc:
93
+ mapping.register_type(key) do |*args|
94
+ precision = extract_precision(args.last)
95
+ klass.new(precision: precision)
96
+ end
97
+ end
98
+
99
+ private
100
+
101
+ module TimeValueWithPrecision
102
+ def type_cast_for_database(value)
103
+ if value.acts_like?(:time) && value.respond_to?(:usec)
104
+ zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
105
+ result = value.send(zone_conversion_method).to_s(:db)
106
+ case precision
107
+ when 1..6
108
+ "#{result}.#{sprintf("%0#{precision}d", value.usec / 10**(6 - precision))}"
109
+ when 0, nil
110
+ result
111
+ end
112
+ else
113
+ super
114
+ end
115
+ end
116
+ end
117
+
118
+ class MysqlTime < Type::Time # :nodoc:
119
+ include TimeValueWithPrecision
120
+ end
121
+
122
+ class MysqlDateTime < Type::DateTime # :nodoc:
123
+ include TimeValueWithPrecision
124
+ end
125
+ end
126
+ end
127
+ end
128
+
4
129
  module ConnectionAdapters
5
130
  class AbstractMysqlAdapter < AbstractAdapter
131
+ prepend Mysql::Awesome
132
+
133
+ class Column < ConnectionAdapters::Column # :nodoc:
134
+ prepend Mysql::Awesome::Column
135
+ end
6
136
 
7
137
  class ChangeColumnDefinition < Struct.new(:column, :name) #:nodoc:
8
138
  end
@@ -95,12 +225,6 @@ module ActiveRecord
95
225
  end
96
226
  end
97
227
 
98
- class Column < ConnectionAdapters::Column # :nodoc:
99
- def unsigned?
100
- sql_type =~ /unsigned/i
101
- end
102
- end
103
-
104
228
  def options_for_column_spec(table_name)
105
229
  if collation = select_one("SHOW TABLE STATUS LIKE '#{table_name}'")["Collation"]
106
230
  super.merge(collation: collation)
@@ -132,28 +256,6 @@ module ActiveRecord
132
256
  raw_table_options.sub(/(ENGINE=\w+)(?: AUTO_INCREMENT=\d+)/, '\1')
133
257
  end
134
258
 
135
- alias type_to_sql_without_awesome type_to_sql
136
- def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = false)
137
- case type.to_s
138
- when 'integer'
139
- case limit
140
- when nil, 4, 11; 'int' # compatibility with MySQL default
141
- else
142
- type_to_sql_without_awesome(type, limit, precision, scale)
143
- end.tap do |sql_type|
144
- sql_type << ' unsigned' if unsigned
145
- end
146
- when 'float', 'decimal'
147
- type_to_sql_without_awesome(type, limit, precision, scale).tap do |sql_type|
148
- sql_type << ' unsigned' if unsigned
149
- end
150
- when 'primary_key'
151
- "#{type_to_sql(:integer, limit, precision, scale, unsigned)} auto_increment PRIMARY KEY"
152
- else
153
- type_to_sql_without_awesome(type, limit, precision, scale)
154
- end
155
- end
156
-
157
259
  def add_column_sql(table_name, column_name, type, options = {})
158
260
  td = create_table_definition(table_name)
159
261
  cd = td.new_column_definition(column_name, type, options)
@@ -1,7 +1,7 @@
1
1
  module ActiveRecord
2
2
  module Mysql
3
3
  module Awesome
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.2"
5
5
  end
6
6
  end
7
7
  end
data/test/.gitignore ADDED
@@ -0,0 +1 @@
1
+ /config.yml
@@ -0,0 +1,98 @@
1
+ require 'cases/helper'
2
+ require 'support/schema_dumping_helper'
3
+
4
+ if mysql_56?
5
+ class DateTimeTest < ActiveRecord::TestCase
6
+ include SchemaDumpingHelper
7
+
8
+ class Foo < ActiveRecord::Base; end
9
+
10
+ def test_default_datetime_precision
11
+ ActiveRecord::Base.connection.create_table(:foos, force: true)
12
+ ActiveRecord::Base.connection.add_column :foos, :created_at, :datetime
13
+ ActiveRecord::Base.connection.add_column :foos, :updated_at, :datetime
14
+ assert_nil activerecord_column_option('foos', 'created_at', 'precision')
15
+ end
16
+
17
+ def test_datetime_data_type_with_precision
18
+ ActiveRecord::Base.connection.create_table(:foos, force: true)
19
+ ActiveRecord::Base.connection.add_column :foos, :created_at, :datetime, precision: 1
20
+ ActiveRecord::Base.connection.add_column :foos, :updated_at, :datetime, precision: 5
21
+ assert_equal 1, activerecord_column_option('foos', 'created_at', 'precision')
22
+ assert_equal 5, activerecord_column_option('foos', 'updated_at', 'precision')
23
+ end
24
+
25
+ def test_timestamps_helper_with_custom_precision
26
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
27
+ t.timestamps null: true, precision: 4
28
+ end
29
+ assert_equal 4, activerecord_column_option('foos', 'created_at', 'precision')
30
+ assert_equal 4, activerecord_column_option('foos', 'updated_at', 'precision')
31
+ end
32
+
33
+ def test_passing_precision_to_datetime_does_not_set_limit
34
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
35
+ t.timestamps null: true, precision: 4
36
+ end
37
+ assert_nil activerecord_column_option("foos", "created_at", "limit")
38
+ assert_nil activerecord_column_option("foos", "updated_at", "limit")
39
+ end
40
+
41
+ def test_invalid_datetime_precision_raises_error
42
+ assert_raises ActiveRecord::ActiveRecordError do
43
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
44
+ t.timestamps null: true, precision: 7
45
+ end
46
+ end
47
+ end
48
+
49
+ def test_mysql_agrees_with_activerecord_about_precision
50
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
51
+ t.timestamps null: true, precision: 4
52
+ end
53
+ assert_equal 4, mysql_datetime_precision('foos', 'created_at')
54
+ assert_equal 4, mysql_datetime_precision('foos', 'updated_at')
55
+ end
56
+
57
+ def test_datetime_format_according_to_precision
58
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
59
+ t.datetime :created_at, precision: 0
60
+ t.datetime :updated_at, precision: 4
61
+ end
62
+ date = ::Time.utc(2014, 8, 17, 12, 30, 0, 999999)
63
+ Foo.create!(created_at: date, updated_at: date)
64
+ assert foo = Foo.find_by(created_at: date)
65
+ assert_equal date.to_s, foo.created_at.to_s
66
+ assert_equal date.to_s, foo.updated_at.to_s
67
+ assert_equal 000000, foo.created_at.usec
68
+ assert_equal 999900, foo.updated_at.usec
69
+ end
70
+
71
+ def test_schema_dump_includes_datetime_precision
72
+ ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
73
+ t.datetime :created_at, precision: 4
74
+ t.datetime :updated_at, precision: 6
75
+ end
76
+ schema = dump_table_schema "foos"
77
+ assert_match %r{t.datetime\s+"created_at",\s+precision: 4$}, schema
78
+ assert_match %r{t.datetime\s+"updated_at",\s+precision: 6$}, schema
79
+ end
80
+
81
+ private
82
+
83
+ def mysql_datetime_precision(table_name, column_name)
84
+ results = ActiveRecord::Base.connection.exec_query("SELECT column_name, datetime_precision FROM information_schema.columns WHERE table_name ='#{table_name}'")
85
+ result = results.find do |result_hash|
86
+ result_hash["column_name"] == column_name
87
+ end
88
+ result && result["datetime_precision"]
89
+ end
90
+
91
+ def activerecord_column_option(tablename, column_name, option)
92
+ result = ActiveRecord::Base.connection.columns(tablename).find do |column|
93
+ column.name == column_name
94
+ end
95
+ result && result.send(option)
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,51 @@
1
+ require 'bundler'
2
+ Bundler.setup
3
+
4
+ require 'activerecord-mysql-awesome'
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,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
data/test/config.rb ADDED
@@ -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,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 CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-mysql-awesome
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryuta Kamizono
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-12 00:00:00.000000000 Z
11
+ date: 2014-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,7 +80,7 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
- description: Awecome patches backported for ActiveRecord MySQL adapters
83
+ description: Awesome patches backported for ActiveRecord MySQL adapters
84
84
  email:
85
85
  - kamipo@gmail.com
86
86
  executables: []
@@ -88,6 +88,7 @@ extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
90
  - ".gitignore"
91
+ - ".travis.yml"
91
92
  - Gemfile
92
93
  - LICENSE.txt
93
94
  - README.md
@@ -101,6 +102,15 @@ files:
101
102
  - lib/activerecord/mysql/awesome/base.rb
102
103
  - lib/activerecord/mysql/awesome/railtie.rb
103
104
  - lib/activerecord/mysql/awesome/version.rb
105
+ - test/.gitignore
106
+ - test/cases/datetime_test.rb
107
+ - test/cases/helper.rb
108
+ - test/cases/test_case.rb
109
+ - test/config.example.yml
110
+ - test/config.rb
111
+ - test/support/config.rb
112
+ - test/support/connection.rb
113
+ - test/support/schema_dumping_helper.rb
104
114
  homepage: https://github.com/kamipo/activerecord-mysql-awesome
105
115
  licenses:
106
116
  - MIT
@@ -113,7 +123,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
123
  requirements:
114
124
  - - ">="
115
125
  - !ruby/object:Gem::Version
116
- version: '0'
126
+ version: 2.0.0
117
127
  required_rubygems_version: !ruby/object:Gem::Requirement
118
128
  requirements:
119
129
  - - ">="
@@ -124,5 +134,14 @@ rubyforge_project:
124
134
  rubygems_version: 2.2.2
125
135
  signing_key:
126
136
  specification_version: 4
127
- summary: Awecome patches backported for ActiveRecord MySQL adapters
128
- test_files: []
137
+ summary: Awesome patches backported for ActiveRecord MySQL adapters
138
+ test_files:
139
+ - test/.gitignore
140
+ - test/cases/datetime_test.rb
141
+ - test/cases/helper.rb
142
+ - test/cases/test_case.rb
143
+ - test/config.example.yml
144
+ - test/config.rb
145
+ - test/support/config.rb
146
+ - test/support/connection.rb
147
+ - test/support/schema_dumping_helper.rb