| 
      
      
      From: Michael N. <mne...@us...> - 2002-10-22 14:53:11
      
     | 
| Update of /cvsroot/ruby-dbi/src/lib/dbd_pg
In directory usw-pr-cvs1:/tmp/cvs-serv9172
Modified Files:
	Pg.rb 
Log Message:
reverted to old transaction handling schema; removed usage of SET AUTOCOMMIT TO ON|OFF.
Index: Pg.rb
===================================================================
RCS file: /cvsroot/ruby-dbi/src/lib/dbd_pg/Pg.rb,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- Pg.rb	22 Oct 2002 14:00:16 -0000	1.28
+++ Pg.rb	22 Oct 2002 14:53:07 -0000	1.29
@@ -102,6 +102,10 @@
           @attr.each { |k,v| self[k] = v} 
 
           load_type_map
+
+          @in_transaction = false
+          self['AutoCommit'] = true    # Postgres starts in unchained mode (AutoCommit=on) by default 
+
         rescue PGError => err
           raise DBI::OperationalError.new(err.message)
         end
@@ -109,8 +113,8 @@
         # DBD Protocol -----------------------------------------------
 
         def disconnect
-          unless @attr['AutoCommit']
-            @connection.exec("ROLLBACK")   # rollback outstanding transactions
+          if not @attr['AutoCommit'] and @in_transaction
+            @connection.exec("COMMIT")   # commit outstanding transactions
           end
           @connection.close
         end
@@ -236,7 +240,6 @@
           Statement.new(self, statement)
         end
         
-        # Note: 'AutoCommit' returns nil <=> Postgres' default mode  
         def [](attr)
           case attr
           when 'pg_client_encoding'
@@ -249,8 +252,18 @@
         def []=(attr, value)
           case attr
           when 'AutoCommit'
-            # TODO: Are outstanding transactions committed?
-            @connection.exec("SET AUTOCOMMIT TO " + (value ? "ON" : "OFF"))
+            if @attr['AutoCommit'] != value then
+              if value    # turn AutoCommit ON
+                if @in_transaction
+                  # TODO: commit outstanding transactions?
+                  @connection.exec("COMMIT")
+                  @in_transaction = false
+                end
+              else        # turn AutoCommit OFF
+                @in_transaction = false
+              end
+            end
+            # value is assigned below
           when 'pg_client_encoding'
             @connection.set_client_encoding(value)
           else
@@ -264,13 +277,21 @@
         end
 
         def commit
-          # TODO: what if in autocommit mode?
-          @connection.exec("COMMIT")
+          if @in_transaction
+            @connection.exec("COMMIT")
+            @in_transaction = false
+          else
+            # TODO: Warn?
+          end
         end
 
         def rollback
-          # TODO: what if in autocommit mode?
-          @connection.exec("ROLLBACK")
+          if @in_transaction
+            @connection.exec("ROLLBACK")
+            @in_transaction = false
+          else
+            # TODO: Warn?
+          end
         end
 
         # Other Public Methods ---------------------------------------
@@ -282,6 +303,15 @@
           @coerce.coerce(converter, obj)
         end
 
+        def in_transaction?
+          @in_transaction
+        end
+
+        def start_transaction
+          @connection.exec("BEGIN")
+          @in_transaction = true
+        end
+
      if PGconn.respond_to?(:quote)
 
         def quote(value)
@@ -342,36 +372,63 @@
         public
 
         def __blob_import(file)
+          start_transaction unless @in_transaction
           @connection.lo_import(file)
+          #if @attr['AutoCommit']
+          #  @connection.exec("COMMIT")
+          #  @in_transaction = false
+          #end
         rescue PGError => err
           raise DBI::DatabaseError.new(err.message) 
         end
 
         def __blob_export(oid, file)
+          start_transaction unless @in_transaction
           @connection.lo_export(oid.to_i, file)
+          #if @attr['AutoCommit']
+          #  @connection.exec("COMMIT")
+          #  @in_transaction = false
+          #end
         rescue PGError => err
           raise DBI::DatabaseError.new(err.message) 
         end
 
         def __blob_create(mode=PGlarge::INV_READ)
+          start_transaction unless @in_transaction
           @connection.lo_create(mode)
+          #if @attr['AutoCommit']
+          #  @connection.exec("COMMIT")
+          #  @in_transaction = false
+          #end
         rescue PGError => err
           raise DBI::DatabaseError.new(err.message) 
         end
 
         def __blob_open(oid, mode=PGlarge::INV_READ)
+          start_transaction unless @in_transaction
           @connection.lo_open(oid.to_i, mode)
+          #if @attr['AutoCommit']
+          #  @connection.exec("COMMIT")
+          #  @in_transaction = false
+          #end
         rescue PGError => err
           raise DBI::DatabaseError.new(err.message) 
         end
 
         def __blob_unlink(oid)
+          start_transaction unless @in_transaction
           @connection.lo_unlink(oid.to_i)
+          #if @attr['AutoCommit']
+          #  @connection.exec("COMMIT")
+          #  @in_transaction = false
+          #end
         rescue PGError => err
           raise DBI::DatabaseError.new(err.message) 
         end
 
         def __blob_read(oid, length=nil)
+          # TODO: do we really nead an open transaction for reading?
+          start_transaction unless @in_transaction
           blob = @connection.lo_open(oid.to_i, PGlarge::INV_READ)
           blob.open
           if length.nil?
@@ -444,6 +501,9 @@
 
           boundsql = @prep_sql.bind(@bindvars)
 
+          if not SQL.query?(boundsql) and not @db['AutoCommit'] then
+            @db.start_transaction unless @db.in_transaction?
+          end
           pg_result = @db.connection.exec(boundsql)
           @result = Tuples.new(@db, pg_result)
 
 |