Skip to content

Commit 16d7435

Browse files
committed
Add test for uninitialized LOB out bind
1 parent 6d5b26a commit 16d7435

File tree

1 file changed

+258
-0
lines changed

1 file changed

+258
-0
lines changed

test/uninitializedLob.js

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
/* Copyright (c) 2016, 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+
* 65. uninitializedLob.js
23+
*
24+
* DESCRIPTION
25+
* This test is provided by GitHub user for issue #344
26+
* It tests an uninitialized LOB returns from a PL/SQL block.
27+
*
28+
* NUMBERING RULE
29+
* Test numbers follow this numbering rule:
30+
* 1 - 20 are reserved for basic functional tests
31+
* 21 - 50 are reserved for data type supporting tests
32+
* 51 onwards are for other tests
33+
*
34+
*****************************************************************************/
35+
'use strict';
36+
37+
var oracledb = require('oracledb');
38+
var async = require('async');
39+
var should = require('should');
40+
var crypto = require('crypto');
41+
var stream = require('stream');
42+
var dbConfig = require('./dbconfig.js');
43+
44+
describe('65. uninitializedLob.js', function() {
45+
46+
if(dbConfig.externalAuth){
47+
var credential = { externalAuth: true, connectString: dbConfig.connectString };
48+
} else {
49+
var credential = dbConfig;
50+
}
51+
52+
var connection = null;
53+
before(function(done) {
54+
async.series([
55+
function(callback) {
56+
oracledb.getConnection(credential, function(err, conn) {
57+
should.not.exist(err);
58+
connection = conn;
59+
callback();
60+
});
61+
},
62+
function createTab(callback) {
63+
var proc = "BEGIN \n" +
64+
" DECLARE \n" +
65+
" e_table_exists EXCEPTION; \n" +
66+
" PRAGMA EXCEPTION_INIT(e_table_exists, -00942);\n " +
67+
" BEGIN \n" +
68+
" EXECUTE IMMEDIATE ('DROP TABLE testlobdpi'); \n" +
69+
" EXCEPTION \n" +
70+
" WHEN e_table_exists \n" +
71+
" THEN NULL; \n" +
72+
" END; \n" +
73+
" EXECUTE IMMEDIATE (' \n" +
74+
" CREATE TABLE testlobdpi ( \n" +
75+
" id NUMBER NOT NULL PRIMARY KEY, \n" +
76+
" spoc_cm_id NUMBER, \n" +
77+
" created_timestamp TIMESTAMP(5) DEFAULT SYSTIMESTAMP, \n" +
78+
" modified_timestamp TIMESTAMP(5) DEFAULT SYSTIMESTAMP \n" +
79+
" ) \n" +
80+
" '); \n" +
81+
"END; ";
82+
83+
connection.execute(
84+
proc,
85+
function(err) {
86+
should.not.exist(err);
87+
callback();
88+
}
89+
);
90+
},
91+
function createSeq(callback) {
92+
var proc = "BEGIN \n" +
93+
" DECLARE \n" +
94+
" e_sequence_exists EXCEPTION; \n" +
95+
" PRAGMA EXCEPTION_INIT(e_sequence_exists, -02289);\n " +
96+
" BEGIN \n" +
97+
" EXECUTE IMMEDIATE ('DROP SEQUENCE testlobdpi_seq'); \n" +
98+
" EXCEPTION \n" +
99+
" WHEN e_sequence_exists \n" +
100+
" THEN NULL; \n" +
101+
" END; \n" +
102+
" EXECUTE IMMEDIATE (' \n" +
103+
" CREATE SEQUENCE testlobdpi_seq INCREMENT BY 1 START WITH 1 NOMAXVALUE CACHE 50 ORDER \n" +
104+
" '); \n" +
105+
"END; ";
106+
107+
connection.execute(
108+
proc,
109+
function(err) {
110+
should.not.exist(err);
111+
callback();
112+
}
113+
);
114+
},
115+
function(callback) {
116+
var proc = "create or replace trigger testlobdpi_rbi \n" +
117+
" before insert on testlobdpi referencing old as old new as new \n" +
118+
" for each row \n" +
119+
"begin \n" +
120+
" :new.id := testlobdpi_seq.nextval;\n" +
121+
"end;";
122+
connection.execute(
123+
proc,
124+
function(err) {
125+
should.not.exist(err);
126+
callback();
127+
}
128+
);
129+
},
130+
function(callback) {
131+
var proc = "create or replace trigger testlobdpi_rbu \n" +
132+
" before update on testlobdpi referencing old as old new as new \n" +
133+
" for each row \n" +
134+
"begin \n" +
135+
" :new.modified_timestamp := systimestamp;\n" +
136+
"end;";
137+
connection.execute(
138+
proc,
139+
function(err) {
140+
should.not.exist(err);
141+
callback();
142+
}
143+
);
144+
},
145+
function(callback) {
146+
var sql = "ALTER TABLE testlobdpi ADD (blob_1 BLOB, unit32_1 NUMBER, date_1 TIMESTAMP(5), " +
147+
" string_1 VARCHAR2(250), CONSTRAINT string_1_uk UNIQUE (string_1))";
148+
149+
connection.execute(
150+
sql,
151+
function(err) {
152+
should.not.exist(err);
153+
callback();
154+
}
155+
);
156+
}
157+
], done);
158+
}) // before
159+
160+
after(function(done) {
161+
async.series([
162+
function(callback) {
163+
connection.execute(
164+
"DROP SEQUENCE testlobdpi_seq",
165+
function(err) {
166+
should.not.exist(err);
167+
callback();
168+
}
169+
);
170+
},
171+
function(callback) {
172+
connection.execute(
173+
"DROP TABLE testlobdpi",
174+
function(err) {
175+
should.not.exist(err);
176+
callback();
177+
}
178+
);
179+
},
180+
function(callback) {
181+
connection.release(function(err) {
182+
should.not.exist(err);
183+
callback();
184+
});
185+
}
186+
], done);
187+
}) // after
188+
189+
it('65.1 an uninitialized Lob is returned from a PL/SQL block', function(done) {
190+
// async's times applies a function n times in series.
191+
async.timesSeries(3, function(n, next) {
192+
var string_1 = n%2;
193+
var proc = "DECLARE \n" +
194+
" row_count NUMBER := 0;" +
195+
" negative_one NUMBER := -1;" +
196+
"BEGIN \n" +
197+
" SELECT COUNT(*) INTO row_count FROM testlobdpi WHERE (string_1 = :string_1);" +
198+
" IF (row_count = 0 ) THEN\n" +
199+
" INSERT INTO testlobdpi (blob_1, string_1, spoc_cm_id) \n" +
200+
" VALUES (empty_blob(), :string_1, :spoc_cm_id) \n" +
201+
" RETURNING id, blob_1 INTO :id, :blob_1; \n" +
202+
" ELSE \n" +
203+
" :id := negative_one;\n" +
204+
" :blob_1 := null; \n" +
205+
" END IF;\n" +
206+
"END; ";
207+
208+
connection.execute(
209+
proc,
210+
{
211+
id : {type: oracledb.NUMBER, dir: oracledb.BIND_OUT},
212+
blob_1 : {type: oracledb.BLOB, dir: oracledb.BIND_OUT},
213+
string_1 : string_1,
214+
spoc_cm_id: 1
215+
},
216+
{ outFormat: oracledb.OBJECT, autoCommit: false },
217+
function(err, result) {
218+
if(err) {
219+
console.error(err.message);
220+
return next(err);
221+
}
222+
223+
//console.log(n + ':',result);
224+
225+
if (result.outBinds.id == -1) {
226+
// a dup was found
227+
return next(null)
228+
}
229+
230+
var randomBlob = new Buffer(0);
231+
crypto.randomBytes(16, function(ex, buf) {
232+
var passthrough = new stream.PassThrough();
233+
passthrough.on('error', function(err) {
234+
should.not.exist(err);
235+
});
236+
237+
result.outBinds.blob_1.on('error', function(err) {
238+
should.not.exist(err);
239+
})
240+
241+
result.outBinds.blob_1.on('finish',function(err) {
242+
next(err);
243+
});
244+
245+
passthrough.write(buf, function() {
246+
passthrough.pipe(result.outBinds.blob_1);
247+
passthrough.end();
248+
});
249+
});
250+
251+
}
252+
);
253+
}, function(err) {
254+
should.not.exist(err);
255+
done();
256+
});
257+
}) //65.1
258+
})

0 commit comments

Comments
 (0)