@@ -31,6 +31,7 @@ const LobImpl = require('../impl/lob.js');
3131const constants = require ( './protocol/constants.js' ) ;
3232const LobOpMessage = require ( './protocol/messages/lobOp.js' ) ;
3333const errors = require ( '../errors.js' ) ;
34+ const types = require ( '../types.js' ) ;
3435
3536class ThinLobImpl extends LobImpl {
3637
@@ -54,6 +55,11 @@ class ThinLobImpl extends LobImpl {
5455 await this . conn . _protocol . _processMessage ( message ) ;
5556 if ( options . operation === constants . TNS_LOB_OP_READ ) {
5657 return ( message . data ) ? message . data : null ;
58+ } else if (
59+ options . operation === constants . TNS_LOB_OP_FILE_EXISTS ||
60+ options . operation === constants . TNS_LOB_OP_FILE_ISOPEN
61+ ) {
62+ return message . boolFlag ;
5763 } else {
5864 return message . amount ;
5965 }
@@ -127,10 +133,26 @@ class ThinLobImpl extends LobImpl {
127133 // Internal method returning the data obtained from the database.
128134 //---------------------------------------------------------------------------
129135 async getData ( offset = 1 , len = this . _length ) {
136+ let shouldClose = false ;
130137 if ( ! len ) {
131138 len = this . _length ;
132139 }
133- return await this . read ( offset , len ) ;
140+ if ( this . dbType === types . DB_TYPE_BFILE ) {
141+ if ( ! await this . isFileOpen ( ) ) {
142+ shouldClose = true ;
143+ await this . openFile ( ) ;
144+ }
145+ }
146+ let data ;
147+ // if read fails and BFILE was opened by application, we close it.
148+ try {
149+ data = await this . read ( offset , len ) ;
150+ } finally {
151+ if ( shouldClose ) {
152+ await this . closeFile ( ) ;
153+ }
154+ }
155+ return data ;
134156 }
135157
136158 //---------------------------------------------------------------------------
@@ -207,6 +229,45 @@ class ThinLobImpl extends LobImpl {
207229 await this . _getChunkSizeAsync ( ) ;
208230 }
209231
232+ //---------------------------------------------------------------------------
233+ // fileExists()
234+ //
235+ // Internal method for returning whether the file referenced by a BFILE
236+ // exists.
237+ //---------------------------------------------------------------------------
238+ async fileExists ( ) {
239+ this . checkConn ( ) ;
240+ const options = {
241+ operation : constants . TNS_LOB_OP_FILE_EXISTS ,
242+ sourceLobImpl : this ,
243+ } ;
244+ return await this . _sendMessage ( options ) ;
245+ }
246+
247+ //---------------------------------------------------------------------------
248+ // getDirFileName()
249+ //
250+ // Internal method for returning the directory alias and name of the file
251+ // referenced by a BFILE
252+ //---------------------------------------------------------------------------
253+ getDirFileName ( ) {
254+ const dirNameOffset = constants . TNS_LOB_LOC_FIXED_OFFSET + 2 ;
255+ const dirNameLen = this . _locator . readUInt16BE (
256+ constants . TNS_LOB_LOC_FIXED_OFFSET
257+ ) ;
258+ const fileNameOffset = constants . TNS_LOB_LOC_FIXED_OFFSET + dirNameLen + 4 ;
259+ const fileNameLen = this . _locator . readUInt16BE (
260+ dirNameOffset + dirNameLen
261+ ) ;
262+ const dirName = this . _locator . slice (
263+ dirNameOffset , dirNameOffset + dirNameLen
264+ ) . toString ( ) ;
265+ const fileName = this . _locator . slice (
266+ fileNameOffset , fileNameOffset + fileNameLen
267+ ) . toString ( ) ;
268+ return { dirName : dirName , fileName : fileName } ;
269+ }
270+
210271 //---------------------------------------------------------------------------
211272 // checkConn()
212273 //
@@ -231,6 +292,20 @@ class ThinLobImpl extends LobImpl {
231292 }
232293 }
233294
295+ //---------------------------------------------------------------------------
296+ // closeFile()
297+ //
298+ // Internal method to close the opened file for BFILE LOBs.
299+ //---------------------------------------------------------------------------
300+ async closeFile ( ) {
301+ this . checkConn ( ) ;
302+ const options = {
303+ operation : constants . TNS_LOB_OP_FILE_CLOSE ,
304+ sourceLobImpl : this ,
305+ } ;
306+ await this . _sendMessage ( options ) ;
307+ }
308+
234309 //---------------------------------------------------------------------------
235310 // init()
236311 //
@@ -251,6 +326,56 @@ class ThinLobImpl extends LobImpl {
251326 this . _pieceSize = chunkSize ;
252327 }
253328
329+ //---------------------------------------------------------------------------
330+ // isFileOpen()
331+ //
332+ // Internal method to check if the file is already open.
333+ //---------------------------------------------------------------------------
334+ async isFileOpen ( ) {
335+ const options = {
336+ operation : constants . TNS_LOB_OP_FILE_ISOPEN ,
337+ sourceLobImpl : this
338+ } ;
339+ await this . _sendMessage ( options ) ;
340+ }
341+
342+ //---------------------------------------------------------------------------
343+ // openFile()
344+ //
345+ // Internal method for opening file (BFILE).
346+ //---------------------------------------------------------------------------
347+ async openFile ( ) {
348+ this . checkConn ( ) ;
349+ const options = {
350+ operation : constants . TNS_LOB_OP_FILE_OPEN ,
351+ sourceLobImpl : this ,
352+ amount : constants . TNS_LOB_OPEN_READ_ONLY ,
353+ sendAmount : true
354+ } ;
355+ return await this . _sendMessage ( options ) ;
356+ }
357+
358+ //---------------------------------------------------------------------------
359+ // setDirFileName()
360+ //
361+ // Internal method for setting the directory alias and name of the file
362+ // referenced by a BFILE
363+ //---------------------------------------------------------------------------
364+ setDirFileName ( dirObject ) {
365+ const dirNameLen = Buffer . byteLength ( dirObject . dirName ) ;
366+ const dirNameOffset = constants . TNS_LOB_LOC_FIXED_OFFSET + 2 ;
367+ const fileNameOffset = dirNameOffset + dirNameLen + 2 ;
368+ const fileNameLen = Buffer . byteLength ( dirObject . fileName ) ;
369+ const newLocLen = fileNameOffset + fileNameLen ;
370+ const newLocator = Buffer . allocUnsafe ( newLocLen ) ;
371+ this . _locator . copy ( newLocator , 0 , 0 , constants . TNS_LOB_LOC_FIXED_OFFSET + 1 ) ;
372+ newLocator . writeUInt16BE ( dirNameLen , constants . TNS_LOB_LOC_FIXED_OFFSET ) ;
373+ newLocator . write ( dirObject . dirName , dirNameOffset ) ;
374+ newLocator . writeInt16BE ( fileNameLen , dirNameOffset + dirNameLen ) ;
375+ newLocator . write ( dirObject . fileName , fileNameOffset ) ;
376+ this . _locator = newLocator ;
377+ }
378+
254379}
255380
256381module . exports = ThinLobImpl ;
0 commit comments