diff --git a/handler/web/schedule.go b/handler/web/schedule.go index 8ff5274..7610d1b 100644 --- a/handler/web/schedule.go +++ b/handler/web/schedule.go @@ -156,7 +156,7 @@ func (h *ScheduleHandler) PaginationHandler(w http.ResponseWriter, r *http.Reque return nil } - schedules := schedule.Paginate(cUser.ID, (current-1)*row, row, search) + schedules := schedule.WithQuery(cUser.ID, (current-1)*row, row, search) tr := "" for _, v := range schedules { diff --git a/models/request.go b/models/request.go index 6015ab6..bdded5d 100644 --- a/models/request.go +++ b/models/request.go @@ -1,6 +1,7 @@ package models import ( + "encoding/json" "fmt" "strings" "time" @@ -13,7 +14,7 @@ type Request struct { UserID int `json:"user_id" validate:"number"` Url string `json:"url" validate:"required,url"` Method string `json:"method" validate:"required,oneof=GET POST PUT PATCH"` - Content string `json:"content" validate:"omitempty,json"` + Content json.RawMessage `json:"content" validate:"omitempty,json"` Active bool `json:"active" validate:"boolean"` User *User `json:"user,omitempty"` RequestHeaders []*RequestHeader `json:"request_headers,omitempty"` diff --git a/models/schedule.go b/models/schedule.go index 34e0a91..033ba35 100644 --- a/models/schedule.go +++ b/models/schedule.go @@ -1,6 +1,7 @@ package models import ( + "encoding/json" "fmt" "strings" "time" @@ -19,10 +20,11 @@ type Schedule struct { Retries int `json:"retries" validate:"number"` Running bool `json:"running" validate:"boolean"` Active bool `json:"active" validate:"boolean"` + User *User `json:"user,omitempty"` Group *Group `json:"group,omitempty"` Request *Request `json:"request,omitempty"` Notification *Notification `json:"notification,omitempty"` - Webhook *Webhook `json:"webhook,omitempty"` + Webhook []*Webhook `json:"webhook,omitempty"` CreatedAt *time.Time `json:"created_at,omitempty"` UpdatedAt *time.Time `json:"updated_at,omitempty"` DeletedAt *time.Time `json:"deleted_at,omitempty"` @@ -291,3 +293,69 @@ func (m *Schedule) Delete(id, userID int) error { return nil } + +func (m *Schedule) WithQuery(userID, offset, limit int, search string) []*Schedule { + schedules := []*Schedule{} + + // prepare schedules paginate + stmt, err := config.App().DB.Prepare(config.App().QUERY["SCHEDULE_MAPS"]) + if err != nil { + return schedules + } + + // query + rows, err := stmt.Query(userID, "%"+search+"%", offset, limit) + if err != nil { + return schedules + } + defer func() { + _ = stmt.Close() + _ = rows.Close() + }() + for rows.Next() { + schedule := &Schedule{} + var userJson string + var groupJson string + var requestJson string + var notificationJson string + var webhookJson string + + if err := rows.Scan(&schedule.ID, &schedule.UserID, &schedule.GroupID, &schedule.RequestID, &schedule.NotificationID, &schedule.Timing, &schedule.Timeout, &schedule.Retries, &schedule.Running, &schedule.Active, &schedule.CreatedAt, &schedule.UpdatedAt, &schedule.DeletedAt, &userJson, &groupJson, &requestJson, ¬ificationJson, &webhookJson); err != nil { + return schedules + } + + user := &User{} + if err := json.Unmarshal([]byte(userJson), &user); err != nil { + return schedules + } + schedule.User = user + + group := &Group{} + if err := json.Unmarshal([]byte(groupJson), &group); err != nil { + return schedules + } + schedule.Group = group + + request := &Request{} + if err := json.Unmarshal([]byte(requestJson), &request); err != nil { + return schedules + } + schedule.Request = request + + notification := &Notification{} + if err := json.Unmarshal([]byte(notificationJson), ¬ification); err != nil { + return schedules + } + schedule.Notification = notification + + webhooks := []*Webhook{} + if err := json.Unmarshal([]byte(webhookJson), &webhooks); err != nil { + return schedules + } + schedule.Webhook = webhooks + + schedules = append(schedules, schedule) + } + + return schedules +} diff --git a/query.sql b/query.sql index 8683458..a34dbaa 100644 --- a/query.sql +++ b/query.sql @@ -300,4 +300,125 @@ WHERE nm.id=$1 AND n.user_id=$2 AND nm.deleted_at isnull AND n.deleted_at isnull -- NOTIFICATION_MESSAGE_DELETE UPDATE notify_messages SET deleted_at=$1, updated_at=$2 FROM notifications -WHERE notifications.id=notify_messages.notification_id AND notify_messages.id=$3 AND notifications.user_id=$4; \ No newline at end of file +WHERE notifications.id=notify_messages.notification_id AND notify_messages.id=$3 AND notifications.user_id=$4; + + +-- SCHEDULE_MAPS +WITH schedule_lists AS ( + SELECT + s.*, + json_build_object( + 'id', u.id, + 'fullname', u.fullname, + 'email', u.email, + 'phone', u.phone + ) as user, + json_build_object( + 'id', g.id, + 'uid', g.uid, + 'name', g.name, + 'active', g.active, + 'parent', ( + SELECT json_build_object( + 'id', p.id, + 'name', p.name + ) + FROM groups p + WHERE p.id = g.uid + ) + ) as group, + json_build_object( + 'id', r.id, + 'user_id', r.user_id, + 'url', r.url, + 'method', r.method, + 'content', r.content, + 'active', r.active, + 'headers', ( + SELECT json_agg( + json_build_object( + 'id', rh.id, + 'key', rh.key, + 'value', rh.value, + 'active', rh.active + ) + ) + FROM request_headers rh + WHERE rh.request_id = r.id + ) + ) as request, + json_build_object( + 'id', n.id, + 'user_id', n.user_id, + 'title', n.title, + 'content', n.content, + 'is_mail', n.is_mail, + 'is_message', n.is_mail, + 'active', n.active, + 'emails', ( + SELECT json_agg( + json_build_object( + 'id', ne.id, + 'email', ne.email, + 'active', ne.active + ) + ) + FROM notify_emails ne + WHERE ne.notification_id = n.id + ), + 'messages', ( + SELECT json_agg( + json_build_object( + 'id', nm.id, + 'phone', nm.phone, + 'active', nm.active + ) + ) + FROM notify_messages nm + WHERE nm.notification_id = n.id + ) + ) as notification, + json_agg( + json_build_object( + 'id', w.id, + 'schedule_id', w.schedule_id, + 'request_id', w.request_id, + 'active', w.active, + 'requests', ( + SELECT json_agg( + json_build_object( + 'id', r.id, + 'url', r.url, + 'content', r.content, + 'active', r.active, + 'headers', ( + SELECT json_agg( + json_build_object( + 'id', rh.id, + 'key', rh.key, + 'value', rh.value, + 'active', rh.active + ) + ) + FROM request_headers rh + WHERE rh.request_id = r.id + ) + ) + ) + FROM requests r + WHERE r.id = w.request_id + ) + ) + ) as webhooks + FROM schedules as s + JOIN users AS u ON u.id = s.user_id + JOIN groups AS g ON g.id = s.group_id + JOIN requests AS r ON r.id = s.request_id + JOIN notifications n on n.id=s.notification_id + LEFT JOIN webhooks w on w.schedule_id=s.id + GROUP BY s.id, u.id, g.id, r.id, n.id +) +SELECT * FROM schedule_lists +WHERE user_id=$1 AND deleted_at isnull +AND (timing ilike $2 OR "group"->>'name' ilike $2 OR request->>'url' ilike $2 OR notification->>'title' ilike $2) +ORDER BY id DESC offset $3 LIMIT $4; \ No newline at end of file diff --git a/services/request.go b/services/request.go index a727284..e25e779 100644 --- a/services/request.go +++ b/services/request.go @@ -1,6 +1,7 @@ package services import ( + "encoding/json" "fmt" "net/http" "strconv" @@ -176,7 +177,7 @@ func (s *RequestService) RequestBulkService(w http.ResponseWriter, r *http.Reque UserID: cUser.ID, Url: bulk.Url, Method: bulk.Method, - Content: bulk.Content, + Content: json.RawMessage(bulk.Content), Active: bulk.Active, } diff --git a/services/schedule.go b/services/schedule.go index bfee963..2e19ca3 100644 --- a/services/schedule.go +++ b/services/schedule.go @@ -1,6 +1,7 @@ package services import ( + "encoding/json" "fmt" "net/http" "strconv" @@ -360,7 +361,7 @@ func (s *ScheduleService) BulkService(w http.ResponseWriter, r *http.Request) (i request.Url = bulk.Request.Url request.Method = bulk.Request.Method - request.Content = bulk.Request.Content + request.Content = json.RawMessage(bulk.Request.Content) request.Active = bulk.Request.Active exists, err := request.UrlExists()