Commit:    9fb0dba4be197b677b6ff7df23a110698d12530b
Author:    Andrey Hristov <and...@php.net>         Thu, 7 Feb 2013 16:05:27 
+0100
Parents:   0547a36e95ec36025a30e93e971d26b6b1ecf0e9
Branches:  PHP-5.5 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=9fb0dba4be197b677b6ff7df23a110698d12530b

Log:
Add support for commit and rollback options.
Add support for explicitly starting a transaction - modes also available.
Using the API makes the life of load balancer mysqlnd plugins easier/possible.

Changed paths:
  M  ext/mysqlnd/mysqlnd.c
  M  ext/mysqlnd/mysqlnd_enum_n_def.h
  M  ext/mysqlnd/mysqlnd_structs.h

diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c
index 1bab6f5..d7ddcb5 100644
--- a/ext/mysqlnd/mysqlnd.c
+++ b/ext/mysqlnd/mysqlnd.c
@@ -2617,12 +2617,79 @@ MYSQLND_METHOD(mysqlnd_conn_data, 
set_autocommit)(MYSQLND_CONN_DATA * conn, unsi
 static enum_func_status
 MYSQLND_METHOD(mysqlnd_conn_data, tx_commit)(MYSQLND_CONN_DATA * conn 
TSRMLS_DC)
 {
-       size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, 
tx_commit);
+       return conn->m->tx_commit_or_rollback(conn, TRUE, TRANS_COR_NO_OPT, 
NULL TSRMLS_CC);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_conn_data::tx_rollback */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_conn_data, tx_rollback)(MYSQLND_CONN_DATA * conn 
TSRMLS_DC)
+{
+       return conn->m->tx_commit_or_rollback(conn, FALSE, TRANS_COR_NO_OPT, 
NULL TSRMLS_CC);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_tx_cor_options_to_string */
+static void
+MYSQLND_METHOD(mysqlnd_conn_data, tx_cor_options_to_string)(const 
MYSQLND_CONN_DATA * const conn, smart_str * str, const unsigned int mode 
TSRMLS_DC)
+{
+       if (mode & TRANS_COR_AND_CHAIN && !(mode & TRANS_COR_AND_NO_CHAIN)) {
+               if (str->len) {
+                       smart_str_appendl(str, ", ", sizeof(", ") - 1);
+               }
+               smart_str_appendl(str, "AND CHAIN", sizeof("AND CHAIN") - 1);
+       } else if (mode & TRANS_COR_AND_NO_CHAIN && !(mode & 
TRANS_COR_AND_CHAIN)) {
+               if (str->len) {
+                       smart_str_appendl(str, ", ", sizeof(", ") - 1);
+               }
+               smart_str_appendl(str, "AND NO CHAIN", sizeof("AND NO CHAIN") - 
1);
+       }
+
+       if (mode & TRANS_COR_RELEASE && !(mode & TRANS_COR_NO_RELEASE)) {
+               if (str->len) {
+                       smart_str_appendl(str, ", ", sizeof(", ") - 1);
+               }
+               smart_str_appendl(str, "RELEASE", sizeof("RELEASE") - 1);
+       } else if (mode & TRANS_COR_NO_RELEASE && !(mode & TRANS_COR_RELEASE)) {
+               if (str->len) {
+                       smart_str_appendl(str, ", ", sizeof(", ") - 1);
+               }
+               smart_str_appendl(str, "NO RELEASE", sizeof("NO RELEASE") - 1);
+       }
+       smart_str_0(str);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_conn_data::tx_commit_ex */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_conn_data, tx_commit_or_rollback)(MYSQLND_CONN_DATA * 
conn, const zend_bool commit, const unsigned int flags, const char * const name 
TSRMLS_DC)
+{
+       size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, 
tx_commit_or_rollback);
        enum_func_status ret = FAIL;
-       DBG_ENTER("mysqlnd_conn_data::tx_commit");
+       DBG_ENTER("mysqlnd_conn_data::tx_commit_or_rollback");
 
        if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
-               ret = conn->m->query(conn, "COMMIT", sizeof("COMMIT") - 1 
TSRMLS_CC);
+               do {
+                       smart_str tmp_str = {0, 0, 0};
+                       conn->m->tx_cor_options_to_string(conn, &tmp_str, flags 
TSRMLS_CC);
+                       smart_str_0(&tmp_str);
+
+                       {
+                               char * query;
+                               unsigned int query_len = mnd_sprintf(&query, 0, 
(commit? "COMMIT %s":"ROLLBACK %s"), tmp_str.c? tmp_str.c:"");
+                               smart_str_free(&tmp_str);
+
+                               if (!query) {
+                                       SET_OOM_ERROR(*conn->error_info);
+                                       break;
+                               }
+                               ret = conn->m->query(conn, query, query_len 
TSRMLS_CC);
+                               mnd_sprintf_free(query);
+                       }
+               } while (0);
                conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);  
        }
 
@@ -2631,16 +2698,55 @@ MYSQLND_METHOD(mysqlnd_conn_data, 
tx_commit)(MYSQLND_CONN_DATA * conn TSRMLS_DC)
 /* }}} */
 
 
-/* {{{ mysqlnd_conn_data::tx_rollback */
+/* {{{ mysqlnd_conn_data::tx_begin */
 static enum_func_status
-MYSQLND_METHOD(mysqlnd_conn_data, tx_rollback)(MYSQLND_CONN_DATA * conn 
TSRMLS_DC)
+MYSQLND_METHOD(mysqlnd_conn_data, tx_begin)(MYSQLND_CONN_DATA * conn, const 
unsigned int mode, const char * const name TSRMLS_DC)
 {
-       size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, 
tx_rollback);
+       size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, 
tx_begin);
        enum_func_status ret = FAIL;
-       DBG_ENTER("mysqlnd_conn_data::tx_rollback");
+       DBG_ENTER("mysqlnd_conn_data::tx_begin");
 
        if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
-               ret = conn->m->query(conn, "ROLLBACK", sizeof("ROLLBACK") - 1 
TSRMLS_CC);
+               do {
+                       smart_str tmp_str = {0, 0, 0};
+                       if (mode & TRANS_START_WITH_CONSISTENT_SNAPSHOT) {
+                               if (tmp_str.len) {
+                                       smart_str_appendl(&tmp_str, ", ", 
sizeof(", ") - 1);
+                               }
+                               smart_str_appendl(&tmp_str, "WITH CONSISTENT 
SNAPSHOT", sizeof("WITH CONSISTENT SNAPSHOT") - 1);
+                       }
+                       if (mode & TRANS_START_READ_WRITE) {
+                               if (tmp_str.len) {
+                                       smart_str_appendl(&tmp_str, ", ", 
sizeof(", ") - 1);
+                               }
+                               smart_str_appendl(&tmp_str, "READ WRITE", 
sizeof("READ WRITE") - 1);
+                       }
+                       if (mode & TRANS_START_READ_ONLY) {
+                               if (tmp_str.len) {
+                                       smart_str_appendl(&tmp_str, ", ", 
sizeof(", ") - 1);
+                               }
+                               smart_str_appendl(&tmp_str, "READ ONLY", 
sizeof("READ ONLY") - 1);
+                       }
+                       smart_str_0(&tmp_str);
+
+                       {
+                               char * commented_name = NULL;
+                               unsigned int commented_name_len = name? 
mnd_sprintf(&commented_name, 0, " /*%s*/", name):0;
+                               char * query;
+                               unsigned int query_len = mnd_sprintf(&query, 0, 
"START TRANSACTION%s %s", commented_name? commented_name:"", tmp_str.c? 
tmp_str.c:"");
+                               smart_str_free(&tmp_str);
+
+                               if (!query) {
+                                       SET_OOM_ERROR(*conn->error_info);
+                                       break;
+                               }
+                               ret = conn->m->query(conn, query, query_len 
TSRMLS_CC);
+                               mnd_sprintf_free(query);
+                               if (commented_name) {
+                                       mnd_sprintf_free(commented_name);
+                               }
+                       }
+               } while (0);
                conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);  
        }
 
@@ -2649,6 +2755,9 @@ MYSQLND_METHOD(mysqlnd_conn_data, 
tx_rollback)(MYSQLND_CONN_DATA * conn TSRMLS_D
 /* }}} */
 
 
+typedef enum_func_status       (*func_mysqlnd_conn_data__)(MYSQLND_CONN_DATA * 
conn, const unsigned int flags, const char * const name TSRMLS_DC);
+
+
 /* {{{ mysqlnd_conn_data::local_tx_start */
 static enum_func_status
 MYSQLND_METHOD(mysqlnd_conn_data, local_tx_start)(MYSQLND_CONN_DATA * conn, 
size_t this_func TSRMLS_DC)
@@ -2763,6 +2872,10 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_conn_data)
        MYSQLND_METHOD(mysqlnd_conn_data, set_autocommit),
        MYSQLND_METHOD(mysqlnd_conn_data, tx_commit),
        MYSQLND_METHOD(mysqlnd_conn_data, tx_rollback),
+       MYSQLND_METHOD(mysqlnd_conn_data, tx_begin),
+       MYSQLND_METHOD(mysqlnd_conn_data, tx_commit_or_rollback),
+       MYSQLND_METHOD(mysqlnd_conn_data, tx_cor_options_to_string),
+
        MYSQLND_METHOD(mysqlnd_conn_data, local_tx_start),
        MYSQLND_METHOD(mysqlnd_conn_data, local_tx_end),
        MYSQLND_METHOD(mysqlnd_conn_data, execute_init_commands),
diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h
index cf5b027..1d645a8 100644
--- a/ext/mysqlnd/mysqlnd_enum_n_def.h
+++ b/ext/mysqlnd/mysqlnd_enum_n_def.h
@@ -108,6 +108,18 @@
 
 #define MYSQLND_NET_FLAG_USE_COMPRESSION 1
 
+
+#define TRANS_START_NO_OPT                                             0
+#define TRANS_START_WITH_CONSISTENT_SNAPSHOT   1
+#define TRANS_START_READ_WRITE                                 2
+#define TRANS_START_READ_ONLY                                  4
+
+#define TRANS_COR_NO_OPT               0
+#define TRANS_COR_AND_CHAIN            1
+#define TRANS_COR_AND_NO_CHAIN 2
+#define TRANS_COR_RELEASE              4
+#define TRANS_COR_NO_RELEASE   8
+
 typedef enum mysqlnd_extension
 {
        MYSQLND_MYSQL = 0,
diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h
index b88004a..7d22daf 100644
--- a/ext/mysqlnd/mysqlnd_structs.h
+++ b/ext/mysqlnd/mysqlnd_structs.h
@@ -23,6 +23,8 @@
 #ifndef MYSQLND_STRUCTS_H
 #define MYSQLND_STRUCTS_H
 
+#include "ext/standard/php_smart_str.h"
+
 #define MYSQLND_TYPEDEFED_METHODS
 
 #define MYSQLND_CLASS_METHOD_TABLE_NAME(class) mysqlnd_##class##_methods
@@ -31,6 +33,7 @@
 #define MYSQLND_CLASS_METHODS_START(class)     
MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(class) = {
 #define MYSQLND_CLASS_METHODS_END                      }
 
+
 typedef struct st_mysqlnd_memory_pool MYSQLND_MEMORY_POOL;
 typedef struct st_mysqlnd_memory_pool_chunk MYSQLND_MEMORY_POOL_CHUNK;
 typedef struct st_mysqlnd_memory_pool_chunk_llist 
MYSQLND_MEMORY_POOL_CHUNK_LLIST;
@@ -480,6 +483,9 @@ typedef MYSQLND_RES *               
(*func_mysqlnd_conn_data__result_init)(unsigned int fiel
 typedef enum_func_status       
(*func_mysqlnd_conn_data__set_autocommit)(MYSQLND_CONN_DATA * conn, unsigned 
int mode TSRMLS_DC);
 typedef enum_func_status       
(*func_mysqlnd_conn_data__tx_commit)(MYSQLND_CONN_DATA * conn TSRMLS_DC);
 typedef enum_func_status       
(*func_mysqlnd_conn_data__tx_rollback)(MYSQLND_CONN_DATA * conn TSRMLS_DC);
+typedef enum_func_status       
(*func_mysqlnd_conn_data__tx_begin)(MYSQLND_CONN_DATA * conn, const unsigned 
int mode, const char * const name TSRMLS_DC);
+typedef enum_func_status       
(*func_mysqlnd_conn_data__tx_commit_or_rollback)(MYSQLND_CONN_DATA * conn, 
const zend_bool commit, const unsigned int flags, const char * const name 
TSRMLS_DC);
+typedef void                           
(*func_mysqlnd_conn_data__tx_cor_options_to_string)(const MYSQLND_CONN_DATA * 
const conn, smart_str * tmp_str, const unsigned int mode TSRMLS_DC);
 
 typedef enum_func_status       
(*func_mysqlnd_conn_data__local_tx_start)(MYSQLND_CONN_DATA * conn, size_t 
this_func TSRMLS_DC);
 typedef enum_func_status       
(*func_mysqlnd_conn_data__local_tx_end)(MYSQLND_CONN_DATA * conn, size_t 
this_func, enum_func_status status TSRMLS_DC);
@@ -566,6 +572,9 @@ struct st_mysqlnd_conn_data_methods
        func_mysqlnd_conn_data__set_autocommit set_autocommit;
        func_mysqlnd_conn_data__tx_commit tx_commit;
        func_mysqlnd_conn_data__tx_rollback tx_rollback;
+       func_mysqlnd_conn_data__tx_begin tx_begin;
+       func_mysqlnd_conn_data__tx_commit_or_rollback tx_commit_or_rollback;
+       func_mysqlnd_conn_data__tx_cor_options_to_string 
tx_cor_options_to_string;
 
        func_mysqlnd_conn_data__local_tx_start local_tx_start;
        func_mysqlnd_conn_data__local_tx_end local_tx_end;
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to