@@ -92,40 +92,37 @@ class SyntaxError extends antlr4.error.ErrorListener {
9292}
9393
9494// Dropdown for Catalog and Schema
95- function SQLDropDown ( { text, values, onSelect } ) {
96- const items = values || [ ] ;
97- const [ data , setData ] = React . useState ( { items : items , current : undefined } ) ;
95+ function SQLDropDown ( { text, values = [ ] , onSelect, selected } ) {
9896
9997 function selectItem ( item ) {
100- if ( item !== data . current ) {
98+ if ( item !== selected ) {
10199 onSelect ( item ) ;
102- setData ( { ...data , current : item } ) ;
103100 }
104101 }
105102
106103 return (
107104 < div className = "btn-group" >
108105 < button type = "button" className = "btn btn-secondary dropdown-toggle bg-white text-dark"
109106 data-bs-toggle = "dropdown" aria-haspopup = "true"
110- aria-expanded = "false" > { text } </ button >
107+ aria-expanded = "false" > { selected ?? text } </ button >
111108 < ul className = "dropdown-menu bg-white" >
112- { items . map ( ( item , idx ) => (
113- < li key = { idx } > < a href = "#" className = { clsx ( 'dropdown-item text-dark' , data . current === item && 'selected' ) } onClick = { ( ) => selectItem ( item ) } > { item } </ a > </ li >
109+ { values . map ( ( item , idx ) => (
110+ < li key = { idx } > < a href = "#" className = { clsx ( 'dropdown-item text-dark' , selected === item && 'selected' ) } onClick = { ( ) => selectItem ( item ) } > { item } </ a > </ li >
114111 ) ) }
115112 </ ul >
116113 </ div >
117114 ) ;
118115}
119116
120- function sqlCleaning ( sqlInfo , errorHandler ) {
117+ function sqlCleaning ( sql , errorHandler ) {
121118 const lastSemicolon = / ( \s * ; \s * ) $ / m;
122119 const limitRE = / l i m i t \s + ( \d + | a l l ) $ / im;
123120 const fetchFirstRE = / f e t c h \s + f i r s t \s + ( \d + ) \s + r o w s \s + o n l y $ / im;
124121 const syntaxError = new SyntaxError ( ) ;
125122
126123 try {
127- sqlInfo . sql = sqlInfo . sql . replace ( lastSemicolon , '' ) . trim ( ) ;
128- const parser = new SqlBaseParser ( new antlr4 . CommonTokenStream ( new SqlBaseLexer ( new UpperCaseCharStream ( sqlInfo . sql ) ) ) ) ;
124+ let cleanSql = sql . replace ( lastSemicolon , '' ) . trim ( ) ;
125+ const parser = new SqlBaseParser ( new antlr4 . CommonTokenStream ( new SqlBaseLexer ( new UpperCaseCharStream ( cleanSql ) ) ) ) ;
129126 const selectDetector = new SelectListener ( ) ;
130127 parser . addErrorListener ( syntaxError ) ;
131128 antlr4 . tree . ParseTreeWalker . DEFAULT . walk ( selectDetector , parser . statement ( ) ) ;
@@ -136,65 +133,66 @@ function sqlCleaning(sqlInfo, errorHandler) {
136133 }
137134 if ( selectDetector . isSelect ) {
138135 if ( typeof ( selectDetector . limit ) === 'string' || selectDetector . limit > 100 ) {
139- sqlInfo . sql = sqlInfo . sql . replace ( limitRE , 'limit 100' ) ;
136+ cleanSql = cleanSql . replace ( limitRE , 'limit 100' ) ;
140137 } else if ( selectDetector . fetchFirstNRows > 100 ) {
141- sqlInfo . sql = sqlInfo . sql . replace ( fetchFirstRE , 'fetch first 100 rows only' ) ;
138+ cleanSql = cleanSql . replace ( fetchFirstRE , 'fetch first 100 rows only' ) ;
142139 } else if ( selectDetector . limit === - 1 && selectDetector . fetchFirstNRows === - 1 ) {
143- sqlInfo . sql += ' limit 100' ;
140+ cleanSql += ' limit 100' ;
144141 }
145142 }
143+ return cleanSql
146144 } catch ( err ) {
147145 if ( errorHandler ) {
148146 errorHandler ( err ) ;
149147 }
150148 return false ;
151149 }
152- return true ;
153150}
154151
155152// SQL Input, including sql text, catalog(optional), and schema(optional)
156153export function SQLInput ( { handleSQL, show, enabled, initialSQL, errorHandler } ) {
157- const sqlInfo = React . useRef ( { sql : undefined , catalog : undefined , schema : undefined } ) ;
158- const [ data , setData ] = React . useState ( { catalogs : [ ] , schemas : [ ] } ) ;
159- const [ code , setCode ] = React . useState ( initialSQL ) ;
160-
154+ const [ sql , setSql ] = React . useState ( initialSQL ) ;
155+ const [ catalog , setCatalog ] = React . useState ( undefined ) ;
156+ const [ schema , setSchema ] = React . useState ( undefined ) ;
157+ const [ catalogs , setCatalogs ] = React . useState ( [ ] ) ;
158+ const [ schemas , setSchemas ] = React . useState ( [ ] ) ;
159+
161160 const checkValue = ( ) => {
162- if ( code . length > 0 ) {
163- sqlInfo . current . sql = code ;
164- if ( sqlCleaning ( sqlInfo . current , errorHandler ) ) {
165- setCode ( sqlInfo . current . sql ) ;
166- handleSQL ( sqlInfo . current ) ;
161+ if ( sql . length > 0 ) {
162+ let cleanSql = sqlCleaning ( sql , errorHandler ) ;
163+ if ( cleanSql ) {
164+ setSql ( cleanSql ) ;
165+ handleSQL ( cleanSql , catalog , schema ) ;
167166 }
168167 }
169168 } ;
170169
171- async function setCatalog ( catalog ) {
172- sqlInfo . current . catalog = catalog ;
170+ async function catalogSelected ( catalog ) {
171+ setCatalog ( catalog ) ;
173172 // also reset schema
174- setData ( { ...data , schemas : [ ] } ) ;
173+ setSchema ( undefined ) ;
174+ setSchemas ( [ ] ) ;
175175 // fetch schemas from the catalog
176176 const client = createClient ( ) ;
177177 try {
178- const schemas = await client . getSchemas ( catalog ) ;
179- setData ( { ... data , schemas } ) ;
178+ const fetchedSchemas = await client . getSchemas ( catalog ) ;
179+ setSchemas ( fetchedSchemas )
180180 } catch ( e ) {
181181 // use this to report the issue
182182 console . error ( e ) ;
183183 }
184184 }
185-
186- function setSchema ( schema ) {
187- sqlInfo . current . schema = schema ;
188- setData ( { ...data } ) ;
185+ const schemaSelected = ( schema ) => {
186+ setSchema ( schema ) ;
189187 }
190188
191189 React . useEffect ( ( ) => {
192190 //fetch catalogs:
193191 async function getCatalogs ( ) {
194192 const client = createClient ( ) ;
195193 try {
196- const catalogs = await client . getCatalogs ( ) ;
197- setData ( { ... data , catalogs } ) ;
194+ const fetchedCatalogs = await client . getCatalogs ( ) ;
195+ setCatalogs ( fetchedCatalogs )
198196 } catch ( e ) {
199197 // use this to report the issue
200198 console . error ( e ) ;
@@ -208,9 +206,9 @@ export function SQLInput({ handleSQL, show, enabled, initialSQL, errorHandler })
208206 < div className = "row" >
209207 < div className = "col-12" >
210208 < div className = 'input-group' role = 'group' >
211- < SQLDropDown text = 'Catalog' values = { data . catalogs } onSelect = { setCatalog } />
209+ < SQLDropDown text = 'Catalog' values = { catalogs } onSelect = { catalogSelected } selected = { catalog } />
212210
213- < SQLDropDown text = 'Schema' values = { data . schemas } onSelect = { setSchema } />
211+ < SQLDropDown text = 'Schema' values = { schemas } onSelect = { schemaSelected } selected = { schema } />
214212
215213 < div className = "btn-group" >
216214 < button className = { clsx ( 'btn' , 'btn-success' , ! enabled && 'disabled' ) } type = "button" onClick = { checkValue } > Run</ button >
@@ -221,9 +219,9 @@ export function SQLInput({ handleSQL, show, enabled, initialSQL, errorHandler })
221219 < div className = "row" >
222220 < div className = "col-12" >
223221 < Editor
224- value = { code }
225- onValueChange = { code => setCode ( code ) }
226- highlight = { code => highlight ( code , languages . sql ) }
222+ value = { sql }
223+ onValueChange = { setSql }
224+ highlight = { val => highlight ( val , languages . sql ) }
227225 padding = { 10 }
228226 style = { {
229227 fontFamily : '"Fira code", "Fira Mono", monospace' ,
0 commit comments