oci8_collection.c 24 KB

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