1
- // Copyright (c) 2022, 2023 , Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024 , Oracle and/or its affiliates.
2
2
3
3
//-----------------------------------------------------------------------------
4
4
//
26
26
27
27
'use strict' ;
28
28
29
- const { createNVPair, findValue } = require ( "./nvStrToNvPair.js" ) ;
29
+ const { createNVPair} = require ( "./nvStrToNvPair.js" ) ;
30
30
const fs = require ( 'fs' ) ;
31
31
const process = require ( 'process' ) ;
32
32
const readline = require ( 'readline' ) ;
@@ -59,12 +59,21 @@ function tnsnamesFilePath(configDir) {
59
59
return filePathVal ;
60
60
}
61
61
}
62
+ //Structure for each tnsnames.ora file
63
+ class tnsnamesElement {
62
64
65
+ constructor ( ) {
66
+ this . readInProgress = false ;
67
+ this . waiters = [ ] ;
68
+ this . aliasht = new Map ( ) ; // It will have key as alias and value as its aliases value
69
+ this . modTime = new Map ( ) ; // It will have tnsnames filename and also all its ifile and its modified time
70
+ }
71
+ }
63
72
class NLParamParser {
64
73
65
74
constructor ( ) {
66
- this . waiters = [ ] ;
67
- this . readInProgress = false ;
75
+ // key as tnsnames.ora(file_name) and value will be tnsnamesStruct<ht(alias key and value), modTime>
76
+ this . tnsnamesHT = new Map ( ) ;
68
77
}
69
78
/**
70
79
* Reads the given file line by line and stores the
@@ -73,29 +82,35 @@ class NLParamParser {
73
82
* @returns {Promise }
74
83
*/
75
84
async initializeNlpa ( file_path ) {
76
- if ( this . readInProgress ) {
85
+ let tnsFileStruct ;
86
+ if ( this . tnsnamesHT . has ( file_path ) )
87
+ tnsFileStruct = this . tnsnamesHT . get ( file_path ) ;
88
+ else
89
+ tnsFileStruct = new tnsnamesElement ( ) ;
90
+ if ( tnsFileStruct . readInProgress ) {
77
91
await new Promise ( ( resolve ) => {
78
- this . waiters . push ( resolve ) ;
92
+ tnsFileStruct . waiters . push ( resolve ) ;
79
93
} ) ;
80
94
}
81
- if ( ! this . checkModfTime ( ) ) {
95
+ /* check modification time of all files in the cache
96
+ including the file_path */
97
+ if ( ! this . checkModfTime ( tnsFileStruct ) ) {
82
98
/* No File has been modified */
83
- return this . ht ;
99
+ return tnsFileStruct . aliasht ;
84
100
}
85
- this . ht = new Map ( ) ;
86
- this . modTime = new Map ( ) ; //stores modified time of each IFile
87
- this . readInProgress = true ;
88
- await this . start ( file_path , 0 ) ; //start with 0 depth (tnsnames.ora)
89
- return this . ht ;
101
+ tnsFileStruct . readInProgress = true ;
102
+ await this . start ( file_path , 0 , tnsFileStruct ) ; //start with 0 depth (tnsnames.ora)
103
+ this . tnsnamesHT . set ( file_path , tnsFileStruct ) ;
104
+ return tnsFileStruct . aliasht ;
90
105
}
91
106
92
- async start ( file_path , depth ) {
107
+ async start ( file_path , depth , tnsFileStruct ) {
93
108
94
109
if ( depth > MAX_IFILE_DEPTH )
95
110
return ; //ignore after max depth
96
111
const stat = fs . statSync ( file_path ) ;
97
112
// store file path and its modified time.
98
- this . modTime . set ( file_path , stat . mtime ) ;
113
+ tnsFileStruct . modTime . set ( file_path , stat . mtime ) ;
99
114
// Creating a readable stream from file
100
115
// readline module reads line by line
101
116
// but from a readable stream only.
@@ -129,7 +144,7 @@ class NLParamParser {
129
144
nvElem = nvElem + line ;
130
145
131
146
} else if ( nvElem . length != 0 ) {
132
- await this . addNLPListElement ( nvElem , depth ) ; // Add Parameter to Hashtable
147
+ await this . addNLPListElement ( nvElem , depth , tnsFileStruct ) ; // Add Parameter to Hashtable
133
148
nvElem = "" ; // Clear first, before storing current line
134
149
135
150
line = this . checkNLPforComments ( line ) ;
@@ -138,12 +153,12 @@ class NLParamParser {
138
153
}
139
154
}
140
155
if ( nvElem . length != 0 ) { // at eof, still one more parameter to read
141
- await this . addNLPListElement ( nvElem , depth ) ;
156
+ await this . addNLPListElement ( nvElem , depth , tnsFileStruct ) ;
142
157
nvElem = "" ; // clear nvElem buffer after added
143
158
}
144
- this . readInProgress = false ;
159
+ tnsFileStruct . readInProgress = false ;
145
160
let waiter ;
146
- while ( ( waiter = this . waiters . pop ( ) ) ) {
161
+ while ( ( waiter = tnsFileStruct . waiters . pop ( ) ) ) {
147
162
waiter ( ) ;
148
163
}
149
164
}
@@ -173,9 +188,11 @@ class NLParamParser {
173
188
return str1 . join ( '' ) ;
174
189
}
175
190
// check if any of the IFiles has been changed
176
- checkModfTime ( ) {
177
- if ( this . modTime ) {
178
- for ( const [ key , value ] of this . modTime ) {
191
+ checkModfTime ( tnsFileStruct ) {
192
+ // There may be multiple tnsnames.ora files. So check if the tnsnames.ora
193
+ // in question is already cached
194
+ if ( tnsFileStruct . modTime . size != 0 ) {
195
+ for ( const [ key , value ] of tnsFileStruct . modTime ) {
179
196
if ( fs . existsSync ( key ) ) {
180
197
const stat = fs . statSync ( key ) ;
181
198
if ( ( stat . mtime - value > 0 ) ) {
@@ -193,7 +210,7 @@ class NLParamParser {
193
210
* adds name value pairs from the input buffer into the hash table.
194
211
* @param {string } ibuf
195
212
*/
196
- async addNLPListElement ( ibuf , depth ) {
213
+ async addNLPListElement ( ibuf , depth , tnsFileStruct ) {
197
214
const res = ibuf . split ( / \r ? \n / ) . filter ( element => element ) ;
198
215
for ( let i = 0 ; i < res . length ; i ++ ) {
199
216
if ( res [ i ] . charAt ( 0 ) != '(' ) {
@@ -205,33 +222,15 @@ class NLParamParser {
205
222
nvp . name = uname ;
206
223
// support for ifile
207
224
if ( uname == 'IFILE' ) {
208
- await this . start ( nvp . atom , depth + 1 ) ;
225
+ await this . start ( nvp . atom , depth + 1 , tnsFileStruct ) ;
209
226
} else {
210
227
const unames = uname . split ( "," ) ; //multiple aliases (alias1, alias2, alias3)
211
228
for ( let i = 0 ; i < unames . length ; i ++ ) {
212
- this . ht . set ( unames [ i ] , nvp ) ;
229
+ tnsFileStruct . aliasht . set ( unames [ i ] , nvp ) ;
213
230
}
214
231
}
215
232
}
216
233
}
217
- toString ( ) {
218
- let out = "" ;
219
- this . ht . forEach ( ( value ) => {
220
- out = out + value . toString ( ) + "\n" ;
221
- } ) ;
222
- return out ;
223
- }
224
- /**
225
- * if key is address/port then it returns the port value from the
226
- * address NVPAIR.
227
- * @param {string } key
228
- * @returns {string }
229
- */
230
- findValueOf ( key ) {
231
- const myarr = key . split ( '/' ) ;
232
- return ( findValue ( this . ht . get ( myarr [ 0 ] . toUpperCase ( ) ) , myarr ) ) ;
233
- }
234
-
235
234
}
236
235
237
236
module . exports = {
0 commit comments