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