oci8_collection.c 23 KB

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