1
+ /* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. */
2
+
3
+ /******************************************************************************
4
+ *
5
+ * You may not use the identified files except in compliance with the Apache
6
+ * License, Version 2.0 (the "License.")
7
+ *
8
+ * You may obtain a copy of the License at
9
+ * http://www.apache.org/licenses/LICENSE-2.0.
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ *
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ *
18
+ * The node-oracledb test suite uses 'mocha', 'should' and 'async'.
19
+ * See LICENSE.md for relevant licenses.
20
+ *
21
+ * NAME
22
+ * 245. fetchLobAsStrBuf.js
23
+ *
24
+ * DESCRIPTION
25
+ * Testing CLOB binding as String with DML and Blob binding as Buffer with DML
26
+ *
27
+ *****************************************************************************/
28
+ 'use strict' ;
29
+
30
+ var oracledb = require ( 'oracledb' ) ;
31
+ var should = require ( 'should' ) ;
32
+ var async = require ( 'async' ) ;
33
+ var dbConfig = require ( './dbconfig.js' ) ;
34
+ var random = require ( './random.js' ) ;
35
+ var assist = require ( './dataTypeAssist.js' ) ;
36
+
37
+ describe ( '245. fetchLobAsStrBuf.js' , function ( ) {
38
+ var connection = null ;
39
+ var insertID = 1 ;
40
+ var tableName = "fetchLobAsStrBuf_table" ;
41
+ var fun_create_table = "BEGIN \n" +
42
+ " DECLARE \n" +
43
+ " e_table_missing EXCEPTION; \n" +
44
+ " PRAGMA EXCEPTION_INIT(e_table_missing, -00942);\n" +
45
+ " BEGIN \n" +
46
+ " EXECUTE IMMEDIATE ('DROP TABLE " + tableName + " PURGE' ); \n" +
47
+ " EXCEPTION \n" +
48
+ " WHEN e_table_missing \n" +
49
+ " THEN NULL; \n" +
50
+ " END; \n" +
51
+ " EXECUTE IMMEDIATE ( ' \n" +
52
+ " CREATE TABLE " + tableName + " ( \n" +
53
+ " id NUMBER, \n" +
54
+ " clob_col clob, \n" +
55
+ " blob_col blob \n" +
56
+ " ) \n" +
57
+ " '); \n" +
58
+ "END; " ;
59
+ var drop_table = "DROP TABLE " + tableName + " PURGE" ;
60
+
61
+ before ( function ( done ) {
62
+ oracledb . getConnection ( dbConfig , function ( err , conn ) {
63
+ should . not . exist ( err ) ;
64
+ connection = conn ;
65
+ done ( ) ;
66
+ } ) ;
67
+ } ) ;
68
+
69
+ after ( function ( done ) {
70
+ connection . release ( function ( err ) {
71
+ should . not . exist ( err ) ;
72
+ done ( ) ;
73
+ } ) ;
74
+ } ) ;
75
+
76
+ var executeSQL = function ( sql , callback ) {
77
+ connection . execute (
78
+ sql ,
79
+ function ( err ) {
80
+ should . not . exist ( err ) ;
81
+ return callback ( ) ;
82
+ }
83
+ ) ;
84
+ } ;
85
+
86
+ var insertIntoTable = function ( id , contentClob , contentBlob , callback ) {
87
+ if ( contentClob == "EMPTY_CLOB" && contentBlob == "EMPTY_BLOB" ) {
88
+ connection . execute ( "insert INTO fetchLobAsStrBuf_table values(:id, EMPTY_CLOB(), EMPTY_BLOB())" ,
89
+ [ id ] ,
90
+ function ( err , result ) {
91
+ should . not . exist ( err ) ;
92
+ should . strictEqual ( result . rowsAffected , 1 ) ;
93
+ callback ( ) ;
94
+ } ) ;
95
+ }
96
+ else {
97
+ var sql = "insert into fetchLobAsStrBuf_table (id, clob_col, blob_col) values(:id, :str, :buf)" ;
98
+ var bindings = {
99
+ id : { val : id } ,
100
+ str : { val :contentClob , type :oracledb . STRING , dir :oracledb . BIND_IN } ,
101
+ buf : { val :contentBlob , type :oracledb . BUFFER , dir :oracledb . BIND_IN }
102
+ } ;
103
+ connection . execute ( sql , bindings ,
104
+ function ( err , result ) {
105
+ should . not . exist ( err ) ;
106
+ should . strictEqual ( result . rowsAffected , 1 ) ;
107
+ callback ( ) ;
108
+ } ) ;
109
+ }
110
+ } ;
111
+
112
+ var checkInsertResult = function ( id , contentClob , specialStr , contentBlob , callback ) {
113
+ async . series ( [
114
+ function ( cb ) {
115
+ var sql = "select clob_col from fetchLobAsStrBuf_table where id = " + id ;
116
+ verifyClobValueWithString ( sql , contentClob , specialStr , cb ) ;
117
+ } ,
118
+ function ( cb ) {
119
+ var sql = "select blob_col from fetchLobAsStrBuf_table where id = " + id ;
120
+ verifyBlobValueWithBuffer ( sql , contentBlob , specialStr , cb ) ;
121
+ }
122
+ ] , callback ) ;
123
+ } ;
124
+
125
+ var verifyClobValueWithString = function ( selectSql , originalString , specialStr , callback ) {
126
+ connection . execute (
127
+ selectSql ,
128
+ function ( err , result ) {
129
+ should . not . exist ( err ) ;
130
+ var lob = result . rows [ 0 ] [ 0 ] ;
131
+ if ( originalString == '' || originalString == undefined || originalString == null ) {
132
+ should . not . exist ( lob ) ;
133
+ return callback ( ) ;
134
+ } else {
135
+ should . exist ( lob ) ;
136
+ // set the encoding so we get a 'string' not a 'buffer'
137
+ lob . setEncoding ( 'utf8' ) ;
138
+ var clobData = '' ;
139
+
140
+ lob . on ( 'data' , function ( chunk ) {
141
+ clobData += chunk ;
142
+ } ) ;
143
+
144
+ lob . on ( 'error' , function ( err ) {
145
+ should . not . exist ( err , "lob.on 'error' event." ) ;
146
+ } ) ;
147
+
148
+ lob . on ( 'end' , function ( err ) {
149
+ should . not . exist ( err ) ;
150
+ if ( originalString == "EMPTY_CLOB" ) {
151
+ should . strictEqual ( clobData , "" ) ;
152
+ } else {
153
+ var resultLength = clobData . length ;
154
+ var specStrLength = specialStr . length ;
155
+ should . strictEqual ( resultLength , originalString . length ) ;
156
+ should . strictEqual ( clobData . substring ( 0 , specStrLength ) , specialStr ) ;
157
+ should . strictEqual ( clobData . substring ( resultLength - specStrLength , resultLength ) , specialStr ) ;
158
+ }
159
+ return callback ( ) ;
160
+ } ) ;
161
+ }
162
+ }
163
+ ) ;
164
+ } ;
165
+
166
+ var verifyBlobValueWithBuffer = function ( selectSql , originalBuffer , specialStr , callback ) {
167
+ connection . execute (
168
+ selectSql ,
169
+ function ( err , result ) {
170
+ should . not . exist ( err ) ;
171
+ var lob = result . rows [ 0 ] [ 0 ] ;
172
+ if ( originalBuffer == '' || originalBuffer == undefined ) {
173
+ should . not . exist ( lob ) ;
174
+ return callback ( ) ;
175
+ } else {
176
+ should . exist ( lob ) ;
177
+ var blobData = Buffer . alloc ( 0 ) ;
178
+ var totalLength = 0 ;
179
+
180
+ lob . on ( 'data' , function ( chunk ) {
181
+ totalLength = totalLength + chunk . length ;
182
+ blobData = Buffer . concat ( [ blobData , chunk ] , totalLength ) ;
183
+ } ) ;
184
+
185
+ lob . on ( 'error' , function ( err ) {
186
+ should . not . exist ( err , "lob.on 'error' event." ) ;
187
+ } ) ;
188
+
189
+ lob . on ( 'end' , function ( ) {
190
+ if ( originalBuffer == "EMPTY_BLOB" ) {
191
+ var nullBuffer = Buffer . from ( '' , "utf-8" ) ;
192
+ should . strictEqual ( assist . compare2Buffers ( blobData , nullBuffer ) , true ) ;
193
+ } else {
194
+ should . strictEqual ( totalLength , originalBuffer . length ) ;
195
+ var specStrLength = specialStr . length ;
196
+ should . strictEqual ( blobData . toString ( 'utf8' , 0 , specStrLength ) , specialStr ) ;
197
+ should . strictEqual ( blobData . toString ( 'utf8' , ( totalLength - specStrLength ) , totalLength ) , specialStr ) ;
198
+ should . strictEqual ( assist . compare2Buffers ( blobData , originalBuffer ) , true ) ;
199
+ }
200
+ return callback ( ) ;
201
+ } ) ;
202
+ }
203
+ }
204
+ ) ;
205
+ } ;
206
+
207
+ describe ( '245.1 CLOB,BLOB Insert' , function ( ) {
208
+
209
+ before ( function ( done ) {
210
+ executeSQL ( fun_create_table , done ) ;
211
+ } ) ;
212
+
213
+ after ( function ( done ) {
214
+ executeSQL ( drop_table , done ) ;
215
+ } ) ;
216
+
217
+ it ( '245.1.1 Insert and fetch CLOB,BLOB with EMPTY_CLOB and EMPTY_BLOB' , function ( done ) {
218
+ var id = insertID ++ ;
219
+ var contentClob = "EMPTY_CLOB" ;
220
+ var contentBlob = "EMPTY_BLOB" ;
221
+ async . series ( [
222
+ function ( cb ) {
223
+ insertIntoTable ( id , contentClob , contentBlob , cb ) ;
224
+ } ,
225
+ function ( cb ) {
226
+ checkInsertResult ( id , contentClob , null , contentBlob , cb ) ;
227
+ }
228
+ ] , done ) ;
229
+ } ) ;
230
+
231
+ it ( '245.1.2 Insert and fetch CLOB,BLOB with String and Buffer of length 32K' , function ( done ) {
232
+ var id = insertID ++ ;
233
+ var contentLength = 32768 ;
234
+ var specialStr = "245.1.2" ;
235
+ var contentClob = random . getRandomString ( contentLength , specialStr ) ;
236
+ var contentBlob = Buffer . from ( contentClob , "utf-8" ) ;
237
+
238
+ async . series ( [
239
+ function ( cb ) {
240
+ insertIntoTable ( id , contentClob , contentBlob , cb ) ;
241
+ } ,
242
+ function ( cb ) {
243
+ checkInsertResult ( id , contentClob , specialStr , contentBlob , cb ) ;
244
+ }
245
+ ] , done ) ;
246
+
247
+ } ) ;
248
+
249
+ it ( '245.1.3 Insert and fetch CLOB,BLOB with String and Buffer of length (1MB + 1)' , function ( done ) {
250
+ var id = insertID ++ ;
251
+ var contentLength = 1048577 ;
252
+ var specialStr = "245.1.2" ;
253
+ var contentClob = random . getRandomString ( contentLength , specialStr ) ;
254
+ var contentBlob = Buffer . from ( contentClob , "utf-8" ) ;
255
+
256
+ async . series ( [
257
+ function ( cb ) {
258
+ insertIntoTable ( id , contentClob , contentBlob , cb ) ;
259
+ } ,
260
+ function ( cb ) {
261
+ checkInsertResult ( id , contentClob , specialStr , contentBlob , cb ) ;
262
+ }
263
+ ] , done ) ;
264
+
265
+ } ) ;
266
+ } ) ;
267
+
268
+ } ) ;
0 commit comments