activerecord-mysql-awesome 0.0.4 → 0.0.5
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.
- 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
|