Selaa lähdekoodia

Refactor campaigns query into two: 'query' and 'get'

Kailash Nadh 6 vuotta sitten
vanhempi
commit
93c952082c
5 muutettua tiedostoa jossa 39 lisäystä ja 14 poistoa
  1. 12 8
      campaigns.go
  2. 1 1
      manager_db.go
  3. 1 1
      models/models.go
  4. 2 1
      queries.go
  5. 23 3
      queries.sql

+ 12 - 8
campaigns.go

@@ -21,8 +21,12 @@ import (
 // campaignReq is a wrapper over the Campaign model.
 type campaignReq struct {
 	models.Campaign
-	MessengerID string        `json:"messenger"`
-	Lists       pq.Int64Array `json:"lists"`
+
+	// This overrides Campaign.Lists to receive and
+	// write a list of int IDs during creation and updation.
+	// Campaign.Lists is JSONText for sending lists children
+	// to the outside world.
+	ListIDs pq.Int64Array `db:"-" json:"lists"`
 
 	// This is only relevant to campaign test requests.
 	SubscriberEmails pq.StringArray `json:"subscribers"`
@@ -74,7 +78,7 @@ func handleGetCampaigns(c echo.Context) error {
 		query = string(regexFullTextQuery.ReplaceAll([]byte(query), []byte("&")))
 	}
 
-	err := app.Queries.GetCampaigns.Select(&out.Results, id, pq.StringArray(status), query, pg.Offset, pg.Limit)
+	err := app.Queries.QueryCampaigns.Select(&out.Results, id, pq.StringArray(status), query, pg.Offset, pg.Limit)
 	if err != nil {
 		return echo.NewHTTPError(http.StatusInternalServerError,
 			fmt.Sprintf("Error fetching campaigns: %s", pqErrMsg(err)))
@@ -199,7 +203,7 @@ func handleCreateCampaign(c echo.Context) error {
 		pq.StringArray(normalizeTags(o.Tags)),
 		"email",
 		o.TemplateID,
-		o.Lists,
+		o.ListIDs,
 	); err != nil {
 		if err == sql.ErrNoRows {
 			return echo.NewHTTPError(http.StatusBadRequest,
@@ -230,7 +234,7 @@ func handleUpdateCampaign(c echo.Context) error {
 	}
 
 	var cm models.Campaign
-	if err := app.Queries.GetCampaigns.Get(&cm, id, "", 0, 1); err != nil {
+	if err := app.Queries.GetCampaign.Get(&cm, id); err != nil {
 		if err == sql.ErrNoRows {
 			return echo.NewHTTPError(http.StatusBadRequest, "Campaign not found.")
 		}
@@ -263,7 +267,7 @@ func handleUpdateCampaign(c echo.Context) error {
 		o.SendAt,
 		pq.StringArray(normalizeTags(o.Tags)),
 		o.TemplateID,
-		o.Lists)
+		o.ListIDs)
 	if err != nil {
 		return echo.NewHTTPError(http.StatusInternalServerError,
 			fmt.Sprintf("Error updating campaign: %s", pqErrMsg(err)))
@@ -288,7 +292,7 @@ func handleUpdateCampaignStatus(c echo.Context) error {
 	}
 
 	var cm models.Campaign
-	if err := app.Queries.GetCampaigns.Get(&cm, id, "", 0, 1); err != nil {
+	if err := app.Queries.GetCampaign.Get(&cm, id); err != nil {
 		if err == sql.ErrNoRows {
 			return echo.NewHTTPError(http.StatusBadRequest, "Campaign not found.")
 		}
@@ -361,7 +365,7 @@ func handleDeleteCampaign(c echo.Context) error {
 	}
 
 	var cm models.Campaign
-	if err := app.Queries.GetCampaigns.Get(&cm, id, "", 0, 1); err != nil {
+	if err := app.Queries.GetCampaign.Get(&cm, id); err != nil {
 		if err == sql.ErrNoRows {
 			return echo.NewHTTPError(http.StatusBadRequest, "Campaign not found.")
 		}

+ 1 - 1
manager_db.go

@@ -38,7 +38,7 @@ func (r *runnerDB) NextSubscribers(campID, limit int) ([]*models.Subscriber, err
 // GetCampaign fetches a campaign from the database.
 func (r *runnerDB) GetCampaign(campID int) (*models.Campaign, error) {
 	var out = &models.Campaign{}
-	err := r.queries.GetCampaigns.Get(out, campID, "", 0, 1)
+	err := r.queries.GetCampaign.Get(out, campID)
 	return out, err
 }
 

+ 1 - 1
models/models.go

@@ -134,7 +134,7 @@ type Campaign struct {
 	Tags        pq.StringArray `db:"tags" json:"tags"`
 	TemplateID  int            `db:"template_id" json:"template_id"`
 	MessengerID string         `db:"messenger" json:"messenger"`
-	Lists       types.JSONText `json:"lists"`
+	Lists       types.JSONText `db:"lists" json:"lists"`
 
 	View   int `db:"views" json:"views"`
 	Clicks int `db:"clicks" json:"clicks"`

+ 2 - 1
queries.go

@@ -42,7 +42,8 @@ type Queries struct {
 	DeleteLists *sqlx.Stmt `query:"delete-lists"`
 
 	CreateCampaign           *sqlx.Stmt `query:"create-campaign"`
-	GetCampaigns             *sqlx.Stmt `query:"get-campaigns"`
+	QueryCampaigns           *sqlx.Stmt `query:"query-campaigns"`
+	GetCampaign              *sqlx.Stmt `query:"get-campaign"`
 	GetCampaignForPreview    *sqlx.Stmt `query:"get-campaign-for-preview"`
 	GetCampaignStats         *sqlx.Stmt `query:"get-campaign-stats"`
 	NextCampaigns            *sqlx.Stmt `query:"next-campaigns"`

+ 23 - 3
queries.sql

@@ -252,7 +252,7 @@ INSERT INTO campaign_lists (campaign_id, list_id, list_name)
     (SELECT (SELECT id FROM camp), id, name FROM lists WHERE id=ANY($11::INT[]))
     RETURNING (SELECT id FROM camp);
 
--- name: get-campaigns
+-- name: query-campaigns
 -- Here, 'lists' is returned as an aggregated JSON array from campaign_lists because
 -- the list reference may have been deleted.
 -- While the results are sliced using offset+limit,
@@ -290,6 +290,26 @@ LEFT JOIN views AS v ON (v.campaign_id = camps.id)
 LEFT JOIN clicks AS c ON (c.campaign_id = camps.id)
 ORDER BY camps.created_at DESC;
 
+-- name: get-campaign
+WITH camp AS (
+    SELECT * FROM campaigns WHERE id = $1
+), views AS (
+    SELECT campaign_id, COUNT(campaign_id) as num FROM campaign_views
+    WHERE campaign_id = ANY(SELECT id FROM camp)
+    GROUP BY campaign_id
+),
+clicks AS (
+    SELECT campaign_id, COUNT(campaign_id) as num FROM link_clicks
+    WHERE campaign_id = ANY(SELECT id FROM camp)
+    GROUP BY campaign_id
+)
+SELECT *,
+    COALESCE(v.num, 0) AS views,
+    COALESCE(c.num, 0) AS clicks
+FROM camp
+LEFT JOIN views AS v ON (v.campaign_id = camp.id)
+LEFT JOIN clicks AS c ON (c.campaign_id = camp.id);
+
 -- name: get-campaign-for-preview
 SELECT campaigns.*, COALESCE(templates.body, (SELECT body FROM templates WHERE is_default = true LIMIT 1)) AS template_body,
 (
@@ -394,9 +414,9 @@ WITH camp AS (
         updated_at=NOW()
     WHERE id = $1 RETURNING id
 ),
-    -- Reset the relationships
 d AS (
-    DELETE FROM campaign_lists WHERE campaign_id = $1
+    -- Reset list relationships
+    DELETE FROM campaign_lists WHERE campaign_id = $1 AND NOT(list_id = ANY($10))
 )
 INSERT INTO campaign_lists (campaign_id, list_id, list_name)
     (SELECT $1 as campaign_id, id, name FROM lists WHERE id=ANY($10::INT[]))