File Coverage

Oracle.xsi
Criterion Covered Total %
statement 13 196 6.6
branch n/a
condition n/a
subroutine n/a
pod n/a
total 13 196 6.6


line stmt bran cond sub pod time code
1             # $Id: Driver.xst 9153 2007-02-22 02:36:14Z timbo $
2             # Copyright (c) 1997-2002 Tim Bunce Ireland
3             # Copyright (c) 2002 Jonathan Leffler
4             #
5             # You may distribute under the terms of either the GNU General Public
6             # License or the Artistic License, as specified in the Perl README file.
7              
8              
9             #include "Driver_xst.h"
10              
11              
12             MODULE = DBD::Oracle PACKAGE = DBD::Oracle
13              
14             REQUIRE:    1.929
15             PROTOTYPES: DISABLE
16              
17             BOOT:
18                 items = 0; /* avoid 'unused variable' warning */
19 20               DBISTATE_INIT;
20                 /* XXX this interface will change: */
21 20               DBI_IMP_SIZE("DBD::Oracle::dr::imp_data_size", sizeof(imp_drh_t));
22 20               DBI_IMP_SIZE("DBD::Oracle::db::imp_data_size", sizeof(imp_dbh_t));
23 20               DBI_IMP_SIZE("DBD::Oracle::st::imp_data_size", sizeof(imp_sth_t));
24 20               dbd_init(DBIS);
25              
26              
27             # ------------------------------------------------------------
28             # driver level interface
29             # ------------------------------------------------------------
30             MODULE = DBD::Oracle PACKAGE = DBD::Oracle::dr
31              
32              
33             #ifdef dbd_discon_all
34              
35             # disconnect_all renamed and ALIAS'd to avoid length clash on VMS :-(
36             void
37             discon_all_(drh)
38                 SV * drh
39                 ALIAS:
40             disconnect_all = 1
41                 CODE:
42                 D_imp_drh(drh);
43                 if (0) ix = ix; /* avoid unused variable warning */
44                 ST(0) = dbd_discon_all(drh, imp_drh) ? &sv_yes : &sv_no;
45              
46             #endif /* dbd_discon_all */
47              
48              
49             #ifdef dbd_dr_data_sources
50              
51             void
52             data_sources(drh, attr = Nullsv)
53                 SV *drh
54                 SV *attr
55                 PPCODE:
56                 {
57             D_imp_drh(drh);
58             AV *av = dbd_dr_data_sources(drh, imp_drh, attr);
59             if (av) {
60             int i;
61             int n = AvFILL(av)+1;
62             EXTEND(sp, n);
63             for (i = 0; i < n; ++i) {
64             PUSHs(AvARRAY(av)[i]);
65             }
66             }
67                 }
68              
69             #endif
70              
71              
72             # ------------------------------------------------------------
73             # database level interface
74             # ------------------------------------------------------------
75             MODULE = DBD::Oracle PACKAGE = DBD::Oracle::db
76              
77              
78             void
79             _login(dbh, dbname, username, password, attribs=Nullsv)
80                 SV * dbh
81                 char * dbname
82                 SV * username
83                 SV * password
84                 SV * attribs
85                 CODE:
86                 {
87                 STRLEN lna;
88 18               D_imp_dbh(dbh);
89 18               char *u = (SvOK(username)) ? SvPV(username,lna) : "";
90 18               char *p = (SvOK(password)) ? SvPV(password,lna) : "";
91             #ifdef dbd_db_login6
92 18               ST(0) = dbd_db_login6(dbh, imp_dbh, dbname, u, p, attribs) ? &sv_yes : &sv_no;
93             #else
94                 ST(0) = dbd_db_login( dbh, imp_dbh, dbname, u, p) ? &sv_yes : &sv_no;
95             #endif
96                 }
97              
98              
99             void
100             selectall_arrayref(...)
101                 PREINIT:
102                 SV *sth;
103                 SV **maxrows_svp;
104                 SV **tmp_svp;
105                 SV *attr = &PL_sv_undef;
106                 imp_sth_t *imp_sth;
107                 CODE:
108 0               if (items > 2) {
109 0           attr = ST(2);
110 0           if (SvROK(attr) &&
111 0           (DBD_ATTRIB_TRUE(attr,"Slice",5,tmp_svp) || DBD_ATTRIB_TRUE(attr,"Columns",7,tmp_svp))
112             ) {
113             /* fallback to perl implementation */
114 0           ST(0) = dbixst_bounce_method("DBD::Oracle::db::SUPER::selectall_arrayref", items);
115 0           XSRETURN(1);
116             }
117                 }
118                 /* --- prepare --- */
119 0           if (SvROK(ST(1))) {
120             sth = ST(1);
121             }
122             else {
123 0           sth = dbixst_bounce_method("prepare", 3);
124 0           if (!SvROK(sth))
125 0           XSRETURN_UNDEF;
126             }
127 0           imp_sth = (imp_sth_t*)(DBIh_COM(sth));
128             /* --- bind_param --- */
129 0           if (items > 3) { /* need to bind params before execute */
130 0           if (!dbdxst_bind_params(sth, imp_sth, items-2, ax+2) ) {
131 0           XSRETURN_UNDEF;
132             }
133             }
134             /* --- execute --- */
135 0           DBIc_ROW_COUNT(imp_sth) = 0;
136 0           if ( dbd_st_execute(sth, imp_sth) <= -2 ) { /* -2 == error */
137 0           XSRETURN_UNDEF;
138             }
139             /* --- fetchall --- */
140 0           maxrows_svp = DBD_ATTRIB_GET_SVP(attr, "MaxRows", 7);
141 0           ST(0) = dbdxst_fetchall_arrayref(sth, &PL_sv_undef, (maxrows_svp) ? *maxrows_svp : &PL_sv_undef);
142            
143            
144             void
145             selectrow_arrayref(...)
146             ALIAS:
147             selectrow_array = 1
148             PREINIT:
149 0           int is_selectrow_array = (ix == 1);
150             imp_sth_t *imp_sth;
151             SV *sth;
152             AV *row_av;
153             PPCODE:
154 0           if (SvROK(ST(1))) {
155             sth = ST(1);
156             }
157             else {
158             /* --- prepare --- */
159 0           sth = dbixst_bounce_method("prepare", 3);
160 0           if (!SvROK(sth)) {
161 0           if (is_selectrow_array) { XSRETURN_EMPTY; } else { XSRETURN_UNDEF; }
162             }
163             }
164 0           imp_sth = (imp_sth_t*)(DBIh_COM(sth));
165             /* --- bind_param --- */
166 0           if (items > 3) { /* need to bind params before execute */
167 0           if (!dbdxst_bind_params(sth, imp_sth, items-2, ax+2) ) {
168 0           if (is_selectrow_array) { XSRETURN_EMPTY; } else { XSRETURN_UNDEF; }
169             }
170             }
171             /* --- execute --- */
172 0           DBIc_ROW_COUNT(imp_sth) = 0;
173 0           if ( dbd_st_execute(sth, imp_sth) <= -2 ) { /* -2 == error */
174 0           if (is_selectrow_array) { XSRETURN_EMPTY; } else { XSRETURN_UNDEF; }
175             }
176             /* --- fetchrow_arrayref --- */
177 0           row_av = dbd_st_fetch(sth, imp_sth);
178 0           if (!row_av) {
179 0           if (GIMME == G_SCALAR)
180 0           PUSHs(&PL_sv_undef);
181             }
182 0           else if (is_selectrow_array) {
183             int i;
184 0           int num_fields = AvFILL(row_av)+1;
185 0           if (GIMME == G_SCALAR)
186             num_fields = 1; /* return just first field */
187 0           EXTEND(sp, num_fields);
188 0           for(i=0; i < num_fields; ++i) {
189 0           PUSHs(AvARRAY(row_av)[i]);
190             }
191             }
192             else {
193 0           PUSHs( sv_2mortal(newRV((SV *)row_av)) );
194             }
195             /* --- finish --- */
196             #ifdef dbd_st_finish3
197             dbd_st_finish3(sth, imp_sth, 0);
198             #else
199 0           dbd_st_finish(sth, imp_sth);
200             #endif
201            
202            
203             #ifdef dbd_db_do4 /* deebeedee-deebee-doo, deebee-doobee-dah? */
204            
205             void
206             do(dbh, statement, params = Nullsv)
207             SV * dbh
208             char * statement
209             SV * params
210             CODE:
211             {
212             D_imp_dbh(dbh);
213             IV retval;
214             retval = dbd_db_do4(dbh, imp_dbh, statement, params);
215             /* remember that dbd_db_do4 must return <= -2 for error */
216             if (retval == 0) /* ok with no rows affected */
217             XST_mPV(0, "0E0"); /* (true but zero) */
218             else if (retval < -1) /* -1 == unknown number of rows */
219             XST_mUNDEF(0); /* <= -2 means error */
220             else
221             XST_mIV(0, retval); /* typically 1, rowcount or -1 */
222             }
223            
224             #endif
225            
226            
227             #ifdef dbd_db_last_insert_id
228            
229             void
230             last_insert_id(dbh, catalog, schema, table, field, attr=Nullsv)
231             SV * dbh
232             SV * catalog
233             SV * schema
234             SV * table
235             SV * field
236             SV * attr
237             CODE:
238             {
239             D_imp_dbh(dbh);
240             ST(0) = dbd_db_last_insert_id(dbh, imp_dbh, catalog, schema, table, field, attr);
241             }
242            
243             #endif
244            
245            
246             void
247             commit(dbh)
248             SV * dbh
249             CODE:
250 0           D_imp_dbh(dbh);
251 0           if (DBIc_has(imp_dbh,DBIcf_AutoCommit) && DBIc_WARN(imp_dbh))
252 0           warn("commit ineffective with AutoCommit enabled");
253 0           ST(0) = dbd_db_commit(dbh, imp_dbh) ? &sv_yes : &sv_no;
254            
255            
256             void
257             rollback(dbh)
258             SV * dbh
259             CODE:
260 0           D_imp_dbh(dbh);
261 0           if (DBIc_has(imp_dbh,DBIcf_AutoCommit) && DBIc_WARN(imp_dbh))
262 0           warn("rollback ineffective with AutoCommit enabled");
263 0           ST(0) = dbd_db_rollback(dbh, imp_dbh) ? &sv_yes : &sv_no;
264            
265            
266             void
267             disconnect(dbh)
268             SV * dbh
269             CODE:
270 0           D_imp_dbh(dbh);
271 0           if ( !DBIc_ACTIVE(imp_dbh) ) {
272 0           XSRETURN_YES;
273             }
274             /* pre-disconnect checks and tidy-ups */
275 0           if (DBIc_CACHED_KIDS(imp_dbh)) {
276 0           SvREFCNT_dec(DBIc_CACHED_KIDS(imp_dbh)); /* cast them to the winds */
277 0           DBIc_CACHED_KIDS(imp_dbh) = Nullhv;
278             }
279             /* Check for disconnect() being called whilst refs to cursors */
280             /* still exists. This possibly needs some more thought. */
281 0           if (DBIc_ACTIVE_KIDS(imp_dbh) && DBIc_WARN(imp_dbh) && !dirty) {
282             STRLEN lna;
283 0           char *plural = (DBIc_ACTIVE_KIDS(imp_dbh)==1) ? "" : "s";
284 0           warn("%s->disconnect invalidates %d active statement handle%s %s",
285             SvPV(dbh,lna), (int)DBIc_ACTIVE_KIDS(imp_dbh), plural,
286             "(either destroy statement handles or call finish on them before disconnecting)");
287             }
288 0           ST(0) = dbd_db_disconnect(dbh, imp_dbh) ? &sv_yes : &sv_no;
289 0           DBIc_ACTIVE_off(imp_dbh); /* ensure it's off, regardless */
290            
291            
292             void
293             STORE(dbh, keysv, valuesv)
294             SV * dbh
295             SV * keysv
296             SV * valuesv
297             CODE:
298 0           D_imp_dbh(dbh);
299 0           if (SvGMAGICAL(valuesv))
300 0           mg_get(valuesv);
301 0           ST(0) = &sv_yes;
302 0           if (!dbd_db_STORE_attrib(dbh, imp_dbh, keysv, valuesv))
303 0           if (!DBIc_DBISTATE(imp_dbh)->set_attr(dbh, keysv, valuesv))
304 0           ST(0) = &sv_no;
305            
306            
307             void
308             FETCH(dbh, keysv)
309             SV * dbh
310             SV * keysv
311             CODE:
312 0           D_imp_dbh(dbh);
313 0           SV *valuesv = dbd_db_FETCH_attrib(dbh, imp_dbh, keysv);
314 0           if (!valuesv)
315 0           valuesv = DBIc_DBISTATE(imp_dbh)->get_attr(dbh, keysv);
316 0           ST(0) = valuesv; /* dbd_db_FETCH_attrib did sv_2mortal */
317            
318            
319             void
320             DESTROY(dbh)
321             SV * dbh
322             PPCODE:
323             /* keep in sync with default DESTROY in DBI.xs */
324 18           D_imp_dbh(dbh);
325 18           ST(0) = &sv_yes;
326 18           if (!DBIc_IMPSET(imp_dbh)) { /* was never fully set up */
327             STRLEN lna;
328 18           if (DBIc_WARN(imp_dbh) && !dirty && DBIc_DBISTATE(imp_dbh)->debug >= 2)
329 0           PerlIO_printf(DBIc_LOGPIO(imp_dbh),
330             " DESTROY for %s ignored - handle not initialised\n",
331             SvPV(dbh,lna));
332             }
333             else {
334             /* pre-disconnect checks and tidy-ups */
335 0           if (DBIc_CACHED_KIDS(imp_dbh)) {
336 0           SvREFCNT_dec(DBIc_CACHED_KIDS(imp_dbh)); /* cast them to the winds */
337 0           DBIc_CACHED_KIDS(imp_dbh) = Nullhv;
338             }
339 0           if (DBIc_IADESTROY(imp_dbh)) { /* want's ineffective destroy */
340 0           DBIc_ACTIVE_off(imp_dbh);
341 0           if (DBIc_DBISTATE(imp_dbh)->debug)
342 0           PerlIO_printf(DBIc_LOGPIO(imp_dbh), " DESTROY %s skipped due to InactiveDestroy\n", SvPV_nolen(dbh));
343             }
344 0           if (DBIc_ACTIVE(imp_dbh)) {
345 0           if (!DBIc_has(imp_dbh,DBIcf_AutoCommit)) {
346             /* Application is using transactions and hasn't explicitly disconnected.
347             Some databases will automatically commit on graceful disconnect.
348             Since we're about to gracefully disconnect as part of the DESTROY
349             we want to be sure we're not about to implicitly commit changes
350             that are incomplete and should be rolled back. (The DESTROY may
351             be due to a RaiseError, for example.) So we rollback here.
352             This will be harmless if the application has issued a commit,
353             XXX Could add an attribute flag to indicate that the driver
354             doesn't have this problem. Patches welcome.
355             XXX or could just move the DBIc_is(imp_dbh, DBIcf_Executed) test
356             to cover the rollback as well. That just needs sanity checking
357             that DBIcf_Executed is set by any/all possible way to execute a
358             statement that might start a transaction.
359             */
360 0           if (DBIc_WARN(imp_dbh)
361             && DBIc_is(imp_dbh, DBIcf_Executed) /* has not just called commit/rollback */
362             && (!dirty || DBIc_DBISTATE(imp_dbh)->debug >= 3)
363             )
364 0           warn("Issuing rollback() for database handle being DESTROY'd without explicit disconnect()");
365 0           dbd_db_rollback(dbh, imp_dbh); /* ROLLBACK! */
366             }
367 0           dbd_db_disconnect(dbh, imp_dbh);
368 0           DBIc_ACTIVE_off(imp_dbh); /* ensure it's off, regardless */
369             }
370 0           dbd_db_destroy(dbh, imp_dbh);
371             }
372            
373            
374             #ifdef dbd_take_imp_data
375            
376             void
377             take_imp_data(h)
378             SV * h
379             CODE:
380             D_imp_xxh(h);
381             /* dbd_take_imp_data() returns &sv_no (or other defined but false value)
382                  * to indicate "preparations complete, now call SUPER::take_imp_data" for me.
383                  * Anything else is returned to the caller via sv_2mortal(sv), typically that
384                  * would be &sv_undef for error or an SV holding the imp_data.
385                  */
386             SV *sv = dbd_take_imp_data(h, imp_xxh, NULL);
387             ST(0) = (SvOK(sv) && !SvTRUE(sv))
388             ? dbixst_bounce_method("DBD::Oracle::db::SUPER::take_imp_data", items)
389             : sv_2mortal(sv);
390            
391             #endif
392            
393             #ifdef dbd_db_data_sources
394            
395             void
396             data_sources(dbh, attr = Nullsv)
397             SV *dbh
398