11import _ from "lodash" ;
2+ import moment from "moment" ;
23import BigQueryQuery from "./bigquery_query" ;
34import ResponseParser , { IResultFormat } from "./response_parser" ;
4- import { countBy } from "lodash-es" ;
5+ import { countBy , size } from "lodash-es" ;
6+ import { sheets } from "googleapis/build/src/apis/sheets" ;
57
8+ const Shifted = "_shifted" ;
69function sleep ( ms ) {
710 return new Promise ( resolve => {
811 setTimeout ( resolve , ms ) ;
@@ -40,7 +43,95 @@ export class BigQueryDatasource {
4043 }
4144 throw BigQueryDatasource . formatBigqueryError ( msg ) ;
4245 }
46+ private static _createTimeShiftQuery ( query ) {
47+ const res = BigQueryQuery . getTimeShift ( query . rawSql ) ;
48+ if ( ! res ) {
49+ return res ;
50+ }
51+ const copy = query . constructor ( ) ;
52+ for ( const attr in query ) {
53+ if ( query . hasOwnProperty ( attr ) ) {
54+ copy [ attr ] = query [ attr ] ;
55+ }
56+ }
57+ copy . rawSql = BigQueryQuery . replaceTimeShift ( copy . rawSql ) ;
58+ copy . format += "#" + res ;
59+ copy . refId += Shifted + "_" + res ;
60+ return copy ;
61+ }
62+
63+ private static _getShiftPeriod ( strInterval ) {
64+ const shift = strInterval . match ( / \d + / ) [ 0 ] ;
65+ strInterval = strInterval . substr ( shift . length , strInterval . length ) ;
66+ if ( strInterval === "m" ) {
67+ strInterval = "M" ;
68+ }
69+
70+ if ( strInterval === "min" ) {
71+ strInterval = "m" ;
72+ }
73+ return [ strInterval , shift ] ;
74+ }
75+ private static _setupTimeShiftQuery ( query , options ) {
76+ const index = query . format . indexOf ( "#" ) ;
77+ const copy = options . constructor ( ) ;
78+ for ( const attr in options ) {
79+ if ( options . hasOwnProperty ( attr ) ) {
80+ copy [ attr ] = options [ attr ] ;
81+ }
82+ }
83+ if ( index === - 1 ) {
84+ return copy ;
85+ }
86+ let strInterval = query . format . substr ( index + 1 , query . format . len ) ;
87+ const res = BigQueryDatasource . _getShiftPeriod ( strInterval ) ;
88+ strInterval = res [ 0 ] ;
89+ if (
90+ ! [ "s" , "min" , "h" , "d" , "w" , "m" , "w" , "y" , "M" ] . includes ( strInterval )
91+ ) {
92+ return copy ;
93+ }
94+ query . format = query . format . substr ( 0 , index ) ;
95+ strInterval = res [ 0 ] ;
96+ const shift = res [ 1 ] ;
97+ if ( strInterval === "m" ) {
98+ strInterval = "M" ;
99+ }
100+
101+ if ( strInterval === "min" ) {
102+ strInterval = "m" ;
103+ }
104+ copy . range . from = options . range . from . subtract (
105+ parseInt ( shift , 10 ) ,
106+ strInterval
107+ ) ;
108+ copy . range . to = options . range . to . subtract ( parseInt ( shift , 10 ) , strInterval ) ;
109+ return copy ;
110+ }
43111
112+ private static _updatePartition ( q , options ) {
113+ if ( q . indexOf ( "AND _PARTITIONTIME >= " ) < 1 ) {
114+ return q ;
115+ }
116+ if ( q . indexOf ( "AND _PARTITIONTIME <" ) < 1 ) {
117+ return q ;
118+ }
119+ const from = q . substr ( q . indexOf ( "AND _PARTITIONTIME >= " ) + 22 , 21 ) ;
120+
121+ const newFrom =
122+ "'" +
123+ BigQueryQuery . formatDateToString ( options . range . from . _d , "-" , true ) +
124+ "'" ;
125+ q = q . replace ( from , newFrom ) ;
126+ const to = q . substr ( q . indexOf ( "AND _PARTITIONTIME < " ) + 21 , 21 ) ;
127+ const newTo =
128+ "'" +
129+ BigQueryQuery . formatDateToString ( options . range . to . _d , "-" , true ) +
130+ "'" ;
131+
132+ q = q . replace ( to , newTo ) + "\n " ;
133+ return q ;
134+ }
44135 public authenticationType : string ;
45136 public projectName : string ;
46137 private readonly id : any ;
@@ -99,10 +190,25 @@ export class BigQueryDatasource {
99190 if ( queries . length === 0 ) {
100191 return this . $q . when ( { data : [ ] } ) ;
101192 }
193+ _ . map ( queries , query => {
194+ const newQuery = BigQueryDatasource . _createTimeShiftQuery ( query ) ;
195+ if ( newQuery ) {
196+ queries . push ( newQuery ) ;
197+ }
198+ } ) ;
102199 const allQueryPromise = _ . map ( queries , query => {
103200 const tmpQ = this . queryModel . target . rawSql ;
104201 this . queryModel . target . rawSql = query . rawSql ;
105- const q = this . queryModel . expend_macros ( options ) ;
202+ const modOptions = BigQueryDatasource . _setupTimeShiftQuery (
203+ query ,
204+ options
205+ ) ;
206+ let q = this . queryModel . expend_macros ( modOptions ) ;
207+ q = BigQueryDatasource . _updatePartition ( q , modOptions ) ;
208+ if ( query . refId . search ( Shifted ) > - 1 ) {
209+ q = this . _updateAlias ( q , modOptions , query . refId ) ;
210+ }
211+ console . log ( q ) ;
106212 this . queryModel . target . rawSql = tmpQ ;
107213 return this . doQuery ( q , options . panelId + query . refId ) . then ( response => {
108214 return ResponseParser . parseDataQuery ( response , query . format ) ;
@@ -120,6 +226,20 @@ export class BigQueryDatasource {
120226 }
121227 }
122228 }
229+ for ( const d of data ) {
230+ if ( d . target . search ( Shifted ) > - 1 ) {
231+ const res = BigQueryDatasource . _getShiftPeriod (
232+ d . target . substring ( d . target . lastIndexOf ( "_" ) + 1 , d . target . length )
233+ ) ;
234+ const shiftPeriod = res [ 0 ] ;
235+ const shiftVal = res [ 1 ] ;
236+ for ( let i = 0 ; i < d . datapoints . length ; i ++ ) {
237+ d . datapoints [ i ] [ 1 ] = moment ( d . datapoints [ i ] [ 1 ] )
238+ . subtract ( shiftVal , shiftPeriod )
239+ . valueOf ( ) ;
240+ }
241+ }
242+ }
123243 return { data } ;
124244 }
125245 ) ;
@@ -179,8 +299,7 @@ export class BigQueryDatasource {
179299 return ResponseParser . parseTableFields ( data , filter ) ;
180300 }
181301
182-
183- public async getDefaultProject ( ) {
302+ public async getDefaultProject ( ) {
184303 try {
185304 if ( this . authenticationType === "gce" || ! this . projectName ) {
186305 let data ;
@@ -405,4 +524,25 @@ export class BigQueryDatasource {
405524 }
406525 return data ;
407526 }
527+ private _updateAlias ( q , options , shiftstr ) {
528+ const index = shiftstr . search ( Shifted ) ;
529+ const shifted = shiftstr . substr ( index , shiftstr . length ) ;
530+ for ( const al of options . targets [ 0 ] . select [ 0 ] ) {
531+ if ( al . type === "alias" ) {
532+ q = q . replace ( "AS " + al . params [ 0 ] , "AS " + al . params [ 0 ] + shifted ) ;
533+ return q ;
534+ }
535+ }
536+ const aliasshiftted = [ options . targets [ 0 ] . select [ 0 ] [ 0 ] . params [ 0 ] + shifted ] ;
537+ const oldSelect = this . queryModel . buildValueColumn (
538+ options . targets [ 0 ] . select [ 0 ]
539+ ) ;
540+ const newSelect = this . queryModel . buildValueColumn ( [
541+ options . targets [ 0 ] . select [ 0 ] [ 0 ] ,
542+ options . targets [ 0 ] . select [ 0 ] [ 1 ] ,
543+ { type : "alias" , params : [ aliasshiftted ] }
544+ ] ) ;
545+ q = q . replace ( oldSelect , newSelect ) ;
546+ return q ;
547+ }
408548}
0 commit comments