oci8_collection.c 24 KB

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