@@ -21,7 +21,7 @@ import {
21
21
buildQueryContext ,
22
22
QueryFormData ,
23
23
} from '@superset-ui/core' ;
24
- import moment , { Moment } from 'moment ' ;
24
+ import { computeQueryBComparator } from '../utils ' ;
25
25
26
26
/**
27
27
* The buildQuery function is used to create an instance of QueryContext that's
@@ -38,184 +38,6 @@ import moment, { Moment } from 'moment';
38
38
* if a viz needs multiple different result sets.
39
39
*/
40
40
41
- type MomentTuple = [ moment . Moment | null , moment . Moment | null ] ;
42
-
43
- function getSinceUntil (
44
- timeRange : string | null = null ,
45
- relativeStart : string | null = null ,
46
- relativeEnd : string | null = null ,
47
- ) : MomentTuple {
48
- const separator = ' : ' ;
49
- const effectiveRelativeStart = relativeStart || 'today' ;
50
- const effectiveRelativeEnd = relativeEnd || 'today' ;
51
-
52
- if ( ! timeRange ) {
53
- return [ null , null ] ;
54
- }
55
-
56
- let modTimeRange : string | null = timeRange ;
57
-
58
- if ( timeRange === 'NO_TIME_RANGE' || timeRange === '_(NO_TIME_RANGE)' ) {
59
- return [ null , null ] ;
60
- }
61
-
62
- if ( timeRange ?. startsWith ( 'last' ) && ! timeRange . includes ( separator ) ) {
63
- modTimeRange = timeRange + separator + effectiveRelativeEnd ;
64
- }
65
-
66
- if ( timeRange ?. startsWith ( 'next' ) && ! timeRange . includes ( separator ) ) {
67
- modTimeRange = effectiveRelativeStart + separator + timeRange ;
68
- }
69
-
70
- if (
71
- timeRange ?. startsWith ( 'previous calendar week' ) &&
72
- ! timeRange . includes ( separator )
73
- ) {
74
- return [
75
- moment ( ) . subtract ( 1 , 'week' ) . startOf ( 'week' ) ,
76
- moment ( ) . startOf ( 'week' ) ,
77
- ] ;
78
- }
79
-
80
- if (
81
- timeRange ?. startsWith ( 'previous calendar month' ) &&
82
- ! timeRange . includes ( separator )
83
- ) {
84
- return [
85
- moment ( ) . subtract ( 1 , 'month' ) . startOf ( 'month' ) ,
86
- moment ( ) . startOf ( 'month' ) ,
87
- ] ;
88
- }
89
-
90
- if (
91
- timeRange ?. startsWith ( 'previous calendar year' ) &&
92
- ! timeRange . includes ( separator )
93
- ) {
94
- return [
95
- moment ( ) . subtract ( 1 , 'year' ) . startOf ( 'year' ) ,
96
- moment ( ) . startOf ( 'year' ) ,
97
- ] ;
98
- }
99
-
100
- const timeRangeLookup : Array < [ RegExp , ( ...args : string [ ] ) => Moment ] > = [
101
- [
102
- / ^ l a s t \s + ( d a y | w e e k | m o n t h | q u a r t e r | y e a r ) $ / i,
103
- ( unit : string ) =>
104
- moment ( ) . subtract ( 1 , unit as moment . unitOfTime . DurationConstructor ) ,
105
- ] ,
106
- [
107
- / ^ l a s t \s + ( [ 0 - 9 ] + ) \s + ( s e c o n d | m i n u t e | h o u r | d a y | w e e k | m o n t h | y e a r ) s ? $ / i,
108
- ( delta : string , unit : string ) =>
109
- moment ( ) . subtract ( delta , unit as moment . unitOfTime . DurationConstructor ) ,
110
- ] ,
111
- [
112
- / ^ n e x t \s + ( [ 0 - 9 ] + ) \s + ( s e c o n d | m i n u t e | h o u r | d a y | w e e k | m o n t h | y e a r ) s ? $ / i,
113
- ( delta : string , unit : string ) =>
114
- moment ( ) . add ( delta , unit as moment . unitOfTime . DurationConstructor ) ,
115
- ] ,
116
- [
117
- // eslint-disable-next-line no-useless-escape
118
- / D A T E A D D \( D A T E T I M E \( " ( [ ^ " ] + ) " \) , \s * ( - ? \d + ) , \s * ( [ ^ \) ] + ) \) / i,
119
- ( timePart : string , delta : string , unit : string ) => {
120
- if ( timePart === 'now' ) {
121
- return moment ( ) . add (
122
- delta ,
123
- unit as moment . unitOfTime . DurationConstructor ,
124
- ) ;
125
- }
126
- if ( moment ( timePart . toUpperCase ( ) , true ) . isValid ( ) ) {
127
- return moment ( timePart ) . add (
128
- delta ,
129
- unit as moment . unitOfTime . DurationConstructor ,
130
- ) ;
131
- }
132
- return moment ( ) ;
133
- } ,
134
- ] ,
135
- ] ;
136
-
137
- const sinceAndUntilPartition = modTimeRange
138
- . split ( separator , 2 )
139
- . map ( part => part . trim ( ) ) ;
140
-
141
- const sinceAndUntil : ( Moment | null ) [ ] = sinceAndUntilPartition . map ( part => {
142
- if ( ! part ) {
143
- return null ;
144
- }
145
-
146
- let transformedValue : Moment | null = null ;
147
- // Matching time_range_lookup
148
- const matched = timeRangeLookup . some ( ( [ pattern , fn ] ) => {
149
- const result = part . match ( pattern ) ;
150
- if ( result ) {
151
- transformedValue = fn ( ...result . slice ( 1 ) ) ;
152
- return true ;
153
- }
154
-
155
- if ( part === 'today' ) {
156
- transformedValue = moment ( ) . startOf ( 'day' ) ;
157
- return true ;
158
- }
159
-
160
- if ( part === 'now' ) {
161
- transformedValue = moment ( ) ;
162
- return true ;
163
- }
164
- return false ;
165
- } ) ;
166
-
167
- if ( matched && transformedValue !== null ) {
168
- // Handle the transformed value
169
- } else {
170
- // Handle the case when there was no match
171
- transformedValue = moment ( `${ part } ` ) ;
172
- }
173
-
174
- return transformedValue ;
175
- } ) ;
176
-
177
- const [ _since , _until ] = sinceAndUntil ;
178
-
179
- if ( _since && _until && _since . isAfter ( _until ) ) {
180
- throw new Error ( 'From date cannot be larger than to date' ) ;
181
- }
182
-
183
- return [ _since , _until ] ;
184
- }
185
-
186
- function calculatePrev (
187
- startDate : Moment | null ,
188
- endDate : Moment | null ,
189
- calcType : String ,
190
- ) {
191
- if ( ! startDate || ! endDate ) {
192
- return [ null , null ] ;
193
- }
194
-
195
- const daysBetween = endDate . diff ( startDate , 'days' ) ;
196
-
197
- let startDatePrev = moment ( ) ;
198
- let endDatePrev = moment ( ) ;
199
- if ( calcType === 'y' ) {
200
- startDatePrev = startDate . subtract ( 1 , 'year' ) ;
201
- endDatePrev = endDate . subtract ( 1 , 'year' ) ;
202
- } else if ( calcType === 'w' ) {
203
- startDatePrev = startDate . subtract ( 1 , 'week' ) ;
204
- endDatePrev = endDate . subtract ( 1 , 'week' ) ;
205
- } else if ( calcType === 'm' ) {
206
- startDatePrev = startDate . subtract ( 1 , 'month' ) ;
207
- endDatePrev = endDate . subtract ( 1 , 'month' ) ;
208
- } else if ( calcType === 'r' ) {
209
- startDatePrev = startDate . clone ( ) . subtract ( daysBetween . valueOf ( ) , 'day' ) ;
210
- endDatePrev = startDate ;
211
- } else {
212
- startDatePrev = startDate . subtract ( 1 , 'year' ) ;
213
- endDatePrev = endDate . subtract ( 1 , 'year' ) ;
214
- }
215
-
216
- return [ startDatePrev , endDatePrev ] ;
217
- }
218
-
219
41
export default function buildQuery ( formData : QueryFormData ) {
220
42
const {
221
43
cols : groupby ,
@@ -240,37 +62,19 @@ export default function buildQuery(formData: QueryFormData) {
240
62
? formData . adhoc_filters [ timeFilterIndex ]
241
63
: null ;
242
64
243
- let testSince = null ;
244
- let testUntil = null ;
245
-
246
- if (
247
- timeFilter &&
248
- 'comparator' in timeFilter &&
249
- typeof timeFilter . comparator === 'string'
250
- ) {
251
- let timeRange = timeFilter . comparator . toLocaleLowerCase ( ) ;
252
- if ( extraFormData ?. time_range ) {
253
- timeRange = extraFormData . time_range ;
254
- }
255
- [ testSince , testUntil ] = getSinceUntil ( timeRange ) ;
256
- }
257
-
258
65
let formDataB : QueryFormData ;
66
+ let queryBComparator = null ;
259
67
260
68
if ( timeComparison !== 'c' ) {
261
- const [ prevStartDateMoment , prevEndDateMoment ] = calculatePrev (
262
- testSince ,
263
- testUntil ,
69
+ queryBComparator = computeQueryBComparator (
70
+ formData . adhoc_filters || [ ] ,
264
71
timeComparison ,
72
+ extraFormData ,
265
73
) ;
266
74
267
- const queryBComparator = `${ prevStartDateMoment ?. format (
268
- 'YYYY-MM-DDTHH:mm:ss' ,
269
- ) } : ${ prevEndDateMoment ?. format ( 'YYYY-MM-DDTHH:mm:ss' ) } `;
270
-
271
75
const queryBFilter : any = {
272
76
...timeFilter ,
273
- comparator : queryBComparator . replace ( / Z / g , '' ) ,
77
+ comparator : queryBComparator ,
274
78
} ;
275
79
276
80
const otherFilters = formData . adhoc_filters ?. filter (
0 commit comments