activerecord-mysql-unsigned 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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