From 0d3f8f950bce371d46b345b87a4bb28a26dc4ffb Mon Sep 17 00:00:00 2001
From: "Dmitry E. Oboukhov" <unera@debian.org>
Date: Fri, 7 Jun 2013 22:54:26 +0400
Subject: [PATCH] SQL connectors provide transaction.

---
 src/box/lua/sql.lua           | 34 ++++++++++++++++++++++++++++++++++
 src/lua/pg.cc                 | 11 +++++++++++
 test/box/net_sql.mysql.result | 16 ++++++++++++++++
 test/box/net_sql.mysql.test   |  5 +++++
 test/box/net_sql.pg.result    | 20 ++++++++++++++++++++
 test/box/net_sql.pg.test      |  8 ++++++++
 6 files changed, 94 insertions(+)

diff --git a/src/box/lua/sql.lua b/src/box/lua/sql.lua
index 0a89589272..c9a7001363 100644
--- a/src/box/lua/sql.lua
+++ b/src/box/lua/sql.lua
@@ -174,6 +174,40 @@ box.net.sql = {
         -- quote identifier
         quote_ident = function(self, variable)
             return self.raw:quote_ident(variable)
+        end,
+
+
+        -- begin transaction
+        begin_work = function(self)
+            return self:perform('BEGIN')
+        end,
+
+        -- commit transaction
+        commit  = function(self)
+            return self:perform('COMMIT')
+        end,
+
+        -- rollback transaction
+        rollback = function(self)
+            return self:perform('ROLLBACK')
+        end,
+
+        -- transaction
+        txn = function(self, proc)
+            local raise = self.raise
+            self.raise = true
+            self:begin_work()
+            local res = { pcall(proc, self) }
+
+            self.raise = raise
+            
+            if res[1] then
+                self:commit()
+                return true
+            end
+
+            self:rollback()
+            return false, res[2]
         end
     }
 
diff --git a/src/lua/pg.cc b/src/lua/pg.cc
index c155fe8524..0022f6dd53 100644
--- a/src/lua/pg.cc
+++ b/src/lua/pg.cc
@@ -267,6 +267,15 @@ lua_pg_gc(struct lua_State *L)
 	return 0;
 }
 
+/**
+ * prints warnings from Postgresql into tarantool log
+ */
+static void
+pg_notice(void *arg, const char *message)
+{
+	say_info("Postgresql: %s", message);
+	(void)arg;
+}
 
 /**
  * do connect to postgresql (is run in the other thread)
@@ -277,6 +286,8 @@ pg_connect(va_list ap)
 	const char *constr = va_arg(ap, typeof(constr));
 	PGconn **conn = va_arg(ap, typeof(conn));
 	*conn = PQconnectdb(constr);
+	if (*conn)
+		PQsetNoticeProcessor(*conn, pg_notice, NULL);
 	return 0;
 }
 
diff --git a/test/box/net_sql.mysql.result b/test/box/net_sql.mysql.result
index 5fbb88b143..b0d0697b79 100644
--- a/test/box/net_sql.mysql.result
+++ b/test/box/net_sql.mysql.result
@@ -63,3 +63,19 @@ lua c:quote('test "abc" test')
 ---
  - test \"abc\" test
 ...
+lua c:begin_work()
+---
+ - 0
+...
+lua c:rollback()
+---
+ - 0
+...
+lua c:begin_work()
+---
+ - 0
+...
+lua c:commit()
+---
+ - 0
+...
diff --git a/test/box/net_sql.mysql.test b/test/box/net_sql.mysql.test
index f44c6c4599..d69d064869 100644
--- a/test/box/net_sql.mysql.test
+++ b/test/box/net_sql.mysql.test
@@ -20,3 +20,8 @@ exec admin "lua dump({c:execute('SELECT 1 AS one UNION ALL SELECT 2')})"
 exec admin "lua dump({c:execute('SELECT 1 AS one UNION ALL SELECT 2; SELECT ? AS two', 'abc')})"
 
 exec admin "lua c:quote('test \"abc\" test')"
+
+exec admin "lua c:begin_work()"
+exec admin "lua c:rollback()"
+exec admin "lua c:begin_work()"
+exec admin "lua c:commit()"
diff --git a/test/box/net_sql.pg.result b/test/box/net_sql.pg.result
index b7b3e0d488..c332d72423 100644
--- a/test/box/net_sql.pg.result
+++ b/test/box/net_sql.pg.result
@@ -93,3 +93,23 @@ lua c:quote('abc"cde"def')
 ---
  - 'abc"cde"def'
 ...
+lua c:begin_work()
+---
+ - 0
+...
+lua c:rollback()
+---
+ - 0
+...
+lua c:begin_work()
+---
+ - 0
+...
+lua c:commit()
+---
+ - 0
+...
+lua c:txn(function(dbi) dbi:single('SELECT 1') end)
+---
+ - true
+...
diff --git a/test/box/net_sql.pg.test b/test/box/net_sql.pg.test
index 00311e8521..bab88bb34b 100644
--- a/test/box/net_sql.pg.test
+++ b/test/box/net_sql.pg.test
@@ -30,3 +30,11 @@ exec admin "lua c = box.net.sql.connect('abcd')"
 
 
 exec admin "lua c:quote('abc\"cde\"def')"
+
+
+exec admin "lua c:begin_work()"
+exec admin "lua c:rollback()"
+exec admin "lua c:begin_work()"
+exec admin "lua c:commit()"
+
+exec admin "lua c:txn(function(dbi) dbi:single('SELECT 1') end)"
-- 
GitLab