@@ -23,6 +23,7 @@ import { Table as Arrow } from "apache-arrow";
2323import AnalyticsDataLogo from "./AnalyticsDataLogo" ;
2424import AnalyticsDataInfo from "./AnalyticsDataInfo" ;
2525import { useToast } from "@/hooks/use-toast" ;
26+ import { format } from "sql-formatter" ;
2627
2728export default function Main ( ) {
2829 const { toast } = useToast ( ) ;
@@ -88,171 +89,177 @@ export default function Main() {
8889 } , [ files . length , aggregation . name , rows . length , columns . length ] ) ;
8990
9091 const sqlQuery = ( ( ) => {
91- if ( files . length === 0 ) {
92- return null ;
93- } else if (
94- files . length === 1 &&
95- aggregation . name &&
96- ( rows . length > 0 || columns . length > 0 )
97- ) {
98- const row_list = rows . map ( ( row ) => row . name ) ;
99- const column_list = columns . map ( ( column ) => column . name ) ;
100- const all_fields = [ ...new Set ( [ ...row_list , ...column_list ] ) ] ;
101- const all_fields_string = all_fields
102- . map (
103- ( field ) =>
104- `CAST("${ field } " AS ${
105- getTypeForColumn ( queryFields , files [ 0 ] . name , field ) === "Utf8"
106- ? "VARCHAR"
107- : "DOUBLE"
108- } ) AS "${ field } "`
109- )
110- . join ( ", " ) ;
111- const all_fields_string_groupby = all_fields
112- . map (
113- ( field ) =>
114- `CAST("${ field } " AS ${
115- getTypeForColumn ( queryFields , files [ 0 ] . name , field ) === "Utf8"
116- ? "VARCHAR"
117- : "DOUBLE"
118- } )`
119- )
120- . join ( ", " ) ;
121-
122- return `
123- SELECT ${ all_fields_string } , ${ aggregation . type } (CAST("${
124- aggregation . name
125- } " AS ${
126- getTypeForColumn ( queryFields , files [ 0 ] . name , aggregation . name ) ===
127- "Utf8"
128- ? "VARCHAR"
129- : "DOUBLE"
130- } )) AS "${ aggregation . name } "
131- FROM '${ files [ 0 ] . name } '
132- ${
133- filters . length > 0
134- ? `WHERE ${ filters
135- . map (
136- ( filter ) =>
137- `"${ filter . field } " IN (${ filter . values
138- . map ( ( value ) => `'${ value } '` )
139- . join ( ", " ) } )`
140- )
141- . join ( " AND " ) } `
142- : ""
143- }
144- GROUP BY ${ all_fields_string_groupby }
145- ` ;
146- } else if (
147- files . length > 1 &&
148- aggregation . name &&
149- ( rows . length > 0 || columns . length > 0 )
150- ) {
151- const fields = [ ...rows , ...columns ] ;
152-
153- const uniqueFields = [
154- ...new Set ( fields . map ( ( field ) => JSON . stringify ( field ) ) ) ,
155- ] . map ( ( str ) => JSON . parse ( str ) ) ;
156-
157- const all_fields_string = uniqueFields . map (
158- ( field ) =>
159- `CAST(TABLE${ files . findIndex ( ( file ) => file . name === field . table ) } ."${
160- field . name
161- } " AS ${
162- getTypeForColumn ( queryFields , field . table , field . name ) === "Utf8"
163- ? "VARCHAR"
164- : "DOUBLE"
165- } ) AS "${ field . name } "`
166- ) ;
167-
168- const all_fields_string_groupby = uniqueFields
169- . map (
92+ const generateQuery = ( ) => {
93+ if ( files . length === 0 ) {
94+ return null ;
95+ } else if (
96+ files . length === 1 &&
97+ aggregation . name &&
98+ ( rows . length > 0 || columns . length > 0 )
99+ ) {
100+ const row_list = rows . map ( ( row ) => row . name ) ;
101+ const column_list = columns . map ( ( column ) => column . name ) ;
102+ const all_fields = [ ...new Set ( [ ...row_list , ...column_list ] ) ] ;
103+ const all_fields_string = all_fields
104+ . map (
105+ ( field ) =>
106+ `CAST("${ field } " AS ${
107+ getTypeForColumn ( queryFields , files [ 0 ] . name , field ) === "Utf8"
108+ ? "VARCHAR"
109+ : "DOUBLE"
110+ } ) AS "${ field } "`
111+ )
112+ . join ( ", " ) ;
113+ const all_fields_string_groupby = all_fields
114+ . map (
115+ ( field ) =>
116+ `CAST("${ field } " AS ${
117+ getTypeForColumn ( queryFields , files [ 0 ] . name , field ) === "Utf8"
118+ ? "VARCHAR"
119+ : "DOUBLE"
120+ } )`
121+ )
122+ . join ( ", " ) ;
123+
124+ return `
125+ SELECT ${ all_fields_string } , ${ aggregation . type } (CAST("${
126+ aggregation . name
127+ } " AS ${
128+ getTypeForColumn ( queryFields , files [ 0 ] . name , aggregation . name ) ===
129+ "Utf8"
130+ ? "VARCHAR"
131+ : "DOUBLE"
132+ } )) AS "${ aggregation . name } "
133+ FROM '${ files [ 0 ] . name } '
134+ ${
135+ filters . length > 0
136+ ? `WHERE ${ filters
137+ . map (
138+ ( filter ) =>
139+ `"${ filter . field } " IN (${ filter . values
140+ . map ( ( value ) => `'${ value } '` )
141+ . join ( ", " ) } )`
142+ )
143+ . join ( " AND " ) } `
144+ : ""
145+ }
146+ GROUP BY ${ all_fields_string_groupby }
147+ ` ;
148+ } else if (
149+ files . length > 1 &&
150+ aggregation . name &&
151+ ( rows . length > 0 || columns . length > 0 )
152+ ) {
153+ const fields = [ ...rows , ...columns ] ;
154+
155+ const uniqueFields = [
156+ ...new Set ( fields . map ( ( field ) => JSON . stringify ( field ) ) ) ,
157+ ] . map ( ( str ) => JSON . parse ( str ) ) ;
158+
159+ const all_fields_string = uniqueFields . map (
170160 ( field ) =>
171161 `CAST(TABLE${ files . findIndex (
172162 ( file ) => file . name === field . table
173163 ) } ."${ field . name } " AS ${
174164 getTypeForColumn ( queryFields , field . table , field . name ) === "Utf8"
175165 ? "VARCHAR"
176166 : "DOUBLE"
177- } )`
178- )
179- . join ( ", " ) ;
180-
181- const relationship_list = relationships . map ( ( relationship ) => {
182- const isPrimaryFloat =
183- getTypeForColumn (
184- queryFields ,
185- relationship . primary_table ,
167+ } ) AS "${ field . name } "`
168+ ) ;
169+
170+ const all_fields_string_groupby = uniqueFields
171+ . map (
172+ ( field ) =>
173+ `CAST(TABLE${ files . findIndex (
174+ ( file ) => file . name === field . table
175+ ) } ."${ field . name } " AS ${
176+ getTypeForColumn ( queryFields , field . table , field . name ) ===
177+ "Utf8"
178+ ? "VARCHAR"
179+ : "DOUBLE"
180+ } )`
181+ )
182+ . join ( ", " ) ;
183+
184+ const relationship_list = relationships . map ( ( relationship ) => {
185+ const isPrimaryFloat =
186+ getTypeForColumn (
187+ queryFields ,
188+ relationship . primary_table ,
189+ relationship . primary_key
190+ ) !== "Utf8" ;
191+ const isForeignFloat =
192+ getTypeForColumn (
193+ queryFields ,
194+ relationship . foreign_table ,
195+ relationship . foreign_key
196+ ) !== "Utf8" ;
197+ const castType =
198+ isPrimaryFloat || isForeignFloat ? "DOUBLE" : "VARCHAR" ;
199+
200+ return `CAST(TABLE${ files . findIndex (
201+ ( file ) => file . name === relationship . primary_table
202+ ) } ."${
186203 relationship . primary_key
187- ) !== "Utf8" ;
188- const isForeignFloat =
189- getTypeForColumn (
190- queryFields ,
191- relationship . foreign_table ,
192- relationship . foreign_key
193- ) !== "Utf8" ;
194- const castType =
195- isPrimaryFloat || isForeignFloat ? "DOUBLE" : "VARCHAR" ;
196-
197- return `CAST(TABLE${ files . findIndex (
198- ( file ) => file . name === relationship . primary_table
199- ) } ."${
200- relationship . primary_key
201- } " AS ${ castType } ) = CAST(TABLE${ files . findIndex (
202- ( file ) => file . name === relationship . foreign_table
203- ) } ."${ relationship . foreign_key } " AS ${ castType } )`;
204- } ) ;
204+ } " AS ${ castType } ) = CAST(TABLE${ files . findIndex (
205+ ( file ) => file . name === relationship . foreign_table
206+ ) } ."${ relationship . foreign_key } " AS ${ castType } )`;
207+ } ) ;
205208
206- return `
207- SELECT ${ all_fields_string } , ${ aggregation . type } (CAST("${
208- aggregation . name
209- } " AS ${
210- getTypeForColumn (
211- queryFields ,
212- files [ files . findIndex ( ( file ) => file . name === aggregation . table ) ]
213- . name ,
209+ return `
210+ SELECT ${ all_fields_string } , ${ aggregation . type } (CAST("${
214211 aggregation . name
215- ) === "Utf8"
216- ? "VARCHAR"
217- : "DOUBLE"
218- } )) AS "${ aggregation . name } "
219- FROM '${ files [ 0 ] . name } ' AS TABLE0
220- JOIN ${ files
221- . slice ( 1 )
222- . map (
223- ( file ) =>
224- `'${ file . name } ' AS TABLE${ files . findIndex (
225- ( innerFile ) => file . name === innerFile . name
226- ) } ON ${ relationship_list
227- . filter ( ( relationship ) =>
228- relationship . includes (
229- `TABLE${ files . findIndex (
230- ( innerFile2 ) => file . name === innerFile2 . name
231- ) } `
212+ } " AS ${
213+ getTypeForColumn (
214+ queryFields ,
215+ files [ files . findIndex ( ( file ) => file . name === aggregation . table ) ]
216+ . name ,
217+ aggregation . name
218+ ) === "Utf8"
219+ ? "VARCHAR"
220+ : "DOUBLE"
221+ } )) AS "${ aggregation . name } "
222+ FROM '${ files [ 0 ] . name } ' AS TABLE0
223+ JOIN ${ files
224+ . slice ( 1 )
225+ . map (
226+ ( file ) =>
227+ `'${ file . name } ' AS TABLE${ files . findIndex (
228+ ( innerFile ) => file . name === innerFile . name
229+ ) } ON ${ relationship_list
230+ . filter ( ( relationship ) =>
231+ relationship . includes (
232+ `TABLE${ files . findIndex (
233+ ( innerFile2 ) => file . name === innerFile2 . name
234+ ) } `
235+ )
232236 )
233- )
234- . join ( " AND " ) } `
235- )
236- . join ( " JOIN " ) }
237- ${
238- filters . length > 0
239- ? `WHERE ${ filters
240- . map (
241- ( filter ) =>
242- `TABLE${ files . findIndex (
243- ( file ) => file . name === filter . table
244- ) } ."${ filter . field } " IN (${ filter . values
245- . map ( ( value ) => `'${ value } '` )
246- . join ( ", " ) } )`
247- )
248- . join ( " AND " ) } `
249- : ""
250- }
251- GROUP BY ${ all_fields_string_groupby }
252- ` ;
253- } else {
254- return `SELECT * FROM '${ selectedPreviewFile } ' LIMIT ${ previewRows } ` ;
255- }
237+ . join ( " AND " ) } `
238+ )
239+ . join ( " JOIN " ) }
240+ ${
241+ filters . length > 0
242+ ? `WHERE ${ filters
243+ . map (
244+ ( filter ) =>
245+ `TABLE${ files . findIndex (
246+ ( file ) => file . name === filter . table
247+ ) } ."${ filter . field } " IN (${ filter . values
248+ . map ( ( value ) => `'${ value } '` )
249+ . join ( ", " ) } )`
250+ )
251+ . join ( " AND " ) } `
252+ : ""
253+ }
254+ GROUP BY ${ all_fields_string_groupby }
255+ ` ;
256+ } else {
257+ return `SELECT * FROM '${ selectedPreviewFile } ' LIMIT ${ previewRows } ` ;
258+ }
259+ } ;
260+
261+ const rawQuery = generateQuery ( ) ;
262+ return rawQuery ? format ( rawQuery , { language : "sqlite" } ) : null ;
256263 } ) ( ) ;
257264
258265 const handleRunQuery = async ( ) => {
0 commit comments