@@ -309,12 +309,6 @@ CC_Destructor(ConnectionClass *self)
309309
310310 mylog ("after CC_Cleanup\n" );
311311
312- #ifdef MULTIBYTE
313- if (self -> client_encoding )
314- free (self -> client_encoding );
315- if (self -> server_encoding )
316- free (self -> server_encoding );
317- #endif /* MULTIBYTE */
318312 /* Free up statement holders */
319313 if (self -> stmts )
320314 {
@@ -323,23 +317,6 @@ CC_Destructor(ConnectionClass *self)
323317 }
324318 mylog ("after free statement holders\n" );
325319
326- /* Free cached table info */
327- if (self -> col_info )
328- {
329- int i ;
330-
331- for (i = 0 ; i < self -> ntables ; i ++ )
332- {
333- if (self -> col_info [i ]-> result ) /* Free the SQLColumns
334- * result structure */
335- QR_Destructor (self -> col_info [i ]-> result );
336-
337- free (self -> col_info [i ]);
338- }
339- free (self -> col_info );
340- }
341-
342-
343320 free (self );
344321
345322 mylog ("exit CC_Destructor\n" );
@@ -380,29 +357,77 @@ CC_clear_error(ConnectionClass *self)
380357}
381358
382359
360+ /*
361+ * Used to begin a transaction.
362+ */
363+ char
364+ CC_begin (ConnectionClass * self )
365+ {
366+ char ret = TRUE;
367+ if (!CC_is_in_trans (self ))
368+ {
369+ QResultClass * res = CC_send_query (self , "BEGIN" , NULL );
370+ mylog ("CC_begin: sending BEGIN!\n" );
371+
372+ if (res != NULL )
373+ {
374+ ret = (!QR_aborted (res ) && QR_command_successful (res ));
375+ QR_Destructor (res );
376+ if (ret )
377+ CC_set_in_trans (self );
378+ }
379+ else
380+ ret = FALSE;
381+ }
382+
383+ return ret ;
384+ }
385+
386+ /*
387+ * Used to commit a transaction.
388+ * We are almost always in the middle of a transaction.
389+ */
390+ char
391+ CC_commit (ConnectionClass * self )
392+ {
393+ char ret = FALSE;
394+ if (CC_is_in_trans (self ))
395+ {
396+ QResultClass * res = CC_send_query (self , "COMMIT" , NULL );
397+ mylog ("CC_commit: sending COMMIT!\n" );
398+
399+ CC_set_no_trans (self );
400+
401+ if (res != NULL )
402+ {
403+ ret = QR_command_successful (res );
404+ QR_Destructor (res );
405+ }
406+ else
407+ ret = FALSE;
408+ }
409+
410+ return ret ;
411+ }
412+
383413/*
384414 * Used to cancel a transaction.
385415 * We are almost always in the middle of a transaction.
386416 */
387417char
388418CC_abort (ConnectionClass * self )
389419{
390- QResultClass * res ;
391-
392420 if (CC_is_in_trans (self ))
393421 {
394- res = NULL ;
395-
422+ QResultClass * res = CC_send_query (self , "ROLLBACK" , NULL );
396423 mylog ("CC_abort: sending ABORT!\n" );
397424
398- res = CC_send_query (self , "ABORT" , NULL );
399425 CC_set_no_trans (self );
400426
401427 if (res != NULL )
402428 QR_Destructor (res );
403429 else
404430 return FALSE;
405-
406431 }
407432
408433 return TRUE;
@@ -461,6 +486,37 @@ CC_cleanup(ConnectionClass *self)
461486 }
462487#endif
463488
489+ self -> status = CONN_NOT_CONNECTED ;
490+ self -> transact_status = CONN_IN_AUTOCOMMIT ;
491+ memset (& self -> connInfo , 0 , sizeof (ConnInfo ));
492+ #ifdef DRIVER_CURSOR_IMPLEMENT
493+ self -> connInfo .updatable_cursors = 1 ;
494+ #endif /* DRIVER_CURSOR_IMPLEMENT */
495+ memcpy (& (self -> connInfo .drivers ), & globals , sizeof (globals ));
496+ #ifdef MULTIBYTE
497+ if (self -> client_encoding )
498+ free (self -> client_encoding );
499+ self -> client_encoding = NULL ;
500+ if (self -> server_encoding )
501+ free (self -> server_encoding );
502+ self -> server_encoding = NULL ;
503+ #endif /* MULTIBYTE */
504+ /* Free cached table info */
505+ if (self -> col_info )
506+ {
507+ int i ;
508+
509+ for (i = 0 ; i < self -> ntables ; i ++ )
510+ {
511+ if (self -> col_info [i ]-> result ) /* Free the SQLColumns result structure */
512+ QR_Destructor (self -> col_info [i ]-> result );
513+
514+ free (self -> col_info [i ]);
515+ }
516+ free (self -> col_info );
517+ self -> col_info = NULL ;
518+ }
519+ self -> ntables = 0 ;
464520 mylog ("exit CC_Cleanup\n" );
465521 return TRUE;
466522}
@@ -516,7 +572,6 @@ md5_auth_send(ConnectionClass *self, const char *salt)
516572 ConnInfo * ci = & (self -> connInfo );
517573 SocketClass * sock = self -> sock ;
518574
519- mylog ("MD5 user=%s password=%s\n" , ci -> username , ci -> password );
520575 if (!(pwd1 = malloc (MD5_PASSWD_LEN + 1 )))
521576 return 1 ;
522577 if (!EncryptMD5 (ci -> password , ci -> username , strlen (ci -> username ), pwd1 ))
@@ -601,9 +656,10 @@ CC_connect(ConnectionClass *self, char do_password)
601656 ci -> drivers .conn_settings ,
602657 encoding ? encoding : "" );
603658#else
604- qlog (" extra_systable_prefixes='%s', conn_settings='%s'\n" ,
659+ qlog (" extra_systable_prefixes='%s', conn_settings='%s', protocol='%s' \n" ,
605660 ci -> drivers .extra_systable_prefixes ,
606- ci -> drivers .conn_settings );
661+ ci -> drivers .conn_settings ,
662+ ci -> protocol );
607663#endif
608664
609665 if (self -> status != CONN_NOT_CONNECTED )
@@ -1037,7 +1093,8 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
10371093 ReadyToReturn ,
10381094 tuples_return = FALSE,
10391095 query_completed = FALSE,
1040- before_64 = PG_VERSION_LT (self , 6.4 );
1096+ before_64 = PG_VERSION_LT (self , 6.4 ),
1097+ used_passed_result_object = FALSE;
10411098
10421099 /* ERROR_MSG_LENGTH is suffcient */
10431100 static char msgbuffer [ERROR_MSG_LENGTH + 1 ];
@@ -1289,6 +1346,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
12891346 else
12901347 { /* next fetch, so reuse an existing result */
12911348
1349+ used_passed_result_object = TRUE;
12921350 /*
12931351 * called from QR_next_tuple and must return
12941352 * immediately.
@@ -1373,9 +1431,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
13731431 QR_Destructor (res );
13741432 if (result_in && retres != result_in )
13751433 {
1376- if (qi && qi -> result_in )
1377- ;
1378- else
1434+ if (!used_passed_result_object )
13791435 QR_Destructor (result_in );
13801436 }
13811437 return retres ;
0 commit comments