activerecord 5.0.0.beta3 → 5.0.0.beta4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +225 -8
- data/examples/performance.rb +0 -1
- data/examples/simple.rb +0 -1
- data/lib/active_record.rb +0 -1
- data/lib/active_record/associations.rb +10 -6
- data/lib/active_record/associations/association.rb +1 -1
- data/lib/active_record/associations/builder/collection_association.rb +5 -1
- data/lib/active_record/associations/join_dependency.rb +1 -1
- data/lib/active_record/associations/preloader.rb +1 -0
- data/lib/active_record/associations/preloader/through_association.rb +15 -8
- data/lib/active_record/attribute/user_provided_default.rb +10 -5
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
- data/lib/active_record/attributes.rb +3 -3
- data/lib/active_record/autosave_association.rb +1 -1
- data/lib/active_record/base.rb +2 -1
- data/lib/active_record/collection_cache_key.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +0 -19
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +7 -8
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/quoting.rb +7 -1
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +16 -2
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +9 -4
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +20 -10
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +85 -20
- data/lib/active_record/connection_adapters/abstract/transaction.rb +13 -1
- data/lib/active_record/connection_adapters/abstract_adapter.rb +37 -16
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +119 -108
- data/lib/active_record/connection_adapters/column.rb +5 -6
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +125 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +27 -6
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -13
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +18 -55
- data/lib/active_record/connection_adapters/postgresql/column.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +7 -10
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +65 -25
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +59 -30
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +7 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +19 -56
- data/lib/active_record/connection_adapters/statement_pool.rb +6 -4
- data/lib/active_record/core.rb +13 -4
- data/lib/active_record/enum.rb +1 -1
- data/lib/active_record/errors.rb +9 -0
- data/lib/active_record/fixture_set/file.rb +7 -1
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +4 -0
- data/lib/active_record/log_subscriber.rb +1 -1
- data/lib/active_record/migration.rb +4 -4
- data/lib/active_record/migration/compatibility.rb +1 -1
- data/lib/active_record/model_schema.rb +12 -0
- data/lib/active_record/nested_attributes.rb +1 -1
- data/lib/active_record/persistence.rb +1 -1
- data/lib/active_record/query_cache.rb +13 -16
- data/lib/active_record/querying.rb +1 -1
- data/lib/active_record/railtie.rb +8 -11
- data/lib/active_record/railties/databases.rake +5 -5
- data/lib/active_record/reflection.rb +21 -4
- data/lib/active_record/relation.rb +10 -10
- data/lib/active_record/relation/batches.rb +29 -9
- data/lib/active_record/relation/delegation.rb +0 -1
- data/lib/active_record/relation/finder_methods.rb +27 -8
- data/lib/active_record/relation/predicate_builder.rb +4 -2
- data/lib/active_record/relation/where_clause.rb +2 -1
- data/lib/active_record/schema_dumper.rb +39 -24
- data/lib/active_record/scoping/default.rb +2 -1
- data/lib/active_record/suppressor.rb +5 -1
- data/lib/active_record/tasks/database_tasks.rb +6 -4
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/type.rb +1 -1
- data/lib/active_record/type/internal/abstract_json.rb +1 -5
- data/lib/active_record/type/time.rb +12 -0
- data/lib/active_record/validations/uniqueness.rb +1 -4
- data/lib/rails/generators/active_record/model/model_generator.rb +15 -11
- data/lib/rails/generators/active_record/model/templates/application_record.rb +2 -0
- metadata +11 -8
@@ -1,11 +1,9 @@
|
|
1
|
-
require 'set'
|
2
|
-
|
3
1
|
module ActiveRecord
|
4
2
|
# :stopdoc:
|
5
3
|
module ConnectionAdapters
|
6
4
|
# An abstract definition of a column in a table.
|
7
5
|
class Column
|
8
|
-
attr_reader :name, :
|
6
|
+
attr_reader :name, :default, :sql_type_metadata, :null, :table_name, :default_function, :collation, :comment
|
9
7
|
|
10
8
|
delegate :precision, :scale, :limit, :type, :sql_type, to: :sql_type_metadata, allow_nil: true
|
11
9
|
|
@@ -15,14 +13,15 @@ module ActiveRecord
|
|
15
13
|
# +default+ is the type-casted default value, such as +new+ in <tt>sales_stage varchar(20) default 'new'</tt>.
|
16
14
|
# +sql_type_metadata+ is various information about the type of the column
|
17
15
|
# +null+ determines if this column allows +NULL+ values.
|
18
|
-
def initialize(name, default, sql_type_metadata = nil, null = true, default_function = nil, collation = nil)
|
16
|
+
def initialize(name, default, sql_type_metadata = nil, null = true, table_name = nil, default_function = nil, collation = nil, comment: nil)
|
19
17
|
@name = name.freeze
|
18
|
+
@table_name = table_name
|
20
19
|
@sql_type_metadata = sql_type_metadata
|
21
20
|
@null = null
|
22
21
|
@default = default
|
23
22
|
@default_function = default_function
|
24
23
|
@collation = collation
|
25
|
-
@
|
24
|
+
@comment = comment
|
26
25
|
end
|
27
26
|
|
28
27
|
def has_default?
|
@@ -54,7 +53,7 @@ module ActiveRecord
|
|
54
53
|
protected
|
55
54
|
|
56
55
|
def attributes_for_hash
|
57
|
-
[self.class, name, default, sql_type_metadata, null, default_function, collation]
|
56
|
+
[self.class, name, default, sql_type_metadata, null, table_name, default_function, collation]
|
58
57
|
end
|
59
58
|
end
|
60
59
|
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
module MySQL
|
4
|
+
module DatabaseStatements
|
5
|
+
# Returns an ActiveRecord::Result instance.
|
6
|
+
def select_all(arel, name = nil, binds = [], preparable: nil)
|
7
|
+
result = if ExplainRegistry.collect? && prepared_statements
|
8
|
+
unprepared_statement { super }
|
9
|
+
else
|
10
|
+
super
|
11
|
+
end
|
12
|
+
@connection.next_result while @connection.more_results?
|
13
|
+
result
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns a record hash with the column names as keys and column values
|
17
|
+
# as values.
|
18
|
+
def select_one(arel, name = nil, binds = [])
|
19
|
+
arel, binds = binds_from_relation(arel, binds)
|
20
|
+
@connection.query_options.merge!(as: :hash)
|
21
|
+
select_result(to_sql(arel, binds), name, binds) do |result|
|
22
|
+
@connection.next_result while @connection.more_results?
|
23
|
+
result.first
|
24
|
+
end
|
25
|
+
ensure
|
26
|
+
@connection.query_options.merge!(as: :array)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns an array of arrays containing the field values.
|
30
|
+
# Order is the same as that returned by +columns+.
|
31
|
+
def select_rows(sql, name = nil, binds = [])
|
32
|
+
select_result(sql, name, binds) do |result|
|
33
|
+
@connection.next_result while @connection.more_results?
|
34
|
+
result.to_a
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Executes the SQL statement in the context of this connection.
|
39
|
+
def execute(sql, name = nil)
|
40
|
+
if @connection
|
41
|
+
# make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
|
42
|
+
# made since we established the connection
|
43
|
+
@connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
|
44
|
+
end
|
45
|
+
|
46
|
+
super
|
47
|
+
end
|
48
|
+
|
49
|
+
def exec_query(sql, name = 'SQL', binds = [], prepare: false)
|
50
|
+
if without_prepared_statement?(binds)
|
51
|
+
execute_and_free(sql, name) do |result|
|
52
|
+
ActiveRecord::Result.new(result.fields, result.to_a) if result
|
53
|
+
end
|
54
|
+
else
|
55
|
+
exec_stmt_and_free(sql, name, binds, cache_stmt: prepare) do |_, result|
|
56
|
+
ActiveRecord::Result.new(result.fields, result.to_a) if result
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def exec_delete(sql, name, binds)
|
62
|
+
if without_prepared_statement?(binds)
|
63
|
+
execute_and_free(sql, name) { @connection.affected_rows }
|
64
|
+
else
|
65
|
+
exec_stmt_and_free(sql, name, binds) { |stmt| stmt.affected_rows }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
alias :exec_update :exec_delete
|
69
|
+
|
70
|
+
protected
|
71
|
+
|
72
|
+
def last_inserted_id(result)
|
73
|
+
@connection.last_id
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def select_result(sql, name = nil, binds = [])
|
79
|
+
if without_prepared_statement?(binds)
|
80
|
+
execute_and_free(sql, name) { |result| yield result }
|
81
|
+
else
|
82
|
+
exec_stmt_and_free(sql, name, binds, cache_stmt: true) { |_, result| yield result }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def exec_stmt_and_free(sql, name, binds, cache_stmt: false)
|
87
|
+
if @connection
|
88
|
+
# make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
|
89
|
+
# made since we established the connection
|
90
|
+
@connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
|
91
|
+
end
|
92
|
+
|
93
|
+
type_casted_binds = binds.map { |attr| type_cast(attr.value_for_database) }
|
94
|
+
|
95
|
+
log(sql, name, binds) do
|
96
|
+
if cache_stmt
|
97
|
+
cache = @statements[sql] ||= {
|
98
|
+
stmt: @connection.prepare(sql)
|
99
|
+
}
|
100
|
+
stmt = cache[:stmt]
|
101
|
+
else
|
102
|
+
stmt = @connection.prepare(sql)
|
103
|
+
end
|
104
|
+
|
105
|
+
begin
|
106
|
+
result = stmt.execute(*type_casted_binds)
|
107
|
+
rescue Mysql2::Error => e
|
108
|
+
if cache_stmt
|
109
|
+
@statements.delete(sql)
|
110
|
+
else
|
111
|
+
stmt.close
|
112
|
+
end
|
113
|
+
raise e
|
114
|
+
end
|
115
|
+
|
116
|
+
ret = yield stmt, result
|
117
|
+
result.free if result
|
118
|
+
stmt.close unless cache_stmt
|
119
|
+
ret
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
module MySQL
|
4
|
+
module Quoting # :nodoc:
|
5
|
+
QUOTED_TRUE, QUOTED_FALSE = '1', '0'
|
6
|
+
|
7
|
+
def quote_column_name(name)
|
8
|
+
@quoted_column_names[name] ||= "`#{super.gsub('`', '``')}`"
|
9
|
+
end
|
10
|
+
|
11
|
+
def quote_table_name(name)
|
12
|
+
@quoted_table_names[name] ||= super.gsub('.', '`.`')
|
13
|
+
end
|
14
|
+
|
15
|
+
def quoted_true
|
16
|
+
QUOTED_TRUE
|
17
|
+
end
|
18
|
+
|
19
|
+
def unquoted_true
|
20
|
+
1
|
21
|
+
end
|
22
|
+
|
23
|
+
def quoted_false
|
24
|
+
QUOTED_FALSE
|
25
|
+
end
|
26
|
+
|
27
|
+
def unquoted_false
|
28
|
+
0
|
29
|
+
end
|
30
|
+
|
31
|
+
def quoted_date(value)
|
32
|
+
if supports_datetime_with_precision?
|
33
|
+
super
|
34
|
+
else
|
35
|
+
super.sub(/\.\d{6}\z/, '')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def _quote(value)
|
42
|
+
if value.is_a?(Type::Binary::Data)
|
43
|
+
"x'#{value.hex}'"
|
44
|
+
else
|
45
|
+
super
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -2,6 +2,9 @@ module ActiveRecord
|
|
2
2
|
module ConnectionAdapters
|
3
3
|
module MySQL
|
4
4
|
class SchemaCreation < AbstractAdapter::SchemaCreation
|
5
|
+
delegate :quote, to: :@conn
|
6
|
+
private :quote
|
7
|
+
|
5
8
|
private
|
6
9
|
|
7
10
|
def visit_DropForeignKey(name)
|
@@ -22,6 +25,14 @@ module ActiveRecord
|
|
22
25
|
add_column_position!(change_column_sql, column_options(o.column))
|
23
26
|
end
|
24
27
|
|
28
|
+
def add_table_options!(create_sql, options)
|
29
|
+
super
|
30
|
+
|
31
|
+
if comment = options[:comment]
|
32
|
+
create_sql << " COMMENT #{quote(comment)}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
25
36
|
def column_options(o)
|
26
37
|
column_options = super
|
27
38
|
column_options[:charset] = o.charset
|
@@ -29,13 +40,21 @@ module ActiveRecord
|
|
29
40
|
end
|
30
41
|
|
31
42
|
def add_column_options!(sql, options)
|
32
|
-
if options[:charset]
|
33
|
-
sql << " CHARACTER SET #{
|
43
|
+
if charset = options[:charset]
|
44
|
+
sql << " CHARACTER SET #{charset}"
|
34
45
|
end
|
35
|
-
|
36
|
-
|
46
|
+
|
47
|
+
if collation = options[:collation]
|
48
|
+
sql << " COLLATE #{collation}"
|
37
49
|
end
|
50
|
+
|
38
51
|
super
|
52
|
+
|
53
|
+
if comment = options[:comment]
|
54
|
+
sql << " COMMENT #{quote(comment)}"
|
55
|
+
end
|
56
|
+
|
57
|
+
sql
|
39
58
|
end
|
40
59
|
|
41
60
|
def add_column_position!(sql, options)
|
@@ -44,12 +63,14 @@ module ActiveRecord
|
|
44
63
|
elsif options[:after]
|
45
64
|
sql << " AFTER #{quote_column_name(options[:after])}"
|
46
65
|
end
|
66
|
+
|
47
67
|
sql
|
48
68
|
end
|
49
69
|
|
50
70
|
def index_in_create(table_name, column_name, options)
|
51
|
-
index_name, index_type, index_columns, _, _, index_using = @conn.add_index_options(table_name, column_name, options)
|
52
|
-
"
|
71
|
+
index_name, index_type, index_columns, _, _, index_using, comment = @conn.add_index_options(table_name, column_name, options)
|
72
|
+
index_option = " COMMENT #{quote(comment)}" if comment
|
73
|
+
"#{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})#{index_option} "
|
53
74
|
end
|
54
75
|
end
|
55
76
|
end
|
@@ -3,18 +3,13 @@ module ActiveRecord
|
|
3
3
|
module MySQL
|
4
4
|
module ColumnDumper
|
5
5
|
def column_spec_for_primary_key(column)
|
6
|
-
spec = {}
|
7
6
|
if column.bigint?
|
8
|
-
spec
|
7
|
+
spec = { id: :bigint.inspect }
|
9
8
|
spec[:default] = schema_default(column) || 'nil' unless column.auto_increment?
|
10
|
-
spec[:unsigned] = 'true' if column.unsigned?
|
11
|
-
elsif column.auto_increment?
|
12
|
-
spec[:unsigned] = 'true' if column.unsigned?
|
13
|
-
return if spec.empty?
|
14
9
|
else
|
15
|
-
spec
|
16
|
-
spec.merge!(prepare_column_options(column).delete_if { |key, _| [:name, :type, :null].include?(key) })
|
10
|
+
spec = super
|
17
11
|
end
|
12
|
+
spec[:unsigned] = 'true' if column.unsigned?
|
18
13
|
spec
|
19
14
|
end
|
20
15
|
|
@@ -30,6 +25,10 @@ module ActiveRecord
|
|
30
25
|
|
31
26
|
private
|
32
27
|
|
28
|
+
def default_primary_key?(column)
|
29
|
+
super && column.auto_increment?
|
30
|
+
end
|
31
|
+
|
33
32
|
def schema_type(column)
|
34
33
|
if column.sql_type == 'tinyblob'
|
35
34
|
:blob
|
@@ -38,16 +37,12 @@ module ActiveRecord
|
|
38
37
|
end
|
39
38
|
end
|
40
39
|
|
41
|
-
def schema_limit(column)
|
42
|
-
super unless column.type == :boolean
|
43
|
-
end
|
44
|
-
|
45
40
|
def schema_precision(column)
|
46
41
|
super unless /time/ === column.sql_type && column.precision == 0
|
47
42
|
end
|
48
43
|
|
49
44
|
def schema_collation(column)
|
50
|
-
if column.collation && table_name = column.
|
45
|
+
if column.collation && table_name = column.table_name
|
51
46
|
@table_collation_cache ||= {}
|
52
47
|
@table_collation_cache[table_name] ||= select_one("SHOW TABLE STATUS LIKE '#{table_name}'")["Collation"]
|
53
48
|
column.collation.inspect if column.collation != @table_collation_cache[table_name]
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'active_record/connection_adapters/abstract_mysql_adapter'
|
2
|
+
require 'active_record/connection_adapters/mysql/database_statements'
|
2
3
|
|
3
4
|
gem 'mysql2', '>= 0.3.18', '< 0.5'
|
4
5
|
require 'mysql2'
|
6
|
+
raise 'mysql2 0.4.3 is not supported. Please upgrade to 0.4.4+' if Mysql2::VERSION == '0.4.3'
|
5
7
|
|
6
8
|
module ActiveRecord
|
7
9
|
module ConnectionHandling # :nodoc:
|
@@ -16,7 +18,7 @@ module ActiveRecord
|
|
16
18
|
if config[:flags].kind_of? Array
|
17
19
|
config[:flags].push "FOUND_ROWS".freeze
|
18
20
|
else
|
19
|
-
config[:flags] |= Mysql2::Client::FOUND_ROWS
|
21
|
+
config[:flags] |= Mysql2::Client::FOUND_ROWS
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
@@ -35,9 +37,11 @@ module ActiveRecord
|
|
35
37
|
class Mysql2Adapter < AbstractMysqlAdapter
|
36
38
|
ADAPTER_NAME = 'Mysql2'.freeze
|
37
39
|
|
40
|
+
include MySQL::DatabaseStatements
|
41
|
+
|
38
42
|
def initialize(connection, logger, connection_options, config)
|
39
43
|
super
|
40
|
-
@prepared_statements = false
|
44
|
+
@prepared_statements = false unless config.key?(:prepared_statements)
|
41
45
|
configure_connection
|
42
46
|
end
|
43
47
|
|
@@ -45,6 +49,18 @@ module ActiveRecord
|
|
45
49
|
!mariadb? && version >= '5.7.8'
|
46
50
|
end
|
47
51
|
|
52
|
+
def supports_comments?
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
def supports_comments_in_create?
|
57
|
+
true
|
58
|
+
end
|
59
|
+
|
60
|
+
def supports_savepoints?
|
61
|
+
true
|
62
|
+
end
|
63
|
+
|
48
64
|
# HELPER METHODS ===========================================
|
49
65
|
|
50
66
|
def each_hash(result) # :nodoc:
|
@@ -95,59 +111,6 @@ module ActiveRecord
|
|
95
111
|
end
|
96
112
|
end
|
97
113
|
|
98
|
-
#--
|
99
|
-
# DATABASE STATEMENTS ======================================
|
100
|
-
#++
|
101
|
-
|
102
|
-
# Returns a record hash with the column names as keys and column values
|
103
|
-
# as values.
|
104
|
-
def select_one(arel, name = nil, binds = [])
|
105
|
-
arel, binds = binds_from_relation(arel, binds)
|
106
|
-
execute(to_sql(arel, binds), name).each(as: :hash) do |row|
|
107
|
-
@connection.next_result while @connection.more_results?
|
108
|
-
return row
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# Returns an array of arrays containing the field values.
|
113
|
-
# Order is the same as that returned by +columns+.
|
114
|
-
def select_rows(sql, name = nil, binds = [])
|
115
|
-
result = execute(sql, name)
|
116
|
-
@connection.next_result while @connection.more_results?
|
117
|
-
result.to_a
|
118
|
-
end
|
119
|
-
|
120
|
-
# Executes the SQL statement in the context of this connection.
|
121
|
-
def execute(sql, name = nil)
|
122
|
-
if @connection
|
123
|
-
# make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
|
124
|
-
# made since we established the connection
|
125
|
-
@connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
|
126
|
-
end
|
127
|
-
|
128
|
-
super
|
129
|
-
end
|
130
|
-
|
131
|
-
def exec_query(sql, name = 'SQL', binds = [], prepare: false)
|
132
|
-
result = execute(sql, name)
|
133
|
-
@connection.next_result while @connection.more_results?
|
134
|
-
ActiveRecord::Result.new(result.fields, result.to_a)
|
135
|
-
end
|
136
|
-
|
137
|
-
def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
|
138
|
-
execute to_sql(sql, binds), name
|
139
|
-
end
|
140
|
-
|
141
|
-
def exec_delete(sql, name, binds)
|
142
|
-
execute to_sql(sql, binds), name
|
143
|
-
@connection.affected_rows
|
144
|
-
end
|
145
|
-
alias :exec_update :exec_delete
|
146
|
-
|
147
|
-
def last_inserted_id(result)
|
148
|
-
@connection.last_id
|
149
|
-
end
|
150
|
-
|
151
114
|
private
|
152
115
|
|
153
116
|
def connect
|