@@ -7,19 +7,19 @@ import {settingsManager} from '../../../services/settings';
77import type { ColumnType } from '../../../types/api/query' ;
88import { TracingLevelNumber } from '../../../types/api/query' ;
99import type { QueryAction , QueryRequestParams , QuerySettings } from '../../../types/store/query' ;
10- import type {
11- QueryResponseChunk ,
12- SessionChunk ,
13- StreamDataChunk ,
14- } from '../../../types/store/streaming' ;
10+ import type { StreamDataChunk } from '../../../types/store/streaming' ;
1511import { QUERIES_HISTORY_KEY } from '../../../utils/constants' ;
16- import { isQueryErrorResponse , parseResult } from '../../../utils/query' ;
12+ import { isQueryErrorResponse } from '../../../utils/query' ;
1713import { isNumeric } from '../../../utils/utils' ;
1814import type { RootState } from '../../defaultStore' ;
1915import { api } from '../api' ;
2016
21- import { preparePlanData } from './preparePlanData' ;
2217import { prepareQueryData } from './prepareQueryData' ;
18+ import {
19+ addStreamingChunks as addStreamingChunksReducer ,
20+ setStreamQueryResponse as setStreamQueryResponseReducer ,
21+ setStreamSession as setStreamSessionReducer ,
22+ } from './streamingReducers' ;
2323import type { QueryResult , QueryState } from './types' ;
2424import { getActionAndSyntaxFromQueryMode , getQueryInHistory } from './utils' ;
2525
@@ -128,152 +128,9 @@ const slice = createSlice({
128128 setQueryHistoryFilter : ( state , action : PayloadAction < string > ) => {
129129 state . history . filter = action . payload ;
130130 } ,
131- setStreamSession : ( state , action : PayloadAction < SessionChunk > ) => {
132- if ( ! state . result ) {
133- return ;
134- }
135-
136- if ( ! state . result . data ) {
137- state . result . data = prepareQueryData ( null ) ;
138- }
139-
140- const chunk = action . payload ;
141- state . result . isLoading = true ;
142- state . result . queryId = chunk . meta . query_id ;
143- state . result . data . traceId = chunk . meta . trace_id ;
144- } ,
145- addStreamingChunks : ( state , action : PayloadAction < StreamDataChunk [ ] > ) => {
146- if ( ! state . result ) {
147- return ;
148- }
149-
150- if ( ! state . result . data ) {
151- state . result . data = prepareQueryData ( null ) ;
152- }
153-
154- // Initialize speed metrics if not present
155- if ( ! state . result . speedMetrics ) {
156- state . result . speedMetrics = {
157- rowsPerSecond : 0 ,
158- lastUpdateTime : Date . now ( ) ,
159- recentChunks : [ ] ,
160- } ;
161- }
162-
163- const currentTime = Date . now ( ) ;
164- let totalNewRows = 0 ;
165-
166- const mergedStreamDataChunks = new Map < number , StreamDataChunk > ( ) ;
167- for ( const chunk of action . payload ) {
168- const currentMergedChunk = mergedStreamDataChunks . get ( chunk . meta . result_index ) ;
169- const chunkRowCount = ( chunk . result . rows || [ ] ) . length ;
170- totalNewRows += chunkRowCount ;
171-
172- if ( currentMergedChunk ) {
173- if ( ! currentMergedChunk . result . rows ) {
174- currentMergedChunk . result . rows = [ ] ;
175- }
176- for ( const row of chunk . result . rows || [ ] ) {
177- currentMergedChunk . result . rows . push ( row ) ;
178- }
179- } else {
180- mergedStreamDataChunks . set ( chunk . meta . result_index , chunk ) ;
181- }
182- }
183-
184- // Update speed metrics
185- const metrics = state . result . speedMetrics ;
186- metrics . recentChunks . push ( {
187- timestamp : currentTime ,
188- rowCount : totalNewRows ,
189- } ) ;
190-
191- // Keep only chunks from the last 5 seconds
192- const WINDOW_SIZE = 5000 ; // 5 seconds in milliseconds
193- metrics . recentChunks = metrics . recentChunks . filter (
194- ( chunk ) => currentTime - chunk . timestamp <= WINDOW_SIZE ,
195- ) ;
196-
197- // Calculate moving average
198- if ( metrics . recentChunks . length > 0 ) {
199- const oldestChunkTime = metrics . recentChunks [ 0 ] . timestamp ;
200- const timeWindow = ( currentTime - oldestChunkTime ) / 1000 ; // Convert to seconds
201- const totalRows = metrics . recentChunks . reduce (
202- ( sum , chunk ) => sum + chunk . rowCount ,
203- 0 ,
204- ) ;
205- metrics . rowsPerSecond = timeWindow > 0 ? totalRows / timeWindow : 0 ;
206- }
207-
208- metrics . lastUpdateTime = currentTime ;
209-
210- if ( ! state . result . data . resultSets ) {
211- state . result . data . resultSets = [ ] ;
212- }
213-
214- for ( const [ resultIndex , chunk ] of mergedStreamDataChunks . entries ( ) ) {
215- const { columns, rows} = chunk . result ;
216-
217- if ( ! state . result . data . resultSets [ resultIndex ] ) {
218- state . result . data . resultSets [ resultIndex ] = {
219- columns : [ ] ,
220- result : [ ] ,
221- } ;
222- }
223-
224- if ( columns && ! state . result . data . resultSets [ resultIndex ] . columns ?. length ) {
225- state . result . data . resultSets [ resultIndex ] . columns ?. push ( INDEX_COLUMN ) ;
226- for ( const column of columns ) {
227- state . result . data . resultSets [ resultIndex ] . columns ?. push ( column ) ;
228- }
229- }
230-
231- const indexedRows = rows || [ ] ;
232- const startIndex =
233- state . result ?. data ?. resultSets ?. [ resultIndex ] . result ?. length || 1 ;
234-
235- indexedRows . forEach ( ( row , index ) => {
236- row . unshift ( startIndex + index ) ;
237- } ) ;
238-
239- const formattedRows = parseResult (
240- indexedRows ,
241- state . result . data . resultSets [ resultIndex ] . columns || [ ] ,
242- ) ;
243-
244- for ( const row of formattedRows ) {
245- state . result . data . resultSets [ resultIndex ] . result ?. push ( row ) ;
246- }
247- }
248- } ,
249- setStreamQueryResponse : ( state , action : PayloadAction < QueryResponseChunk > ) => {
250- if ( ! state . result ) {
251- return ;
252- }
253-
254- if ( ! state . result . data ) {
255- state . result . data = prepareQueryData ( null ) ;
256- }
257-
258- state . result . isLoading = false ;
259-
260- const chunk = action . payload ;
261- if ( 'error' in chunk ) {
262- state . result . error = chunk ;
263- } else if ( 'plan' in chunk ) {
264- if ( ! state . result . data ) {
265- state . result . data = prepareQueryData ( null ) ;
266- }
267-
268- const { plan : rawPlan , stats} = chunk ;
269- const { simplifiedPlan, ...planData } = preparePlanData ( rawPlan , stats ) ;
270- state . result . data . preparedPlan =
271- Object . keys ( planData ) . length > 0 ? planData : undefined ;
272- state . result . data . simplifiedPlan = simplifiedPlan ;
273- state . result . data . plan = chunk . plan ;
274- state . result . data . stats = chunk . stats ;
275- }
276- } ,
131+ setStreamSession : setStreamSessionReducer ,
132+ addStreamingChunks : addStreamingChunksReducer ,
133+ setStreamQueryResponse : setStreamQueryResponseReducer ,
277134 } ,
278135 selectors : {
279136 selectQueriesHistoryFilter : ( state ) => state . history . filter || '' ,
0 commit comments