Skip to content

Commit 7bfa6dd

Browse files
brasicbyroot
authored andcommitted
Copy the in_transaction flag into Trilogy::Result
This flag (SERVER_STATUS_IN_TRANS, position 0x0001) is part of the server_status bitfield sent with every OK_Packet which is already stored on the connection. But this particular data is not always safe to read from the connection since in some cases one or more queries may have been executed since the result was generated. So to increase safety let's also store it on the Result itself.
1 parent d942e41 commit 7bfa6dd

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

contrib/ruby/ext/trilogy-ruby/cext.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ static VALUE Trilogy_BaseConnectionError, Trilogy_ProtocolError, Trilogy_SSLErro
161161

162162
static ID id_socket, id_host, id_port, id_username, id_password, id_found_rows, id_connect_timeout, id_read_timeout,
163163
id_write_timeout, id_keepalive_enabled, id_keepalive_idle, id_keepalive_interval, id_keepalive_count,
164-
id_ivar_affected_rows, id_ivar_fields, id_ivar_last_insert_id, id_ivar_rows, id_ivar_query_time, id_password,
164+
id_ivar_affected_rows, id_ivar_fields, id_ivar_last_insert_id, id_ivar_rows, id_ivar_query_time, id_password, id_ivar_in_transaction,
165165
id_database, id_enable_cleartext_plugin, id_ssl_ca, id_ssl_capath, id_ssl_cert, id_ssl_cipher, id_ssl_crl, id_ssl_crlpath, id_ssl_key,
166166
id_ssl_mode, id_tls_ciphersuites, id_tls_min_version, id_tls_max_version, id_multi_statement, id_multi_result,
167167
id_from_code, id_from_errno, id_connection_options, id_max_allowed_packet;
@@ -944,6 +944,9 @@ static VALUE read_query_response(VALUE vargs)
944944

945945
rb_ivar_set(result, id_ivar_query_time, DBL2NUM(query_time));
946946

947+
rb_ivar_set(result, id_ivar_in_transaction,
948+
(ctx->conn.server_status & TRILOGY_SERVER_STATUS_IN_TRANS) ? Qtrue : Qfalse);
949+
947950
if (rc == TRILOGY_OK) {
948951
rb_ivar_set(result, id_ivar_last_insert_id, ULL2NUM(ctx->conn.last_insert_id));
949952

@@ -1431,6 +1434,14 @@ RUBY_FUNC_EXPORTED void Init_cext(void)
14311434
rb_global_variable(&Trilogy_AuthPluginError);
14321435
Trilogy_AuthPluginError = rb_const_get(Trilogy, rb_intern("AuthPluginError"));
14331436

1437+
rb_define_attr(Trilogy_Result, "affected_rows", 1, 0);
1438+
rb_define_attr(Trilogy_Result, "fields", 1, 0);
1439+
rb_define_attr(Trilogy_Result, "last_insert_id", 1, 0);
1440+
rb_define_attr(Trilogy_Result, "rows", 1, 0);
1441+
rb_define_attr(Trilogy_Result, "query_time", 1, 0);
1442+
rb_define_attr(Trilogy_Result, "in_transaction", 1, 0);
1443+
rb_define_alias(Trilogy_Result, "in_transaction?", "in_transaction");
1444+
14341445
id_socket = rb_intern("socket");
14351446
id_host = rb_intern("host");
14361447
id_port = rb_intern("port");
@@ -1468,6 +1479,7 @@ RUBY_FUNC_EXPORTED void Init_cext(void)
14681479
id_ivar_rows = rb_intern("@rows");
14691480
id_ivar_query_time = rb_intern("@query_time");
14701481
id_connection_options = rb_intern("@connection_options");
1482+
id_ivar_in_transaction = rb_intern("@in_transaction");
14711483

14721484
rb_trilogy_cast_init();
14731485

contrib/ruby/test/client_test.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ def test_trilogy_query_result_object
336336
assert_equal [{ "a" => 1, "b" => 2 }], result.each_hash.to_a
337337
assert_equal [[1, 2]], result.to_a
338338
assert_kind_of Float, result.query_time
339+
refute_predicate result, :in_transaction?
339340
assert_in_delta 0.1, result.query_time, 0.1
340341
ensure
341342
ensure_closed client
@@ -419,6 +420,24 @@ def test_trilogy_affected_rows_in_found_rows_mode
419420
ensure_closed client
420421
end
421422

423+
def test_trilogy_in_transaction_flag_on_result
424+
client = new_tcp_client
425+
create_test_table(client)
426+
427+
refute_predicate client.query("SELECT 1"), :in_transaction?
428+
refute_predicate client.query("INSERT INTO trilogy_test (varchar_test, int_test) VALUES ('a', 1)"), :in_transaction?
429+
430+
assert_predicate client.query("BEGIN"), :in_transaction?
431+
assert_predicate client.query("INSERT INTO trilogy_test (varchar_test, int_test) VALUES ('b', 2)"), :in_transaction?
432+
433+
refute_predicate client.query("COMMIT"), :in_transaction?
434+
435+
assert_predicate client.query("BEGIN"), :in_transaction?
436+
refute_predicate client.query("ROLLBACK"), :in_transaction?
437+
ensure
438+
ensure_closed client
439+
end
440+
422441
def test_trilogy_warning_count
423442
client = new_tcp_client
424443
create_test_table(client)

0 commit comments

Comments
 (0)