activerecord-mysql-awesome 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/activerecord-mysql-awesome.gemspec +1 -1
- data/lib/activerecord-mysql-awesome/active_record/connection_adapters/abstract_mysql_adapter.rb +95 -75
- data/lib/activerecord/mysql/awesome/version.rb +1 -1
- data/test/cases/date_time_precision_test.rb +100 -0
- data/test/cases/primary_keys_test.rb +65 -0
- data/test/cases/time_precision_test.rb +96 -0
- data/test/cases/unsigned_type_test.rb +18 -4
- metadata +10 -8
- data/test/cases/datetime_test.rb +0 -98
- data/test/cases/primary_key_any_type_test.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 61fbabfdb8b2dbef3e83d6ffbc24e95550aa1822
|
4
|
+
data.tar.gz: 3963c7f71541e73241acc40f8b6745e6821134ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9d4eac2a815ed770221b9c9f0df096603534003dbf15e939fcd868ec7ed7a43974cfd02eec72782ffbe340062c63216f2582afdcb533c41c6240c64757b3ea2
|
7
|
+
data.tar.gz: e436050985e009b96b3aefcb60b5a619519f98a3be5154fefe2f7ae593f443fc007076808695c9bcc53b8ab4e83f9d21c4e59aba00fbd221e485623c2b22f1cd
|
@@ -24,5 +24,5 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency "rake", "~> 10.0"
|
25
25
|
spec.add_runtime_dependency "activesupport", "~> 4.0"
|
26
26
|
spec.add_runtime_dependency "activerecord", "~> 4.0"
|
27
|
-
spec.add_runtime_dependency "mysql2"
|
27
|
+
spec.add_runtime_dependency "mysql2", ">= 0.3.18"
|
28
28
|
end
|
data/lib/activerecord-mysql-awesome/active_record/connection_adapters/abstract_mysql_adapter.rb
CHANGED
@@ -3,7 +3,18 @@ require 'active_record/connection_adapters/abstract_mysql_adapter'
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Mysql
|
5
5
|
module Awesome
|
6
|
-
class ChangeColumnDefinition < Struct.new(:column, :name)
|
6
|
+
class ChangeColumnDefinition < Struct.new(:column, :name)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ColumnMethods
|
10
|
+
def primary_key(name, type = :primary_key, **options)
|
11
|
+
options[:auto_increment] = true if type == :bigint
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def unsigned_integer(*args, **options)
|
16
|
+
args.each { |name| column(name, :unsigned_integer, options) }
|
17
|
+
end
|
7
18
|
end
|
8
19
|
|
9
20
|
class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition
|
@@ -11,21 +22,26 @@ module ActiveRecord
|
|
11
22
|
end
|
12
23
|
|
13
24
|
class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
|
25
|
+
include ColumnMethods
|
26
|
+
|
14
27
|
def initialize(types, name, temporary, options, as = nil)
|
15
28
|
super(types, name, temporary, options)
|
16
29
|
@as = as
|
17
30
|
end
|
18
31
|
|
19
|
-
def
|
20
|
-
options[:auto_increment] ||= type == :bigint
|
21
|
-
super
|
22
|
-
end
|
23
|
-
|
24
|
-
def new_column_definition(name, type, options) # :nodoc:
|
32
|
+
def new_column_definition(name, type, options)
|
25
33
|
column = super
|
26
|
-
column.
|
27
|
-
|
28
|
-
|
34
|
+
case column.type
|
35
|
+
when :primary_key
|
36
|
+
column.type = :integer
|
37
|
+
column.auto_increment = true
|
38
|
+
when :unsigned_integer
|
39
|
+
column.type = :integer
|
40
|
+
column.unsigned = true
|
41
|
+
end
|
42
|
+
column.auto_increment ||= options[:auto_increment]
|
43
|
+
column.unsigned ||= options[:unsigned]
|
44
|
+
column.charset = options[:charset]
|
29
45
|
column.collation = options[:collation]
|
30
46
|
column
|
31
47
|
end
|
@@ -37,6 +53,10 @@ module ActiveRecord
|
|
37
53
|
end
|
38
54
|
end
|
39
55
|
|
56
|
+
class Table < ActiveRecord::ConnectionAdapters::Table
|
57
|
+
include ColumnMethods
|
58
|
+
end
|
59
|
+
|
40
60
|
module SchemaCreation
|
41
61
|
def visit_AddColumn(o)
|
42
62
|
add_column_position!("ADD #{accept(o)}", column_options(o))
|
@@ -89,11 +109,15 @@ module ActiveRecord
|
|
89
109
|
sql
|
90
110
|
end
|
91
111
|
|
92
|
-
def type_to_sql(type, limit, precision, scale, unsigned
|
112
|
+
def type_to_sql(type, limit, precision, scale, unsigned)
|
93
113
|
@conn.type_to_sql(type.to_sym, limit, precision, scale, unsigned)
|
94
114
|
end
|
95
115
|
end
|
96
116
|
|
117
|
+
def update_table_definition(table_name, base)
|
118
|
+
Table.new(table_name, base)
|
119
|
+
end
|
120
|
+
|
97
121
|
module Column
|
98
122
|
def unsigned?
|
99
123
|
sql_type =~ /unsigned/i
|
@@ -108,35 +132,36 @@ module ActiveRecord
|
|
108
132
|
end
|
109
133
|
end
|
110
134
|
|
111
|
-
|
112
|
-
|
113
|
-
return super unless column && column.type
|
135
|
+
def quote(value, column = nil)
|
136
|
+
return super unless column && /time/ === column.sql_type
|
114
137
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
result = value.to_s(:db)
|
121
|
-
precision = column.precision
|
122
|
-
case precision
|
123
|
-
when 1..6
|
124
|
-
"'#{result}.#{sprintf("%0#{precision}d", value.usec / 10**(6 - precision))}'"
|
125
|
-
else
|
126
|
-
"'#{result}'"
|
127
|
-
end
|
128
|
-
else
|
129
|
-
super
|
130
|
-
end
|
131
|
-
else
|
132
|
-
super
|
138
|
+
if value.acts_like?(:time)
|
139
|
+
zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
|
140
|
+
|
141
|
+
if value.respond_to?(zone_conversion_method)
|
142
|
+
value = value.send(zone_conversion_method)
|
133
143
|
end
|
134
144
|
end
|
135
145
|
|
146
|
+
if (precision = column.precision) && value.respond_to?(:usec)
|
147
|
+
number_of_insignificant_digits = 6 - precision
|
148
|
+
round_power = 10 ** number_of_insignificant_digits
|
149
|
+
value = value.change(usec: value.usec / round_power * round_power)
|
150
|
+
end
|
151
|
+
|
152
|
+
result = value.to_s(:db)
|
153
|
+
if value.respond_to?(:usec) && value.usec > 0
|
154
|
+
"'#{result}.#{sprintf("%06d", value.usec)}'"
|
155
|
+
else
|
156
|
+
"'#{result}'"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
if ActiveRecord::VERSION::STRING < "4.2.0"
|
136
161
|
module Column
|
137
162
|
def extract_limit(sql_type)
|
138
163
|
case sql_type
|
139
|
-
when
|
164
|
+
when /time/i; nil
|
140
165
|
else
|
141
166
|
super
|
142
167
|
end
|
@@ -144,8 +169,12 @@ module ActiveRecord
|
|
144
169
|
|
145
170
|
def extract_precision(sql_type)
|
146
171
|
case sql_type
|
147
|
-
when
|
148
|
-
|
172
|
+
when /time/i
|
173
|
+
if sql_type =~ /\((\d+)(,\d+)?\)/
|
174
|
+
$1.to_i
|
175
|
+
else
|
176
|
+
0
|
177
|
+
end
|
149
178
|
else
|
150
179
|
super
|
151
180
|
end
|
@@ -156,8 +185,8 @@ module ActiveRecord
|
|
156
185
|
|
157
186
|
def initialize_type_map(m) # :nodoc:
|
158
187
|
super
|
159
|
-
register_class_with_precision m, %r(time)i,
|
160
|
-
register_class_with_precision m, %r(datetime)i,
|
188
|
+
register_class_with_precision m, %r(time)i, Type::Time
|
189
|
+
register_class_with_precision m, %r(datetime)i, Type::DateTime
|
161
190
|
end
|
162
191
|
|
163
192
|
def register_class_with_precision(mapping, key, klass) # :nodoc:
|
@@ -167,59 +196,41 @@ module ActiveRecord
|
|
167
196
|
end
|
168
197
|
end
|
169
198
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
|
176
|
-
value = value.send(zone_conversion_method) if value.respond_to?(zone_conversion_method)
|
177
|
-
result = value.to_s(:db)
|
178
|
-
case precision
|
179
|
-
when 1..6
|
180
|
-
"#{result}.#{sprintf("%0#{precision}d", value.usec / 10**(6 - precision))}"
|
181
|
-
else
|
182
|
-
result
|
183
|
-
end
|
184
|
-
else
|
185
|
-
super
|
186
|
-
end
|
199
|
+
def extract_precision(sql_type)
|
200
|
+
if /time/ === sql_type
|
201
|
+
super || 0
|
202
|
+
else
|
203
|
+
super
|
187
204
|
end
|
188
205
|
end
|
189
|
-
|
190
|
-
class MysqlTime < Type::Time # :nodoc:
|
191
|
-
include TimeValueWithPrecision
|
192
|
-
end
|
193
|
-
|
194
|
-
class MysqlDateTime < Type::DateTime # :nodoc:
|
195
|
-
include TimeValueWithPrecision
|
196
|
-
end
|
197
206
|
end
|
198
207
|
|
199
208
|
public
|
200
209
|
|
210
|
+
def supports_datetime_with_precision?
|
211
|
+
(version[0] == 5 && version[1] >= 6) || version[0] >= 6
|
212
|
+
end
|
213
|
+
|
201
214
|
def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = false)
|
202
|
-
|
203
|
-
|
204
|
-
when 'integer'
|
215
|
+
sql = case type
|
216
|
+
when :integer
|
205
217
|
case limit
|
206
218
|
when nil, 4, 11; 'int' # compatibility with MySQL default
|
207
219
|
else
|
208
220
|
super(type, limit, precision, scale)
|
209
221
|
end
|
210
|
-
when
|
211
|
-
"#{type_to_sql(:integer, limit, precision, scale, unsigned)} auto_increment PRIMARY KEY"
|
212
|
-
when 'datetime', 'time'
|
213
|
-
return super(type, limit, precision, scale) unless precision
|
214
|
-
|
215
|
-
native_type = native_database_types[type.to_sym][:name]
|
222
|
+
when :datetime, :time
|
216
223
|
case precision
|
217
|
-
when
|
218
|
-
|
224
|
+
when nil; super(type, limit, precision, scale)
|
225
|
+
when 0..6; "#{type}(#{precision})"
|
226
|
+
else raise(ActiveRecordError, "No #{type} type has precision of #{precision}. The allowed range of precision is from 0 to 6")
|
219
227
|
end
|
220
228
|
else
|
221
229
|
super(type, limit, precision, scale)
|
222
230
|
end
|
231
|
+
|
232
|
+
sql << ' unsigned' if unsigned && type != :primary_key
|
233
|
+
sql
|
223
234
|
end
|
224
235
|
|
225
236
|
def options_for_column_spec(table_name)
|
@@ -233,8 +244,9 @@ module ActiveRecord
|
|
233
244
|
def column_spec_for_primary_key(column, options)
|
234
245
|
spec = {}
|
235
246
|
if column.auto_increment?
|
236
|
-
|
237
|
-
spec[:
|
247
|
+
spec[:id] = ':bigint' if column.bigint?
|
248
|
+
spec[:unsigned] = 'true' if column.unsigned?
|
249
|
+
return if spec.empty?
|
238
250
|
else
|
239
251
|
spec[:id] = column.type.inspect
|
240
252
|
spec.merge!(prepare_column_options(column, options).delete_if { |key, _| [:name, :type, :null].include?(key) })
|
@@ -244,6 +256,8 @@ module ActiveRecord
|
|
244
256
|
|
245
257
|
def prepare_column_options(column, options) # :nodoc:
|
246
258
|
spec = super
|
259
|
+
spec.delete(:precision) if /time/ === column.sql_type && column.precision == 0
|
260
|
+
spec.delete(:limit) if :boolean === column.type
|
247
261
|
spec[:unsigned] = 'true' if column.unsigned?
|
248
262
|
if column.collation && column.collation != options[:collation]
|
249
263
|
spec[:collation] = column.collation.inspect
|
@@ -265,6 +279,12 @@ module ActiveRecord
|
|
265
279
|
raw_table_options.sub(/(ENGINE=\w+)(?: AUTO_INCREMENT=\d+)/, '\1')
|
266
280
|
end
|
267
281
|
|
282
|
+
def drop_table(table_name, options = {})
|
283
|
+
execute "DROP#{' TEMPORARY' if options[:temporary]} TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
|
284
|
+
end
|
285
|
+
|
286
|
+
protected
|
287
|
+
|
268
288
|
def add_column_sql(table_name, column_name, type, options = {})
|
269
289
|
td = create_table_definition(table_name)
|
270
290
|
cd = td.new_column_definition(column_name, type, options)
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'cases/helper'
|
2
|
+
require 'support/schema_dumping_helper'
|
3
|
+
|
4
|
+
if ActiveRecord::Base.connection.supports_datetime_with_precision?
|
5
|
+
class DateTimePrecisionTest < ActiveRecord::TestCase
|
6
|
+
include SchemaDumpingHelper
|
7
|
+
|
8
|
+
class Foo < ActiveRecord::Base; end
|
9
|
+
|
10
|
+
setup do
|
11
|
+
@connection = ActiveRecord::Base.connection
|
12
|
+
end
|
13
|
+
|
14
|
+
teardown do
|
15
|
+
@connection.schema_cache.clear!
|
16
|
+
@connection.drop_table :foos, if_exists: true
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_datetime_data_type_with_precision
|
20
|
+
@connection.create_table(:foos, force: true)
|
21
|
+
@connection.add_column :foos, :created_at, :datetime, precision: 0
|
22
|
+
@connection.add_column :foos, :updated_at, :datetime, precision: 5
|
23
|
+
assert_equal 0, activerecord_column_option('foos', 'created_at', 'precision')
|
24
|
+
assert_equal 5, activerecord_column_option('foos', 'updated_at', 'precision')
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_timestamps_helper_with_custom_precision
|
28
|
+
@connection.create_table(:foos, force: true) do |t|
|
29
|
+
t.timestamps null: false, precision: 4
|
30
|
+
end
|
31
|
+
assert_equal 4, activerecord_column_option('foos', 'created_at', 'precision')
|
32
|
+
assert_equal 4, activerecord_column_option('foos', 'updated_at', 'precision')
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_passing_precision_to_datetime_does_not_set_limit
|
36
|
+
@connection.create_table(:foos, force: true) do |t|
|
37
|
+
t.timestamps null: false, precision: 4
|
38
|
+
end
|
39
|
+
assert_nil activerecord_column_option('foos', 'created_at', 'limit')
|
40
|
+
assert_nil activerecord_column_option('foos', 'updated_at', 'limit')
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_invalid_datetime_precision_raises_error
|
44
|
+
assert_raises ActiveRecord::ActiveRecordError do
|
45
|
+
@connection.create_table(:foos, force: true) do |t|
|
46
|
+
t.timestamps null: false, precision: 7
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_database_agrees_with_activerecord_about_precision
|
52
|
+
@connection.create_table(:foos, force: true) do |t|
|
53
|
+
t.timestamps null: false, precision: 4
|
54
|
+
end
|
55
|
+
assert_equal 4, database_datetime_precision('foos', 'created_at')
|
56
|
+
assert_equal 4, database_datetime_precision('foos', 'updated_at')
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_formatting_datetime_according_to_precision
|
60
|
+
@connection.create_table(:foos, force: true) do |t|
|
61
|
+
t.datetime :created_at, precision: 0
|
62
|
+
t.datetime :updated_at, precision: 4
|
63
|
+
end
|
64
|
+
date = ::Time.utc(2014, 8, 17, 12, 30, 0, 999999)
|
65
|
+
Foo.create!(created_at: date, updated_at: date)
|
66
|
+
assert foo = Foo.find_by(created_at: date)
|
67
|
+
assert_equal 1, Foo.where(updated_at: date).count
|
68
|
+
assert_equal date.to_s, foo.created_at.to_s
|
69
|
+
assert_equal date.to_s, foo.updated_at.to_s
|
70
|
+
assert_equal 000000, foo.created_at.usec
|
71
|
+
assert_equal 999900, foo.updated_at.usec
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_schema_dump_includes_datetime_precision
|
75
|
+
@connection.create_table(:foos, force: true) do |t|
|
76
|
+
t.timestamps null: false, precision: 6
|
77
|
+
end
|
78
|
+
output = dump_table_schema("foos")
|
79
|
+
assert_match %r{t\.datetime\s+"created_at",\s+precision: 6,\s+null: false$}, output
|
80
|
+
assert_match %r{t\.datetime\s+"updated_at",\s+precision: 6,\s+null: false$}, output
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def database_datetime_precision(table_name, column_name)
|
86
|
+
results = @connection.exec_query("SELECT column_name, datetime_precision FROM information_schema.columns WHERE table_name = '#{table_name}'")
|
87
|
+
result = results.find do |result_hash|
|
88
|
+
result_hash["column_name"] == column_name
|
89
|
+
end
|
90
|
+
result && result["datetime_precision"].to_i
|
91
|
+
end
|
92
|
+
|
93
|
+
def activerecord_column_option(tablename, column_name, option)
|
94
|
+
result = @connection.columns(tablename).find do |column|
|
95
|
+
column.name == column_name
|
96
|
+
end
|
97
|
+
result && result.send(option)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,65 @@
|
|
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.drop_table 'barcodes', if_exists: true
|
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
|
32
|
+
|
33
|
+
class PrimaryKeyBigSerialTest < ActiveRecord::TestCase
|
34
|
+
include SchemaDumpingHelper
|
35
|
+
|
36
|
+
class Widget < ActiveRecord::Base
|
37
|
+
end
|
38
|
+
|
39
|
+
setup do
|
40
|
+
@connection = ActiveRecord::Base.connection
|
41
|
+
@connection.create_table(:widgets, id: :bigint, unsigned: true, force: true)
|
42
|
+
end
|
43
|
+
|
44
|
+
teardown do
|
45
|
+
@connection.drop_table 'widgets', if_exists: true
|
46
|
+
end
|
47
|
+
|
48
|
+
test "primary key column type with bigint" do
|
49
|
+
column = @connection.columns(:widgets).find { |c| c.name == 'id' }
|
50
|
+
assert column.auto_increment?
|
51
|
+
assert_equal :integer, column.type
|
52
|
+
assert_equal 8, column.limit
|
53
|
+
assert column.unsigned?
|
54
|
+
end
|
55
|
+
|
56
|
+
test "primary key with bigserial are automatically numbered" do
|
57
|
+
widget = Widget.create!
|
58
|
+
assert_not_nil widget.id
|
59
|
+
end
|
60
|
+
|
61
|
+
test "schema dump primary key with bigint" do
|
62
|
+
schema = dump_table_schema "widgets"
|
63
|
+
assert_match %r{create_table "widgets", id: :bigint, unsigned: true}, schema
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'cases/helper'
|
2
|
+
require 'support/schema_dumping_helper'
|
3
|
+
|
4
|
+
if ActiveRecord::Base.connection.supports_datetime_with_precision?
|
5
|
+
class TimePrecisionTest < ActiveRecord::TestCase
|
6
|
+
include SchemaDumpingHelper
|
7
|
+
|
8
|
+
class Foo < ActiveRecord::Base; end
|
9
|
+
|
10
|
+
setup do
|
11
|
+
@connection = ActiveRecord::Base.connection
|
12
|
+
end
|
13
|
+
|
14
|
+
teardown do
|
15
|
+
@connection.schema_cache.clear!
|
16
|
+
@connection.drop_table :foos, if_exists: true
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_time_data_type_with_precision
|
20
|
+
@connection.create_table(:foos, force: true)
|
21
|
+
@connection.add_column :foos, :start, :time, precision: 3
|
22
|
+
@connection.add_column :foos, :finish, :time, precision: 6
|
23
|
+
assert_equal 3, activerecord_column_option('foos', 'start', 'precision')
|
24
|
+
assert_equal 6, activerecord_column_option('foos', 'finish', 'precision')
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_passing_precision_to_time_does_not_set_limit
|
28
|
+
@connection.create_table(:foos, force: true) do |t|
|
29
|
+
t.time :start, precision: 3
|
30
|
+
t.time :finish, precision: 6
|
31
|
+
end
|
32
|
+
assert_nil activerecord_column_option('foos', 'start', 'limit')
|
33
|
+
assert_nil activerecord_column_option('foos', 'finish', 'limit')
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_invalid_time_precision_raises_error
|
37
|
+
assert_raises ActiveRecord::ActiveRecordError do
|
38
|
+
@connection.create_table(:foos, force: true) do |t|
|
39
|
+
t.time :start, precision: 7
|
40
|
+
t.time :finish, precision: 7
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_database_agrees_with_activerecord_about_precision
|
46
|
+
@connection.create_table(:foos, force: true) do |t|
|
47
|
+
t.time :start, precision: 2
|
48
|
+
t.time :finish, precision: 4
|
49
|
+
end
|
50
|
+
assert_equal 2, database_datetime_precision('foos', 'start')
|
51
|
+
assert_equal 4, database_datetime_precision('foos', 'finish')
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_formatting_time_according_to_precision
|
55
|
+
@connection.create_table(:foos, force: true) do |t|
|
56
|
+
t.time :start, precision: 0
|
57
|
+
t.time :finish, precision: 4
|
58
|
+
end
|
59
|
+
time = ::Time.utc(2000, 1, 1, 12, 30, 0, 999999)
|
60
|
+
Foo.create!(start: time, finish: time)
|
61
|
+
assert foo = Foo.find_by(start: time)
|
62
|
+
assert_equal 1, Foo.where(finish: time).count
|
63
|
+
assert_equal time.to_s, foo.start.to_s
|
64
|
+
assert_equal time.to_s, foo.finish.to_s
|
65
|
+
assert_equal 000000, foo.start.usec
|
66
|
+
assert_equal 999900, foo.finish.usec
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_schema_dump_includes_time_precision
|
70
|
+
@connection.create_table(:foos, force: true) do |t|
|
71
|
+
t.time :start, precision: 4
|
72
|
+
t.time :finish, precision: 6
|
73
|
+
end
|
74
|
+
output = dump_table_schema("foos")
|
75
|
+
assert_match %r{t\.time\s+"start",\s+precision: 4$}, output
|
76
|
+
assert_match %r{t\.time\s+"finish",\s+precision: 6$}, output
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def database_datetime_precision(table_name, column_name)
|
82
|
+
results = @connection.exec_query("SELECT column_name, datetime_precision FROM information_schema.columns WHERE table_name = '#{table_name}'")
|
83
|
+
result = results.find do |result_hash|
|
84
|
+
result_hash["column_name"] == column_name
|
85
|
+
end
|
86
|
+
result && result["datetime_precision"].to_i
|
87
|
+
end
|
88
|
+
|
89
|
+
def activerecord_column_option(tablename, column_name, option)
|
90
|
+
result = @connection.columns(tablename).find do |column|
|
91
|
+
column.name == column_name
|
92
|
+
end
|
93
|
+
result && result.send(option)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -10,7 +10,6 @@ class UnsignedTypeTest < ActiveRecord::TestCase
|
|
10
10
|
setup do
|
11
11
|
@connection = ActiveRecord::Base.connection
|
12
12
|
@connection.create_table("unsigned_types", force: true) do |t|
|
13
|
-
t.column :unsigned_integer, "int unsigned"
|
14
13
|
t.integer :unsigned_integer, unsigned: true
|
15
14
|
t.float :unsigned_float, unsigned: true
|
16
15
|
t.decimal :unsigned_decimal, unsigned: true, precision: 10, scale: 2
|
@@ -18,10 +17,15 @@ class UnsignedTypeTest < ActiveRecord::TestCase
|
|
18
17
|
end
|
19
18
|
|
20
19
|
teardown do
|
21
|
-
|
20
|
+
@connection.drop_table "unsigned_types", if_exists: true
|
22
21
|
end
|
23
22
|
|
24
|
-
|
23
|
+
test "unsigned int max value is in range" do
|
24
|
+
assert expected = UnsignedType.create(unsigned_integer: 4294967295)
|
25
|
+
assert_equal expected, UnsignedType.find_by(unsigned_integer: 4294967295)
|
26
|
+
end
|
27
|
+
|
28
|
+
test "minus value is out of range" do
|
25
29
|
assert_raise(ActiveRecord::StatementInvalid, RangeError) do
|
26
30
|
UnsignedType.create(unsigned_integer: -10)
|
27
31
|
end
|
@@ -33,7 +37,17 @@ class UnsignedTypeTest < ActiveRecord::TestCase
|
|
33
37
|
end
|
34
38
|
end
|
35
39
|
|
36
|
-
|
40
|
+
test "schema definition can use unsigned_integer type" do
|
41
|
+
@connection.change_table("unsigned_types") do |t|
|
42
|
+
t.unsigned_integer :unsigned_number
|
43
|
+
end
|
44
|
+
|
45
|
+
column = @connection.columns("unsigned_types").find { |c| c.name == 'unsigned_number' }
|
46
|
+
assert_equal :integer, column.type
|
47
|
+
assert column.unsigned?
|
48
|
+
end
|
49
|
+
|
50
|
+
test "schema dump includes unsigned option" do
|
37
51
|
schema = dump_table_schema "unsigned_types"
|
38
52
|
assert_match %r{t.integer\s+"unsigned_integer",(?:\s+limit: 4,)?\s+unsigned: true$}, schema
|
39
53
|
assert_match %r{t.float\s+"unsigned_float",(?:\s+limit: 24,)?\s+unsigned: true$}, schema
|
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.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryuta Kamizono
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 0.3.18
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 0.3.18
|
83
83
|
description: Awesome patches backported for ActiveRecord MySQL adapters
|
84
84
|
email:
|
85
85
|
- kamipo@gmail.com
|
@@ -105,12 +105,13 @@ files:
|
|
105
105
|
- test/.gitignore
|
106
106
|
- test/cases/bigint_pk_test.rb
|
107
107
|
- test/cases/charset_collation_test.rb
|
108
|
-
- test/cases/
|
108
|
+
- test/cases/date_time_precision_test.rb
|
109
109
|
- test/cases/helper.rb
|
110
|
-
- test/cases/
|
110
|
+
- test/cases/primary_keys_test.rb
|
111
111
|
- test/cases/strict_mode_test.rb
|
112
112
|
- test/cases/table_options_test.rb
|
113
113
|
- test/cases/test_case.rb
|
114
|
+
- test/cases/time_precision_test.rb
|
114
115
|
- test/cases/unsigned_type_test.rb
|
115
116
|
- test/config.example.yml
|
116
117
|
- test/config.rb
|
@@ -146,12 +147,13 @@ test_files:
|
|
146
147
|
- test/.gitignore
|
147
148
|
- test/cases/bigint_pk_test.rb
|
148
149
|
- test/cases/charset_collation_test.rb
|
149
|
-
- test/cases/
|
150
|
+
- test/cases/date_time_precision_test.rb
|
150
151
|
- test/cases/helper.rb
|
151
|
-
- test/cases/
|
152
|
+
- test/cases/primary_keys_test.rb
|
152
153
|
- test/cases/strict_mode_test.rb
|
153
154
|
- test/cases/table_options_test.rb
|
154
155
|
- test/cases/test_case.rb
|
156
|
+
- test/cases/time_precision_test.rb
|
155
157
|
- test/cases/unsigned_type_test.rb
|
156
158
|
- test/config.example.yml
|
157
159
|
- test/config.rb
|
data/test/cases/datetime_test.rb
DELETED
@@ -1,98 +0,0 @@
|
|
1
|
-
require 'cases/helper'
|
2
|
-
require 'support/schema_dumping_helper'
|
3
|
-
|
4
|
-
if mysql_56?
|
5
|
-
class DateTimeTest < ActiveRecord::TestCase
|
6
|
-
include SchemaDumpingHelper
|
7
|
-
|
8
|
-
class Foo < ActiveRecord::Base; end
|
9
|
-
|
10
|
-
def test_default_datetime_precision
|
11
|
-
ActiveRecord::Base.connection.create_table(:foos, force: true)
|
12
|
-
ActiveRecord::Base.connection.add_column :foos, :created_at, :datetime
|
13
|
-
ActiveRecord::Base.connection.add_column :foos, :updated_at, :datetime
|
14
|
-
assert_nil activerecord_column_option('foos', 'created_at', 'precision')
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_datetime_data_type_with_precision
|
18
|
-
ActiveRecord::Base.connection.create_table(:foos, force: true)
|
19
|
-
ActiveRecord::Base.connection.add_column :foos, :created_at, :datetime, precision: 1
|
20
|
-
ActiveRecord::Base.connection.add_column :foos, :updated_at, :datetime, precision: 5
|
21
|
-
assert_equal 1, activerecord_column_option('foos', 'created_at', 'precision')
|
22
|
-
assert_equal 5, activerecord_column_option('foos', 'updated_at', 'precision')
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_timestamps_helper_with_custom_precision
|
26
|
-
ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
|
27
|
-
t.timestamps null: true, precision: 4
|
28
|
-
end
|
29
|
-
assert_equal 4, activerecord_column_option('foos', 'created_at', 'precision')
|
30
|
-
assert_equal 4, activerecord_column_option('foos', 'updated_at', 'precision')
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_passing_precision_to_datetime_does_not_set_limit
|
34
|
-
ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
|
35
|
-
t.timestamps null: true, precision: 4
|
36
|
-
end
|
37
|
-
assert_nil activerecord_column_option("foos", "created_at", "limit")
|
38
|
-
assert_nil activerecord_column_option("foos", "updated_at", "limit")
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_invalid_datetime_precision_raises_error
|
42
|
-
assert_raises ActiveRecord::ActiveRecordError do
|
43
|
-
ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
|
44
|
-
t.timestamps null: true, precision: 7
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def test_mysql_agrees_with_activerecord_about_precision
|
50
|
-
ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
|
51
|
-
t.timestamps null: true, precision: 4
|
52
|
-
end
|
53
|
-
assert_equal 4, mysql_datetime_precision('foos', 'created_at')
|
54
|
-
assert_equal 4, mysql_datetime_precision('foos', 'updated_at')
|
55
|
-
end
|
56
|
-
|
57
|
-
def test_datetime_format_according_to_precision
|
58
|
-
ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
|
59
|
-
t.datetime :created_at, precision: 0
|
60
|
-
t.datetime :updated_at, precision: 4
|
61
|
-
end
|
62
|
-
date = ::Time.utc(2014, 8, 17, 12, 30, 0, 999999)
|
63
|
-
Foo.create!(created_at: date, updated_at: date)
|
64
|
-
assert foo = Foo.find_by(created_at: date)
|
65
|
-
assert_equal date.to_s, foo.created_at.to_s
|
66
|
-
assert_equal date.to_s, foo.updated_at.to_s
|
67
|
-
assert_equal 000000, foo.created_at.usec
|
68
|
-
assert_equal 999900, foo.updated_at.usec
|
69
|
-
end
|
70
|
-
|
71
|
-
def test_schema_dump_includes_datetime_precision
|
72
|
-
ActiveRecord::Base.connection.create_table(:foos, force: true) do |t|
|
73
|
-
t.datetime :created_at, precision: 4
|
74
|
-
t.datetime :updated_at, precision: 6
|
75
|
-
end
|
76
|
-
schema = dump_table_schema "foos"
|
77
|
-
assert_match %r{t.datetime\s+"created_at",\s+precision: 4$}, schema
|
78
|
-
assert_match %r{t.datetime\s+"updated_at",\s+precision: 6$}, schema
|
79
|
-
end
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
def mysql_datetime_precision(table_name, column_name)
|
84
|
-
results = ActiveRecord::Base.connection.exec_query("SELECT column_name, datetime_precision FROM information_schema.columns WHERE table_name ='#{table_name}'")
|
85
|
-
result = results.find do |result_hash|
|
86
|
-
result_hash["column_name"] == column_name
|
87
|
-
end
|
88
|
-
result && result["datetime_precision"]
|
89
|
-
end
|
90
|
-
|
91
|
-
def activerecord_column_option(tablename, column_name, option)
|
92
|
-
result = ActiveRecord::Base.connection.columns(tablename).find do |column|
|
93
|
-
column.name == column_name
|
94
|
-
end
|
95
|
-
result && result.send(option)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
@@ -1,31 +0,0 @@
|
|
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
|