Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Oracle OCI Sample database server.
0003  *  basic sample to demonstrate OCI operations
0004  *
0005  * @file atmisv47_oci.c
0006  */
0007 /* -----------------------------------------------------------------------------
0008  * Enduro/X Middleware Platform for Distributed Transaction Processing
0009  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0010  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0011  * This software is released under one of the following licenses:
0012  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0013  * See LICENSE file for full text.
0014  * -----------------------------------------------------------------------------
0015  * AGPL license:
0016  *
0017  * This program is free software; you can redistribute it and/or modify it under
0018  * the terms of the GNU Affero General Public License, version 3 as published
0019  * by the Free Software Foundation;
0020  *
0021  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0022  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0023  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0024  * for more details.
0025  *
0026  * You should have received a copy of the GNU Affero General Public License along 
0027  * with this program; if not, write to the Free Software Foundation, Inc.,
0028  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0029  *
0030  * -----------------------------------------------------------------------------
0031  * A commercial use license is available from Mavimax, Ltd
0032  * contact@mavimax.com
0033  * -----------------------------------------------------------------------------
0034  */
0035 
0036 #include <stdio.h>
0037 #include <stdlib.h>
0038 
0039 #include <ndebug.h>
0040 #include <atmi.h>
0041 #include <ndrstandard.h>
0042 #include <ubf.h>
0043 #include <ubfutil.h>
0044 #include <test.fd.h>
0045 #include <string.h>
0046 #include "test47.h"
0047 #include <oci.h>
0048 
0049 /*---------------------------Externs------------------------------------*/
0050 /*---------------------------Macros-------------------------------------*/
0051 /*---------------------------Enums--------------------------------------*/
0052 /*---------------------------Typedefs-----------------------------------*/
0053 /*---------------------------Globals------------------------------------*/
0054 /*---------------------------Statics------------------------------------*/
0055 exprivate OCIEnv        *M_oci_env;
0056 exprivate OCISvcCtx     *M_oci_svc_ctx;
0057 
0058 /*---------------------------Prototypes---------------------------------*/
0059 
0060 /**
0061  *  Perform insert using the XA transaction
0062  */
0063 exprivate int do_insert(char *accnum, long balance)
0064 {
0065     int           ret;
0066     OCIStmt       *stmt_h=NULL;
0067     OCIError      *err_h=NULL;
0068     char stmt[1024];
0069     
0070     snprintf(stmt, sizeof(stmt), "INSERT INTO accounts(accnum, balance) VALUES('%s', %ld)",
0071         accnum, balance);
0072 
0073     if (OCI_SUCCESS != OCIHandleAlloc( (dvoid *)M_oci_env, (dvoid **)&err_h,
0074                                      OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0))
0075     {
0076         NDRX_LOG(log_error, "Unable to allocate error handle");
0077         EXFAIL_OUT(ret);
0078     }
0079 
0080     if (OCI_SUCCESS != OCIHandleAlloc( (dvoid *)M_oci_env, (dvoid **)&stmt_h,
0081                              OCI_HTYPE_STMT, (size_t)0, (dvoid **)0))
0082     {
0083         NDRX_LOG(log_error, "Unable to allocate statement handle");
0084         EXFAIL_OUT(ret);
0085     }
0086     
0087     if (OCI_SUCCESS != OCIStmtPrepare(stmt_h, err_h, stmt,
0088                                         (ub4) strlen(stmt),
0089                                         (ub4) OCI_NTV_SYNTAX,
0090                                         (ub4) OCI_DEFAULT))
0091     {
0092         NDRX_LOG(log_error, "Failed to prepare stmt");
0093         EXFAIL_OUT(ret);
0094     }
0095 
0096     ret = OCIStmtExecute(M_oci_svc_ctx, stmt_h, err_h,
0097                             (ub4)1, (ub4)0,
0098                             (CONST OCISnapshot *)NULL,
0099                             (OCISnapshot *)NULL, OCI_DEFAULT);
0100 
0101     if (OCI_SUCCESS != ret && OCI_SUCCESS_WITH_INFO != ret)
0102     {
0103         NDRX_LOG(log_error, "Failed to execute ret: %d", ret);
0104         EXFAIL_OUT(ret);
0105     }
0106 
0107     ret=EXSUCCEED;
0108     
0109 out:
0110     if (NULL!=stmt_h)
0111     {
0112         OCIHandleFree((dvoid *)stmt_h, (ub4)OCI_HTYPE_STMT);
0113     }
0114 
0115     if (NULL!=err_h)
0116     {
0117         OCIHandleFree((dvoid *)err_h, (ub4)OCI_HTYPE_ERROR);
0118     }
0119 
0120     return ret;
0121 }
0122 
0123 /**
0124  * This service will make an account
0125  */
0126 void ACCOPEN_OCI (TPSVCINFO *p_svc)
0127 {
0128     int ret=EXSUCCEED;
0129     UBFH *p_ub = (UBFH *)p_svc->data;
0130     int tran_started=EXFALSE;
0131     long h_balance;
0132     char h_accnum[1024];
0133     TPTRANID trn;
0134     
0135     NDRX_LOG(log_debug, "%s got call", __func__);
0136 
0137     if (!tpgetlev())
0138     {
0139         /* start a transaction */
0140         if (EXSUCCEED!=tpbegin(60, 0))
0141         {
0142             NDRX_LOG(log_error, "Failed to start transaction: %s", 
0143                     tpstrerror(tperrno));
0144             EXFAIL_OUT(ret);
0145         }
0146         tran_started=EXTRUE;
0147     }
0148     
0149     /* Just print the buffer */
0150     ndrx_debug_dump_UBF(log_debug, "ACCOPEN_OCI got call", p_ub);
0151     
0152     if (EXSUCCEED!=tpsuspend (&trn, 0))
0153     {
0154         NDRX_LOG(log_error, "failed to suspend: %s", tpstrerror(tperrno));
0155         EXFAIL_OUT(ret);
0156     }
0157 
0158     if (EXSUCCEED!=tpresume (&trn, 0))
0159     {
0160         NDRX_LOG(log_error, "failed to resume: %s", tpstrerror(tperrno));
0161         EXFAIL_OUT(ret);
0162     }
0163 
0164     if (EXFAIL==Bget(p_ub, T_STRING_FLD, 0, h_accnum, 0))
0165     {
0166         NDRX_LOG(log_error, "TESTERROR: Failed to get T_STRING_FLD: %s", 
0167                  Bstrerror(Berror));
0168         EXFAIL_OUT(ret);
0169     }
0170     
0171     if (EXFAIL==Bget(p_ub, T_LONG_FLD, 0, (char *)&h_balance, 0))
0172     {
0173         NDRX_LOG(log_error, "TESTERROR: Failed to get h_balance: %s", 
0174                  Bstrerror(Berror));
0175         EXFAIL_OUT(ret);
0176     }
0177     
0178     NDRX_LOG(log_info, "Opening account: [%s] balance: [%ld]", 
0179             h_accnum, h_balance);
0180     
0181     if (EXSUCCEED!=do_insert(h_accnum, h_balance))
0182     {
0183         EXFAIL_OUT(ret);
0184     }
0185 
0186     NDRX_LOG(log_debug, "OK");
0187     
0188 out:
0189         
0190     if (tran_started)
0191     {
0192         if (EXSUCCEED==ret)
0193         {
0194             if (EXSUCCEED!=tpcommit(0))
0195             {
0196                 NDRX_LOG(log_error, "Failed to commit: %s", tpstrerror(tperrno));
0197                 ret=EXFAIL;
0198             }
0199         }
0200         
0201         if (EXFAIL==ret)
0202         {
0203             if (EXSUCCEED!=tpabort(0))
0204             {
0205                 NDRX_LOG(log_error, "Failed to abort: %s", tpstrerror(tperrno));
0206             }
0207         }
0208     }
0209 
0210     tpreturn(  ret==EXSUCCEED?TPSUCCESS:TPFAIL,
0211                 0L,
0212                 (char *)p_ub,
0213                 0L,
0214                 0L);
0215 }
0216 
0217 /**
0218  * Do initialization
0219  */
0220 int NDRX_INTEGRA(tpsvrinit)(int argc, char **argv)
0221 {
0222     int ret = EXSUCCEED;
0223     char *p;
0224     NDRX_LOG(log_debug, "tpsvrinit called");
0225     
0226     if (EXSUCCEED!=tpopen())
0227     {
0228         NDRX_LOG(log_error, "Failed to open DB!");
0229         EXFAIL_OUT(ret);
0230     }
0231 
0232     /* Get the XA env: */
0233     if (NULL == (M_oci_env = xaoEnv(NULL)))
0234     {
0235         NDRX_LOG(log_error, "xaoEnv returned a NULL pointer\n");
0236         EXFAIL_OUT(ret);
0237     }
0238 
0239     if (NULL == (M_oci_svc_ctx = xaoSvcCtx(NULL)))
0240     {
0241         NDRX_LOG(log_error, "xaoSvcCtx returned a NULL pointer\n");
0242         EXFAIL_OUT(ret);
0243     }
0244     
0245     if (EXSUCCEED!=tpadvertise("ACCOPEN_OCI", ACCOPEN_OCI))
0246     {
0247         NDRX_LOG(log_error, "Failed to initialize ACCOPEN_OCI!");
0248         EXFAIL_OUT(ret);
0249     }
0250     
0251     
0252 out:
0253     return ret;
0254 }
0255 
0256 /**
0257  * Do de-initialization
0258  */
0259 void NDRX_INTEGRA(tpsvrdone)(void)
0260 {
0261     NDRX_LOG(log_debug, "tpsvrdone called");
0262     
0263     tpclose();
0264     
0265 }
0266 
0267 /* vim: set ts=4 sw=4 et smartindent: */