This source file includes following definitions.
- php_oci_lob_create
- php_oci_lob_get_length
- php_oci_lob_callback
- php_oci_lob_calculate_buffer
- php_oci_lob_read
- php_oci_lob_write
- php_oci_lob_set_buffering
- php_oci_lob_get_buffering
- php_oci_lob_copy
- php_oci_lob_close
- php_oci_temp_lob_close
- php_oci_lob_flush
- php_oci_lob_free
- php_oci_lob_import
- php_oci_lob_append
- php_oci_lob_truncate
- php_oci_lob_erase
- php_oci_lob_is_equal
- php_oci_lob_write_tmp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
46 #include <fcntl.h>
47
48 #ifndef O_BINARY
49 #define O_BINARY 0
50 #endif
51
52
53
54 php_oci_descriptor *php_oci_lob_create (php_oci_connection *connection, zend_long type)
55 {
56 php_oci_descriptor *descriptor;
57 sword errstatus;
58
59 switch (type) {
60 case OCI_DTYPE_FILE:
61 case OCI_DTYPE_LOB:
62 case OCI_DTYPE_ROWID:
63
64 break;
65 default:
66 php_error_docref(NULL, E_WARNING, "Unknown descriptor type %pd", type);
67 return NULL;
68 break;
69 }
70
71 descriptor = ecalloc(1, sizeof(php_oci_descriptor));
72 descriptor->type = (ub4) type;
73 descriptor->connection = connection;
74 ++GC_REFCOUNT(descriptor->connection->id);
75
76 PHP_OCI_CALL_RETURN(errstatus, OCIDescriptorAlloc, (connection->env, (dvoid*)&(descriptor->descriptor), descriptor->type, (size_t) 0, (dvoid **) 0));
77
78 if (errstatus != OCI_SUCCESS) {
79 OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus);
80 PHP_OCI_HANDLE_ERROR(connection, OCI_G(errcode));
81 efree(descriptor);
82 return NULL;
83 } else {
84 OCI_G(errcode) = 0;
85 }
86
87 PHP_OCI_REGISTER_RESOURCE(descriptor, le_descriptor);
88
89 descriptor->lob_current_position = 0;
90 descriptor->lob_size = -1;
91 descriptor->buffering = PHP_OCI_LOB_BUFFER_DISABLED;
92 descriptor->charset_form = SQLCS_IMPLICIT;
93 descriptor->charset_id = connection->charset;
94 descriptor->is_open = 0;
95 descriptor->chunk_size = 0;
96
97 if (descriptor->type == OCI_DTYPE_LOB || descriptor->type == OCI_DTYPE_FILE) {
98
99 if (!connection->descriptors) {
100 ALLOC_HASHTABLE(connection->descriptors);
101 zend_hash_init(connection->descriptors, 0, NULL, php_oci_descriptor_flush_hash_dtor, 0);
102 connection->descriptor_count = 0;
103 }
104
105 descriptor->index = (connection->descriptor_count)++;
106 if (connection->descriptor_count == LONG_MAX) {
107 php_error_docref(NULL, E_WARNING, "Internal descriptor counter has reached limit");
108 php_oci_connection_descriptors_free(connection);
109 return NULL;
110 }
111
112 zend_hash_index_update_ptr(connection->descriptors, descriptor->index, descriptor);
113 }
114 return descriptor;
115
116 }
117
118
119
120
121 int php_oci_lob_get_length (php_oci_descriptor *descriptor, ub4 *length)
122 {
123 php_oci_connection *connection = descriptor->connection;
124 sword errstatus;
125
126 *length = 0;
127
128 if (descriptor->lob_size >= 0) {
129 *length = descriptor->lob_size;
130 return 0;
131 } else {
132 if (descriptor->type == OCI_DTYPE_FILE) {
133 PHP_OCI_CALL_RETURN(errstatus, OCILobFileOpen, (connection->svc, connection->err, descriptor->descriptor, OCI_FILE_READONLY));
134 if (errstatus != OCI_SUCCESS) {
135 connection->errcode = php_oci_error(connection->err, errstatus);
136 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
137 return 1;
138 }
139 }
140
141 PHP_OCI_CALL_RETURN(errstatus, OCILobGetLength, (connection->svc, connection->err, descriptor->descriptor, (ub4 *)length));
142
143 if (errstatus != OCI_SUCCESS) {
144 connection->errcode = php_oci_error(connection->err, errstatus);
145 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
146 return 1;
147 }
148
149 descriptor->lob_size = *length;
150
151 if (descriptor->type == OCI_DTYPE_FILE) {
152 PHP_OCI_CALL_RETURN(errstatus, OCILobFileClose, (connection->svc, connection->err, descriptor->descriptor));
153
154 if (errstatus != OCI_SUCCESS) {
155 connection->errcode = php_oci_error(connection->err, errstatus);
156 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
157 return 1;
158 }
159 }
160
161 connection->errcode = 0;
162 }
163 return 0;
164 }
165
166
167
168
169 sb4 php_oci_lob_callback (dvoid *ctxp, CONST dvoid *bufxp, oraub8 len, ub1 piece, dvoid **changed_bufpp, oraub8 *changed_lenp)
170 {
171 ub4 lenp = (ub4) len;
172 php_oci_lob_ctx *ctx = (php_oci_lob_ctx *)ctxp;
173
174 switch (piece)
175 {
176 case OCI_LAST_PIECE:
177 if ((*(ctx->lob_len) + lenp) > (ctx->alloc_len)) {
178
179 *(ctx->lob_data) = NULL;
180 *(ctx->lob_len) = 0;
181 return OCI_ERROR;
182 }
183 memcpy(*(ctx->lob_data) + *(ctx->lob_len), bufxp, (size_t) lenp);
184 *(ctx->lob_len) += lenp;
185 *(*(ctx->lob_data) + *(ctx->lob_len)) = 0x00;
186 return OCI_CONTINUE;
187
188 case OCI_FIRST_PIECE:
189 case OCI_NEXT_PIECE:
190 if ((*(ctx->lob_len) + lenp) > ctx->alloc_len) {
191
192 *(ctx->lob_data) = NULL;
193 *(ctx->lob_len) = 0;
194 return OCI_ERROR;
195 }
196 memcpy(*(ctx->lob_data) + *(ctx->lob_len), bufxp, (size_t) lenp);
197 *(ctx->lob_len) += lenp;
198 return OCI_CONTINUE;
199
200 default: {
201 php_error_docref(NULL, E_WARNING, "Unexpected LOB piece id received (value:%d)", piece);
202 *(ctx->lob_data) = NULL;
203 *(ctx->lob_len) = 0;
204 return OCI_ERROR;
205 }
206 }
207 }
208
209
210
211
212 static inline int php_oci_lob_calculate_buffer(php_oci_descriptor *descriptor, zend_long read_length)
213 {
214 php_oci_connection *connection = descriptor->connection;
215 ub4 chunk_size;
216 sword errstatus;
217
218 if (descriptor->type == OCI_DTYPE_FILE) {
219 return (int) read_length;
220 }
221
222 if (!descriptor->chunk_size) {
223 PHP_OCI_CALL_RETURN(errstatus, OCILobGetChunkSize, (connection->svc, connection->err, descriptor->descriptor, &chunk_size));
224
225 if (errstatus != OCI_SUCCESS) {
226 connection->errcode = php_oci_error(connection->err, errstatus);
227 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
228 return (int) read_length;
229 }
230 descriptor->chunk_size = chunk_size;
231 connection->errcode = 0;
232 }
233
234 if ((read_length % descriptor->chunk_size) != 0) {
235 return (int) descriptor->chunk_size * (((int) read_length / descriptor->chunk_size) + 1);
236 }
237 return (int) read_length;
238 }
239
240
241
242
243 int php_oci_lob_read (php_oci_descriptor *descriptor, zend_long read_length, zend_long initial_offset, char **data, ub4 *data_len)
244 {
245 php_oci_connection *connection = descriptor->connection;
246 ub4 length = 0;
247 int buffer_size = PHP_OCI_LOB_BUFFER_SIZE;
248 php_oci_lob_ctx ctx;
249 ub1 *bufp;
250 oraub8 bytes_read, offset = 0;
251 oraub8 requested_len = read_length;
252 oraub8 chars_read = 0;
253 int is_clob = 0;
254 sb4 bytes_per_char = 1;
255 sword errstatus;
256
257 *data_len = 0;
258 *data = NULL;
259
260 ctx.lob_len = data_len;
261 ctx.lob_data = data;
262 ctx.alloc_len = 0;
263
264 if (php_oci_lob_get_length(descriptor, &length)) {
265 return 1;
266 }
267
268 if (length <= 0) {
269 return 0;
270 }
271
272 if (initial_offset > length) {
273 php_error_docref(NULL, E_WARNING, "Offset must be less than size of the LOB");
274 return 1;
275 }
276
277 if (read_length == -1) {
278 requested_len = length;
279 }
280
281 if ((ub4) requested_len > (length - (ub4) initial_offset)) {
282 requested_len = length - initial_offset;
283 }
284
285 if (requested_len <= 0) {
286 return 0;
287 }
288
289 offset = initial_offset;
290
291 if (descriptor->type == OCI_DTYPE_FILE) {
292 PHP_OCI_CALL_RETURN(errstatus, OCILobFileOpen, (connection->svc, connection->err, descriptor->descriptor, OCI_FILE_READONLY));
293
294 if (errstatus != OCI_SUCCESS) {
295 connection->errcode = php_oci_error(connection->err, errstatus);
296 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
297 return 1;
298 }
299 } else {
300 ub2 charset_id = 0;
301
302 PHP_OCI_CALL_RETURN(errstatus, OCILobCharSetId, (connection->env, connection->err, descriptor->descriptor, &charset_id));
303
304 if (errstatus != OCI_SUCCESS) {
305 connection->errcode = php_oci_error(connection->err, errstatus);
306 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
307 return 1;
308 }
309
310 if (charset_id > 0) {
311 is_clob = 1;
312 }
313 }
314
315 if (is_clob) {
316 PHP_OCI_CALL_RETURN(errstatus, OCINlsNumericInfoGet, (connection->env, connection->err, &bytes_per_char, OCI_NLS_CHARSET_MAXBYTESZ));
317
318 if (errstatus != OCI_SUCCESS) {
319 connection->errcode = php_oci_error(connection->err, errstatus);
320 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
321 return 1;
322 }
323 } else {
324
325 }
326
327 ctx.alloc_len = ((ub4) requested_len + 1) * bytes_per_char;
328 *data = ecalloc(bytes_per_char, requested_len + 1);
329
330 if (is_clob) {
331 chars_read = requested_len;
332 bytes_read = 0;
333 } else {
334 chars_read = 0;
335 bytes_read = requested_len;
336 }
337
338 buffer_size = ((int) requested_len < buffer_size ) ? (int) requested_len : buffer_size;
339 buffer_size = php_oci_lob_calculate_buffer(descriptor, buffer_size);
340
341 bufp = (ub1 *) ecalloc(1, buffer_size);
342 PHP_OCI_CALL_RETURN(errstatus, OCILobRead2,
343 (
344 connection->svc,
345 connection->err,
346 descriptor->descriptor,
347 (oraub8 *)&bytes_read,
348 (oraub8 *)&chars_read,
349 (oraub8) offset + 1,
350 (dvoid *) bufp,
351 (oraub8) buffer_size,
352 OCI_FIRST_PIECE,
353 (dvoid *)&ctx,
354 (OCICallbackLobRead2) php_oci_lob_callback,
355 (ub2) descriptor->charset_id,
356 (ub1) descriptor->charset_form
357 )
358 );
359
360 efree(bufp);
361
362 if (is_clob) {
363 offset = descriptor->lob_current_position + chars_read;
364 } else {
365 offset = descriptor->lob_current_position + bytes_read;
366 }
367
368 if (errstatus != OCI_SUCCESS) {
369 connection->errcode = php_oci_error(connection->err, errstatus);
370 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
371 if (*data) {
372 efree(*data);
373 *data = NULL;
374 }
375 *data_len = 0;
376 return 1;
377 }
378
379 descriptor->lob_current_position = (int)offset;
380
381 if (descriptor->type == OCI_DTYPE_FILE) {
382 PHP_OCI_CALL_RETURN(errstatus, OCILobFileClose, (connection->svc, connection->err, descriptor->descriptor));
383
384 if (errstatus != OCI_SUCCESS) {
385 connection->errcode = php_oci_error(connection->err, errstatus);
386 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
387 if (*data) {
388 efree(*data);
389 *data = NULL;
390 }
391 *data_len = 0;
392 return 1;
393 }
394 }
395
396 connection->errcode = 0;
397 return 0;
398 }
399
400
401
402
403 int php_oci_lob_write (php_oci_descriptor *descriptor, ub4 offset, char *data, int data_len, ub4 *bytes_written)
404 {
405 OCILobLocator *lob = (OCILobLocator *) descriptor->descriptor;
406 php_oci_connection *connection = (php_oci_connection *) descriptor->connection;
407 ub4 lob_length;
408 sword errstatus;
409
410 *bytes_written = 0;
411 if (php_oci_lob_get_length(descriptor, &lob_length)) {
412 return 1;
413 }
414
415 if (!data || data_len <= 0) {
416 return 0;
417 }
418
419 if (offset > descriptor->lob_current_position) {
420 offset = descriptor->lob_current_position;
421 }
422
423 PHP_OCI_CALL_RETURN(errstatus, OCILobWrite,
424 (
425 connection->svc,
426 connection->err,
427 lob,
428 (ub4 *)&data_len,
429 (ub4) offset + 1,
430 (dvoid *) data,
431 (ub4) data_len,
432 OCI_ONE_PIECE,
433 (dvoid *)0,
434 (OCICallbackLobWrite) 0,
435 (ub2) descriptor->charset_id,
436 (ub1) descriptor->charset_form
437 )
438 );
439
440 if (errstatus) {
441 connection->errcode = php_oci_error(connection->err, errstatus);
442 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
443 *bytes_written = 0;
444 return 1;
445 }
446 *bytes_written = data_len;
447 descriptor->lob_current_position += data_len;
448
449 if ((int) descriptor->lob_current_position > (int) descriptor->lob_size) {
450 descriptor->lob_size = descriptor->lob_current_position;
451 }
452
453
454 if (descriptor->buffering == PHP_OCI_LOB_BUFFER_ENABLED) {
455 descriptor->buffering = PHP_OCI_LOB_BUFFER_USED;
456 }
457
458 connection->errcode = 0;
459 return 0;
460 }
461
462
463
464
465 int php_oci_lob_set_buffering (php_oci_descriptor *descriptor, int on_off)
466 {
467 php_oci_connection *connection = descriptor->connection;
468 sword errstatus;
469
470 if (!on_off && descriptor->buffering == PHP_OCI_LOB_BUFFER_DISABLED) {
471
472 return 0;
473 }
474
475 if (on_off && descriptor->buffering != PHP_OCI_LOB_BUFFER_DISABLED) {
476
477 return 0;
478 }
479
480 if (on_off) {
481 PHP_OCI_CALL_RETURN(errstatus, OCILobEnableBuffering, (connection->svc, connection->err, descriptor->descriptor));
482 } else {
483 PHP_OCI_CALL_RETURN(errstatus, OCILobDisableBuffering, (connection->svc, connection->err, descriptor->descriptor));
484 }
485
486 if (errstatus != OCI_SUCCESS) {
487 connection->errcode = php_oci_error(connection->err, errstatus);
488 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
489 return 1;
490 }
491 descriptor->buffering = on_off ? PHP_OCI_LOB_BUFFER_ENABLED : PHP_OCI_LOB_BUFFER_DISABLED;
492 connection->errcode = 0;
493 return 0;
494 }
495
496
497
498
499 int php_oci_lob_get_buffering (php_oci_descriptor *descriptor)
500 {
501 if (descriptor->buffering != PHP_OCI_LOB_BUFFER_DISABLED) {
502 return 1;
503 } else {
504 return 0;
505 }
506 }
507
508
509
510
511 int php_oci_lob_copy (php_oci_descriptor *descriptor_dest, php_oci_descriptor *descriptor_from, zend_long length)
512 {
513 php_oci_connection *connection = descriptor_dest->connection;
514 ub4 length_dest, length_from, copy_len;
515 sword errstatus;
516
517 if (php_oci_lob_get_length(descriptor_dest, &length_dest)) {
518 return 1;
519 }
520
521 if (php_oci_lob_get_length(descriptor_from, &length_from)) {
522 return 1;
523 }
524
525 if (length == -1) {
526 copy_len = length_from - descriptor_from->lob_current_position;
527 } else {
528 copy_len = (ub4) length;
529 }
530
531 if ((int)copy_len <= 0) {
532
533 return 1;
534 }
535
536 PHP_OCI_CALL_RETURN(errstatus, OCILobCopy,
537 (
538 connection->svc,
539 connection->err,
540 descriptor_dest->descriptor,
541 descriptor_from->descriptor,
542 copy_len,
543 descriptor_dest->lob_current_position+1,
544 descriptor_from->lob_current_position+1
545 )
546 );
547
548 if (errstatus != OCI_SUCCESS) {
549 connection->errcode = php_oci_error(connection->err, errstatus);
550 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
551 return 1;
552 }
553
554 connection->errcode = 0;
555 return 0;
556 }
557
558
559
560
561 int php_oci_lob_close (php_oci_descriptor *descriptor)
562 {
563 php_oci_connection *connection = descriptor->connection;
564 sword errstatus;
565
566 if (descriptor->is_open) {
567 PHP_OCI_CALL_RETURN(errstatus, OCILobClose, (connection->svc, connection->err, descriptor->descriptor));
568
569 if (errstatus != OCI_SUCCESS) {
570 connection->errcode = php_oci_error(connection->err, errstatus);
571 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
572 return 1;
573 }
574 connection->errcode = 0;
575 }
576
577 if (php_oci_temp_lob_close(descriptor)) {
578 return 1;
579 }
580
581 return 0;
582 }
583
584
585
586
587 int php_oci_temp_lob_close (php_oci_descriptor *descriptor)
588 {
589 php_oci_connection *connection = descriptor->connection;
590 int is_temporary;
591 sword errstatus;
592
593 PHP_OCI_CALL_RETURN(errstatus, OCILobIsTemporary, (connection->env,connection->err, descriptor->descriptor, &is_temporary));
594
595 if (errstatus != OCI_SUCCESS) {
596 connection->errcode = php_oci_error(connection->err, errstatus);
597 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
598 return 1;
599 }
600
601 if (is_temporary) {
602 PHP_OCI_CALL_RETURN(errstatus, OCILobFreeTemporary, (connection->svc, connection->err, descriptor->descriptor));
603
604 if (errstatus != OCI_SUCCESS) {
605 connection->errcode = php_oci_error(connection->err, errstatus);
606 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
607 return 1;
608 }
609 }
610 connection->errcode = 0;
611 return 0;
612 }
613
614
615
616
617 int php_oci_lob_flush(php_oci_descriptor *descriptor, zend_long flush_flag)
618 {
619 OCILobLocator *lob = descriptor->descriptor;
620 php_oci_connection *connection = descriptor->connection;
621 sword errstatus;
622
623 if (!lob) {
624 return 1;
625 }
626
627 switch (flush_flag) {
628 case 0:
629 case OCI_LOB_BUFFER_FREE:
630
631 break;
632 default:
633 php_error_docref(NULL, E_WARNING, "Invalid flag value: %pd", flush_flag);
634 return 1;
635 break;
636 }
637
638
639
640
641 if (descriptor->buffering != PHP_OCI_LOB_BUFFER_USED) {
642 return 0;
643 }
644
645 PHP_OCI_CALL_RETURN(errstatus, OCILobFlushBuffer, (connection->svc, connection->err, lob, (ub4) flush_flag));
646
647 if (errstatus != OCI_SUCCESS) {
648 connection->errcode = php_oci_error(connection->err, errstatus);
649 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
650 return 1;
651 }
652
653
654 descriptor->buffering = PHP_OCI_LOB_BUFFER_ENABLED;
655 connection->errcode = 0;
656 return 0;
657 }
658
659
660
661
662 void php_oci_lob_free (php_oci_descriptor *descriptor)
663 {
664 if (!descriptor || !descriptor->connection) {
665 return;
666 }
667
668 if (descriptor->connection->descriptors) {
669 if (zend_hash_num_elements(descriptor->connection->descriptors) == 0) {
670 descriptor->connection->descriptor_count = 0;
671 } else {
672
673 zend_hash_index_del(descriptor->connection->descriptors, descriptor->index);
674 if (descriptor->index + 1 == descriptor->connection->descriptor_count) {
675
676
677
678
679
680
681
682
683
684
685
686 descriptor->connection->descriptor_count--;
687 }
688 }
689 }
690
691
692 if ((descriptor->type == OCI_DTYPE_FILE || descriptor->type == OCI_DTYPE_LOB) && descriptor->buffering == PHP_OCI_LOB_BUFFER_USED) {
693 php_oci_lob_flush(descriptor, OCI_LOB_BUFFER_FREE);
694 }
695
696 if (descriptor->type == OCI_DTYPE_LOB) {
697 php_oci_temp_lob_close(descriptor);
698 }
699
700 PHP_OCI_CALL(OCIDescriptorFree, (descriptor->descriptor, descriptor->type));
701
702 zend_list_delete(descriptor->connection->id);
703 efree(descriptor);
704 }
705
706
707
708
709 int php_oci_lob_import (php_oci_descriptor *descriptor, char *filename)
710 {
711 int fp;
712 ub4 loblen;
713 OCILobLocator *lob = (OCILobLocator *)descriptor->descriptor;
714 php_oci_connection *connection = descriptor->connection;
715 char buf[8192];
716 ub4 offset = 1;
717 sword errstatus;
718
719 #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3) || (PHP_MAJOR_VERSION > 5)
720
721 if (php_check_open_basedir(filename)) {
722 #else
723 if ((PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(filename)) {
724 #endif
725 return 1;
726 }
727
728 if ((fp = VCWD_OPEN(filename, O_RDONLY|O_BINARY)) == -1) {
729 php_error_docref(NULL, E_WARNING, "Can't open file %s", filename);
730 return 1;
731 }
732
733 while ((loblen = read(fp, &buf, sizeof(buf))) > 0) {
734 PHP_OCI_CALL_RETURN(errstatus,
735 OCILobWrite,
736 (
737 connection->svc,
738 connection->err,
739 lob,
740 &loblen,
741 offset,
742 (dvoid *) &buf,
743 loblen,
744 OCI_ONE_PIECE,
745 (dvoid *)0,
746 (OCICallbackLobWrite) 0,
747 (ub2) descriptor->charset_id,
748 (ub1) descriptor->charset_form
749 )
750 );
751
752 if (errstatus != OCI_SUCCESS) {
753 connection->errcode = php_oci_error(connection->err, errstatus);
754 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
755 close(fp);
756 return 1;
757 } else {
758 connection->errcode = 0;
759 }
760 offset += loblen;
761 }
762 close(fp);
763
764 return 0;
765 }
766
767
768
769
770 int php_oci_lob_append (php_oci_descriptor *descriptor_dest, php_oci_descriptor *descriptor_from)
771 {
772 php_oci_connection *connection = descriptor_dest->connection;
773 OCILobLocator *lob_dest = descriptor_dest->descriptor;
774 OCILobLocator *lob_from = descriptor_from->descriptor;
775 ub4 dest_len, from_len;
776 sword errstatus;
777
778 if (php_oci_lob_get_length(descriptor_dest, &dest_len)) {
779 return 1;
780 }
781
782 if (php_oci_lob_get_length(descriptor_from, &from_len)) {
783 return 1;
784 }
785
786 if (from_len <= 0) {
787 return 0;
788 }
789
790 PHP_OCI_CALL_RETURN(errstatus, OCILobAppend, (connection->svc, connection->err, lob_dest, lob_from));
791
792 if (errstatus != OCI_SUCCESS) {
793 connection->errcode = php_oci_error(connection->err, errstatus);
794 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
795 return 1;
796 }
797 connection->errcode = 0;
798 return 0;
799 }
800
801
802
803
804 int php_oci_lob_truncate (php_oci_descriptor *descriptor, zend_long new_lob_length)
805 {
806 php_oci_connection *connection = descriptor->connection;
807 OCILobLocator *lob = descriptor->descriptor;
808 ub4 lob_length;
809 sword errstatus;
810
811 if (php_oci_lob_get_length(descriptor, &lob_length)) {
812 return 1;
813 }
814
815 if (lob_length <= 0) {
816 return 0;
817 }
818
819 if (new_lob_length < 0) {
820 php_error_docref(NULL, E_WARNING, "Size must be greater than or equal to 0");
821 return 1;
822 }
823
824 if (new_lob_length > lob_length) {
825 php_error_docref(NULL, E_WARNING, "Size must be less than or equal to the current LOB size");
826 return 1;
827 }
828
829 PHP_OCI_CALL_RETURN(errstatus, OCILobTrim, (connection->svc, connection->err, lob, (ub4) new_lob_length));
830
831 if (errstatus != OCI_SUCCESS) {
832 connection->errcode = php_oci_error(connection->err, errstatus);
833 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
834 return 1;
835 }
836
837 descriptor->lob_size = (ub4) new_lob_length;
838 connection->errcode = 0;
839
840 return 0;
841 }
842
843
844
845
846 int php_oci_lob_erase (php_oci_descriptor *descriptor, zend_long offset, ub4 length, ub4 *bytes_erased)
847 {
848 php_oci_connection *connection = descriptor->connection;
849 OCILobLocator *lob = descriptor->descriptor;
850 ub4 lob_length;
851 sword errstatus;
852
853 *bytes_erased = 0;
854
855 if (php_oci_lob_get_length(descriptor, &lob_length)) {
856 return 1;
857 }
858
859 if (offset == -1) {
860 offset = descriptor->lob_current_position;
861 }
862
863 if (length == -1) {
864 length = lob_length;
865 }
866
867 PHP_OCI_CALL_RETURN(errstatus, OCILobErase, (connection->svc, connection->err, lob, (ub4 *)&length, (ub4) offset+1));
868
869 if (errstatus != OCI_SUCCESS) {
870 connection->errcode = php_oci_error(connection->err, errstatus);
871 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
872 return 1;
873 }
874
875 *bytes_erased = length;
876 connection->errcode = 0;
877 return 0;
878 }
879
880
881
882
883 int php_oci_lob_is_equal (php_oci_descriptor *descriptor_first, php_oci_descriptor *descriptor_second, boolean *result)
884 {
885 php_oci_connection *connection = descriptor_first->connection;
886 OCILobLocator *first_lob = descriptor_first->descriptor;
887 OCILobLocator *second_lob = descriptor_second->descriptor;
888 sword errstatus;
889
890 PHP_OCI_CALL_RETURN(errstatus, OCILobIsEqual, (connection->env, first_lob, second_lob, result));
891
892 if (errstatus) {
893 connection->errcode = php_oci_error(connection->err, errstatus);
894 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
895 return 1;
896 }
897 connection->errcode = 0;
898 return 0;
899 }
900
901
902
903
904 int php_oci_lob_write_tmp (php_oci_descriptor *descriptor, zend_long type, char *data, int data_len)
905 {
906 php_oci_connection *connection = descriptor->connection;
907 OCILobLocator *lob = descriptor->descriptor;
908 ub4 bytes_written = 0;
909 sword errstatus;
910
911 switch (type) {
912 case OCI_TEMP_BLOB:
913 case OCI_TEMP_CLOB:
914
915 break;
916 default:
917 php_error_docref(NULL, E_WARNING, "Invalid temporary lob type: %pd", type);
918 return 1;
919 break;
920 }
921
922 if (data_len < 0) {
923 return 1;
924 }
925
926 PHP_OCI_CALL_RETURN(errstatus, OCILobCreateTemporary,
927 (
928 connection->svc,
929 connection->err,
930 lob,
931 OCI_DEFAULT,
932 OCI_DEFAULT,
933 (ub1)type,
934 OCI_ATTR_NOCACHE,
935 OCI_DURATION_SESSION
936 )
937 );
938
939 if (errstatus) {
940 connection->errcode = php_oci_error(connection->err, errstatus);
941 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
942 return 1;
943 }
944
945 PHP_OCI_CALL_RETURN(errstatus, OCILobOpen, (connection->svc, connection->err, lob, OCI_LOB_READWRITE));
946
947 if (errstatus) {
948 connection->errcode = php_oci_error(connection->err, errstatus);
949 PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
950 return 1;
951 }
952
953 descriptor->is_open = 1;
954 connection->errcode = 0;
955
956 return php_oci_lob_write(descriptor, 0, data, data_len, &bytes_written);
957 }
958
959
960 #endif
961
962
963
964
965
966
967
968
969