1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2016 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Stig S�ther Bakken <ssb@php.net> |
16 | Thies C. Arntzen <thies@thieso.net> |
17 | |
18 | Collection support by Andy Sautins <asautins@veripost.net> |
19 | Temporary LOB support by David Benson <dbenson@mancala.com> |
20 | ZTS per process OCIPLogon by Harald Radi <harald.radi@nme.at> |
21 | |
22 | Redesigned by: Antony Dovgal <antony@zend.com> |
23 | Andi Gutmans <andi@zend.com> |
24 | Wez Furlong <wez@omniti.com> |
25 +----------------------------------------------------------------------+
26 */
27
28 /* $Id$ */
29
30
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include "php.h"
37 #include "ext/standard/info.h"
38 #include "php_ini.h"
39
40 #if HAVE_OCI8
41
42 #include "php_oci8.h"
43 #include "php_oci8_int.h"
44
45 /* {{{ php_oci_collection_create()
46 Create and return connection handle */
php_oci_collection_create(php_oci_connection * connection,char * tdo,int tdo_len,char * schema,int schema_len TSRMLS_DC)47 php_oci_collection *php_oci_collection_create(php_oci_connection *connection, char *tdo, int tdo_len, char *schema, int schema_len TSRMLS_DC)
48 {
49 dvoid *dschp1 = NULL;
50 dvoid *parmp1;
51 dvoid *parmp2;
52 php_oci_collection *collection;
53 sword errstatus;
54
55 collection = emalloc(sizeof(php_oci_collection));
56
57 collection->connection = connection;
58 collection->collection = NULL;
59 zend_list_addref(collection->connection->id);
60
61 /* get type handle by name */
62 PHP_OCI_CALL_RETURN(errstatus, OCITypeByName,
63 (
64 connection->env,
65 connection->err,
66 connection->svc,
67 (text *) schema,
68 (ub4) schema_len,
69 (text *) tdo,
70 (ub4) tdo_len,
71 (CONST text *) 0,
72 (ub4) 0,
73 OCI_DURATION_SESSION,
74 OCI_TYPEGET_ALL,
75 &(collection->tdo)
76 )
77 );
78
79 if (errstatus != OCI_SUCCESS) {
80 goto CLEANUP;
81 }
82
83 /* allocate describe handle */
84 PHP_OCI_CALL_RETURN(errstatus, OCIHandleAlloc, (connection->env, (dvoid **) &dschp1, (ub4) OCI_HTYPE_DESCRIBE, (size_t) 0, (dvoid **) 0));
85
86 if (errstatus != OCI_SUCCESS) {
87 goto CLEANUP;
88 }
89
90 /* describe TDO */
91 PHP_OCI_CALL_RETURN(errstatus, OCIDescribeAny,
92 (
93 connection->svc,
94 connection->err,
95 (dvoid *) collection->tdo,
96 (ub4) 0,
97 OCI_OTYPE_PTR,
98 (ub1) OCI_DEFAULT,
99 (ub1) OCI_PTYPE_TYPE,
100 dschp1
101 )
102 );
103
104 if (errstatus != OCI_SUCCESS) {
105 goto CLEANUP;
106 }
107
108 /* get first parameter handle */
109 PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *) dschp1, (ub4) OCI_HTYPE_DESCRIBE, (dvoid *)&parmp1, (ub4 *)0, (ub4)OCI_ATTR_PARAM, connection->err));
110
111 if (errstatus != OCI_SUCCESS) {
112 goto CLEANUP;
113 }
114
115 /* get the collection type code of the attribute */
116 PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet,
117 (
118 (dvoid*) parmp1,
119 (ub4) OCI_DTYPE_PARAM,
120 (dvoid*) &(collection->coll_typecode),
121 (ub4 *) 0,
122 (ub4) OCI_ATTR_COLLECTION_TYPECODE,
123 connection->err
124 )
125 );
126
127 if (errstatus != OCI_SUCCESS) {
128 goto CLEANUP;
129 }
130
131 switch(collection->coll_typecode) {
132 case OCI_TYPECODE_TABLE:
133 case OCI_TYPECODE_VARRAY:
134 /* get collection element handle */
135 PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet,
136 (
137 (dvoid*) parmp1,
138 (ub4) OCI_DTYPE_PARAM,
139 (dvoid*) &parmp2,
140 (ub4 *) 0,
141 (ub4) OCI_ATTR_COLLECTION_ELEMENT,
142 connection->err
143 )
144 );
145
146 if (errstatus != OCI_SUCCESS) {
147 goto CLEANUP;
148 }
149
150 /* get REF of the TDO for the type */
151 PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet,
152 (
153 (dvoid*) parmp2,
154 (ub4) OCI_DTYPE_PARAM,
155 (dvoid*) &(collection->elem_ref),
156 (ub4 *) 0,
157 (ub4) OCI_ATTR_REF_TDO,
158 connection->err
159 )
160 );
161
162 if (errstatus != OCI_SUCCESS) {
163 goto CLEANUP;
164 }
165
166 /* get the TDO (only header) */
167 PHP_OCI_CALL_RETURN(errstatus, OCITypeByRef,
168 (
169 connection->env,
170 connection->err,
171 collection->elem_ref,
172 OCI_DURATION_SESSION,
173 OCI_TYPEGET_HEADER,
174 &(collection->element_type)
175 )
176 );
177
178 if (errstatus != OCI_SUCCESS) {
179 goto CLEANUP;
180 }
181
182 /* get typecode */
183 PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet,
184 (
185 (dvoid*) parmp2,
186 (ub4) OCI_DTYPE_PARAM,
187 (dvoid*) &(collection->element_typecode),
188 (ub4 *) 0,
189 (ub4) OCI_ATTR_TYPECODE,
190 connection->err
191 )
192 );
193
194 if (errstatus != OCI_SUCCESS) {
195 goto CLEANUP;
196 }
197 break;
198 /* we only support VARRAYs and TABLEs */
199 default:
200 php_error_docref(NULL TSRMLS_CC, E_WARNING, "unknown collection type %d", collection->coll_typecode);
201 break;
202 }
203
204 /* Create object to hold return table */
205 PHP_OCI_CALL_RETURN(errstatus, OCIObjectNew,
206 (
207 connection->env,
208 connection->err,
209 connection->svc,
210 OCI_TYPECODE_TABLE,
211 collection->tdo,
212 (dvoid *)0,
213 OCI_DURATION_DEFAULT,
214 TRUE,
215 (dvoid **) &(collection->collection)
216 )
217 );
218
219 if (errstatus != OCI_SUCCESS) {
220 goto CLEANUP;
221 }
222
223 /* free the describe handle (Bug #44113) */
224 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) dschp1, OCI_HTYPE_DESCRIBE));
225 PHP_OCI_REGISTER_RESOURCE(collection, le_collection);
226 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
227 return collection;
228
229 CLEANUP:
230
231 if (dschp1) {
232 /* free the describe handle (Bug #44113) */
233 PHP_OCI_CALL(OCIHandleFree, ((dvoid *) dschp1, OCI_HTYPE_DESCRIBE));
234 }
235 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
236 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
237 php_oci_collection_close(collection TSRMLS_CC);
238 return NULL;
239 }
240 /* }}} */
241
242 /* {{{ php_oci_collection_size()
243 Return size of the collection */
php_oci_collection_size(php_oci_collection * collection,sb4 * size TSRMLS_DC)244 int php_oci_collection_size(php_oci_collection *collection, sb4 *size TSRMLS_DC)
245 {
246 php_oci_connection *connection = collection->connection;
247 sword errstatus;
248
249 PHP_OCI_CALL_RETURN(errstatus, OCICollSize, (connection->env, connection->err, collection->collection, (sb4 *)size));
250
251 if (errstatus != OCI_SUCCESS) {
252 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
253 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
254 return 1;
255 }
256 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
257 return 0;
258 }
259 /* }}} */
260
261 /* {{{ php_oci_collection_max()
262 Return max number of elements in the collection */
php_oci_collection_max(php_oci_collection * collection,long * max TSRMLS_DC)263 int php_oci_collection_max(php_oci_collection *collection, long *max TSRMLS_DC)
264 {
265 php_oci_connection *connection = collection->connection;
266
267 PHP_OCI_CALL_RETURN(*max, OCICollMax, (connection->env, collection->collection));
268
269 /* error handling is not necessary here? */
270 return 0;
271 }
272 /* }}} */
273
274 /* {{{ php_oci_collection_trim()
275 Trim collection to the given number of elements */
php_oci_collection_trim(php_oci_collection * collection,long trim_size TSRMLS_DC)276 int php_oci_collection_trim(php_oci_collection *collection, long trim_size TSRMLS_DC)
277 {
278 php_oci_connection *connection = collection->connection;
279 sword errstatus;
280
281 PHP_OCI_CALL_RETURN(errstatus, OCICollTrim, (connection->env, connection->err, trim_size, collection->collection));
282
283 if (errstatus != OCI_SUCCESS) {
284 errstatus = php_oci_error(connection->err, errstatus TSRMLS_CC);
285 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
286 return 1;
287 }
288 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
289 return 0;
290 }
291 /* }}} */
292
293 /* {{{ php_oci_collection_append_null()
294 Append NULL element to the end of the collection */
php_oci_collection_append_null(php_oci_collection * collection TSRMLS_DC)295 int php_oci_collection_append_null(php_oci_collection *collection TSRMLS_DC)
296 {
297 OCIInd null_index = OCI_IND_NULL;
298 php_oci_connection *connection = collection->connection;
299 sword errstatus;
300
301 /* append NULL element */
302 PHP_OCI_CALL_RETURN(errstatus, OCICollAppend, (connection->env, connection->err, (dvoid *)0, &null_index, collection->collection));
303
304 if (errstatus != OCI_SUCCESS) {
305 errstatus = php_oci_error(connection->err, errstatus TSRMLS_CC);
306 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
307 return 1;
308 }
309 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
310 return 0;
311 }
312 /* }}} */
313
314 /* {{{ php_oci_collection_append_date()
315 Append DATE element to the end of the collection (use "DD-MON-YY" format) */
php_oci_collection_append_date(php_oci_collection * collection,char * date,int date_len TSRMLS_DC)316 int php_oci_collection_append_date(php_oci_collection *collection, char *date, int date_len TSRMLS_DC)
317 {
318 OCIInd new_index = OCI_IND_NOTNULL;
319 OCIDate oci_date;
320 php_oci_connection *connection = collection->connection;
321 sword errstatus;
322
323 /* format and language are NULLs, so format is "DD-MON-YY" and language is the default language of the session */
324 PHP_OCI_CALL_RETURN(errstatus, OCIDateFromText, (connection->err, (CONST text *)date, date_len, NULL, 0, NULL, 0, &oci_date));
325
326 if (errstatus != OCI_SUCCESS) {
327 /* failed to convert string to date */
328 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
329 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
330 return 1;
331 }
332
333 PHP_OCI_CALL_RETURN(errstatus, OCICollAppend,
334 (
335 connection->env,
336 connection->err,
337 (dvoid *) &oci_date,
338 (dvoid *) &new_index,
339 (OCIColl *) collection->collection
340 )
341 );
342
343 if (errstatus != OCI_SUCCESS) {
344 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
345 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
346 return 1;
347 }
348
349 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
350 return 0;
351 }
352 /* }}} */
353
354 /* {{{ php_oci_collection_append_number()
355 Append NUMBER to the end of the collection */
php_oci_collection_append_number(php_oci_collection * collection,char * number,int number_len TSRMLS_DC)356 int php_oci_collection_append_number(php_oci_collection *collection, char *number, int number_len TSRMLS_DC)
357 {
358 OCIInd new_index = OCI_IND_NOTNULL;
359 double element_double;
360 OCINumber oci_number;
361 php_oci_connection *connection = collection->connection;
362 sword errstatus;
363
364 element_double = zend_strtod(number, NULL);
365
366 PHP_OCI_CALL_RETURN(errstatus, OCINumberFromReal, (connection->err, &element_double, sizeof(double), &oci_number));
367
368 if (errstatus != OCI_SUCCESS) {
369 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
370 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
371 return 1;
372 }
373
374 PHP_OCI_CALL_RETURN(errstatus, OCICollAppend,
375 (
376 connection->env,
377 connection->err,
378 (dvoid *) &oci_number,
379 (dvoid *) &new_index,
380 (OCIColl *) collection->collection
381 )
382 );
383
384 if (errstatus != OCI_SUCCESS) {
385 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
386 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
387 return 1;
388 }
389
390 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
391 return 0;
392 }
393 /* }}} */
394
395 /* {{{ php_oci_collection_append_string()
396 Append STRING to the end of the collection */
php_oci_collection_append_string(php_oci_collection * collection,char * element,int element_len TSRMLS_DC)397 int php_oci_collection_append_string(php_oci_collection *collection, char *element, int element_len TSRMLS_DC)
398 {
399 OCIInd new_index = OCI_IND_NOTNULL;
400 OCIString *ocistr = (OCIString *)0;
401 php_oci_connection *connection = collection->connection;
402 sword errstatus;
403
404 PHP_OCI_CALL_RETURN(errstatus, OCIStringAssignText, (connection->env, connection->err, (CONST oratext *)element, element_len, &ocistr));
405
406 if (errstatus != OCI_SUCCESS) {
407 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
408 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
409 return 1;
410 }
411
412 PHP_OCI_CALL_RETURN(errstatus, OCICollAppend,
413 (
414 connection->env,
415 connection->err,
416 (dvoid *) ocistr,
417 (dvoid *) &new_index,
418 (OCIColl *) collection->collection
419 )
420 );
421
422 if (errstatus != OCI_SUCCESS) {
423 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
424 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
425 return 1;
426 }
427
428 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
429 return 0;
430 }
431 /* }}} */
432
433 /* {{{ php_oci_collection_append()
434 Append wrapper. Appends any supported element to the end of the collection */
php_oci_collection_append(php_oci_collection * collection,char * element,int element_len TSRMLS_DC)435 int php_oci_collection_append(php_oci_collection *collection, char *element, int element_len TSRMLS_DC)
436 {
437 if (element_len == 0) {
438 return php_oci_collection_append_null(collection TSRMLS_CC);
439 }
440
441 switch(collection->element_typecode) {
442 case OCI_TYPECODE_DATE:
443 return php_oci_collection_append_date(collection, element, element_len TSRMLS_CC);
444 break;
445
446 case OCI_TYPECODE_VARCHAR2 :
447 return php_oci_collection_append_string(collection, element, element_len TSRMLS_CC);
448 break;
449
450 case OCI_TYPECODE_UNSIGNED16 : /* UNSIGNED SHORT */
451 case OCI_TYPECODE_UNSIGNED32 : /* UNSIGNED LONG */
452 case OCI_TYPECODE_REAL : /* REAL */
453 case OCI_TYPECODE_DOUBLE : /* DOUBLE */
454 case OCI_TYPECODE_INTEGER : /* INT */
455 case OCI_TYPECODE_SIGNED16 : /* SHORT */
456 case OCI_TYPECODE_SIGNED32 : /* LONG */
457 case OCI_TYPECODE_DECIMAL : /* DECIMAL */
458 case OCI_TYPECODE_FLOAT : /* FLOAT */
459 case OCI_TYPECODE_NUMBER : /* NUMBER */
460 case OCI_TYPECODE_SMALLINT : /* SMALLINT */
461 return php_oci_collection_append_number(collection, element, element_len TSRMLS_CC);
462 break;
463
464 default:
465 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown or unsupported type of element: %d", collection->element_typecode);
466 return 1;
467 break;
468 }
469 /* never reached */
470 return 1;
471 }
472 /* }}} */
473
474 /* {{{ php_oci_collection_element_get()
475 Get the element with the given index */
php_oci_collection_element_get(php_oci_collection * collection,long index,zval ** result_element TSRMLS_DC)476 int php_oci_collection_element_get(php_oci_collection *collection, long index, zval **result_element TSRMLS_DC)
477 {
478 php_oci_connection *connection = collection->connection;
479 dvoid *element;
480 OCIInd *element_index;
481 boolean exists;
482 oratext buff[1024];
483 ub4 buff_len = 1024;
484 sword errstatus;
485
486 MAKE_STD_ZVAL(*result_element);
487 ZVAL_NULL(*result_element);
488
489 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
490
491 PHP_OCI_CALL_RETURN(errstatus, OCICollGetElem,
492 (
493 connection->env,
494 connection->err,
495 collection->collection,
496 (ub4)index,
497 &exists,
498 &element,
499 (dvoid **)&element_index
500 )
501 );
502
503 if (errstatus != OCI_SUCCESS) {
504 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
505 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
506 FREE_ZVAL(*result_element);
507 return 1;
508 }
509
510 if (exists == 0) {
511 /* element doesn't exist */
512 FREE_ZVAL(*result_element);
513 return 1;
514 }
515
516 if (*element_index == OCI_IND_NULL) {
517 /* this is not an error, we're returning NULL here */
518 return 0;
519 }
520
521 switch (collection->element_typecode) {
522 case OCI_TYPECODE_DATE:
523 PHP_OCI_CALL_RETURN(errstatus, OCIDateToText, (connection->err, element, 0, 0, 0, 0, &buff_len, buff));
524
525 if (errstatus != OCI_SUCCESS) {
526 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
527 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
528 FREE_ZVAL(*result_element);
529 return 1;
530 }
531
532 ZVAL_STRINGL(*result_element, (char *)buff, buff_len, 1);
533 Z_STRVAL_P(*result_element)[buff_len] = '\0';
534
535 return 0;
536 break;
537
538 case OCI_TYPECODE_VARCHAR2:
539 {
540 OCIString *oci_string = *(OCIString **)element;
541 text *str;
542
543 PHP_OCI_CALL_RETURN(str, OCIStringPtr, (connection->env, oci_string));
544
545 if (str) {
546 ZVAL_STRING(*result_element, (char *)str, 1);
547 }
548 return 0;
549 }
550 break;
551
552 case OCI_TYPECODE_UNSIGNED16: /* UNSIGNED SHORT */
553 case OCI_TYPECODE_UNSIGNED32: /* UNSIGNED LONG */
554 case OCI_TYPECODE_REAL: /* REAL */
555 case OCI_TYPECODE_DOUBLE: /* DOUBLE */
556 case OCI_TYPECODE_INTEGER: /* INT */
557 case OCI_TYPECODE_SIGNED16: /* SHORT */
558 case OCI_TYPECODE_SIGNED32: /* LONG */
559 case OCI_TYPECODE_DECIMAL: /* DECIMAL */
560 case OCI_TYPECODE_FLOAT: /* FLOAT */
561 case OCI_TYPECODE_NUMBER: /* NUMBER */
562 case OCI_TYPECODE_SMALLINT: /* SMALLINT */
563 {
564 double double_number;
565
566 PHP_OCI_CALL_RETURN(errstatus, OCINumberToReal, (connection->err, (CONST OCINumber *) element, (uword) sizeof(double), (dvoid *) &double_number));
567
568 if (errstatus != OCI_SUCCESS) {
569 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
570 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
571 FREE_ZVAL(*result_element);
572 return 1;
573 }
574
575 ZVAL_DOUBLE(*result_element, double_number);
576
577 return 0;
578 }
579 break;
580 default:
581 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown or unsupported type of element: %d", collection->element_typecode);
582 FREE_ZVAL(*result_element);
583 return 1;
584 break;
585 }
586 /* never reached */
587 return 1;
588 }
589 /* }}} */
590
591 /* {{{ php_oci_collection_element_set_null()
592 Set the element with the given index to NULL */
php_oci_collection_element_set_null(php_oci_collection * collection,long index TSRMLS_DC)593 int php_oci_collection_element_set_null(php_oci_collection *collection, long index TSRMLS_DC)
594 {
595 OCIInd null_index = OCI_IND_NULL;
596 php_oci_connection *connection = collection->connection;
597 sword errstatus;
598
599 /* set NULL element */
600 PHP_OCI_CALL_RETURN(errstatus, OCICollAssignElem, (connection->env, connection->err, (ub4) index, (dvoid *)"", &null_index, collection->collection));
601
602 if (errstatus != OCI_SUCCESS) {
603 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
604 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
605 return 1;
606 }
607 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
608 return 0;
609 }
610 /* }}} */
611
612 /* {{{ php_oci_collection_element_set_date()
613 Change element's value to the given DATE */
php_oci_collection_element_set_date(php_oci_collection * collection,long index,char * date,int date_len TSRMLS_DC)614 int php_oci_collection_element_set_date(php_oci_collection *collection, long index, char *date, int date_len TSRMLS_DC)
615 {
616 OCIInd new_index = OCI_IND_NOTNULL;
617 OCIDate oci_date;
618 php_oci_connection *connection = collection->connection;
619 sword errstatus;
620
621 /* format and language are NULLs, so format is "DD-MON-YY" and language is the default language of the session */
622 PHP_OCI_CALL_RETURN(errstatus, OCIDateFromText, (connection->err, (CONST text *)date, date_len, NULL, 0, NULL, 0, &oci_date));
623
624 if (errstatus != OCI_SUCCESS) {
625 /* failed to convert string to date */
626 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
627 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
628 return 1;
629 }
630
631 PHP_OCI_CALL_RETURN(errstatus, OCICollAssignElem,
632 (
633 connection->env,
634 connection->err,
635 (ub4)index,
636 (dvoid *) &oci_date,
637 (dvoid *) &new_index,
638 (OCIColl *) collection->collection
639 )
640 );
641
642 if (errstatus != OCI_SUCCESS) {
643 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
644 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
645 return 1;
646 }
647
648 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
649 return 0;
650 }
651 /* }}} */
652
653 /* {{{ php_oci_collection_element_set_number()
654 Change element's value to the given NUMBER */
php_oci_collection_element_set_number(php_oci_collection * collection,long index,char * number,int number_len TSRMLS_DC)655 int php_oci_collection_element_set_number(php_oci_collection *collection, long index, char *number, int number_len TSRMLS_DC)
656 {
657 OCIInd new_index = OCI_IND_NOTNULL;
658 double element_double;
659 OCINumber oci_number;
660 php_oci_connection *connection = collection->connection;
661 sword errstatus;
662
663 element_double = zend_strtod(number, NULL);
664
665 PHP_OCI_CALL_RETURN(errstatus, OCINumberFromReal, (connection->err, &element_double, sizeof(double), &oci_number));
666
667 if (errstatus != OCI_SUCCESS) {
668 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
669 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
670 return 1;
671 }
672
673 PHP_OCI_CALL_RETURN(errstatus, OCICollAssignElem,
674 (
675 connection->env,
676 connection->err,
677 (ub4) index,
678 (dvoid *) &oci_number,
679 (dvoid *) &new_index,
680 (OCIColl *) collection->collection
681 )
682 );
683
684 if (errstatus != OCI_SUCCESS) {
685 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
686 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
687 return 1;
688 }
689
690 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
691 return 0;
692 }
693 /* }}} */
694
695 /* {{{ php_oci_collection_element_set_string()
696 Change element's value to the given string */
php_oci_collection_element_set_string(php_oci_collection * collection,long index,char * element,int element_len TSRMLS_DC)697 int php_oci_collection_element_set_string(php_oci_collection *collection, long index, char *element, int element_len TSRMLS_DC)
698 {
699 OCIInd new_index = OCI_IND_NOTNULL;
700 OCIString *ocistr = (OCIString *)0;
701 php_oci_connection *connection = collection->connection;
702 sword errstatus;
703
704 PHP_OCI_CALL_RETURN(errstatus, OCIStringAssignText, (connection->env, connection->err, (CONST oratext *)element, element_len, &ocistr));
705
706 if (errstatus != OCI_SUCCESS) {
707 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
708 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
709 return 1;
710 }
711
712 PHP_OCI_CALL_RETURN(errstatus, OCICollAssignElem,
713 (
714 connection->env,
715 connection->err,
716 (ub4)index,
717 (dvoid *) ocistr,
718 (dvoid *) &new_index,
719 (OCIColl *) collection->collection
720 )
721 );
722
723 if (errstatus != OCI_SUCCESS) {
724 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
725 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
726 return 1;
727 }
728
729 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
730 return 0;
731 }
732 /* }}} */
733
734 /* {{{ php_oci_collection_element_set()
735 Collection element setter */
php_oci_collection_element_set(php_oci_collection * collection,long index,char * value,int value_len TSRMLS_DC)736 int php_oci_collection_element_set(php_oci_collection *collection, long index, char *value, int value_len TSRMLS_DC)
737 {
738 if (value_len == 0) {
739 return php_oci_collection_element_set_null(collection, index TSRMLS_CC);
740 }
741
742 switch(collection->element_typecode) {
743 case OCI_TYPECODE_DATE:
744 return php_oci_collection_element_set_date(collection, index, value, value_len TSRMLS_CC);
745 break;
746
747 case OCI_TYPECODE_VARCHAR2 :
748 return php_oci_collection_element_set_string(collection, index, value, value_len TSRMLS_CC);
749 break;
750
751 case OCI_TYPECODE_UNSIGNED16 : /* UNSIGNED SHORT */
752 case OCI_TYPECODE_UNSIGNED32 : /* UNSIGNED LONG */
753 case OCI_TYPECODE_REAL : /* REAL */
754 case OCI_TYPECODE_DOUBLE : /* DOUBLE */
755 case OCI_TYPECODE_INTEGER : /* INT */
756 case OCI_TYPECODE_SIGNED16 : /* SHORT */
757 case OCI_TYPECODE_SIGNED32 : /* LONG */
758 case OCI_TYPECODE_DECIMAL : /* DECIMAL */
759 case OCI_TYPECODE_FLOAT : /* FLOAT */
760 case OCI_TYPECODE_NUMBER : /* NUMBER */
761 case OCI_TYPECODE_SMALLINT : /* SMALLINT */
762 return php_oci_collection_element_set_number(collection, index, value, value_len TSRMLS_CC);
763 break;
764
765 default:
766 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown or unsupported type of element: %d", collection->element_typecode);
767 return 1;
768 break;
769 }
770 /* never reached */
771 return 1;
772 }
773 /* }}} */
774
775 /* {{{ php_oci_collection_assign()
776 Assigns a value to the collection from another collection */
php_oci_collection_assign(php_oci_collection * collection_dest,php_oci_collection * collection_from TSRMLS_DC)777 int php_oci_collection_assign(php_oci_collection *collection_dest, php_oci_collection *collection_from TSRMLS_DC)
778 {
779 php_oci_connection *connection = collection_dest->connection;
780 sword errstatus;
781
782 PHP_OCI_CALL_RETURN(errstatus, OCICollAssign, (connection->env, connection->err, collection_from->collection, collection_dest->collection));
783
784 if (errstatus != OCI_SUCCESS) {
785 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
786 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
787 return 1;
788 }
789 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
790 return 0;
791 }
792 /* }}} */
793
794 /* {{{ php_oci_collection_close()
795 Destroy collection and all associated resources */
php_oci_collection_close(php_oci_collection * collection TSRMLS_DC)796 void php_oci_collection_close(php_oci_collection *collection TSRMLS_DC)
797 {
798 php_oci_connection *connection = collection->connection;
799 sword errstatus;
800
801 if (collection->collection) {
802 PHP_OCI_CALL_RETURN(errstatus, OCIObjectFree, (connection->env, connection->err, (dvoid *)collection->collection, (ub2)OCI_OBJECTFREE_FORCE));
803
804 if (errstatus != OCI_SUCCESS) {
805 connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
806 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
807 } else {
808 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
809 }
810 }
811
812 zend_list_delete(collection->connection->id);
813 efree(collection);
814 return;
815 }
816 /* }}} */
817
818 #endif /* HAVE_OCI8 */
819
820 /*
821 * Local variables:
822 * tab-width: 4
823 * c-basic-offset: 4
824 * End:
825 * vim600: noet sw=4 ts=4 fdm=marker
826 * vim<600: noet sw=4 ts=4
827 */
828