Skip to content

Commit 8df31d8

Browse files
pieternnfx
authored andcommitted
Make query schedules work
1 parent b35eedb commit 8df31d8

File tree

3 files changed

+341
-6
lines changed

3 files changed

+341
-6
lines changed

sqlanalytics/api/query.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,29 @@ type Query struct {
1111
Name string `json:"name"`
1212
Description string `json:"description"`
1313
Query string `json:"query"`
14-
Schedule *QuerySchedule `json:"schedule,omitempty"`
14+
Schedule *QuerySchedule `json:"schedule"`
1515
Options *QueryOptions `json:"options,omitempty"`
1616
Tags []string `json:"tags,omitempty"`
1717
Visualizations []json.RawMessage `json:"visualizations,omitempty"`
1818
}
1919

2020
// QuerySchedule ...
2121
type QuerySchedule struct {
22+
// Interval in seconds.
23+
//
24+
// For daily schedules, this MUST be a multiple of 86400.
25+
// For weekly schedules, this MUST be a multiple of 604800.
26+
//
2227
Interval int `json:"interval"`
28+
29+
// Time of day, for daily and weekly schedules.
30+
Time *string `json:"time"`
31+
32+
// Day of week, for weekly schedules.
33+
DayOfWeek *string `json:"day_of_week"`
34+
35+
// Schedule should be active until this date.
36+
Until *string `json:"until"`
2337
}
2438

2539
// QueryOptions ...

sqlanalytics/resource_query.go

Lines changed: 104 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package sqlanalytics
33
import (
44
"context"
55
"encoding/json"
6+
"fmt"
67
"log"
78
"reflect"
89
"strings"
@@ -25,7 +26,30 @@ type QueryEntity struct {
2526

2627
// QuerySchedule ...
2728
type 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+
118145
func (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

Comments
 (0)