1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2018 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 #if PHP_VERSION_ID < 70300
56 ++GC_REFCOUNT(collection->connection->id);
57 #else
58 GC_ADDREF(collection->connection->id);
59 #endif
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, 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);
236 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
237 php_oci_collection_close(collection);
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)244 int php_oci_collection_size(php_oci_collection *collection, sb4 *size)
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);
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,zend_long * max)263 int php_oci_collection_max(php_oci_collection *collection, zend_long *max)
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,zend_long trim_size)276 int php_oci_collection_trim(php_oci_collection *collection, zend_long trim_size)
277 {
278 php_oci_connection *connection = collection->connection;
279 sword errstatus;
280
281 PHP_OCI_CALL_RETURN(errstatus, OCICollTrim, (connection->env, connection->err, (sb4) trim_size, collection->collection));
282
283 if (errstatus != OCI_SUCCESS) {
284 errstatus = php_oci_error(connection->err, errstatus);
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)295 int php_oci_collection_append_null(php_oci_collection *collection)
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);
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)316 int php_oci_collection_append_date(php_oci_collection *collection, char *date, int date_len)
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);
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);
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)356 int php_oci_collection_append_number(php_oci_collection *collection, char *number, int number_len)
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);
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);
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)397 int php_oci_collection_append_string(php_oci_collection *collection, char *element, int element_len)
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);
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);
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)435 int php_oci_collection_append(php_oci_collection *collection, char *element, int element_len)
436 {
437 if (element_len == 0) {
438 return php_oci_collection_append_null(collection);
439 }
440
441 switch(collection->element_typecode) {
442 case OCI_TYPECODE_DATE:
443 return php_oci_collection_append_date(collection, element, element_len);
444 break;
445
446 case OCI_TYPECODE_VARCHAR2 :
447 return php_oci_collection_append_string(collection, element, element_len);
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);
462 break;
463
464 default:
465 php_error_docref(NULL, 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,zend_long index,zval * result_element)476 int php_oci_collection_element_get(php_oci_collection *collection, zend_long index, zval *result_element)
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 ZVAL_NULL(result_element);
487
488 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
489
490 PHP_OCI_CALL_RETURN(errstatus, OCICollGetElem,
491 (
492 connection->env,
493 connection->err,
494 collection->collection,
495 (ub4)index,
496 &exists,
497 &element,
498 (dvoid **)&element_index
499 )
500 );
501
502 if (errstatus != OCI_SUCCESS) {
503 connection->errcode = php_oci_error(connection->err, errstatus);
504 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
505 return 1;
506 }
507
508 if (exists == 0) {
509 /* element doesn't exist */
510 return 1;
511 }
512
513 if (*element_index == OCI_IND_NULL) {
514 /* this is not an error, we're returning NULL here */
515 return 0;
516 }
517
518 switch (collection->element_typecode) {
519 case OCI_TYPECODE_DATE:
520 PHP_OCI_CALL_RETURN(errstatus, OCIDateToText, (connection->err, element, 0, 0, 0, 0, &buff_len, buff));
521
522 if (errstatus != OCI_SUCCESS) {
523 connection->errcode = php_oci_error(connection->err, errstatus);
524 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
525 return 1;
526 }
527
528 ZVAL_STRINGL(result_element, (char *)buff, buff_len);
529 Z_STRVAL_P(result_element)[buff_len] = '\0';
530
531 return 0;
532 break;
533
534 case OCI_TYPECODE_VARCHAR2:
535 {
536 OCIString *oci_string = *(OCIString **)element;
537 text *str;
538
539 PHP_OCI_CALL_RETURN(str, OCIStringPtr, (connection->env, oci_string));
540
541 if (str) {
542 ZVAL_STRING(result_element, (char *)str);
543 }
544 return 0;
545 }
546 break;
547
548 case OCI_TYPECODE_UNSIGNED16: /* UNSIGNED SHORT */
549 case OCI_TYPECODE_UNSIGNED32: /* UNSIGNED LONG */
550 case OCI_TYPECODE_REAL: /* REAL */
551 case OCI_TYPECODE_DOUBLE: /* DOUBLE */
552 case OCI_TYPECODE_INTEGER: /* INT */
553 case OCI_TYPECODE_SIGNED16: /* SHORT */
554 case OCI_TYPECODE_SIGNED32: /* LONG */
555 case OCI_TYPECODE_DECIMAL: /* DECIMAL */
556 case OCI_TYPECODE_FLOAT: /* FLOAT */
557 case OCI_TYPECODE_NUMBER: /* NUMBER */
558 case OCI_TYPECODE_SMALLINT: /* SMALLINT */
559 {
560 double double_number;
561
562 PHP_OCI_CALL_RETURN(errstatus, OCINumberToReal, (connection->err, (CONST OCINumber *) element, (uword) sizeof(double), (dvoid *) &double_number));
563
564 if (errstatus != OCI_SUCCESS) {
565 connection->errcode = php_oci_error(connection->err, errstatus);
566 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
567 return 1;
568 }
569
570 ZVAL_DOUBLE(result_element, double_number);
571
572 return 0;
573 }
574 break;
575 default:
576 php_error_docref(NULL, E_NOTICE, "Unknown or unsupported type of element: %d", collection->element_typecode);
577 return 1;
578 break;
579 }
580 /* never reached */
581 return 1;
582 }
583 /* }}} */
584
585 /* {{{ php_oci_collection_element_set_null()
586 Set the element with the given index to NULL */
php_oci_collection_element_set_null(php_oci_collection * collection,zend_long index)587 int php_oci_collection_element_set_null(php_oci_collection *collection, zend_long index)
588 {
589 OCIInd null_index = OCI_IND_NULL;
590 php_oci_connection *connection = collection->connection;
591 sword errstatus;
592
593 /* set NULL element */
594 PHP_OCI_CALL_RETURN(errstatus, OCICollAssignElem, (connection->env, connection->err, (ub4) index, (dvoid *)"", &null_index, collection->collection));
595
596 if (errstatus != OCI_SUCCESS) {
597 connection->errcode = php_oci_error(connection->err, errstatus);
598 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
599 return 1;
600 }
601 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
602 return 0;
603 }
604 /* }}} */
605
606 /* {{{ php_oci_collection_element_set_date()
607 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)608 int php_oci_collection_element_set_date(php_oci_collection *collection, zend_long index, char *date, int date_len)
609 {
610 OCIInd new_index = OCI_IND_NOTNULL;
611 OCIDate oci_date;
612 php_oci_connection *connection = collection->connection;
613 sword errstatus;
614
615 /* format and language are NULLs, so format is "DD-MON-YY" and language is the default language of the session */
616 PHP_OCI_CALL_RETURN(errstatus, OCIDateFromText, (connection->err, (CONST text *)date, date_len, NULL, 0, NULL, 0, &oci_date));
617
618 if (errstatus != OCI_SUCCESS) {
619 /* failed to convert string to date */
620 connection->errcode = php_oci_error(connection->err, errstatus);
621 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
622 return 1;
623 }
624
625 PHP_OCI_CALL_RETURN(errstatus, OCICollAssignElem,
626 (
627 connection->env,
628 connection->err,
629 (ub4)index,
630 (dvoid *) &oci_date,
631 (dvoid *) &new_index,
632 (OCIColl *) collection->collection
633 )
634 );
635
636 if (errstatus != OCI_SUCCESS) {
637 connection->errcode = php_oci_error(connection->err, errstatus);
638 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
639 return 1;
640 }
641
642 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
643 return 0;
644 }
645 /* }}} */
646
647 /* {{{ php_oci_collection_element_set_number()
648 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)649 int php_oci_collection_element_set_number(php_oci_collection *collection, zend_long index, char *number, int number_len)
650 {
651 OCIInd new_index = OCI_IND_NOTNULL;
652 double element_double;
653 OCINumber oci_number;
654 php_oci_connection *connection = collection->connection;
655 sword errstatus;
656
657 element_double = zend_strtod(number, NULL);
658
659 PHP_OCI_CALL_RETURN(errstatus, OCINumberFromReal, (connection->err, &element_double, sizeof(double), &oci_number));
660
661 if (errstatus != OCI_SUCCESS) {
662 connection->errcode = php_oci_error(connection->err, errstatus);
663 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
664 return 1;
665 }
666
667 PHP_OCI_CALL_RETURN(errstatus, OCICollAssignElem,
668 (
669 connection->env,
670 connection->err,
671 (ub4) index,
672 (dvoid *) &oci_number,
673 (dvoid *) &new_index,
674 (OCIColl *) collection->collection
675 )
676 );
677
678 if (errstatus != OCI_SUCCESS) {
679 connection->errcode = php_oci_error(connection->err, errstatus);
680 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
681 return 1;
682 }
683
684 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
685 return 0;
686 }
687 /* }}} */
688
689 /* {{{ php_oci_collection_element_set_string()
690 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)691 int php_oci_collection_element_set_string(php_oci_collection *collection, zend_long index, char *element, int element_len)
692 {
693 OCIInd new_index = OCI_IND_NOTNULL;
694 OCIString *ocistr = (OCIString *)0;
695 php_oci_connection *connection = collection->connection;
696 sword errstatus;
697
698 PHP_OCI_CALL_RETURN(errstatus, OCIStringAssignText, (connection->env, connection->err, (CONST oratext *)element, element_len, &ocistr));
699
700 if (errstatus != OCI_SUCCESS) {
701 connection->errcode = php_oci_error(connection->err, errstatus);
702 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
703 return 1;
704 }
705
706 PHP_OCI_CALL_RETURN(errstatus, OCICollAssignElem,
707 (
708 connection->env,
709 connection->err,
710 (ub4)index,
711 (dvoid *) ocistr,
712 (dvoid *) &new_index,
713 (OCIColl *) collection->collection
714 )
715 );
716
717 if (errstatus != OCI_SUCCESS) {
718 connection->errcode = php_oci_error(connection->err, errstatus);
719 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
720 return 1;
721 }
722
723 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
724 return 0;
725 }
726 /* }}} */
727
728 /* {{{ php_oci_collection_element_set()
729 Collection element setter */
php_oci_collection_element_set(php_oci_collection * collection,zend_long index,char * value,int value_len)730 int php_oci_collection_element_set(php_oci_collection *collection, zend_long index, char *value, int value_len)
731 {
732 if (value_len == 0) {
733 return php_oci_collection_element_set_null(collection, index);
734 }
735
736 switch(collection->element_typecode) {
737 case OCI_TYPECODE_DATE:
738 return php_oci_collection_element_set_date(collection, index, value, value_len);
739 break;
740
741 case OCI_TYPECODE_VARCHAR2 :
742 return php_oci_collection_element_set_string(collection, index, value, value_len);
743 break;
744
745 case OCI_TYPECODE_UNSIGNED16 : /* UNSIGNED SHORT */
746 case OCI_TYPECODE_UNSIGNED32 : /* UNSIGNED LONG */
747 case OCI_TYPECODE_REAL : /* REAL */
748 case OCI_TYPECODE_DOUBLE : /* DOUBLE */
749 case OCI_TYPECODE_INTEGER : /* INT */
750 case OCI_TYPECODE_SIGNED16 : /* SHORT */
751 case OCI_TYPECODE_SIGNED32 : /* LONG */
752 case OCI_TYPECODE_DECIMAL : /* DECIMAL */
753 case OCI_TYPECODE_FLOAT : /* FLOAT */
754 case OCI_TYPECODE_NUMBER : /* NUMBER */
755 case OCI_TYPECODE_SMALLINT : /* SMALLINT */
756 return php_oci_collection_element_set_number(collection, index, value, value_len);
757 break;
758
759 default:
760 php_error_docref(NULL, E_NOTICE, "Unknown or unsupported type of element: %d", collection->element_typecode);
761 return 1;
762 break;
763 }
764 /* never reached */
765 return 1;
766 }
767 /* }}} */
768
769 /* {{{ php_oci_collection_assign()
770 Assigns a value to the collection from another collection */
php_oci_collection_assign(php_oci_collection * collection_dest,php_oci_collection * collection_from)771 int php_oci_collection_assign(php_oci_collection *collection_dest, php_oci_collection *collection_from)
772 {
773 php_oci_connection *connection = collection_dest->connection;
774 sword errstatus;
775
776 PHP_OCI_CALL_RETURN(errstatus, OCICollAssign, (connection->env, connection->err, collection_from->collection, collection_dest->collection));
777
778 if (errstatus != OCI_SUCCESS) {
779 connection->errcode = php_oci_error(connection->err, errstatus);
780 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
781 return 1;
782 }
783 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
784 return 0;
785 }
786 /* }}} */
787
788 /* {{{ php_oci_collection_close()
789 Destroy collection and all associated resources */
php_oci_collection_close(php_oci_collection * collection)790 void php_oci_collection_close(php_oci_collection *collection)
791 {
792 php_oci_connection *connection = collection->connection;
793 sword errstatus;
794
795 if (collection->collection) {
796 PHP_OCI_CALL_RETURN(errstatus, OCIObjectFree, (connection->env, connection->err, (dvoid *)collection->collection, (ub2)OCI_OBJECTFREE_FORCE));
797
798 if (errstatus != OCI_SUCCESS) {
799 connection->errcode = php_oci_error(connection->err, errstatus);
800 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
801 } else {
802 connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
803 }
804 }
805
806 zend_list_delete(collection->connection->id);
807 efree(collection);
808 return;
809 }
810 /* }}} */
811
812 #endif /* HAVE_OCI8 */
813
814 /*
815 * Local variables:
816 * tab-width: 4
817 * c-basic-offset: 4
818 * End:
819 * vim600: noet sw=4 ts=4 fdm=marker
820 * vim<600: noet sw=4 ts=4
821 */
822