activerecord-mysql-awesome 0.0.2 → 0.0.3

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: 5c4fa2c015cdf2511abc7e277b57491d4dcbbd28
4
- data.tar.gz: 37e2778cd1ed6cd57748d255753aba1741371b4f
3
+ metadata.gz: c9d3de13790545a2190a85fb7821c32d6c301b03
4
+ data.tar.gz: 91241e834c5079dd00ac97a24fa66f47324ca159
5
5
  SHA512:
6
- metadata.gz: 55f18e15f1694fcb7365e3716d0394e2181bc11248d38a1b5de2c08b10794b597d490f047b88467afb93bf45d9a6f72726d08955b04d838dc0f23eaf8786ac1a
7
- data.tar.gz: b039c7d9c91e43d1a8e8d575cc0363bd5b8daf8fcd9e30766af98b8470314ef7f59148244d071ae249630c756db0f0579ae01f94e17b3ad97143c4182410281d
6
+ metadata.gz: b0d28575ed05697be4e981e11813663fe6259d1cc7bcabb2bdeb5b99ca9336ad07964717091c6c55eb13f6b1f5b9a93ece087beb8fedbdae51d1b325be189777
7
+ data.tar.gz: 87c10585a3c76084d660354c8f4f9a0bc6a5fcd454f1cdd1dccbdfc12c6536b4adda6d3617745b3dda84d666ecc6fbf94d11696a640126ca64a5dc0e4d918db4
data/.travis.yml CHANGED
@@ -2,10 +2,11 @@ language: ruby
2
2
  rvm:
3
3
  - 2.0.0
4
4
  - 2.1
5
+ - 2.2
5
6
  - ruby-head
6
7
  env:
7
- - "AR_VERSION=4.0.12"
8
- - "AR_VERSION=4.1.8"
9
- - "AR_VERSION=4.2.0.rc3"
8
+ - "AR_VERSION=4.0.13"
9
+ - "AR_VERSION=4.1.9"
10
+ - "AR_VERSION=4.2.0"
10
11
  before_install:
11
12
  - mysql -e "create database activerecord_unittest;"
@@ -7,6 +7,12 @@ module ActiveRecord
7
7
  { table_name: table_name }
8
8
  end
9
9
 
10
+ def column_spec_for_primary_key(column, options)
11
+ return if column.type == :integer
12
+ spec = { id: column.type.inspect }
13
+ spec.merge!(prepare_column_options(column, options).delete_if { |key, _| [:name, :type].include?(key) })
14
+ end
15
+
10
16
  def table_options(table_name)
11
17
  nil
12
18
  end
@@ -4,18 +4,13 @@ module ActiveRecord
4
4
  module Mysql
5
5
  module Awesome
6
6
  def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = false)
7
+ return "#{type_to_sql(type, limit, precision, scale)} unsigned" if unsigned && type != :primary_key
7
8
  case type.to_s
8
9
  when 'integer'
9
10
  case limit
10
11
  when nil, 4, 11; 'int' # compatibility with MySQL default
11
12
  else
12
13
  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
14
  end
20
15
  when 'primary_key'
21
16
  "#{type_to_sql(:integer, limit, precision, scale, unsigned)} auto_increment PRIMARY KEY"
@@ -36,6 +31,14 @@ module ActiveRecord
36
31
  def unsigned?
37
32
  sql_type =~ /unsigned/i
38
33
  end
34
+
35
+ def bigint?
36
+ sql_type =~ /bigint/i
37
+ end
38
+
39
+ def auto_increment?
40
+ extra == 'auto_increment'
41
+ end
39
42
  end
40
43
 
41
44
  if ActiveRecord::VERSION::STRING < "4.2.0"
@@ -46,12 +49,13 @@ module ActiveRecord
46
49
  when :datetime, :time
47
50
  if value.acts_like?(:time) && value.respond_to?(:usec)
48
51
  zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
49
- result = value.send(zone_conversion_method).to_s(:db)
52
+ value = value.send(zone_conversion_method) if value.respond_to?(zone_conversion_method)
53
+ result = value.to_s(:db)
50
54
  precision = column.precision
51
55
  case precision
52
56
  when 1..6
53
57
  "'#{result}.#{sprintf("%0#{precision}d", value.usec / 10**(6 - precision))}'"
54
- when 0, nil
58
+ else
55
59
  "'#{result}'"
56
60
  end
57
61
  else
@@ -102,11 +106,12 @@ module ActiveRecord
102
106
  def type_cast_for_database(value)
103
107
  if value.acts_like?(:time) && value.respond_to?(:usec)
104
108
  zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
105
- result = value.send(zone_conversion_method).to_s(:db)
109
+ value = value.send(zone_conversion_method) if value.respond_to?(zone_conversion_method)
110
+ result = value.to_s(:db)
106
111
  case precision
107
112
  when 1..6
108
113
  "#{result}.#{sprintf("%0#{precision}d", value.usec / 10**(6 - precision))}"
109
- when 0, nil
114
+ else
110
115
  result
111
116
  end
112
117
  else
@@ -147,6 +152,11 @@ module ActiveRecord
147
152
  @as = as
148
153
  end
149
154
 
155
+ def primary_key(name, type = :primary_key, options = {})
156
+ options[:auto_increment] ||= type == :bigint
157
+ super
158
+ end
159
+
150
160
  def new_column_definition(name, type, options) # :nodoc:
151
161
  column = super
152
162
  column.auto_increment = options[:auto_increment]
@@ -159,7 +169,7 @@ module ActiveRecord
159
169
  private
160
170
 
161
171
  def create_column_definition(name, type)
162
- ColumnDefinition.new name, type
172
+ ColumnDefinition.new(name, type)
163
173
  end
164
174
  end
165
175
 
@@ -216,7 +226,7 @@ module ActiveRecord
216
226
  end
217
227
 
218
228
  def type_to_sql(type, limit, precision, scale, unsigned = false)
219
- @conn.type_to_sql type.to_sym, limit, precision, scale, unsigned
229
+ @conn.type_to_sql(type.to_sym, limit, precision, scale, unsigned)
220
230
  end
221
231
 
222
232
  def quote_value(value, column)
@@ -233,6 +243,18 @@ module ActiveRecord
233
243
  end
234
244
  end
235
245
 
246
+ def column_spec_for_primary_key(column, options)
247
+ spec = {}
248
+ if column.auto_increment?
249
+ return unless column.bigint?
250
+ spec[:id] = ':bigint'
251
+ else
252
+ spec[:id] = column.type.inspect
253
+ spec.merge!(prepare_column_options(column, options).delete_if { |key, _| [:name, :type, :null].include?(key) })
254
+ end
255
+ spec
256
+ end
257
+
236
258
  def prepare_column_options(column, options) # :nodoc:
237
259
  spec = super
238
260
  spec[:unsigned] = 'true' if column.unsigned?
@@ -275,7 +297,7 @@ module ActiveRecord
275
297
 
276
298
  td = create_table_definition(table_name)
277
299
  cd = td.new_column_definition(column.name, type, options)
278
- schema_creation.accept ChangeColumnDefinition.new cd, column.name
300
+ schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
279
301
  end
280
302
 
281
303
  def rename_column_sql(table_name, column_name, new_column_name)
@@ -283,13 +305,13 @@ module ActiveRecord
283
305
  options = {
284
306
  default: column.default,
285
307
  null: column.null,
286
- auto_increment: column.extra == "auto_increment"
308
+ auto_increment: column.auto_increment?
287
309
  }
288
310
 
289
311
  current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'", 'SCHEMA')["Type"]
290
312
  td = create_table_definition(table_name)
291
313
  cd = td.new_column_definition(new_column_name, current_type, options)
292
- schema_creation.accept ChangeColumnDefinition.new cd, column.name
314
+ schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
293
315
  end
294
316
 
295
317
  alias configure_connection_without_awesome configure_connection
@@ -304,7 +326,7 @@ module ActiveRecord
304
326
  end
305
327
 
306
328
  def create_table_definition(name, temporary = false, options = nil, as = nil) # :nodoc:
307
- TableDefinition.new native_database_types, name, temporary, options, as
329
+ TableDefinition.new(native_database_types, name, temporary, options, as)
308
330
  end
309
331
  end
310
332
  end
@@ -1,22 +1,33 @@
1
1
  require 'active_record/schema_dumper'
2
2
 
3
3
  module ActiveRecord
4
- class SchemaDumper #:nodoc:
5
- private
4
+ module Mysql
5
+ module Awesome
6
+ module SchemaDumper
7
+ private
8
+
9
+ def table(table, stream)
10
+ @types = @types.merge(@connection.options_for_column_spec(table))
11
+ pk = @connection.primary_key(table)
12
+ pkcol = @connection.columns(table).detect { |c| c.name == pk }
13
+ pkcolspec = @connection.column_spec_for_primary_key(pkcol, @types) if pkcol
14
+ table_options = @connection.table_options(table)
6
15
 
7
- alias table_without_awesome table
8
- def table(table, stream)
9
- @types = @types.merge(@connection.options_for_column_spec(table))
10
- if table_options = @connection.table_options(table)
11
- buf = StringIO.new
12
- table_without_awesome(table, buf)
13
- stream.print buf.string.sub(/(?= do \|t\|)/, ", options: #{table_options.inspect}")
14
- stream
15
- else
16
- table_without_awesome(table, stream)
16
+ buf = StringIO.new
17
+ super(table, buf)
18
+ buf = buf.string
19
+ buf.sub!(/(?=, force: (?:true|:cascade))/, pkcolspec.map {|key, value| ", #{key}: #{value}"}.join) if pkcolspec
20
+ buf.sub!(/(?= do \|t\|)/, ", options: #{table_options.inspect}") if table_options
21
+ stream.print buf
22
+ stream
23
+ ensure
24
+ @types = @connection.native_database_types
25
+ end
17
26
  end
18
- ensure
19
- @types = @connection.native_database_types
20
27
  end
21
28
  end
29
+
30
+ class SchemaDumper #:nodoc:
31
+ prepend Mysql::Awesome::SchemaDumper
32
+ end
22
33
  end
@@ -1,7 +1,7 @@
1
1
  module ActiveRecord
2
2
  module Mysql
3
3
  module Awesome
4
- VERSION = "0.0.2"
4
+ VERSION = "0.0.3"
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,34 @@
1
+ require 'cases/helper'
2
+ require 'support/schema_dumping_helper'
3
+
4
+ class PrimaryKeyBigIntTest < ActiveRecord::TestCase
5
+ include SchemaDumpingHelper
6
+
7
+ class Widget < ActiveRecord::Base
8
+ end
9
+
10
+ setup do
11
+ @connection = ActiveRecord::Base.connection
12
+ @connection.create_table(:widgets, id: :bigint, force: true)
13
+ end
14
+
15
+ teardown do
16
+ @connection.execute("DROP TABLE IF EXISTS widgets")
17
+ end
18
+
19
+ test "primary key column type with bigint" do
20
+ column = Widget.columns_hash[Widget.primary_key]
21
+ assert_equal :integer, column.type
22
+ assert_equal 8, column.limit
23
+ end
24
+
25
+ test "primary key with bigint are automatically numbered" do
26
+ widget = Widget.create!
27
+ assert_not_nil widget.id
28
+ end
29
+
30
+ test "schema dump primary key with bigint" do
31
+ schema = dump_table_schema "widgets"
32
+ assert_match %r{create_table "widgets", id: :bigint}, schema
33
+ end
34
+ end
@@ -0,0 +1,53 @@
1
+ require 'cases/helper'
2
+ require 'support/schema_dumping_helper'
3
+
4
+ class CharsetCollationTest < ActiveRecord::TestCase
5
+ include SchemaDumpingHelper
6
+
7
+ class CharsetCollation < ActiveRecord::Base
8
+ end
9
+
10
+ setup do
11
+ @connection = ActiveRecord::Base.connection
12
+ @connection.create_table("charset_collations", force: true) do |t|
13
+ t.string "string_ascii_bin", charset: 'ascii', collation: 'ascii_bin'
14
+ t.text "text_ucs2_unicode_ci", charset: 'ucs2', collation: 'ucs2_unicode_ci'
15
+ end
16
+ end
17
+
18
+ teardown do
19
+ @connection.drop_table "charset_collations"
20
+ end
21
+
22
+ def test_column
23
+ string_column = CharsetCollation.columns_hash['string_ascii_bin']
24
+ assert_equal 'ascii_bin', string_column.collation
25
+
26
+ text_column = CharsetCollation.columns_hash['text_ucs2_unicode_ci']
27
+ assert_equal 'ucs2_unicode_ci', text_column.collation
28
+ end
29
+
30
+ def test_add_column
31
+ @connection.add_column 'charset_collations', 'title', :string, charset: 'utf8', collation: 'utf8_bin'
32
+
33
+ column = CharsetCollation.columns_hash['title']
34
+ assert_equal 'utf8_bin', column.collation
35
+ end
36
+
37
+ def test_change_column
38
+ @connection.add_column 'charset_collations', 'description', :string, charset: 'utf8', collation: 'utf8_unicode_ci'
39
+ @connection.change_column 'charset_collations', 'description', :text, charset: 'utf8', collation: 'utf8_general_ci'
40
+
41
+ CharsetCollation.reset_column_information
42
+
43
+ column = CharsetCollation.columns_hash['description']
44
+ assert_equal :text, column.type
45
+ assert_equal 'utf8_general_ci', column.collation
46
+ end
47
+
48
+ def test_schema_dump_column_collation
49
+ schema = dump_table_schema "charset_collations"
50
+ assert_match %r{t.string\s+"string_ascii_bin",(?:\s+limit: 255,)?\s+collation: "ascii_bin"$}, schema
51
+ assert_match %r{t.text\s+"text_ucs2_unicode_ci",(?:\s+limit: 65535,)?\s+collation: "ucs2_unicode_ci"$}, schema
52
+ end
53
+ end
@@ -0,0 +1,31 @@
1
+ require 'cases/helper'
2
+ require 'support/schema_dumping_helper'
3
+
4
+ class PrimaryKeyAnyTypeTest < ActiveRecord::TestCase
5
+ include SchemaDumpingHelper
6
+
7
+ class Barcode < ActiveRecord::Base
8
+ end
9
+
10
+ setup do
11
+ @connection = ActiveRecord::Base.connection
12
+ @connection.create_table(:barcodes, primary_key: "code", id: :string, limit: 42, force: true)
13
+ end
14
+
15
+ teardown do
16
+ @connection.execute("DROP TABLE IF EXISTS barcodes")
17
+ end
18
+
19
+ test "primary key with any type and options" do
20
+ assert_equal "code", Barcode.primary_key
21
+
22
+ column = Barcode.columns_hash[Barcode.primary_key]
23
+ assert_equal :string, column.type
24
+ assert_equal 42, column.limit
25
+ end
26
+
27
+ test "schema dump primary key includes type and options" do
28
+ schema = dump_table_schema "barcodes"
29
+ assert_match %r{create_table "barcodes", primary_key: "code", id: :string, limit: 42}, schema
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ require 'cases/helper'
2
+ require 'support/connection_helper'
3
+
4
+ class StrictModeTest < ActiveRecord::TestCase
5
+ include ConnectionHelper
6
+
7
+ def setup
8
+ super
9
+ @connection = ActiveRecord::Base.connection
10
+ end
11
+
12
+ def test_mysql_strict_mode_enabled
13
+ result = @connection.exec_query "SELECT @@SESSION.sql_mode"
14
+ assert_equal [["STRICT_ALL_TABLES"]], result.rows
15
+ end
16
+
17
+ def test_mysql_strict_mode_specified_default
18
+ run_without_connection do |orig_connection|
19
+ ActiveRecord::Base.establish_connection(orig_connection.merge({strict: :default}))
20
+ global_sql_mode = ActiveRecord::Base.connection.exec_query "SELECT @@GLOBAL.sql_mode"
21
+ session_sql_mode = ActiveRecord::Base.connection.exec_query "SELECT @@SESSION.sql_mode"
22
+ assert_equal global_sql_mode.rows, session_sql_mode.rows
23
+ end
24
+ end
25
+
26
+ def test_mysql_strict_mode_disabled
27
+ run_without_connection do |orig_connection|
28
+ ActiveRecord::Base.establish_connection(orig_connection.merge({strict: false}))
29
+ result = ActiveRecord::Base.connection.exec_query "SELECT @@SESSION.sql_mode"
30
+ assert_equal [[""]], result.rows
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+ require 'cases/helper'
2
+ require 'support/schema_dumping_helper'
3
+
4
+ class TableOptionsTest < ActiveRecord::TestCase
5
+ include SchemaDumpingHelper
6
+
7
+ teardown do
8
+ ActiveRecord::Base.connection.drop_table "table_options"
9
+ end
10
+
11
+ def test_dump_table_options
12
+ ActiveRecord::Base.connection.create_table(:table_options, force: true, options: "COMMENT 'london bridge is falling down'")
13
+ output = dump_table_schema("table_options")
14
+ assert_match %r{COMMENT='london bridge is falling down'}, output
15
+ end
16
+ end
@@ -0,0 +1,42 @@
1
+ require 'cases/helper'
2
+ require 'support/schema_dumping_helper'
3
+
4
+ class UnsignedTypeTest < ActiveRecord::TestCase
5
+ include SchemaDumpingHelper
6
+
7
+ class UnsignedType < ActiveRecord::Base
8
+ end
9
+
10
+ setup do
11
+ @connection = ActiveRecord::Base.connection
12
+ @connection.create_table("unsigned_types", force: true) do |t|
13
+ t.column :unsigned_integer, "int unsigned"
14
+ t.integer :unsigned_integer, unsigned: true
15
+ t.float :unsigned_float, unsigned: true
16
+ t.decimal :unsigned_decimal, unsigned: true, precision: 10, scale: 2
17
+ end
18
+ end
19
+
20
+ teardown do
21
+ ActiveRecord::Base.connection.drop_table "unsigned_types"
22
+ end
23
+
24
+ def test_minus_value_is_out_of_range
25
+ assert_raise(ActiveRecord::StatementInvalid, RangeError) do
26
+ UnsignedType.create(unsigned_integer: -10)
27
+ end
28
+ assert_raise(ActiveRecord::StatementInvalid) do
29
+ UnsignedType.create(unsigned_float: -10.0)
30
+ end
31
+ assert_raise(ActiveRecord::StatementInvalid) do
32
+ UnsignedType.create(unsigned_decimal: -10.0)
33
+ end
34
+ end
35
+
36
+ def test_schema_dump_includes_unsigned_option
37
+ schema = dump_table_schema "unsigned_types"
38
+ assert_match %r{t.integer\s+"unsigned_integer",(?:\s+limit: 4,)?\s+unsigned: true$}, schema
39
+ assert_match %r{t.float\s+"unsigned_float",(?:\s+limit: 24,)?\s+unsigned: true$}, schema
40
+ assert_match %r{t.decimal\s+"unsigned_decimal",\s+precision: 10,\s+scale: 2,\s+unsigned: true$}, schema
41
+ end
42
+ 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
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.2
4
+ version: 0.0.3
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-18 00:00:00.000000000 Z
11
+ date: 2015-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -103,13 +103,20 @@ files:
103
103
  - lib/activerecord/mysql/awesome/railtie.rb
104
104
  - lib/activerecord/mysql/awesome/version.rb
105
105
  - test/.gitignore
106
+ - test/cases/bigint_pk_test.rb
107
+ - test/cases/charset_collation_test.rb
106
108
  - test/cases/datetime_test.rb
107
109
  - test/cases/helper.rb
110
+ - test/cases/primary_key_any_type_test.rb
111
+ - test/cases/strict_mode_test.rb
112
+ - test/cases/table_options_test.rb
108
113
  - test/cases/test_case.rb
114
+ - test/cases/unsigned_type_test.rb
109
115
  - test/config.example.yml
110
116
  - test/config.rb
111
117
  - test/support/config.rb
112
118
  - test/support/connection.rb
119
+ - test/support/connection_helper.rb
113
120
  - test/support/schema_dumping_helper.rb
114
121
  homepage: https://github.com/kamipo/activerecord-mysql-awesome
115
122
  licenses:
@@ -131,17 +138,24 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
138
  version: '0'
132
139
  requirements: []
133
140
  rubyforge_project:
134
- rubygems_version: 2.2.2
141
+ rubygems_version: 2.4.5
135
142
  signing_key:
136
143
  specification_version: 4
137
144
  summary: Awesome patches backported for ActiveRecord MySQL adapters
138
145
  test_files:
139
146
  - test/.gitignore
147
+ - test/cases/bigint_pk_test.rb
148
+ - test/cases/charset_collation_test.rb
140
149
  - test/cases/datetime_test.rb
141
150
  - test/cases/helper.rb
151
+ - test/cases/primary_key_any_type_test.rb
152
+ - test/cases/strict_mode_test.rb
153
+ - test/cases/table_options_test.rb
142
154
  - test/cases/test_case.rb
155
+ - test/cases/unsigned_type_test.rb
143
156
  - test/config.example.yml
144
157
  - test/config.rb
145
158
  - test/support/config.rb
146
159
  - test/support/connection.rb
160
+ - test/support/connection_helper.rb
147
161
  - test/support/schema_dumping_helper.rb