@@ -7,12 +7,14 @@ import { zeroStateChanged } from './zero-state';
77import { isLoadedChanged } from './is-loaded' ;
88import { isEqual , pick } from 'lodash' ;
99import type { ThunkDispatch } from 'redux-thunk' ;
10- import { disableEditRules } from './edit-mode' ;
10+ import { disableEditRules , enableEditRules } from './edit-mode' ;
1111import { analyzeSchema } from '@mongodb-js/compass-schema-analysis' ;
1212
1313export type ValidationServerAction = 'error' | 'warn' ;
1414export type ValidationLevel = 'off' | 'moderate' | 'strict' ;
1515
16+ const SAMPLE_SIZE = 1000 ;
17+
1618/**
1719 * The module action prefix.
1820 */
@@ -93,8 +95,20 @@ interface RulesGenerationStartedAction {
9395export const RULES_GENERATION_FAILED =
9496 `${ PREFIX } /RULES_GENERATION_FAILED` as const ;
9597interface RulesGenerationFailedAction {
96- type : typeof RULES_GENERATION_STARTED ;
97- syntaxError : null | { message : string } ;
98+ type : typeof RULES_GENERATION_FAILED ;
99+ message : string ;
100+ }
101+
102+ export const RULES_GENERATION_CLEAR_ERROR =
103+ `${ PREFIX } /RULES_GENERATION_CLEAR_ERROR` as const ;
104+ interface RulesGenerationClearErrorAction {
105+ type : typeof RULES_GENERATION_CLEAR_ERROR ;
106+ }
107+
108+ export const RULES_GENERATION_FINISHED =
109+ `${ PREFIX } /RULES_GENERATION_FINISHED` as const ;
110+ interface RulesGenerationFinishedAction {
111+ type : typeof RULES_GENERATION_FINISHED ;
98112}
99113
100114export type ValidationAction =
@@ -104,7 +118,11 @@ export type ValidationAction =
104118 | ValidationFetchedAction
105119 | ValidationActionChangedAction
106120 | ValidationLevelChangedAction
107- | SyntaxErrorOccurredAction ;
121+ | SyntaxErrorOccurredAction
122+ | RulesGenerationStartedAction
123+ | RulesGenerationFinishedAction
124+ | RulesGenerationFailedAction
125+ | RulesGenerationClearErrorAction ;
108126
109127export interface Validation {
110128 validator : string ;
@@ -124,8 +142,8 @@ export interface ValidationState extends Validation {
124142 syntaxError : null | { message : string } ;
125143 error : null | { message : string } ;
126144 prevValidation ?: Validation ;
127- rulesGenerationStatus ?: 'in-progress' | 'failed' ;
128- rulesGenerationErrorMessage ?: string ;
145+ isRulesGenerationInProgress ?: boolean ;
146+ rulesGenerationError ?: string ;
129147}
130148
131149/**
@@ -205,6 +223,34 @@ const setSyntaxError = (
205223 syntaxError : action . syntaxError ,
206224} ) ;
207225
226+ const startRulesGeneration = ( state : ValidationState ) : ValidationState => ( {
227+ ...state ,
228+ isRulesGenerationInProgress : true ,
229+ rulesGenerationError : undefined ,
230+ } ) ;
231+
232+ const finishRulesGeneration = ( state : ValidationState ) : ValidationState => ( {
233+ ...state ,
234+ isRulesGenerationInProgress : undefined ,
235+ rulesGenerationError : undefined ,
236+ } ) ;
237+
238+ const markRulesGenerationFailure = (
239+ state : ValidationState ,
240+ action : RulesGenerationFailedAction
241+ ) : ValidationState => ( {
242+ ...state ,
243+ isRulesGenerationInProgress : undefined ,
244+ rulesGenerationError : action . message ,
245+ } ) ;
246+
247+ const unsetRulesGenerationError = (
248+ state : ValidationState
249+ ) : ValidationState => ( {
250+ ...state ,
251+ rulesGenerationError : undefined ,
252+ } ) ;
253+
208254/**
209255 * Set validation.
210256 */
@@ -307,6 +353,10 @@ const MAPPINGS: {
307353 [ VALIDATION_ACTION_CHANGED ] : changeValidationAction ,
308354 [ VALIDATION_LEVEL_CHANGED ] : changeValidationLevel ,
309355 [ SYNTAX_ERROR_OCCURRED ] : setSyntaxError ,
356+ [ RULES_GENERATION_STARTED ] : startRulesGeneration ,
357+ [ RULES_GENERATION_FINISHED ] : finishRulesGeneration ,
358+ [ RULES_GENERATION_FAILED ] : markRulesGenerationFailure ,
359+ [ RULES_GENERATION_CLEAR_ERROR ] : unsetRulesGenerationError ,
310360} ;
311361
312362/**
@@ -397,6 +447,11 @@ export const syntaxErrorOccurred = (
397447 syntaxError,
398448} ) ;
399449
450+ export const clearRulesGenerationError =
451+ ( ) : RulesGenerationClearErrorAction => ( {
452+ type : RULES_GENERATION_CLEAR_ERROR ,
453+ } ) ;
454+
400455export const fetchValidation = ( namespace : {
401456 database : string ;
402457 collection : string ;
@@ -553,39 +608,92 @@ export const activateValidation = (): SchemaValidationThunkAction<void> => {
553608 } ;
554609} ;
555610
611+ export const stopRulesGeneration = ( ) : SchemaValidationThunkAction < void > => {
612+ return (
613+ dispatch ,
614+ getState ,
615+ { rulesGenerationAbortControllerRef, connectionInfoRef, track }
616+ ) => {
617+ if ( ! rulesGenerationAbortControllerRef . current ) return ;
618+ // const analysisTime =
619+ // Date.now() - (getState().schemaAnalysis.analysisStartTime ?? 0);
620+ // track(
621+ // 'Schema Analysis Cancelled',
622+ // {
623+ // analysis_time_ms: analysisTime,
624+ // with_filter: Object.entries(query.filter ?? {}).length > 0,
625+ // },
626+ // connectionInfoRef.current
627+ // );
628+
629+ rulesGenerationAbortControllerRef . current ?. abort ( 'Analysis cancelled' ) ;
630+ } ;
631+ } ;
632+
556633/**
557634 * Get $jsonSchema from schema analysis
558635 * @returns
559636 */
560637export const generateValidationRules = ( ) : SchemaValidationThunkAction <
561638 Promise < void >
562639> => {
563- return async ( dispatch , getState , { dataService, logger, preferences } ) => {
640+ return async (
641+ dispatch ,
642+ getState ,
643+ { dataService, logger, preferences, rulesGenerationAbortControllerRef }
644+ ) => {
564645 dispatch ( { type : RULES_GENERATION_STARTED } ) ;
646+ console . log ( 'START' ) ;
647+
648+ rulesGenerationAbortControllerRef . current = new AbortController ( ) ;
649+ const abortSignal = rulesGenerationAbortControllerRef . current . signal ;
650+
651+ const { namespace } = getState ( ) ;
652+ const { maxTimeMS } = preferences . getPreferences ( ) ;
565653
566654 try {
567- ///// TODO
568- const samplingOptions = { } ;
569- const driverOptions = { } ;
570- const abortSignal = new AbortSignal ( ) ;
571- const namespace = '' ;
655+ const samplingOptions = {
656+ query : { } ,
657+ size : SAMPLE_SIZE ,
658+ fields : undefined ,
659+ } ;
660+ const driverOptions = {
661+ maxTimeMS,
662+ } ;
663+ console . log ( 'ANALYZING' ) ;
572664 const schemaAccessor = await analyzeSchema (
573665 dataService ,
574666 abortSignal ,
575- namespace ,
667+ namespace . toString ( ) ,
576668 samplingOptions ,
577669 driverOptions ,
578670 logger ,
579671 preferences
580672 ) ;
673+ if ( abortSignal ?. aborted ) {
674+ throw new Error ( abortSignal ?. reason || new Error ( 'Operation aborted' ) ) ;
675+ }
581676
582- const jsonSchema = await schemaAccessor ?. getMongoDBJsonSchema ( ) ;
677+ console . log ( 'CONVERTING' ) ;
678+ const jsonSchema = await schemaAccessor ?. getMongoDBJsonSchema ( {
679+ signal : abortSignal ,
680+ } ) ;
681+ if ( abortSignal ?. aborted ) {
682+ throw new Error ( abortSignal ?. reason || new Error ( 'Operation aborted' ) ) ;
683+ }
684+ console . log ( 'STRINGIFYING' ) ;
583685 const validator = JSON . stringify ( jsonSchema , undefined , 2 ) ;
584-
686+ console . log ( 'DONE' ) ;
585687 dispatch ( validationLevelChanged ( 'moderate' ) ) ;
586688 dispatch ( validatorChanged ( validator ) ) ;
689+ dispatch ( enableEditRules ( ) ) ;
690+ dispatch ( { type : RULES_GENERATION_FINISHED } ) ;
691+ dispatch ( zeroStateChanged ( false ) ) ;
587692 } catch ( error ) {
588- dispatch ( { type : RULES_GENERATION_FAILED } ) ;
693+ dispatch ( {
694+ type : RULES_GENERATION_FAILED ,
695+ message : `Rules generation failed: ${ ( error as Error ) . message } ` ,
696+ } ) ;
589697 }
590698 } ;
591699} ;
0 commit comments