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