OCILIB (C Driver for Oracle) 3.9.2
D:/Perso/dev/ocilib/ocilib/src/transaction.c
00001 /*
00002     +-----------------------------------------------------------------------------------------+
00003     |                                                                                         |
00004     |                               OCILIB - C Driver for Oracle                              |
00005     |                                                                                         |
00006     |                                (C Wrapper for Oracle OCI)                               |
00007     |                                                                                         |
00008     |                              Website : http://www.ocilib.net                            |
00009     |                                                                                         |
00010     |             Copyright (c) 2007-2011 Vincent ROGIER <vince.rogier@ocilib.net>            |
00011     |                                                                                         |
00012     +-----------------------------------------------------------------------------------------+
00013     |                                                                                         |
00014     |             This library is free software; you can redistribute it and/or               |
00015     |             modify it under the terms of the GNU Lesser General Public                  |
00016     |             License as published by the Free Software Foundation; either                |
00017     |             version 2 of the License, or (at your option) any later version.            |
00018     |                                                                                         |
00019     |             This library is distributed in the hope that it will be useful,             |
00020     |             but WITHOUT ANY WARRANTY; without even the implied warranty of              |
00021     |             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU           |
00022     |             Lesser General Public License for more details.                             |
00023     |                                                                                         |
00024     |             You should have received a copy of the GNU Lesser General Public            |
00025     |             License along with this library; if not, write to the Free                  |
00026     |             Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.          |
00027     |                                                                                         |
00028     +-----------------------------------------------------------------------------------------+
00029 */
00030 
00031 /* --------------------------------------------------------------------------------------------- *
00032  * $Id: transaction.c, v 3.9.2 2011-07-13 00:00 Vincent Rogier $
00033  * --------------------------------------------------------------------------------------------- */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ********************************************************************************************* *
00038  *                            PUBLIC FUNCTIONS
00039  * ********************************************************************************************* */
00040 
00041 /* --------------------------------------------------------------------------------------------- *
00042  * OCI_TransactionCreate
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 OCI_Transaction * OCI_API OCI_TransactionCreate
00046 (
00047     OCI_Connection *con,
00048     unsigned int    timeout,
00049     unsigned int    mode,
00050     OCI_XID        *pxid
00051 )
00052 {
00053     OCI_Item *item         = NULL;
00054     OCI_Transaction *trans = NULL;
00055     boolean res            = TRUE;
00056 
00057     OCI_CHECK_INITIALIZED(NULL);
00058 
00059     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
00060 
00061     /* create transaction object */
00062 
00063     item = OCI_ListAppend(con->trsns, sizeof(*trans));
00064 
00065     if (item != NULL)
00066     {
00067         trans = (OCI_Transaction *) item->data;
00068 
00069         trans->con     = con;
00070         trans->mode    = mode;
00071         trans->timeout = timeout;
00072         trans->local   = (pxid == NULL);
00073 
00074         /* allocate transaction handle */
00075 
00076         if (res == TRUE)
00077         {
00078             res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) trans->con->env,
00079                                                   (dvoid **) (void *) &trans->htr,
00080                                                   (ub4) OCI_HTYPE_TRANS,
00081                                                   (size_t) 0, (dvoid **) NULL));
00082         }
00083 
00084         /* set context transaction attribute */
00085 
00086         OCI_CALL2
00087         (
00088             res, con,
00089 
00090             OCIAttrSet((dvoid *) trans->con->cxt, (ub4) OCI_HTYPE_SVCCTX,
00091                        (dvoid *) trans->htr, (ub4) sizeof(trans->htr),
00092                        (ub4) OCI_ATTR_TRANS, trans->con->err)
00093         )
00094 
00095         /* set XID attribute for global transaction */
00096 
00097         if (pxid != NULL)
00098         {
00099             memcpy(&trans->xid, pxid, sizeof(trans->xid));
00100 
00101             OCI_CALL2
00102             (
00103                 res, con,
00104 
00105                 OCIAttrSet((dvoid *) trans->htr, (ub4) OCI_HTYPE_TRANS,
00106                            (dvoid *) &trans->xid, (ub4) sizeof(trans->xid),
00107                            (ub4) OCI_ATTR_XID, trans->con->err)
00108             )
00109         }
00110     }
00111     else
00112     {
00113        res = FALSE;
00114     }
00115 
00116     /* handle errors */
00117 
00118     if (res == FALSE)
00119     {
00120         OCI_TransactionFree(trans);
00121         trans = NULL;
00122     }
00123 
00124     OCI_RESULT(res);
00125 
00126     return trans;
00127 }
00128 
00129 /* --------------------------------------------------------------------------------------------- *
00130  * OCI_TransactionClose
00131  * --------------------------------------------------------------------------------------------- */
00132 
00133 boolean OCI_TransactionClose
00134 (
00135     OCI_Transaction * trans
00136 )
00137 {
00138     boolean res = TRUE;
00139 
00140     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
00141 
00142     res = OCI_TransactionStop(trans);
00143 
00144     /* close transaction handle */
00145 
00146     if (trans->htr != NULL)
00147     {
00148         OCI_HandleFree((dvoid *) trans->htr, (ub4) OCI_HTYPE_TRANS);
00149     }
00150 
00151     return res;
00152 }
00153 
00154 /* --------------------------------------------------------------------------------------------- *
00155  * OCI_TransactionFree
00156  * --------------------------------------------------------------------------------------------- */
00157 
00158 boolean OCI_API OCI_TransactionFree
00159 (
00160     OCI_Transaction * trans
00161 )
00162 {
00163     boolean res = TRUE;
00164 
00165     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
00166 
00167     res = OCI_TransactionClose(trans);
00168 
00169     /* remove transaction from internal list */
00170 
00171     OCI_ListRemove(trans->con->trsns, trans);
00172 
00173     OCI_FREE(trans);
00174 
00175     OCI_RESULT(res);
00176 
00177     return res;
00178 }
00179 
00180 /* --------------------------------------------------------------------------------------------- *
00181  * OCI_TransactionStart
00182  * --------------------------------------------------------------------------------------------- */
00183 
00184 boolean OCI_API OCI_TransactionStart
00185 (
00186     OCI_Transaction * trans
00187 )
00188 {
00189     boolean res = TRUE;
00190 
00191     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
00192 
00193     OCI_CALL2
00194     (
00195         res, trans->con,
00196 
00197         OCITransStart(trans->con->cxt, trans->con->err, (uword) trans->timeout,
00198                       (ub4) trans->mode)
00199     )
00200 
00201     OCI_RESULT(res);
00202 
00203     return res;
00204 }
00205 
00206 /* --------------------------------------------------------------------------------------------- *
00207  * OCI_TransactionStop
00208  * --------------------------------------------------------------------------------------------- */
00209 
00210 boolean OCI_API OCI_TransactionStop
00211 (
00212     OCI_Transaction * trans
00213 )
00214 {
00215     boolean res = TRUE;
00216 
00217     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
00218 
00219     /* commit or rollback upon auto commit mode */
00220 
00221     if (trans->con->autocom == TRUE)
00222     {
00223         res = OCI_Commit(trans->con);
00224     }
00225     else
00226     {
00227         res = OCI_Rollback(trans->con);
00228     }
00229 
00230     /* detach global transaction */
00231 
00232     if (trans->local == FALSE)
00233     {
00234         OCI_CALL2
00235         (
00236             res, trans->con,
00237 
00238             OCITransDetach(trans->con->cxt, trans->con->err, (ub4) OCI_DEFAULT)
00239         )
00240     }
00241 
00242     OCI_RESULT(res);
00243 
00244     return res;
00245 }
00246 
00247 /* --------------------------------------------------------------------------------------------- *
00248  * OCI_TransactionResume
00249  * --------------------------------------------------------------------------------------------- */
00250 
00251 boolean OCI_API OCI_TransactionResume
00252 (
00253     OCI_Transaction * trans
00254 )
00255 {
00256     boolean res = TRUE;
00257 
00258     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
00259 
00260     OCI_CALL2
00261     (
00262         res, trans->con,
00263 
00264         OCITransStart(trans->con->cxt, trans->con->err,
00265                       (uword) trans->timeout, (ub4) OCI_TRANS_RESUME)
00266     )
00267 
00268     OCI_RESULT(res);
00269 
00270     return res;
00271 }
00272 
00273 /* --------------------------------------------------------------------------------------------- *
00274  * OCI_TransactionPrepare
00275  * --------------------------------------------------------------------------------------------- */
00276 
00277 boolean OCI_API OCI_TransactionPrepare
00278 (
00279     OCI_Transaction * trans
00280 )
00281 {
00282     boolean res = TRUE;
00283 
00284     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
00285 
00286     OCI_CALL2
00287     (
00288         res, trans->con,
00289 
00290         OCITransPrepare(trans->con->cxt, trans->con->err, (ub4) OCI_DEFAULT)
00291     )
00292 
00293     OCI_RESULT(res);
00294 
00295     return res;
00296 }
00297 
00298 /* --------------------------------------------------------------------------------------------- *
00299  * OCI_TransactionForget
00300  * --------------------------------------------------------------------------------------------- */
00301 
00302 boolean OCI_API OCI_TransactionForget
00303 (
00304     OCI_Transaction * trans
00305 )
00306 {
00307     boolean res = TRUE;
00308 
00309     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
00310 
00311     OCI_CALL2
00312     (
00313         res, trans->con,
00314 
00315         OCITransForget(trans->con->cxt, trans->con->err, (ub4) OCI_DEFAULT)
00316     )
00317 
00318     OCI_RESULT(res);
00319 
00320     return res;
00321 }
00322 
00323 /* --------------------------------------------------------------------------------------------- *
00324  * OCI_TransactionGetMode
00325  * --------------------------------------------------------------------------------------------- */
00326 
00327 unsigned int OCI_API OCI_TransactionGetMode
00328 (
00329     OCI_Transaction * trans
00330 )
00331 {
00332     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, OCI_UNKNOWN);
00333 
00334     OCI_RESULT(TRUE);
00335 
00336     return trans->mode;
00337 }
00338 
00339 /* --------------------------------------------------------------------------------------------- *
00340  * OCI_TransactionGetTimeout
00341  * --------------------------------------------------------------------------------------------- */
00342 
00343 unsigned int OCI_API OCI_TransactionGetTimeout
00344 (
00345     OCI_Transaction * trans
00346 )
00347 {
00348     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, 0);
00349 
00350     OCI_RESULT(TRUE);
00351 
00352     return trans->timeout;
00353 }