activerecord-mysql-unsigned 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -0
  3. data/Gemfile +2 -0
  4. data/README.md +1 -1
  5. data/activerecord-mysql-unsigned.gemspec +2 -2
  6. data/lib/activerecord-mysql-unsigned/active_record/v3/connection_adapters/abstract/schema_creation.rb +47 -0
  7. data/lib/activerecord-mysql-unsigned/active_record/v3/connection_adapters/abstract/schema_definitions.rb +9 -33
  8. data/lib/activerecord-mysql-unsigned/active_record/v3/connection_adapters/abstract_mysql_adapter.rb +33 -55
  9. data/lib/activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract/schema_definitions.rb +7 -25
  10. data/lib/activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract_mysql_adapter.rb +86 -59
  11. data/lib/activerecord-mysql-unsigned/base.rb +2 -13
  12. data/lib/activerecord-mysql-unsigned/version.rb +1 -1
  13. data/spec/bigint_primary_key_spec.rb +10 -0
  14. data/spec/support/migrations.rb +1 -1
  15. data/spec/unsigned_spec.rb +11 -5
  16. metadata +10 -18
  17. data/lib/activerecord-mysql-unsigned/active_record/v3/connection_adapters/abstract/schema_statements.rb +0 -35
  18. data/lib/activerecord-mysql-unsigned/active_record/v3/connection_adapters/mysql2_adapter.rb +0 -22
  19. data/lib/activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract/schema_dumper.rb +0 -36
  20. data/lib/activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract/schema_statements.rb +0 -35
  21. data/lib/activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract_adapter.rb +0 -28
  22. data/lib/activerecord-mysql-unsigned/active_record/v4/connection_adapters/mysql2_adapter.rb +0 -22
  23. data/lib/activerecord-mysql-unsigned/active_record/v4_1/connection_adapters/abstract/schema_definitions.rb +0 -40
  24. data/lib/activerecord-mysql-unsigned/active_record/v4_1/connection_adapters/abstract/schema_dumper.rb +0 -35
  25. data/lib/activerecord-mysql-unsigned/active_record/v4_1/connection_adapters/abstract/schema_statements.rb +0 -35
  26. data/lib/activerecord-mysql-unsigned/active_record/v4_1/connection_adapters/abstract_mysql_adapter.rb +0 -98
  27. data/lib/activerecord-mysql-unsigned/active_record/v4_1/connection_adapters/mysql2_adapter.rb +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bb8f5f38a9a5fd9b1b15e1368f3c7958b2c8719a
4
- data.tar.gz: fdb22adc25e2d8da3752f01e92faf34064e9badd
3
+ metadata.gz: 28887c8744010284c741bf409074d986e2e04092
4
+ data.tar.gz: 054d6bc7e97203547459bc040f05d362f14083db
5
5
  SHA512:
6
- metadata.gz: 0652a2d5af79c1ffd3a466240f2d6e5cd357c3997bab5279314632c6e5313f6c70dd6e79f4027a2383882e3b9c80fe1c706a6aa1d394beb2492c53ca38939c2f
7
- data.tar.gz: 5bebff108fcc8bbdf786e8e71e8549ce1b5251ab0c19418a22616c54c48397a7e974fed08f54856c754ec332832b891900da6dc03814bd6c25a5228e71c23450
6
+ metadata.gz: 3f47eeeea032def664defb3990a04c78cb181e1b3a813999d12d3a0f8320f3d52c11c31d94978f3deb87beef30129d39aa0950e78b2051119574ff5edd911c7a
7
+ data.tar.gz: 3ecd003fd8ce4dbd6158dffe52129d54622e950752c009dbedd094005ccdf8f3dbdfbef38f34ca57ed358ba3777dfd61b7101825f832be401bf8cc81963c8654
@@ -1,4 +1,10 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 1.9.3
3
4
  - 2.0.0
4
5
  - 2.1
6
+ env:
7
+ - "AR_VERSION=3.2.21"
8
+ - "AR_VERSION=4.0.12"
9
+ - "AR_VERSION=4.1.8"
10
+ - "AR_VERSION=4.2.0.beta4"
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem "activerecord", "~> #{ENV['AR_VERSION']}" if ENV['AR_VERSION']
4
+
3
5
  # Specify your gem's dependencies in activerecord-mysql-unsigned.gemspec
4
6
  gemspec
data/README.md CHANGED
@@ -7,7 +7,7 @@ Add unsigned option to integer type for ActiveRecord's MySQL2 adapter.
7
7
  ## Support version
8
8
 
9
9
  ```
10
- 4.2 > ActiveRecord::VERSION >= 3.2
10
+ 5.0 > ActiveRecord::VERSION >= 3.2
11
11
  ```
12
12
 
13
13
  ## Installation
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_development_dependency "rspec", "~> 3.0.0"
24
24
  spec.add_development_dependency "database_cleaner"
25
- spec.add_runtime_dependency "activesupport", ">= 3.2", "< 4.2"
26
- spec.add_runtime_dependency "activerecord", ">= 3.2", "< 4.2"
25
+ spec.add_runtime_dependency "activesupport", ">= 3.2", "< 5.0"
26
+ spec.add_runtime_dependency "activerecord", ">= 3.2", "< 5.0"
27
27
  spec.add_runtime_dependency "mysql2"
28
28
  end
@@ -0,0 +1,47 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ class AbstractAdapter
4
+ class SchemaCreation # :nodoc:
5
+ def initialize(conn)
6
+ @conn = conn
7
+ end
8
+
9
+ private
10
+
11
+ def column_options(o)
12
+ column_options = {}
13
+ column_options[:null] = o.null unless o.null.nil?
14
+ column_options[:default] = o.default unless o.default.nil?
15
+ column_options[:column] = o
16
+ column_options[:first] = o.first
17
+ column_options[:after] = o.after
18
+ column_options
19
+ end
20
+
21
+ def quote_column_name(name)
22
+ @conn.quote_column_name name
23
+ end
24
+
25
+ def add_column_options!(sql, options)
26
+ sql << " DEFAULT #{quote_value(options[:default], options[:column])}" if options_include_default?(options)
27
+ # must explicitly check for :null to allow change_column to work on migrations
28
+ if options[:null] == false
29
+ sql << " NOT NULL"
30
+ end
31
+ if options[:auto_increment] == true
32
+ sql << " AUTO_INCREMENT"
33
+ end
34
+ sql
35
+ end
36
+
37
+ def quote_value(value, column)
38
+ @conn.quote(value, column)
39
+ end
40
+
41
+ def options_include_default?(options)
42
+ options.include?(:default) && !(options[:null] == false && options[:default].nil?)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -3,49 +3,25 @@ require 'active_record/connection_adapters/abstract/schema_definitions'
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  class ColumnDefinition
6
- def unsigned=(value)
7
- @unsigned = value
8
- end
9
-
10
- def unsigned
11
- @unsigned
12
- end
13
-
14
- def auto_increment=(value)
15
- @auto_increment = value
16
- end
17
-
18
- def auto_increment
19
- @auto_increment
20
- end
6
+ attr_accessor :unsigned, :first, :after
21
7
 
22
8
  def sql_type
23
- base.type_to_sql(type.to_sym, limit, precision, scale, unsigned, auto_increment) rescue type
9
+ base.type_to_sql(type.to_sym, limit, precision, scale, unsigned) rescue type
24
10
  end
25
11
  end
26
12
 
27
13
  class TableDefinition
14
+ def primary_key(name, type = :primary_key, options = {})
15
+ column(name, type, options.merge(primary_key: true).reverse_merge(unsigned: true))
16
+ end
28
17
 
18
+ alias_method :column_without_unsigned, :column
29
19
  def column(name, type, options = {})
30
- name = name.to_s
31
- type = type.to_sym
32
-
33
- column = self[name] || new_column_definition(@base, name, type)
34
-
35
- limit = options.fetch(:limit) do
36
- native[type][:limit] if native[type].is_a?(Hash)
37
- end
38
-
39
- column.limit = limit
40
- column.unsigned = options[:unsigned]
41
- column.auto_increment = options[:auto_increment]
42
- column.precision = options[:precision]
43
- column.scale = options[:scale]
44
- column.default = options[:default]
45
- column.null = options[:null]
20
+ column_without_unsigned(name, type, options)
21
+ column = self[name]
22
+ column.unsigned = options[:unsigned]
46
23
  self
47
24
  end
48
-
49
25
  end
50
26
  end
51
27
  end
@@ -1,70 +1,48 @@
1
- require 'active_record/connection_adapters/abstract_mysql_adapter'
1
+ require 'activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract_mysql_adapter'
2
2
 
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  class AbstractMysqlAdapter < AbstractAdapter
6
6
 
7
- NATIVE_DATABASE_TYPES.merge!(
8
- primary_key: "int(10) unsigned DEFAULT NULL auto_increment PRIMARY KEY"
9
- )
10
-
11
- # Maps logical Rails types to MySQL-specific data types.
12
- def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = false, auto_increment = false)
13
- case type.to_s
14
- when 'integer'
15
- case limit
16
- when 1
17
- 'tinyint' + (unsigned ? ' unsigned' : '') + (auto_increment ? ' AUTO_INCREMENT' : '')
18
- when 2
19
- 'smallint' + (unsigned ? ' unsigned' : '') + (auto_increment ? ' AUTO_INCREMENT' : '')
20
- when 3
21
- 'mediumint' + (unsigned ? ' unsigned' : '') + (auto_increment ? ' AUTO_INCREMENT' : '')
22
- when nil, 4, 11 # compatibility with MySQL default
23
- if unsigned
24
- 'int(10) unsigned' + (auto_increment ? ' AUTO_INCREMENT' : '')
25
- else
26
- 'int(10)'
27
- end
28
- when 5..8
29
- 'bigint' + (unsigned ? ' unsigned' : '') + (auto_increment ? ' AUTO_INCREMENT' : '')
30
- else raise(ActiveRecordError, "No integer type has byte size #{limit}")
31
- end
32
- when 'text'
33
- case limit
34
- when 0..0xff; 'tinytext'
35
- when nil, 0x100..0xffff; 'text'
36
- when 0x10000..0xffffff; 'mediumtext'
37
- when 0x1000000..0xffffffff; 'longtext'
38
- else raise(ActiveRecordError, "No text type has character length #{limit}")
7
+ class TableDefinition
8
+ def initialize(base)
9
+ @base = base
10
+ end
11
+
12
+ def new_column_definition(name, type, options) # :nodoc:
13
+ column = create_column_definition name, type
14
+ limit = options.fetch(:limit) do
15
+ native[type][:limit] if native[type].is_a?(Hash)
39
16
  end
40
- else
41
- super
17
+
18
+ column.limit = limit
19
+ column.precision = options[:precision]
20
+ column.scale = options[:scale]
21
+ column.unsigned = options[:unsigned]
22
+ column.default = options[:default]
23
+ column.null = options[:null]
24
+ column.first = options[:first]
25
+ column.after = options[:after]
26
+ column
42
27
  end
43
- end
44
28
 
45
- def add_column_sql(table_name, column_name, type, options = {})
46
- add_column_sql = "ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale], options[:unsigned], options[:auto_increment])}"
47
- add_column_options!(add_column_sql, options)
48
- add_column_position!(add_column_sql, options)
49
- add_column_sql
50
- end
29
+ private
51
30
 
52
- def change_column_sql(table_name, column_name, type, options = {})
53
- column = column_for(table_name, column_name)
31
+ def create_column_definition(name, type)
32
+ ColumnDefinition.new @base, name, type
33
+ end
54
34
 
55
- unless type.to_sym == :primary_key
56
- unless options_include_default?(options)
57
- options[:default] = column.default
58
- end
59
- unless options.has_key?(:null)
60
- options[:null] = column.null
61
- end
35
+ def native
36
+ @base.native_database_types
62
37
  end
38
+ end
39
+
40
+ def schema_creation
41
+ SchemaCreation.new self
42
+ end
63
43
 
64
- change_column_sql = "CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale], options[:unsigned], options[:auto_increment])}"
65
- add_column_options!(change_column_sql, options)
66
- add_column_position!(change_column_sql, options)
67
- change_column_sql
44
+ def create_table_definition(name, temporary, options)
45
+ TableDefinition.new self
68
46
  end
69
47
 
70
48
  end
@@ -3,38 +3,20 @@ require 'active_record/connection_adapters/abstract/schema_definitions'
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  class ColumnDefinition
6
-
7
- def unsigned=(value)
8
- @unsigned = value
9
- end
10
-
11
- def unsigned
12
- @unsigned
13
- end
14
-
6
+ attr_accessor :unsigned
15
7
  end
16
8
 
17
9
  class TableDefinition
10
+ def primary_key(name, type = :primary_key, options = {})
11
+ column(name, type, options.merge(primary_key: true).reverse_merge(unsigned: true))
12
+ end
18
13
 
14
+ alias_method :new_column_definition_without_unsigned, :new_column_definition
19
15
  def new_column_definition(name, type, options)
20
- column = create_column_definition name, type
21
- limit = options.fetch(:limit) do
22
- native[type][:limit] if native[type].is_a?(Hash)
23
- end
24
-
25
- column.limit = limit
26
- column.array = options[:array] if column.respond_to?(:array)
27
- column.precision = options[:precision]
28
- column.scale = options[:scale]
29
- column.unsigned = options[:unsigned]
30
- column.default = options[:default]
31
- column.null = options[:null]
32
- column.first = options[:first]
33
- column.after = options[:after]
34
- column.primary_key = type == :primary_key || options[:primary_key]
16
+ column = new_column_definition_without_unsigned(name, type, options)
17
+ column.unsigned = options[:unsigned]
35
18
  column
36
19
  end
37
-
38
20
  end
39
21
  end
40
22
  end
@@ -4,83 +4,110 @@ module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  class AbstractMysqlAdapter < AbstractAdapter
6
6
 
7
- NATIVE_DATABASE_TYPES.merge!(
8
- :primary_key => "int(10) unsigned DEFAULT NULL auto_increment PRIMARY KEY"
9
- )
7
+ class ChangeColumnDefinition < Struct.new(:column, :type, :options) #:nodoc:
8
+ end
10
9
 
11
- # Maps logical Rails types to MySQL-specific data types.
12
- def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = false)
13
- # return earlier, only need overwrite method when unsigned option == true
14
- return super unless unsigned
10
+ class SchemaCreation < AbstractAdapter::SchemaCreation
11
+ def visit_AddColumn(o)
12
+ sql_type = type_to_sql(o.type.to_sym, o.limit, o.precision, o.scale, o.unsigned)
13
+ sql = "ADD #{quote_column_name(o.name)} #{sql_type}"
14
+ add_column_options!(sql, column_options(o)) unless o.type.to_sym == :primary_key
15
+ add_column_position!(sql, column_options(o))
16
+ end
15
17
 
16
- case type.to_s
17
- when 'decimal'
18
- # copy from rails core
19
- # https://github.com/rails/rails/blob/600aaf4234c80064201ee34ddabed216b91559db/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
20
- native = native_database_types[type.to_sym]
21
- column_type_sql = (native.is_a?(Hash) ? native[:name] : native).dup
22
-
23
- scale ||= native[:scale]
24
-
25
- if precision ||= native[:precision]
26
- if scale
27
- column_type_sql << "(#{precision},#{scale}) unsigned"
28
- else
29
- column_type_sql << "(#{precision}) unsigned"
30
- end
31
- elsif scale
32
- raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale is specified"
33
- end
34
-
35
- when 'binary'
36
- case limit
37
- when 0..0xfff; "varbinary(#{limit})"
38
- when nil; "blob"
39
- when 0x1000..0xffffffff; "blob(#{limit})"
40
- else raise(ActiveRecordError, "No binary type has character length #{limit}")
18
+ def visit_ChangeColumnDefinition(o)
19
+ column = o.column
20
+ options = o.options
21
+ sql_type = type_to_sql(o.type, options[:limit], options[:precision], options[:scale], options[:unsigned])
22
+ change_column_sql = "CHANGE #{quote_column_name(column.name)} #{quote_column_name(options[:name])} #{sql_type}"
23
+ add_column_options!(change_column_sql, options.merge(column: column)) unless o.type.to_sym == :primary_key
24
+ add_column_position!(change_column_sql, options)
25
+ end
26
+
27
+ def visit_ColumnDefinition(o)
28
+ sql_type = type_to_sql(o.type.to_sym, o.limit, o.precision, o.scale, o.unsigned)
29
+ column_sql = "#{quote_column_name(o.name)} #{sql_type}"
30
+ add_column_options!(column_sql, column_options(o)) unless o.type.to_sym == :primary_key
31
+ column_sql
32
+ end
33
+
34
+ def column_options(o)
35
+ column_options = super
36
+ column_options[:first] = o.first
37
+ column_options[:after] = o.after
38
+ column_options
39
+ end
40
+
41
+ def add_column_position!(sql, options)
42
+ if options[:first]
43
+ sql << " FIRST"
44
+ elsif options[:after]
45
+ sql << " AFTER #{quote_column_name(options[:after])}"
41
46
  end
47
+ end
48
+
49
+ def type_to_sql(type, limit, precision, scale, unsigned = false)
50
+ @conn.type_to_sql type.to_sym, limit, precision, scale, unsigned
51
+ end
52
+ end
53
+
54
+ class Column < ConnectionAdapters::Column # :nodoc:
55
+ def unsigned?
56
+ sql_type =~ /unsigned/i
57
+ end
58
+ end
59
+
60
+ def prepare_column_options(column, types) # :nodoc:
61
+ spec = super
62
+ spec[:unsigned] = 'true' if column.unsigned?
63
+ spec
64
+ end
65
+
66
+ def migration_keys
67
+ super + [:unsigned]
68
+ end
69
+
70
+ alias_method :type_to_sql_without_unsigned, :type_to_sql
71
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = false)
72
+ case type.to_s
42
73
  when 'integer'
43
74
  case limit
44
- when 1
45
- 'tinyint unsigned'
46
- when 2
47
- 'smallint unsigned'
48
- when 3
49
- 'mediumint unsigned'
50
- when nil, 4, 11 # compatibility with MySQL default
51
- 'int(10) unsigned'
52
- when 5..8
53
- 'bigint unsigned'
54
- else raise(ActiveRecordError, "No integer type has byte size #{limit}")
75
+ when nil, 4, 11; 'int' # compatibility with MySQL default
76
+ else
77
+ type_to_sql_without_unsigned(type, limit, precision, scale)
78
+ end.tap do |sql_type|
79
+ sql_type << ' unsigned' if unsigned
55
80
  end
81
+ when 'float', 'decimal'
82
+ type_to_sql_without_unsigned(type, limit, precision, scale).tap do |sql_type|
83
+ sql_type << ' unsigned' if unsigned
84
+ end
85
+ when 'primary_key'
86
+ "#{type_to_sql(:integer, limit, precision, scale, unsigned)} auto_increment PRIMARY KEY"
56
87
  else
57
- super
88
+ type_to_sql_without_unsigned(type, limit, precision, scale)
58
89
  end
59
90
  end
60
91
 
61
92
  def add_column_sql(table_name, column_name, type, options = {})
62
- add_column_sql = "ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale], options[:unsigned])}"
63
- add_column_options!(add_column_sql, options)
64
- add_column_position!(add_column_sql, options)
65
- add_column_sql
93
+ td = create_table_definition table_name, options[:temporary], options[:options]
94
+ cd = td.new_column_definition(column_name, type, options)
95
+ schema_creation.visit_AddColumn cd
66
96
  end
67
97
 
68
98
  def change_column_sql(table_name, column_name, type, options = {})
69
99
  column = column_for(table_name, column_name)
70
100
 
71
- unless type.to_sym == :primary_key
72
- unless options_include_default?(options)
73
- options[:default] = column.default
74
- end
75
- unless options.has_key?(:null)
76
- options[:null] = column.null
77
- end
101
+ unless options_include_default?(options)
102
+ options[:default] = column.default
103
+ end
104
+
105
+ unless options.has_key?(:null)
106
+ options[:null] = column.null
78
107
  end
79
108
 
80
- change_column_sql = "CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale], options[:unsigned])}"
81
- add_column_options!(change_column_sql, options)
82
- add_column_position!(change_column_sql, options)
83
- change_column_sql
109
+ options[:name] = column.name
110
+ schema_creation.visit_ChangeColumnDefinition ChangeColumnDefinition.new column, type, options
84
111
  end
85
112
 
86
113
  end
@@ -1,21 +1,10 @@
1
- if ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 1
2
- require 'activerecord-mysql-unsigned/active_record/v4_1/connection_adapters/abstract/schema_definitions'
3
- require 'activerecord-mysql-unsigned/active_record/v4_1/connection_adapters/abstract/schema_statements'
4
- require 'activerecord-mysql-unsigned/active_record/v4_1/connection_adapters/abstract/schema_dumper'
5
- require 'activerecord-mysql-unsigned/active_record/v4_1/connection_adapters/abstract_mysql_adapter'
6
- require 'activerecord-mysql-unsigned/active_record/v4_1/connection_adapters/mysql2_adapter'
7
- elsif ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 0
1
+ if ActiveRecord::VERSION::MAJOR == 4
8
2
  require 'activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract/schema_definitions'
9
- require 'activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract/schema_statements'
10
- require 'activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract/schema_dumper'
11
- require 'activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract_adapter'
12
3
  require 'activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract_mysql_adapter'
13
- require 'activerecord-mysql-unsigned/active_record/v4/connection_adapters/mysql2_adapter'
14
4
  elsif ActiveRecord::VERSION::MAJOR == 3
15
5
  require 'activerecord-mysql-unsigned/active_record/v3/connection_adapters/abstract/schema_definitions'
16
- require 'activerecord-mysql-unsigned/active_record/v3/connection_adapters/abstract/schema_statements'
6
+ require 'activerecord-mysql-unsigned/active_record/v3/connection_adapters/abstract/schema_creation'
17
7
  require 'activerecord-mysql-unsigned/active_record/v3/connection_adapters/abstract_mysql_adapter'
18
- require 'activerecord-mysql-unsigned/active_record/v3/connection_adapters/mysql2_adapter'
19
8
  else
20
9
  raise "activerecord-mysql-unsigned supprts ActiveRecord::VERSION::MAJOR >= 3"
21
10
  end
@@ -1,7 +1,7 @@
1
1
  module ActiveRecord
2
2
  module Mysql
3
3
  module Unsigned
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe "primary_key" do
4
+ it "should be bigint with limit: 8" do
5
+ pkcol = Goods.columns_hash[Goods.primary_key]
6
+
7
+ expect(pkcol.unsigned?).to be_truthy
8
+ expect(pkcol.limit).to be 8 if ActiveRecord::VERSION::MAJOR == 4
9
+ end
10
+ end
@@ -17,7 +17,7 @@ ActiveRecord::Migration.verbose = true
17
17
  # create goods table
18
18
  class CreateGoodsTable < ActiveRecord::Migration
19
19
  def self.change
20
- create_table :goods, force: true do |t|
20
+ create_table :goods, force: true, limit: 8 do |t|
21
21
  t.string :name, null: false
22
22
  t.boolean :deleted, default: false
23
23
  end
@@ -30,7 +30,7 @@ describe "INT/Decimal column" do
30
30
  it "not allowed minus value of unsigned int" do
31
31
  @user.unsigned_int = -2147483648
32
32
 
33
- if ActiveRecord::VERSION::MAJOR == 4
33
+ if strict_mode?
34
34
  begin
35
35
  @user.save
36
36
  expect(true).to be_falsey # should not be reached here
@@ -46,10 +46,10 @@ describe "INT/Decimal column" do
46
46
 
47
47
  it "unsigned column has 'unsigned' attribute" do
48
48
  signed_int_col = User.columns[2]
49
- expect(signed_int_col.unsigned).to be_falsey
49
+ expect(signed_int_col.unsigned?).to be_falsey
50
50
 
51
51
  unsigned_int_col = User.columns[3]
52
- expect(unsigned_int_col.unsigned).to be_truthy
52
+ expect(unsigned_int_col.unsigned?).to be_truthy
53
53
  end
54
54
 
55
55
  it "allowed minus value of signed decimal" do
@@ -61,7 +61,7 @@ describe "INT/Decimal column" do
61
61
  it "not allowed minus value of unsigned decimal" do
62
62
  @user.unsigned_decimal = -10
63
63
 
64
- if ActiveRecord::VERSION::MAJOR == 4
64
+ if strict_mode?
65
65
  begin
66
66
  @user.save
67
67
  expect(true).to be_falsey # should not be reached here
@@ -71,7 +71,13 @@ describe "INT/Decimal column" do
71
71
  else
72
72
  @user.save
73
73
  @user.reload
74
- expect(@user.unsigned_int).to be 0 # saved 0
74
+ expect(@user.unsigned_decimal).to eq BigDecimal("0.00") # saved 0.00
75
75
  end
76
76
  end
77
+
78
+ private
79
+
80
+ def strict_mode?
81
+ /STRICT_(?:TRANS|ALL)_TABLES/ =~ ActiveRecord::Base.connection.select_value("SELECT @@SESSION.sql_mode")
82
+ end
77
83
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-mysql-unsigned
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - yo_waka
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-19 00:00:00.000000000 Z
11
+ date: 2014-11-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -75,7 +75,7 @@ dependencies:
75
75
  version: '3.2'
76
76
  - - "<"
77
77
  - !ruby/object:Gem::Version
78
- version: '4.2'
78
+ version: '5.0'
79
79
  type: :runtime
80
80
  prerelease: false
81
81
  version_requirements: !ruby/object:Gem::Requirement
@@ -85,7 +85,7 @@ dependencies:
85
85
  version: '3.2'
86
86
  - - "<"
87
87
  - !ruby/object:Gem::Version
88
- version: '4.2'
88
+ version: '5.0'
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: activerecord
91
91
  requirement: !ruby/object:Gem::Requirement
@@ -95,7 +95,7 @@ dependencies:
95
95
  version: '3.2'
96
96
  - - "<"
97
97
  - !ruby/object:Gem::Version
98
- version: '4.2'
98
+ version: '5.0'
99
99
  type: :runtime
100
100
  prerelease: false
101
101
  version_requirements: !ruby/object:Gem::Requirement
@@ -105,7 +105,7 @@ dependencies:
105
105
  version: '3.2'
106
106
  - - "<"
107
107
  - !ruby/object:Gem::Version
108
- version: '4.2'
108
+ version: '5.0'
109
109
  - !ruby/object:Gem::Dependency
110
110
  name: mysql2
111
111
  requirement: !ruby/object:Gem::Requirement
@@ -135,25 +135,16 @@ files:
135
135
  - Rakefile
136
136
  - activerecord-mysql-unsigned.gemspec
137
137
  - lib/activerecord-mysql-unsigned.rb
138
+ - lib/activerecord-mysql-unsigned/active_record/v3/connection_adapters/abstract/schema_creation.rb
138
139
  - lib/activerecord-mysql-unsigned/active_record/v3/connection_adapters/abstract/schema_definitions.rb
139
- - lib/activerecord-mysql-unsigned/active_record/v3/connection_adapters/abstract/schema_statements.rb
140
140
  - lib/activerecord-mysql-unsigned/active_record/v3/connection_adapters/abstract_mysql_adapter.rb
141
- - lib/activerecord-mysql-unsigned/active_record/v3/connection_adapters/mysql2_adapter.rb
142
141
  - lib/activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract/schema_definitions.rb
143
- - lib/activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract/schema_dumper.rb
144
- - lib/activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract/schema_statements.rb
145
- - lib/activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract_adapter.rb
146
142
  - lib/activerecord-mysql-unsigned/active_record/v4/connection_adapters/abstract_mysql_adapter.rb
147
- - lib/activerecord-mysql-unsigned/active_record/v4/connection_adapters/mysql2_adapter.rb
148
- - lib/activerecord-mysql-unsigned/active_record/v4_1/connection_adapters/abstract/schema_definitions.rb
149
- - lib/activerecord-mysql-unsigned/active_record/v4_1/connection_adapters/abstract/schema_dumper.rb
150
- - lib/activerecord-mysql-unsigned/active_record/v4_1/connection_adapters/abstract/schema_statements.rb
151
- - lib/activerecord-mysql-unsigned/active_record/v4_1/connection_adapters/abstract_mysql_adapter.rb
152
- - lib/activerecord-mysql-unsigned/active_record/v4_1/connection_adapters/mysql2_adapter.rb
153
143
  - lib/activerecord-mysql-unsigned/base.rb
154
144
  - lib/activerecord-mysql-unsigned/railtie.rb
155
145
  - lib/activerecord-mysql-unsigned/version.rb
156
146
  - spec/after_option_spec.rb
147
+ - spec/bigint_primary_key_spec.rb
157
148
  - spec/spec_helper.rb
158
149
  - spec/support/database_cleaner.rb
159
150
  - spec/support/migrations.rb
@@ -180,12 +171,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
171
  version: '0'
181
172
  requirements: []
182
173
  rubyforge_project:
183
- rubygems_version: 2.2.0
174
+ rubygems_version: 2.2.2
184
175
  signing_key:
185
176
  specification_version: 4
186
177
  summary: Add unsigned option to integer type for ActiveRecord's MySQL2 adapter
187
178
  test_files:
188
179
  - spec/after_option_spec.rb
180
+ - spec/bigint_primary_key_spec.rb
189
181
  - spec/spec_helper.rb
190
182
  - spec/support/database_cleaner.rb
191
183
  - spec/support/migrations.rb
@@ -1,35 +0,0 @@
1
- require 'active_record/connection_adapters/abstract/schema_statements'
2
-
3
- module ActiveRecord
4
- module ConnectionAdapters
5
- module SchemaStatements
6
-
7
- def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = nil, auto_increment = nil)
8
- if native = native_database_types[type.to_sym]
9
- column_type_sql = (native.is_a?(Hash) ? native[:name] : native).dup
10
-
11
- if type == :decimal
12
- scale ||= native[:scale]
13
-
14
- if precision ||= native[:precision]
15
- if scale
16
- column_type_sql << "(#{precision},#{scale})"
17
- else
18
- column_type_sql << "(#{precision})"
19
- end
20
- elsif scale
21
- raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale is specified"
22
- end
23
- elsif (type != :primary_key) && (limit ||= native.is_a?(Hash) && native[:limit])
24
- column_type_sql << "(#{limit})"
25
- end
26
-
27
- column_type_sql
28
- else
29
- type
30
- end
31
- end
32
-
33
- end
34
- end
35
- end
@@ -1,22 +0,0 @@
1
- require 'active_record/connection_adapters/mysql2_adapter'
2
-
3
- module ActiveRecord
4
- module ConnectionAdapters
5
- class Mysql2Adapter < AbstractMysqlAdapter
6
-
7
- class Column < AbstractMysqlAdapter::Column
8
- attr_reader :unsigned
9
-
10
- def initialize(name, default, sql_type = nil, null = true, collation = nil)
11
- if sql_type.present?
12
- @unsigned = sql_type.include? "unsigned"
13
- else
14
- @unsigned = false
15
- end
16
- super(name, default, sql_type, null, collation)
17
- end
18
- end
19
-
20
- end
21
- end
22
- end
@@ -1,36 +0,0 @@
1
- require 'active_record/connection_adapters/abstract/schema_dumper'
2
-
3
- module ActiveRecord
4
- module ConnectionAdapters # :nodoc:
5
-
6
- module ColumnDumper
7
-
8
- def prepare_column_options(column, types)
9
- spec = {}
10
- #binding.pry if column.name.include?("ip")
11
- spec[:name] = column.name.inspect
12
-
13
- # AR has an optimization which handles zero-scale decimals as integers. This
14
- # code ensures that the dumper still dumps the column as a decimal.
15
- spec[:type] = if column.type == :integer && /^(numeric|decimal)/ =~ column.sql_type
16
- 'decimal'
17
- else
18
- column.type.to_s
19
- end
20
- spec[:limit] = column.limit.inspect if column.limit != types[column.type][:limit] && spec[:type] != 'decimal'
21
- spec[:precision] = column.precision.inspect if column.precision
22
- spec[:scale] = column.scale.inspect if column.scale
23
- spec[:null] = 'false' unless column.null
24
- spec[:unsigned] = 'true' if column.unsigned
25
- spec[:default] = default_string(column.default) if column.has_default?
26
- spec
27
- end
28
- # Lists the valid migration options
29
- def migration_keys
30
- [:name, :limit, :precision, :unsigned, :scale, :default, :null]
31
- end
32
-
33
- end
34
-
35
- end
36
- end
@@ -1,35 +0,0 @@
1
- require 'active_record/connection_adapters/abstract/schema_statements'
2
-
3
- module ActiveRecord
4
- module ConnectionAdapters
5
- module SchemaStatements
6
-
7
- def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = nil)
8
- if native = native_database_types[type.to_sym]
9
- column_type_sql = (native.is_a?(Hash) ? native[:name] : native).dup
10
-
11
- if type == :decimal
12
- scale ||= native[:scale]
13
-
14
- if precision ||= native[:precision]
15
- if scale
16
- column_type_sql << "(#{precision},#{scale})"
17
- else
18
- column_type_sql << "(#{precision})"
19
- end
20
- elsif scale
21
- raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale is specified"
22
- end
23
- elsif (type != :primary_key) && (limit ||= native.is_a?(Hash) && native[:limit])
24
- column_type_sql << "(#{limit})"
25
- end
26
-
27
- column_type_sql
28
- else
29
- type
30
- end
31
- end
32
-
33
- end
34
- end
35
- end
@@ -1,28 +0,0 @@
1
- require 'active_record/connection_adapters/abstract_adapter'
2
-
3
- module ActiveRecord
4
- module ConnectionAdapters
5
- class AbstractAdapter
6
-
7
- class SchemaCreation
8
- def visit_AddColumn(o)
9
- sql_type = type_to_sql(o.type.to_sym, o.limit, o.precision, o.scale, o.unsigned)
10
- sql = "ADD #{quote_column_name(o.name)} #{sql_type}"
11
- add_column_options!(sql, column_options(o))
12
- end
13
-
14
- def visit_ColumnDefinition(o)
15
- sql_type = type_to_sql(o.type.to_sym, o.limit, o.precision, o.scale, o.unsigned)
16
- column_sql = "#{quote_column_name(o.name)} #{sql_type}"
17
- add_column_options!(column_sql, column_options(o)) unless o.primary_key?
18
- column_sql
19
- end
20
-
21
- def type_to_sql(type, limit, precision, scale, unsigned)
22
- @conn.type_to_sql type.to_sym, limit, precision, scale, unsigned
23
- end
24
- end
25
-
26
- end
27
- end
28
- end
@@ -1,22 +0,0 @@
1
- require 'active_record/connection_adapters/mysql2_adapter'
2
-
3
- module ActiveRecord
4
- module ConnectionAdapters
5
- class Mysql2Adapter < AbstractMysqlAdapter
6
-
7
- class Column < AbstractMysqlAdapter::Column
8
- attr_reader :unsigned
9
-
10
- def initialize(name, default, sql_type = nil, null = true, collation = nil, strict = false, extra = "")
11
- if sql_type.present?
12
- @unsigned = sql_type.include? "unsigned"
13
- else
14
- @unsigned = false
15
- end
16
- super(name, default, sql_type, null, collation, strict, extra)
17
- end
18
- end
19
-
20
- end
21
- end
22
- end
@@ -1,40 +0,0 @@
1
- require 'active_record/connection_adapters/abstract/schema_definitions'
2
-
3
- module ActiveRecord
4
- module ConnectionAdapters
5
- class ColumnDefinition
6
-
7
- def unsigned=(value)
8
- @unsigned = value
9
- end
10
-
11
- def unsigned
12
- @unsigned
13
- end
14
-
15
- end
16
-
17
- class TableDefinition
18
-
19
- def new_column_definition(name, type, options)
20
- column = create_column_definition name, type
21
- limit = options.fetch(:limit) do
22
- native[type][:limit] if native[type].is_a?(Hash)
23
- end
24
-
25
- column.limit = limit
26
- column.array = options[:array] if column.respond_to?(:array)
27
- column.precision = options[:precision]
28
- column.scale = options[:scale]
29
- column.unsigned = options[:unsigned]
30
- column.default = options[:default]
31
- column.null = options[:null]
32
- column.first = options[:first]
33
- column.after = options[:after]
34
- column.primary_key = type == :primary_key || options[:primary_key]
35
- column
36
- end
37
-
38
- end
39
- end
40
- end
@@ -1,35 +0,0 @@
1
- require 'active_record/connection_adapters/abstract/schema_dumper'
2
-
3
- module ActiveRecord
4
- module ConnectionAdapters # :nodoc:
5
- module ColumnDumper
6
-
7
- def prepare_column_options(column, types)
8
- spec = {}
9
- #binding.pry if column.name.include?("ip")
10
- spec[:name] = column.name.inspect
11
-
12
- # AR has an optimization which handles zero-scale decimals as integers. This
13
- # code ensures that the dumper still dumps the column as a decimal.
14
- spec[:type] = if column.type == :integer && /^(numeric|decimal)/ =~ column.sql_type
15
- 'decimal'
16
- else
17
- column.type.to_s
18
- end
19
- spec[:limit] = column.limit.inspect if column.limit != types[column.type][:limit] && spec[:type] != 'decimal'
20
- spec[:precision] = column.precision.inspect if column.precision
21
- spec[:scale] = column.scale.inspect if column.scale
22
- spec[:null] = 'false' unless column.null
23
- spec[:unsigned] = 'true' if column.unsigned
24
- spec[:default] = default_string(column.default) if column.has_default?
25
- spec
26
- end
27
-
28
- # Lists the valid migration options
29
- def migration_keys
30
- [:name, :limit, :precision, :unsigned, :scale, :default, :null]
31
- end
32
-
33
- end
34
- end
35
- end
@@ -1,35 +0,0 @@
1
- require 'active_record/connection_adapters/abstract/schema_statements'
2
-
3
- module ActiveRecord
4
- module ConnectionAdapters
5
- module SchemaStatements
6
-
7
- def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = nil)
8
- if native = native_database_types[type.to_sym]
9
- column_type_sql = (native.is_a?(Hash) ? native[:name] : native).dup
10
-
11
- if type == :decimal
12
- scale ||= native[:scale]
13
-
14
- if precision ||= native[:precision]
15
- if scale
16
- column_type_sql << "(#{precision},#{scale})"
17
- else
18
- column_type_sql << "(#{precision})"
19
- end
20
- elsif scale
21
- raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale is specified"
22
- end
23
- elsif (type != :primary_key) && (limit ||= native.is_a?(Hash) && native[:limit])
24
- column_type_sql << "(#{limit})"
25
- end
26
-
27
- column_type_sql
28
- else
29
- type
30
- end
31
- end
32
-
33
- end
34
- end
35
- end
@@ -1,98 +0,0 @@
1
- require 'forwardable'
2
- require 'active_record/connection_adapters/abstract_mysql_adapter'
3
-
4
- module ActiveRecord
5
- module ConnectionAdapters
6
- class AbstractMysqlAdapter < AbstractAdapter
7
-
8
- class SchemaCreation < AbstractAdapter::SchemaCreation
9
- extend Forwardable
10
- def visit_AddColumn(o)
11
- sql_type = type_to_sql(o.type.to_sym, o.limit, o.precision, o.scale, o.unsigned)
12
- sql = "ADD #{quote_column_name(o.name)} #{sql_type}"
13
- add_column_position!(
14
- add_column_options!(sql, column_options(o)),
15
- column_options(o)
16
- )
17
- end
18
-
19
- def visit_ChangeColumnDefinition(o)
20
- column = o.column
21
- options = o.options
22
- sql_type = type_to_sql(o.type, options[:limit], options[:precision], options[:scale], options[:unsigned])
23
- change_column_sql = "CHANGE #{quote_column_name(column.name)} #{quote_column_name(options[:name])} #{sql_type}"
24
- add_column_options!(change_column_sql, options.merge(column: column))
25
- add_column_position!(change_column_sql, options)
26
- end
27
-
28
- def visit_ColumnDefinition(o)
29
- sql_type = type_to_sql(o.type.to_sym, o.limit, o.precision, o.scale, o.unsigned)
30
- column_sql = "#{quote_column_name(o.name)} #{sql_type}"
31
- add_column_options!(column_sql, column_options(o)) unless o.primary_key?
32
- column_sql
33
- end
34
-
35
- def_delegator :@conn, :type_to_sql, :type_to_sql
36
- end
37
-
38
- NATIVE_DATABASE_TYPES.merge!(
39
- :primary_key => "int(10) unsigned DEFAULT NULL auto_increment PRIMARY KEY"
40
- )
41
-
42
- # Maps logical Rails types to MySQL-specific data types.
43
- def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = false)
44
- # return earlier, only need overwrite method when unsigned option == true
45
- return super unless unsigned
46
-
47
-
48
- case type.to_s
49
- when 'decimal'
50
- # copy from rails core
51
- # https://github.com/rails/rails/blob/600aaf4234c80064201ee34ddabed216b91559db/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
52
- native = native_database_types[type.to_sym]
53
- column_type_sql = (native.is_a?(Hash) ? native[:name] : native).dup
54
-
55
- scale ||= native[:scale]
56
-
57
- if precision ||= native[:precision]
58
- if scale
59
- column_type_sql << "(#{precision},#{scale}) unsigned"
60
- else
61
- column_type_sql << "(#{precision}) unsigned"
62
- end
63
- elsif scale
64
- raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale is specified"
65
- end
66
- when 'binary'
67
- case limit
68
- when 0..0xfff; "varbinary(#{limit})"
69
- when nil; "blob"
70
- when 0x1000..0xffffffff; "blob(#{limit})"
71
- else raise(ActiveRecordError, "No binary type has character length #{limit}")
72
- end
73
- when 'integer'
74
- case limit
75
- when 1
76
- 'tinyint' + (unsigned ? ' unsigned' : '')
77
- when 2
78
- 'smallint' + (unsigned ? ' unsigned' : '')
79
- when 3
80
- 'mediumint' + (unsigned ? ' unsigned' : '')
81
- when nil, 4, 11 # compatibility with MySQL default
82
- if unsigned
83
- 'int(10) unsigned'
84
- else
85
- 'int(10)'
86
- end
87
- when 5..8
88
- 'bigint' + (unsigned ? ' unsigned' : '')
89
- else raise(ActiveRecordError, "No integer type has byte size #{limit}")
90
- end
91
- else
92
- super
93
- end
94
- end
95
-
96
- end
97
- end
98
- end
@@ -1,22 +0,0 @@
1
- require 'active_record/connection_adapters/mysql2_adapter'
2
-
3
- module ActiveRecord
4
- module ConnectionAdapters
5
- class Mysql2Adapter < AbstractMysqlAdapter
6
-
7
- class Column < AbstractMysqlAdapter::Column
8
- attr_reader :unsigned
9
-
10
- def initialize(name, default, sql_type = nil, null = true, collation = nil, strict = false, extra = "")
11
- if sql_type.present?
12
- @unsigned = sql_type.include? "unsigned"
13
- else
14
- @unsigned = false
15
- end
16
- super(name, default, sql_type, null, collation, strict, extra)
17
- end
18
- end
19
-
20
- end
21
- end
22
- end