ora.c
上传用户:xfwatch
上传日期:2020-12-14
资源大小:872k
文件大小:8k
源码类别:

中间件编程

开发平台:

Java

  1. /*
  2.  * JBoss, Home of Professional Open Source
  3.  * Copyright 2009, Red Hat, Inc., and others contributors as indicated
  4.  * by the @authors tag. All rights reserved.
  5.  * See the copyright.txt in the distribution for a
  6.  * full listing of individual contributors.
  7.  * This copyrighted material is made available to anyone wishing to use,
  8.  * modify, copy, or redistribute it subject to the terms and conditions
  9.  * of the GNU Lesser General Public License, v. 2.1.
  10.  * This program is distributed in the hope that it will be useful, but WITHOUT A
  11.  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  12.  * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
  13.  * You should have received a copy of the GNU Lesser General Public License,
  14.  * v.2.1 along with this distribution; if not, write to the Free Software
  15.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  16.  * MA  02110-1301, USA.
  17.  */
  18. /* Based on the code samples in the Oracle Streams Advanced Queuing User's Guide and Reference */
  19. #include "tx/request.h"
  20. #ifdef ORACLE
  21. #include <oci.h>
  22. /* 
  23.  * If a session wont release a lock here's how to recover
  24.  * 
  25.  * find the lock (lock type should be TX):
  26.  * SELECT sid,type,id1,lmode,request from v$lock;
  27.  *
  28.  * find the lock owner:
  29.  * SELECT s.sid, s.serial#, s.osuser, s.program FROM v$session s where s.sid=140;
  30.  * end the session that owns the lock:
  31.  * ALTER SYSTEM KILL SESSION 'sid,serial#';
  32.  *
  33.  */
  34. #ifdef WIN32
  35. extern __declspec(dllimport) struct xa_switch_t xaoswd;
  36. #else
  37. struct xa_switch_t xaoswd;
  38. #endif
  39. /* figure out the oracle error code and message corresponding to an Oracle error */
  40. static void get_error(test_req_t *resp, dvoid *errhp, sword status) {
  41. if  (status == OCI_ERROR) {
  42. text buf[256];
  43. sb4 err = 0;
  44. (void) OCIErrorGet(errhp, (ub4) 1, (text *) NULL, &err, (text *) buf, (ub4) sizeof (buf), OCI_HTYPE_ERROR);
  45. userlogc_snprintf(resp->data, sizeof (resp->data), "%s", buf);
  46. } else {
  47.     userlogc_snprintf(resp->data, sizeof (resp->data), "OCI error: %d", (int) status);
  48. }
  49. }
  50. static void show_error(dvoid *errhp, sword status) {
  51. if  (status == OCI_ERROR) {
  52. text buf[256];
  53. sb4 err = 0;
  54. (void) OCIErrorGet(errhp, (ub4) 1, (text *) NULL, &err, buf, (ub4) sizeof(buf), OCI_HTYPE_ERROR);
  55. userlogc_warn( "TxLog OCI error %d: %s", (int) err, buf);
  56. } else {
  57. userlogc_warn( "TxLog OCI error: %d", (int) status);
  58. }
  59. }
  60. /* execute an SQL statement for the given service context */
  61. static int doSql(OCISvcCtx *svcCtx, OCIStmt *stmthp, OCIError *errhp, text *sql, int empno) {
  62. OCIBind *bndp = (OCIBind *) 0;
  63. sword status = OCIStmtPrepare(stmthp, errhp, (text *) sql, (ub4) strlen((char *)sql),
  64. (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT);
  65. userlogc_debug( "TxLog executing statement: %s :1=%d", sql, empno);
  66. /* bind empno to the statement */
  67. if (empno > 0 && status == OCI_SUCCESS)
  68. status = OCIBindByPos(stmthp, &bndp, errhp, 1, (dvoid *) &empno, (sword) sizeof (empno),
  69. SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
  70. if (status == OCI_SUCCESS)
  71. status = OCIStmtExecute(svcCtx, stmthp, errhp, (ub4) 1, (ub4) 0,
  72. (CONST OCISnapshot *) NULL,
  73. (OCISnapshot *) NULL, OCI_DEFAULT);
  74. if (status != OCI_SUCCESS)
  75. show_error(errhp, status);
  76. return status;
  77. }
  78. /* update test */
  79. static int doUpdate(OCISvcCtx *svcCtx, OCIStmt *stmthp, OCIError *errhp, int empno) {
  80. text *sql = (text *) "UPDATE EMP SET JOB='DIRECTOR' WHERE EMPNO=:1" ;
  81. return doSql(svcCtx, stmthp, errhp, sql, empno);
  82. }
  83. /* insert test */
  84. static int doInsert(OCISvcCtx *svcCtx, OCIStmt *stmthp, OCIError *errhp, int empno) {
  85. text *sql = (text *) "INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)"
  86. " VALUES (:1,'Jim','Janitor','7902','17-DEC-80','900','0','20')";
  87. return doSql(svcCtx, stmthp, errhp, sql, empno);
  88. }
  89. /* delete test WARNING the delete is WHERE EMPNO >= :1 */
  90. static int doDelete(OCISvcCtx *svcCtx, OCIStmt *stmthp, OCIError *errhp, int empno) {
  91. text *sql = (text *) "DELETE FROM EMP WHERE EMPNO >= :1" ;
  92. return doSql(svcCtx, stmthp, errhp, sql, empno);
  93. }
  94. /* select test */
  95. static int doSelect(OCISvcCtx *svcCtx, OCIStmt *stmthp, OCIError *errhp, int empno, int *rcnt) {
  96. OCIBind *bndp = (OCIBind *) 0;
  97. text *sql = (text *) "SELECT ENAME,JOB FROM EMP WHERE EMPNO >= :1" ;
  98. char emp[20];
  99. char job[20];
  100. OCIDefine *stmtdef1 = (OCIDefine *) 0;
  101. OCIDefine *stmtdef2 = (OCIDefine *) 0;
  102. userlogc_debug( "TxLog doSelect: :1=%d", empno);
  103. sword status = OCIStmtPrepare(stmthp, errhp, (text *) sql, (ub4) strlen((char *) sql),
  104. (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT);
  105. /* bind empno to the statement */
  106. if (status == OCI_SUCCESS)
  107. status = OCIBindByPos(stmthp, &bndp, errhp, 1, (dvoid *) &empno, (sword) sizeof (empno),
  108. SQLT_INT, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT);
  109. /* define the output variables for the select */
  110. if (status == OCI_SUCCESS)
  111. status = OCIDefineByPos(stmthp, &stmtdef1, errhp, 1, (dvoid *)&emp,(sword) sizeof (emp), SQLT_STR,
  112. (dvoid *) 0, (ub2 *)0, (ub2 *)0, (ub4) OCI_DEFAULT);
  113. if (status == OCI_SUCCESS)
  114. status = OCIDefineByPos(stmthp, &stmtdef2, errhp, 2, (dvoid *)&job,(sword) sizeof (job), SQLT_STR,
  115. (dvoid *) 0, (ub2 *)0, (ub2 *)0, (ub4) OCI_DEFAULT);
  116. /* exectute the select */
  117. if (status == OCI_SUCCESS)
  118. status = OCIStmtExecute(svcCtx, stmthp, errhp, (ub4) 0, (ub4) 0, (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT);
  119. userlogc_debug( "TxLog executing statement: %s :1=%d", sql, empno);
  120. *rcnt = 0;
  121. if (status != OCI_SUCCESS && status != OCI_NO_DATA) {
  122. show_error(errhp, status);
  123. return status;
  124. } else {
  125. while (1) {
  126. status = OCIStmtFetch(stmthp, errhp, (ub4) 1, (ub4) OCI_FETCH_NEXT, (ub4) OCI_DEFAULT);
  127. if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO)
  128. break;
  129. userlogc_debug( "TxLog Name: %s Job: %s", emp, job);
  130. (*rcnt) += 1;
  131. }
  132. userlogc_debug( "TxLog result: %d", *rcnt);
  133. return OCI_SUCCESS;
  134. }
  135. }
  136. /* the test: insert some data, update it and finally delete it */
  137. static sword doWork(char op, char *arg, OCISvcCtx *svcCtx, OCIStmt *stmthp, OCIError *errhp, test_req_t *resp) {
  138. sword status = OCI_SUCCESS;
  139. int empno;
  140. userlogc_debug( "TxLog doWork op=%c arg=%s", op, arg);
  141. empno = (*arg ? atoi(arg) : 8000);
  142. (resp->data)[0] = 0;
  143. if (op == '0') {
  144. status = doInsert(svcCtx, stmthp, errhp, empno);
  145. } else if (op == '1') {
  146. int rcnt = 0; // no of matching records
  147. status = doSelect(svcCtx, stmthp, errhp, empno, &rcnt);
  148.     userlogc_snprintf(resp->data, sizeof (resp->data), "%d", rcnt);
  149. } else if (op == '2') {
  150. status = doUpdate(svcCtx, stmthp, errhp, empno);
  151. } else if (op == '3') {
  152. status = doDelete(svcCtx, stmthp, errhp, empno);
  153. }
  154. if (status != OCI_SUCCESS)
  155. get_error(resp, errhp, status);
  156. return status;
  157. }
  158. long ora_xaflags()
  159. {
  160. return xaoswd.flags;
  161. }
  162. /**
  163.  * test that blacktie correctly drives oracle xa
  164.  * Precondition: - there is an active transaction (implies that that there is open XA connection)
  165.  *
  166.  * arguments:
  167.  * op - 0 for insert 1 for select 2 for update and 3 for delete (CRUD)
  168.  * arg - used in selects to hold the expected number of records
  169.  * rbuf - used to report error strings (except in a successful select it holds the number of matching records)
  170.  * bufsz - the length of rbuf
  171.  */
  172. int ora_access(test_req_t *req, test_req_t *resp)
  173. {
  174. OCIStmt *stmthp;
  175. OCIError *errhp;
  176. OCIEnv *xaEnv;
  177. OCISvcCtx *svcCtx;
  178. sword status;
  179. userlogc_debug( "TxLog ora_access op=%c data=%s db=%s", req->op, req->data, req->db);
  180. /* opening an XA connection creates an environment and service context */
  181. xaEnv = (struct OCIEnv *) xaoEnv((text *) req->db) ;
  182. svcCtx = (struct OCISvcCtx *) xaoSvcCtx((text *) req->db);
  183. if (!xaEnv || !svcCtx)
  184. return fatal("TxLog ORA:- Unable to obtain env and/or service context!");
  185. /* initialise OCI handles */
  186. if (OCI_SUCCESS != OCIHandleAlloc((dvoid *)xaEnv, (dvoid **)&errhp,
  187. OCI_HTYPE_ERROR, 0, (dvoid **)0))
  188. return fatal("ORA:- Unable to allocate statement handle");
  189. if (OCI_SUCCESS != OCIHandleAlloc((dvoid *)xaEnv, (dvoid **)&stmthp,
  190. OCI_HTYPE_STMT, 0, (dvoid **)0))
  191. return fatal("ORA:- Unable to allocate error handle");
  192. /* run the test */
  193. status = doWork(req->op, req->data, svcCtx, stmthp, errhp, resp);
  194. userlogc_debug( "TxLog %d: doWork %c returned: %s", status, req->op, resp->data);
  195. // return status; // OCI_SUCCESS is 0
  196. return (status != OCI_SUCCESS); // 0 means success
  197. }
  198. #endif