Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Oracle PRO*C Sample database server
0003  *
0004  * @file atmisv47.proc
0005  */
0006 /* -----------------------------------------------------------------------------
0007  * Enduro/X Middleware Platform for Distributed Transaction Processing
0008  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0009  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0010  * This software is released under one of the following licenses:
0011  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012  * See LICENSE file for full text.
0013  * -----------------------------------------------------------------------------
0014  * AGPL license:
0015  *
0016  * This program is free software; you can redistribute it and/or modify it under
0017  * the terms of the GNU Affero General Public License, version 3 as published
0018  * by the Free Software Foundation;
0019  *
0020  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0021  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0022  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0023  * for more details.
0024  *
0025  * You should have received a copy of the GNU Affero General Public License along 
0026  * with this program; if not, write to the Free Software Foundation, Inc.,
0027  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028  *
0029  * -----------------------------------------------------------------------------
0030  * A commercial use license is available from Mavimax, Ltd
0031  * contact@mavimax.com
0032  * -----------------------------------------------------------------------------
0033  */
0034 
0035 #include <stdio.h>
0036 #include <stdlib.h>
0037 
0038 #ifndef ORA_PROC
0039 #include <ndebug.h>
0040 #endif
0041 
0042 #include <atmi.h>
0043 #include <ndrstandard.h>
0044 #include <ubf.h>
0045 #include <ubfutil.h>
0046 #include <test.fd.h>
0047 #include <string.h>
0048 #include "test47.h"
0049 
0050 #include <sqlca.h> 
0051 
0052 
0053 /*---------------------------Externs------------------------------------*/
0054 /*---------------------------Macros-------------------------------------*/
0055 #define PROC_RESTART do { \
0056         /* in dynamic mode Enduro/X xa libs may not track the point where\
0057          * SQL lost connection by it self\
0058          */\
0059         if (M_dyn && (-3135 == sqlca.sqlcode || -3114==sqlca.sqlcode))\
0060         {\
0061             NDRX_LOG(log_error, "Lost connection, let process to re-init");\
0062             if (tran_started)\
0063             {\
0064                 tpabort(0);\
0065             }\
0066             tpexit();\
0067         }\
0068 } while(0)
0069 
0070 /*---------------------------Enums--------------------------------------*/
0071 /*---------------------------Typedefs-----------------------------------*/
0072 /*---------------------------Globals------------------------------------*/
0073 /*---------------------------Statics------------------------------------*/
0074 exprivate char M_errmark[16] = "TESTERROR";
0075 exprivate long M_tout = 60;
0076 exprivate int M_dyn = EXFALSE; /* are we in dynamic mode? */
0077 /*---------------------------Prototypes---------------------------------*/
0078 
0079 /**
0080  * Read "account" balance from DB
0081  * This will work with out transactions (as read only)
0082  */
0083 void BALANCE (TPSVCINFO *p_svc)
0084 {
0085     int ret=EXSUCCEED;
0086     UBFH *p_ub = (UBFH *)p_svc->data;
0087     int tran_started=EXFALSE;
0088 
0089     EXEC SQL BEGIN DECLARE SECTION;
0090     long h_balance;
0091     char h_accnum[1024];
0092     EXEC SQL END DECLARE SECTION;
0093     
0094     NDRX_LOG(log_debug, "%s got call", __func__);
0095     
0096     if (!tpgetlev())
0097     {
0098         /* start a transaction */
0099         if (EXSUCCEED!=tpbegin(M_tout, 0))
0100         {
0101             NDRX_LOG(log_error, "Failed to start transaction: %s", 
0102                     tpstrerror(tperrno));
0103             EXFAIL_OUT(ret);
0104         }
0105         tran_started=EXTRUE;
0106     }
0107 
0108     /* reallocate the buffer... */
0109     p_ub = (UBFH *)tprealloc((char *)p_ub, Bsizeof(p_ub) + 1024);
0110     
0111     if (NULL==p_ub)
0112     {
0113         EXFAIL_OUT(ret);
0114     }
0115 
0116     /* Just print the buffer */
0117     ndrx_debug_dump_UBF(log_debug, "BALANCE got call", p_ub);
0118 
0119     if (EXFAIL==Bget(p_ub, T_STRING_FLD, 0, h_accnum, 0))
0120     {
0121         NDRX_LOG(log_error, "TESTERROR: Failed to get T_STRING_FLD: %s", 
0122                  Bstrerror(Berror));
0123         ret=EXFAIL;
0124         goto out;
0125     }
0126     
0127     NDRX_LOG(log_info, "Search for account: %s", h_accnum);
0128     
0129     EXEC SQL SELECT balance INTO :h_balance
0130              FROM accounts
0131              WHERE accnum = :h_accnum;
0132     
0133     NDRX_LOG(log_info, "Result: %d", sqlca.sqlcode);
0134     
0135     if (sqlca.sqlcode != 0)
0136     {
0137         NDRX_LOG(log_error, "Failed to select: %d: %.70s", 
0138                 sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
0139 
0140         PROC_RESTART;
0141         EXFAIL_OUT(ret);
0142     }
0143     
0144     if (EXFAIL==Bchg(p_ub, T_LONG_FLD, 0, (char *)&h_balance, 0))
0145     {
0146         NDRX_LOG(log_error, "TESTERROR: Failed to set h_balance: %s", 
0147                  Bstrerror(Berror));
0148         ret=EXFAIL;
0149         goto out;
0150     }
0151     
0152 out:
0153 
0154     if (tran_started)
0155     {
0156         if (EXSUCCEED==ret)
0157         {
0158             if (EXSUCCEED!=tpcommit(0))
0159             {
0160                 NDRX_LOG(log_error, "Failed to commit: %s", tpstrerror(tperrno));
0161                 ret=EXFAIL;
0162             }
0163         }
0164         
0165         if (EXFAIL==ret)
0166         {
0167             if (EXSUCCEED!=tpabort(0))
0168             {
0169                 NDRX_LOG(log_error, "Failed to abort: %s", tpstrerror(tperrno));
0170             }
0171         }
0172     }
0173 
0174     tpreturn(  ret==EXSUCCEED?TPSUCCESS:TPFAIL,
0175                 0L,
0176                 (char *)p_ub,
0177                 0L,
0178                 0L);
0179 }
0180 
0181 /**
0182  * This service will make an account
0183  */
0184 void ACCOPEN (TPSVCINFO *p_svc)
0185 {
0186     int ret=EXSUCCEED;
0187     UBFH *p_ub = (UBFH *)p_svc->data;
0188     int tran_started=EXFALSE;
0189     EXEC SQL BEGIN DECLARE SECTION;
0190     long h_balance;
0191     char h_accnum[1024];
0192     EXEC SQL END DECLARE SECTION;
0193     TPTRANID trn;
0194     
0195     NDRX_LOG(log_debug, "%s got call", __func__);
0196 
0197     if (!tpgetlev())
0198     {
0199         /* start a transaction */
0200         if (EXSUCCEED!=tpbegin(M_tout, 0))
0201         {
0202             NDRX_LOG(log_error, "Failed to start transaction: %s", 
0203                     tpstrerror(tperrno));
0204             EXFAIL_OUT(ret);
0205         }
0206         tran_started=EXTRUE;
0207     }
0208     
0209     /* Just print the buffer */
0210     ndrx_debug_dump_UBF(log_debug, "ACCOPEN got call", p_ub);
0211     
0212 
0213     if (EXSUCCEED!=tpsuspend (&trn, 0))
0214     {
0215         NDRX_LOG(log_error, "%s: failed to suspend: %s", M_errmark, tpstrerror(tperrno));
0216         EXFAIL_OUT(ret);
0217     }
0218 
0219     if (EXSUCCEED!=tpresume (&trn, 0))
0220     {
0221         NDRX_LOG(log_error, "%s: failed to resume: %s", M_errmark, tpstrerror(tperrno));
0222         EXFAIL_OUT(ret);
0223     }
0224 
0225     /* suspend again, now resume with no optimization */
0226     if (EXSUCCEED!=tpsuspend (&trn, 0))
0227     {
0228         NDRX_LOG(log_error, "%s: failed to suspend: %s", M_errmark, tpstrerror(tperrno));
0229         EXFAIL_OUT(ret);
0230     }
0231 
0232     if (EXSUCCEED!=tpresume (&trn, TPTXNOOPTIM))
0233     {
0234         NDRX_LOG(log_error, "%s: failed to resume TPTXNOOPTIM: %s", M_errmark, tpstrerror(tperrno));
0235         EXFAIL_OUT(ret);
0236     }
0237 
0238     /* OK continue... */
0239 
0240     if (EXFAIL==Bget(p_ub, T_STRING_FLD, 0, h_accnum, 0))
0241     {
0242         NDRX_LOG(log_error, "TESTERROR: Failed to get T_STRING_FLD: %s", 
0243                  Bstrerror(Berror));
0244         ret=EXFAIL;
0245         goto out;
0246     }
0247     
0248     if (EXFAIL==Bget(p_ub, T_LONG_FLD, 0, (char *)&h_balance, 0))
0249     {
0250         NDRX_LOG(log_error, "TESTERROR: Failed to get h_balance: %s", 
0251                  Bstrerror(Berror));
0252         ret=EXFAIL;
0253         goto out;
0254     }
0255     
0256     NDRX_LOG(log_info, "Opening account: [%s] balance: [%ld]", 
0257             h_accnum, h_balance);
0258     
0259     
0260     EXEC SQL INSERT INTO accounts(accnum, balance)
0261         VALUES(:h_accnum, :h_balance);
0262     
0263     NDRX_LOG(log_info, "Result: %d", sqlca.sqlcode);
0264     
0265     if (sqlca.sqlcode != 0)
0266     {
0267         NDRX_LOG(log_error, "Failed to select: %d: %.70s", 
0268                 sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
0269 
0270         PROC_RESTART;
0271         EXFAIL_OUT(ret);
0272     }
0273     
0274 out:
0275         
0276     if (tran_started)
0277     {
0278         if (EXSUCCEED==ret)
0279         {
0280             if (EXSUCCEED!=tpcommit(0))
0281             {
0282                 NDRX_LOG(log_error, "Failed to commit: %s", tpstrerror(tperrno));
0283                 ret=EXFAIL;
0284             }
0285         }
0286         
0287         if (EXFAIL==ret)
0288         {
0289             if (EXSUCCEED!=tpabort(0))
0290             {
0291                 NDRX_LOG(log_error, "Failed to abort: %s", tpstrerror(tperrno));
0292             }
0293         }
0294     }
0295 
0296     tpreturn(  ret==EXSUCCEED?TPSUCCESS:TPFAIL,
0297                 0L,
0298                 (char *)p_ub,
0299                 0L,
0300                 0L);
0301 }
0302 
0303 
0304 /**
0305  * This service will make an account
0306  */
0307 void ACCCLEAN (TPSVCINFO *p_svc)
0308 {
0309     int ret=EXSUCCEED;
0310     int tran_started=EXFALSE;
0311     EXEC SQL BEGIN DECLARE SECTION;
0312     long h_balance;
0313     char h_accnum[1024];
0314     EXEC SQL END DECLARE SECTION;
0315     
0316     NDRX_LOG(log_debug, "%s got call", __func__);
0317 
0318     if (!tpgetlev())
0319     {
0320         /* start a transaction */
0321         if (EXSUCCEED!=tpbegin(M_tout, 0))
0322         {
0323             NDRX_LOG(log_error, "Failed to start transaction: %s", 
0324                     tpstrerror(tperrno));
0325             EXFAIL_OUT(ret);
0326         }
0327         tran_started=EXTRUE;
0328     }
0329     
0330     EXEC SQL DELETE FROM ACCOUNTS;
0331     
0332     NDRX_LOG(log_info, "Result: %d", sqlca.sqlcode);
0333     
0334     if (sqlca.sqlcode != 0 && sqlca.sqlcode != 100)
0335     {
0336         NDRX_LOG(log_error, "Failed to delete: %d: %.70s", 
0337                 sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
0338 
0339         PROC_RESTART;
0340         EXFAIL_OUT(ret);
0341     }
0342     
0343 out:
0344         
0345     if (tran_started)
0346     {
0347         if (EXSUCCEED==ret)
0348         {
0349             if (EXSUCCEED!=tpcommit(0))
0350             {
0351                 NDRX_LOG(log_error, "Failed to commit: %s", tpstrerror(tperrno));
0352                 ret=EXFAIL;
0353             }
0354         }
0355         
0356         if (EXFAIL==ret)
0357         {
0358             if (EXSUCCEED!=tpabort(0))
0359             {
0360                 NDRX_LOG(log_error, "Failed to abort: %s", tpstrerror(tperrno));
0361             }
0362         }
0363     }
0364 
0365     tpreturn(  ret==EXSUCCEED?TPSUCCESS:TPFAIL,
0366                 0L,
0367                 NULL,
0368                 0L,
0369                 0L);
0370 }
0371 
0372 /**
0373  * Fetch testing
0374  */
0375 void FETCH (TPSVCINFO *p_svc)
0376 {
0377 
0378     EXEC SQL BEGIN DECLARE SECTION;
0379     char h_typecode[17];
0380     EXEC SQL END DECLARE SECTION;
0381     int ret = EXSUCCEED;
0382     long rsplen = 0;
0383     char *odata;
0384 
0385     EXEC SQL DECLARE type_cursor CURSOR FOR
0386         SELECT TYPECODE
0387         FROM ACCOUNT_TYPES;
0388 
0389     if (sqlca.sqlcode != 0)
0390     {
0391         NDRX_LOG(log_error, "Failed to select: %d: %.70s",
0392                 sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
0393         EXFAIL_OUT(ret);
0394     }
0395 
0396     EXEC SQL OPEN type_cursor;
0397 
0398     if (sqlca.sqlcode != 0)
0399     {
0400         NDRX_LOG(log_error, "Failed to select: %d: %.70s",
0401                 sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
0402         EXFAIL_OUT(ret);
0403     }
0404 
0405     for ( ;; )
0406     {
0407 
0408         /* Fetching data */
0409         EXEC SQL FETCH type_cursor 
0410             INTO :h_typecode;
0411 
0412         if ( sqlca.sqlcode == 100 )
0413         {
0414             NDRX_LOG(log_debug, "EOF");
0415             goto out;
0416         }
0417 
0418         if ( sqlca.sqlcode != 0 )
0419         {
0420             NDRX_LOG(log_error, "Failed to fetch: %d: %.70s",
0421                 sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
0422             EXFAIL_OUT(ret);
0423         }
0424 
0425         /* Perform service call (to have suspend) */
0426         odata=NULL;
0427         if (EXSUCCEED!=tpcall("DEL", NULL, 0, &odata, &rsplen, 0))
0428         {
0429             NDRX_LOG(log_error, "Failed to call DEL: %s", tpstrerror(tperrno));
0430             EXFAIL_OUT(ret);
0431         }
0432 
0433     }
0434 
0435 out:
0436     EXEC SQL CLOSE type_cursor;
0437 
0438     tpreturn(  ret==EXSUCCEED?TPSUCCESS:TPFAIL,
0439                 0L,
0440                 NULL,
0441                 0L,
0442                 0L);
0443 
0444 }
0445 
0446 /**
0447  * Do initialization
0448  */
0449 int NDRX_INTEGRA(tpsvrinit)(int argc, char **argv)
0450 {
0451     int ret = EXSUCCEED;
0452     char *p;
0453     NDRX_LOG(log_debug, "tpsvrinit called");
0454     
0455     if (NULL!=getenv(KILL_TEST_ENV))
0456     {
0457         NDRX_STRCPY_SAFE(M_errmark, "LOOPERR");
0458         M_tout = MAX_RSP;
0459     }
0460 
0461     if (NULL!=(p=getenv("NDRX_XA_DRIVERLIB")) && NULL!=strstr(p, "libndrxxaorad"))
0462     {
0463         M_dyn = EXTRUE;
0464     }
0465 
0466     if (EXSUCCEED!=tpopen())
0467     {
0468         NDRX_LOG(log_error, "Failed to open DB!");
0469         EXFAIL_OUT(ret);
0470     }
0471     
0472     if (EXSUCCEED!=tpadvertise("BALANCE", BALANCE))
0473     {
0474         NDRX_LOG(log_error, "Failed to initialize BALANCE!");
0475         EXFAIL_OUT(ret);
0476     }
0477     
0478     if (EXSUCCEED!=tpadvertise("ACCOPEN", ACCOPEN))
0479     {
0480         NDRX_LOG(log_error, "Failed to initialize ACCOPEN!");
0481         EXFAIL_OUT(ret);
0482     }
0483     
0484     if (EXSUCCEED!=tpadvertise("ACCCLEAN", ACCCLEAN))
0485     {
0486         NDRX_LOG(log_error, "Failed to initialize ACCCLEAN!");
0487         EXFAIL_OUT(ret);
0488     }
0489 
0490     if (EXSUCCEED!=tpadvertise("FETCH", FETCH))
0491     {
0492         NDRX_LOG(log_error, "Failed to initialize FETCH!");
0493         EXFAIL_OUT(ret);
0494     }
0495     
0496 out:
0497     return ret;
0498 }
0499 
0500 /**
0501  * Do de-initialization
0502  */
0503 void NDRX_INTEGRA(tpsvrdone)(void)
0504 {
0505     NDRX_LOG(log_debug, "tpsvrdone called");
0506     
0507     tpclose();
0508     
0509 }
0510 
0511 /* vim: set ts=4 sw=4 et smartindent: */