Skip to content

Commit 6c1a3c3

Browse files
authored
Create drcp.c (#213)
* Create drcp.c Accessing DRCP(Database Resident Connection Pool) through OCI (Oracle Call Interface) Session Pool * Update drcp.c Updated the year to 2022 * Updated the year everywhere
1 parent 6bc5b61 commit 6c1a3c3

File tree

1 file changed

+263
-0
lines changed

1 file changed

+263
-0
lines changed

C/drcp.c

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
/* Copyright (c) 2022, Oracle. All rights reserved. */
2+
3+
/* drcp.c */
4+
5+
/* Oracle OCI Database Resident Connection Pooling (DRCP) Example */
6+
/* Christopher Jones, 2022 */
7+
8+
#include <stdio.h>
9+
#include <stdlib.h>
10+
#include <string.h>
11+
#include <unistd.h>
12+
#include <oci.h>
13+
14+
// const OraText userName[] = "SCOTT";
15+
// const OraText userPassword[] = "TIGER";
16+
17+
/* Take the user credentials as inputs*/
18+
OraText userName[129];
19+
OraText userPassword[129];
20+
const OraText connectString[] = "localhost/orclpdb:pooled"; /* Request a "pooled" connection with the correct DB service name */
21+
const OraText connectionClassName[] = "MYTEST"; /* DRCP connection class name */
22+
23+
#define DRCP_PURITY OCI_ATTR_PURITY_SELF /* Reuse DB sessions for maximum pooling benefit */
24+
#define NUM_ITERS 10 /* Default number of times to get a server from the DB pool and do a query */
25+
#define THINK_TIME 3 /* Default seconds to sleep between loop iterations */
26+
27+
static void do_query(OCISvcCtx *svchp, OCIError *errhp);
28+
static void checkerr(OCIError *errhp, sword status);
29+
30+
int main(int argc, char **argv)
31+
{
32+
OCIEnv *envhp = NULL;
33+
OCIError *errhp = NULL;
34+
OCIAuthInfo *authInfop = NULL;
35+
OCISvcCtx *svchp = NULL;
36+
OraText *poolName = NULL;
37+
ub4 poolNameLen = 0;
38+
OCISPool *spoolhp = NULL;
39+
ub4 purity;
40+
int rc;
41+
int i;
42+
int numIters = NUM_ITERS;
43+
int thinkTime = THINK_TIME;
44+
text errbuf[OCI_ERROR_MAXMSG_SIZE];
45+
sb4 oracode;
46+
47+
/*
48+
* Set the loop count and think time between iterations
49+
*/
50+
51+
if (argc == 3)
52+
{
53+
numIters = atoi(argv[1]);
54+
thinkTime = atoi(argv[2]);
55+
}
56+
else if (argc != 1)
57+
{
58+
printf("Usage: %s [loop_count think_time]\n", argv[0]);
59+
exit(1);
60+
}
61+
printf("Iterating %d times with %d second sleep between iterations\n\n", numIters, thinkTime);
62+
63+
/*
64+
* Initialize the DB context
65+
*/
66+
67+
rc = OCIEnvNlsCreate(&envhp, OCI_DEFAULT, 0, NULL, NULL, NULL, 0, NULL, 0, 0);
68+
if (rc != OCI_SUCCESS)
69+
{
70+
oracode = 0;
71+
*errbuf = '\0';
72+
if (envhp)
73+
OCIErrorGet(envhp, 1, NULL, &oracode, errbuf, sizeof(errbuf), OCI_HTYPE_ENV);
74+
if (*errbuf)
75+
printf("OCIEnvNlsCreate failed: %d : %s\n", oracode, errbuf);
76+
else
77+
printf("OCIEnvNlsCreate returned status: %d\n", rc);
78+
exit(1);
79+
}
80+
81+
rc = OCIHandleAlloc(envhp, (void **)&errhp, OCI_HTYPE_ERROR, 0, NULL);
82+
if (rc != OCI_SUCCESS)
83+
{
84+
oracode = 0;
85+
*errbuf = '\0';
86+
OCIErrorGet(envhp, 1, NULL, &oracode, errbuf, sizeof(errbuf), OCI_HTYPE_ENV);
87+
if (*errbuf)
88+
printf("OCIHandleAlloc failed: %d : %s\n", oracode, errbuf);
89+
else
90+
printf("OCIHandleAlloc returned status: %d\n", rc);
91+
exit(1);
92+
}
93+
94+
rc = OCIHandleAlloc(envhp, (void **)&authInfop, OCI_HTYPE_AUTHINFO, 0, NULL);
95+
checkerr(errhp, rc);
96+
97+
rc = OCIHandleAlloc(envhp, (void **)&spoolhp, OCI_HTYPE_SPOOL, 0, NULL);
98+
checkerr(errhp, rc);
99+
100+
printf("Enter the DB username: ");
101+
scanf("%s", userName);
102+
printf("Enter the DB password: ");
103+
scanf("%s", userPassword);
104+
105+
rc = OCISessionPoolCreate(envhp, errhp, spoolhp, &poolName, &poolNameLen,
106+
connectString, strlen((char *)connectString), 0, UB4MAXVAL, 1,
107+
(OraText *)userName, strlen((char *)userName),
108+
(OraText *)userPassword, strlen((char *)userPassword),
109+
OCI_SPC_NO_RLB | OCI_SPC_HOMOGENEOUS);
110+
checkerr(errhp, rc);
111+
if (rc != OCI_SUCCESS && rc != OCI_SUCCESS_WITH_INFO)
112+
exit(1);
113+
/*
114+
* Set the connection class name and purity. These could be set
115+
* inside the loop before OCISessionGet() if the values vary
116+
* between loop iterations, for example if the loop is controlling
117+
* multiple, different kinds of work.
118+
*/
119+
120+
rc = OCIAttrSet(authInfop, OCI_HTYPE_AUTHINFO,
121+
(void *)connectionClassName, strlen((char *)connectionClassName),
122+
OCI_ATTR_CONNECTION_CLASS, errhp);
123+
checkerr(errhp, rc);
124+
125+
/* Uncomment the 4 lines below to set the Purity attribute of the pool to new */
126+
// purity = DRCP_PURITY;
127+
// purity = OCI_ATTR_PURITY_NEW;
128+
// rc = OCIAttrSet(authInfop, OCI_HTYPE_AUTHINFO, (dvoid *)&purity, 0, OCI_ATTR_PURITY, errhp);
129+
// checkerr(errhp, rc);
130+
131+
/*
132+
* Loop, alternately doing DB operations and non-DB operations aka
133+
* sleeping (in this example)
134+
*/
135+
136+
for (i = 0; i < numIters; ++i)
137+
{
138+
/*
139+
* Simulate doing non-DB work between iterations
140+
*/
141+
142+
if (i > 0)
143+
{
144+
printf("\nSleeping %d seconds...\n\n", thinkTime);
145+
sleep(thinkTime);
146+
}
147+
148+
/*
149+
* Get a DRCP pooled server. The associated service handle is
150+
* returned from OCISessionGet and then used for DB
151+
* operations. After use here, the DRCP pooled server is
152+
* released back to the DB pool for reuse by other
153+
* applications.
154+
*/
155+
rc = OCISessionGet(envhp, errhp, &svchp, authInfop, poolName, poolNameLen,
156+
NULL, 0, NULL, NULL, NULL, OCI_SESSGET_SPOOL);
157+
checkerr(errhp, rc);
158+
if (rc != OCI_SUCCESS && rc != OCI_SUCCESS_WITH_INFO)
159+
exit(1);
160+
printf("The user tables available are: \n");
161+
do_query(svchp, errhp);
162+
rc = OCISessionRelease(svchp, errhp, NULL, 0, OCI_DEFAULT);
163+
checkerr(errhp, rc);
164+
if (rc != OCI_SUCCESS && rc != OCI_SUCCESS_WITH_INFO)
165+
exit(1);
166+
}
167+
168+
checkerr(errhp, OCISessionPoolDestroy(spoolhp, errhp, OCI_DEFAULT));
169+
checkerr(errhp, OCIHandleFree((dvoid *)spoolhp, OCI_HTYPE_SPOOL));
170+
checkerr(errhp, OCIHandleFree((dvoid *)authInfop, OCI_HTYPE_AUTHINFO));
171+
OCIHandleFree((dvoid *)errhp, OCI_HTYPE_ERROR);
172+
OCIHandleFree((dvoid *)envhp, OCI_HTYPE_ENV);
173+
174+
exit(0);
175+
}
176+
177+
/*
178+
* Query a single column varchar column
179+
*/
180+
181+
const OraText queryString[] =
182+
"SELECT table_name FROM user_tables WHERE ROWNUM < 21 ORDER BY table_name";
183+
#define COLUMN_LENGTH (128 + 1)
184+
#define ARRAY_SIZE 100 /* Number of rows to array fetch */
185+
186+
static void do_query(OCISvcCtx *svchp, OCIError *errhp)
187+
{
188+
OCIStmt *stmtp = NULL;
189+
OCIDefine *defnpp = NULL;
190+
int rc;
191+
int i;
192+
int num_rows_fetched = 0;
193+
char column_data[ARRAY_SIZE][COLUMN_LENGTH];
194+
195+
rc = OCIStmtPrepare2(svchp, &stmtp, errhp, queryString, strlen((char *)queryString),
196+
NULL, 0, OCI_NTV_SYNTAX, OCI_DEFAULT);
197+
checkerr(errhp, rc);
198+
rc = OCIDefineByPos(stmtp, &defnpp, errhp, 1, (void *)column_data, COLUMN_LENGTH,
199+
SQLT_STR, NULL, NULL, NULL, OCI_DEFAULT);
200+
checkerr(errhp, rc);
201+
rc = OCIStmtExecute(svchp, stmtp, errhp, ARRAY_SIZE, 0, NULL, NULL, OCI_DEFAULT); /* execute & fetch ARRAY_SIZE rows */
202+
if (rc != OCI_NO_DATA) /* OCI_NO_DATA is expected at EOF */
203+
checkerr(errhp, rc);
204+
205+
while (rc == OCI_SUCCESS || rc == OCI_NO_DATA)
206+
{
207+
OCIAttrGet(stmtp, OCI_HTYPE_STMT, (void *)&num_rows_fetched, NULL, OCI_ATTR_ROWS_FETCHED, errhp);
208+
209+
for (i = 0; i < num_rows_fetched; ++i)
210+
printf("%s\n", column_data[i]);
211+
212+
if (rc == OCI_NO_DATA)
213+
break;
214+
215+
rc = OCIStmtFetch2(stmtp, errhp, ARRAY_SIZE, OCI_DEFAULT, 0, OCI_DEFAULT);
216+
if (rc != OCI_NO_DATA) /* OCI_NO_DATA is expected at EOF */
217+
checkerr(errhp, rc);
218+
}
219+
220+
rc = OCIStmtRelease(stmtp, errhp, NULL, 0, OCI_DEFAULT);
221+
checkerr(errhp, rc);
222+
}
223+
224+
/*
225+
* Check Errors
226+
*/
227+
228+
void checkerr(errhp, status)
229+
OCIError *errhp;
230+
sword status;
231+
{
232+
OraText errbuf[OCI_ERROR_MAXMSG_SIZE];
233+
sb4 errcode = 0;
234+
switch (status)
235+
{
236+
case OCI_SUCCESS:
237+
break;
238+
case OCI_SUCCESS_WITH_INFO:
239+
printf("Error - OCI_SUCCESS_WITH_INFO\n");
240+
break;
241+
case OCI_NEED_DATA:
242+
printf("Error - OCI_NEED_DATA\n");
243+
break;
244+
case OCI_NO_DATA:
245+
printf("Error - OCI_NO_DATA\n");
246+
break;
247+
case OCI_ERROR:
248+
OCIErrorGet((void *)errhp, 1, (OraText *)NULL, &errcode, errbuf, sizeof(errbuf), OCI_HTYPE_ERROR);
249+
printf("Error - %.*s\n", (int)sizeof(errbuf), errbuf);
250+
break;
251+
case OCI_INVALID_HANDLE:
252+
printf("Error - OCI_INVALID_HANDLE\n");
253+
break;
254+
case OCI_STILL_EXECUTING:
255+
printf("Error - OCI_STILL_EXECUTE\n");
256+
break;
257+
case OCI_CONTINUE:
258+
printf("Error - OCI_CONTINUE\n");
259+
break;
260+
default:
261+
break;
262+
}
263+
}

0 commit comments

Comments
 (0)