@@ -3,6 +3,7 @@ package sqlanalytics
33import (
44 "context"
55 "encoding/json"
6+ "fmt"
67 "log"
78 "reflect"
89 "strings"
@@ -25,7 +26,30 @@ type QueryEntity struct {
2526
2627// QuerySchedule ...
2728type QuerySchedule struct {
28- Interval int `json:"interval"`
29+ Continuous * QueryScheduleContinuous `json:"continuous,omitempty"`
30+ Daily * QueryScheduleDaily `json:"daily,omitempty"`
31+ Weekly * QueryScheduleWeekly `json:"weekly,omitempty"`
32+ }
33+
34+ // QueryScheduleContinuous ...
35+ type QueryScheduleContinuous struct {
36+ IntervalSeconds int `json:"interval_seconds"`
37+ UntilDate string `json:"until_date,omitempty"`
38+ }
39+
40+ // QueryScheduleDaily ...
41+ type QueryScheduleDaily struct {
42+ IntervalDays int `json:"interval_days"`
43+ TimeOfDay string `json:"time_of_day"`
44+ UntilDate string `json:"until_date,omitempty"`
45+ }
46+
47+ // QueryScheduleWeekly ...
48+ type QueryScheduleWeekly struct {
49+ IntervalWeeks int `json:"interval_weeks"`
50+ DayOfWeek string `json:"day_of_week"`
51+ TimeOfDay string `json:"time_of_day"`
52+ UntilDate string `json:"until_date,omitempty"`
2953}
3054
3155// QueryParameter ...
@@ -115,6 +139,9 @@ func newQueryParameterAllowMultiple(aq *api.QueryParameterMultipleValuesOptions)
115139 }
116140}
117141
142+ const secondsInDay = 24 * 60 * 60
143+ const secondsInWeek = 7 * secondsInDay
144+
118145func (q * QueryEntity ) toAPIObject (schema map [string ]* schema.Schema , data * schema.ResourceData ) (* api.Query , error ) {
119146 // Extract from ResourceData.
120147 if err := common .DataToStructPointer (data , schema , q ); err != nil {
@@ -131,8 +158,32 @@ func (q *QueryEntity) toAPIObject(schema map[string]*schema.Schema, data *schema
131158 aq .Tags = append ([]string {}, q .Tags ... )
132159
133160 if s := q .Schedule ; s != nil {
134- aq .Schedule = & api.QuerySchedule {
135- Interval : s .Interval ,
161+ if sp := s .Continuous ; sp != nil {
162+ aq .Schedule = & api.QuerySchedule {
163+ Interval : sp .IntervalSeconds ,
164+ }
165+ if sp .UntilDate != "" {
166+ aq .Schedule .Until = & sp .UntilDate
167+ }
168+ }
169+ if sp := s .Daily ; sp != nil {
170+ aq .Schedule = & api.QuerySchedule {
171+ Interval : sp .IntervalDays * secondsInDay ,
172+ Time : & sp .TimeOfDay ,
173+ }
174+ if sp .UntilDate != "" {
175+ aq .Schedule .Until = & sp .UntilDate
176+ }
177+ }
178+ if sp := s .Weekly ; sp != nil {
179+ aq .Schedule = & api.QuerySchedule {
180+ Interval : sp .IntervalWeeks * secondsInWeek ,
181+ DayOfWeek : & sp .DayOfWeek ,
182+ Time : & sp .TimeOfDay ,
183+ }
184+ if sp .UntilDate != "" {
185+ aq .Schedule .Until = & sp .UntilDate
186+ }
136187 }
137188 }
138189
@@ -231,9 +282,44 @@ func (q *QueryEntity) fromAPIObject(aq *api.Query, schema map[string]*schema.Sch
231282 q .Tags = append ([]string {}, aq .Tags ... )
232283
233284 if s := aq .Schedule ; s != nil {
234- q .Schedule = & QuerySchedule {
235- Interval : s .Interval ,
285+ q .Schedule = & QuerySchedule {}
286+ if s .Interval % secondsInWeek == 0 {
287+ q .Schedule .Weekly = & QueryScheduleWeekly {
288+ IntervalWeeks : s .Interval / secondsInWeek ,
289+ }
290+ if s .DayOfWeek != nil {
291+ q .Schedule .Weekly .DayOfWeek = * s .DayOfWeek
292+ }
293+ if s .Time != nil {
294+ q .Schedule .Weekly .TimeOfDay = * s .Time
295+ }
296+ if s .Until != nil {
297+ q .Schedule .Weekly .UntilDate = * s .Until
298+ }
299+ } else if s .Interval % secondsInDay == 0 {
300+ q .Schedule .Daily = & QueryScheduleDaily {
301+ IntervalDays : s .Interval / secondsInDay ,
302+ }
303+ if s .Time != nil {
304+ q .Schedule .Daily .TimeOfDay = * s .Time
305+ }
306+ if s .Until != nil {
307+ q .Schedule .Daily .UntilDate = * s .Until
308+ }
309+ } else {
310+ q .Schedule .Continuous = & QueryScheduleContinuous {
311+ IntervalSeconds : s .Interval ,
312+ }
313+ if s .Until != nil {
314+ q .Schedule .Continuous .UntilDate = * s .Until
315+ }
236316 }
317+ } else {
318+ // Overwrite `schedule` in case it's not set on the server side.
319+ // This would have been skipped by `common.StructToData` because of slice emptiness.
320+ // Ideally, the reflection code also sets empty values, but we'd risk
321+ // clobbering values we actually want to keep around in existing code.
322+ data .Set ("schedule" , nil )
237323 }
238324
239325 if aq .Options != nil {
@@ -406,6 +492,19 @@ func ResourceQuery() *schema.Resource {
406492 s := common .StructToSchema (
407493 QueryEntity {},
408494 func (m map [string ]* schema.Schema ) map [string ]* schema.Schema {
495+ // Make different query schedule types mutually exclusive.
496+ {
497+ schedule := m ["schedule" ].Elem .(* schema.Resource )
498+ ns := []string {"continuous" , "daily" , "weekly" }
499+ for _ , n1 := range ns {
500+ for _ , n2 := range ns {
501+ if n1 == n2 {
502+ continue
503+ }
504+ schedule .Schema [n1 ].ConflictsWith = append (schedule .Schema [n1 ].ConflictsWith , fmt .Sprintf ("schedule.0.%s" , n2 ))
505+ }
506+ }
507+ }
409508 return m
410509 })
411510
0 commit comments