Skip to content

Commit

Permalink
while trying to apply our updateBackupData to the new checklist and c…
Browse files Browse the repository at this point in the history
…heckitem stuff we had to make some changes in it.

also, started tracking the board id on each backup row.
  • Loading branch information
fiatjaf committed Jul 15, 2018
1 parent fd30618 commit aba74f6
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 69 deletions.
122 changes: 94 additions & 28 deletions allowed.go
Expand Up @@ -5,56 +5,126 @@ import (
"time"

"github.com/jmoiron/sqlx/types"
"github.com/kr/pretty"
"github.com/lib/pq"
"github.com/rs/zerolog"
)

func onAllowed(logger zerolog.Logger, trello trelloClient, wh Webhook) {
b := wh.Action.Data.Board.Id

switch wh.Action.Type {
case "createCard", "copyCard", "convertToCardFromCheckItem", "moveCardToBoard":
err = saveBackupData(wh.Action.Data.Card.Id, wh.Action.Data.Card)
// if a card is moved from another tracked board to this board
// this will give time to the other webhook to delete everything from the backups
// table so we can recreate everything here.
time.Sleep(time.Second * 2)

saveBackupData(b, wh.Action.Data.Card.Id, wh.Action.Data.Card)
case "deleteCard", "moveCardFromBoard":
err = deleteBackupData(wh.Action.Data.Card.Id)
// delete card, checklists and checkitems
var card Card
fetchBackupData(wh.Action.Data.Card.Id, &card)
for _, idChecklist := range card.IdChecklists {
var checklist Checklist
fetchBackupData(idChecklist, &checklist)
for _, idCheckItem := range checklist.IdCheckItems {
deleteBackupData(b, idCheckItem)
}
}
deleteBackupData(b, wh.Action.Data.Card.Id)
case "updateCard":
var cardValues types.JSONText
cardValues, err = toJSONText(wh.Action.Data.Card)
if err != nil {
break
}

err = saveBackupData(wh.Action.Data.Card.Id, cardValues)
err = saveBackupData(b, wh.Action.Data.Card.Id, cardValues)
case "addMemberToCard":
err = updateBackupData(wh.Action.Data.Card.Id, wh.Action.Data.Card,
`'{"idMembers": []}' || $init || data`,
`jsonb_set(new.data, '{idMembers}', (new.data->'idMembers') || $arg)`,
err = updateBackupData(b, wh.Action.Data.Card.Id, wh.Action.Data.Card,
`'{"idMembers": []}'::jsonb || $init || data`,
`jsonb_set(data, '{idMembers}', (data->'idMembers') || $arg)`,
wh.Action.Data.IdMember,
)
case "removeMemberFromCard":
err = updateBackupData(wh.Action.Data.Card.Id, wh.Action.Data.Card,
`'{"idMembers": []}' || $init || data`,
`jsonb_set(new.data, '{idMembers}', (new.data->'idMembers') - ($arg::jsonb#>>'{}'))`,
err = updateBackupData(b, wh.Action.Data.Card.Id, wh.Action.Data.Card,
`'{"idMembers": []}'::jsonb || $init || data`,
`jsonb_set(data, '{idMembers}', (data->'idMembers') - ($arg::jsonb#>>'{}'))`,
wh.Action.Data.IdMember,
)
case "addLabelToCard":
saveBackupData(wh.Action.Data.Label.Id, wh.Action.Data.Label)
go saveBackupData(b, wh.Action.Data.Label.Id, wh.Action.Data.Label)

err = updateBackupData(wh.Action.Data.Card.Id, wh.Action.Data.Card,
`'{"idLabels": []}' || $init || data`,
`jsonb_set(new.data, '{idLabels}', (new.data->'idLabels') || $arg)`,
err = updateBackupData(b, wh.Action.Data.Card.Id, wh.Action.Data.Card,
`'{"idLabels": []}'::jsonb || $init || data`,
`jsonb_set(data, '{idLabels}', (data->'idLabels') || $arg)`,
wh.Action.Data.Label.Id,
)
case "removeLabelFromCard":
saveBackupData(wh.Action.Data.Label.Id, wh.Action.Data.Label)
go saveBackupData(b, wh.Action.Data.Label.Id, wh.Action.Data.Label)

err = updateBackupData(wh.Action.Data.Card.Id, wh.Action.Data.Card,
`'{"idLabels": []}' || $init || data`,
`jsonb_set(new.data, '{idLabels}', (new.data->'idLabels') - ($arg::jsonb#>>'{}'))`,
err = updateBackupData(b, wh.Action.Data.Card.Id, wh.Action.Data.Card,
`'{"idLabels": []}'::jsonb || $init || data`,
`jsonb_set(data, '{idLabels}', (data->'idLabels') - ($arg::jsonb#>>'{}'))`,
wh.Action.Data.Label.Id,
)
case "createLabel", "updateLabel":
saveBackupData(wh.Action.Data.Label.Id, wh.Action.Data.Label)
err = saveBackupData(b, wh.Action.Data.Label.Id, wh.Action.Data.Label)
case "deleteLabel":
err = deleteBackupData(wh.Action.Data.Label.Id)
err = deleteBackupData(b, wh.Action.Data.Label.Id)
case "addChecklistToCard":
// create checklist on database
go saveBackupData(b, wh.Action.Data.Checklist.Id, wh.Action.Data.Checklist)

// update card
err = updateBackupData(b, wh.Action.Data.Card.Id, wh.Action.Data.Card,
`'{"idChecklists": []}'::jsonb || $init || data`,
`jsonb_set(data, '{idChecklists}', (data->'idChecklists') || $arg)`,
wh.Action.Data.Checklist.Id,
)
case "updateChecklist":
err = saveBackupData(b, wh.Action.Data.Checklist.Id, wh.Action.Data.Checklist)
case "removeChecklistFromCard":
// delete checkitems and checklist
var checklist Checklist
fetchBackupData(wh.Action.Data.Checklist.Id, &checklist)
for _, idCheckItem := range checklist.IdCheckItems {
err = deleteBackupData(b, idCheckItem)
if err != nil {
pretty.Log(err)
}
}
deleteBackupData(b, wh.Action.Data.Checklist.Id)

// update card
err = updateBackupData(b, wh.Action.Data.Card.Id, wh.Action.Data.Card,
`'{"idChecklists": []}'::jsonb || $init || data`,
`jsonb_set(data, '{idChecklists}', (data->'idChecklists') - ($arg::jsonb#>>'{}'))`,
wh.Action.Data.Checklist.Id,
)
case "createCheckItem":
// create checkitem on database
go saveBackupData(b, wh.Action.Data.CheckItem.Id, wh.Action.Data.CheckItem)

// update checklist
err = updateBackupData(b, wh.Action.Data.Checklist.Id, wh.Action.Data.Checklist,
`'{"idCheckItems": []}'::jsonb || $init || data`,
`jsonb_set(data, '{idCheckItems}', (data->'idCheckItems') || $arg)`,
wh.Action.Data.CheckItem.Id,
)
case "updateCheckItem", "updateCheckItemStateOnCard":
err = saveBackupData(b, wh.Action.Data.CheckItem.Id, wh.Action.Data.CheckItem)
case "deleteCheckItem":
// delete checkitem
deleteBackupData(b, wh.Action.Data.CheckItem.Id)

// update checklist
err = updateBackupData(b, wh.Action.Data.Checklist.Id, wh.Action.Data.Checklist,
`'{"idCheckItems": []}'::jsonb || $init || data`,
`jsonb_set(data, '{idCheckItems}', (data->'idCheckItems') - ($arg::jsonb#>>'{}'))`,
wh.Action.Data.CheckItem.Id,
)
case "addAttachmentToCard":
primary := Attachment{
Name: wh.Action.Data.Attachment.Name,
Expand Down Expand Up @@ -82,26 +152,22 @@ func onAllowed(logger zerolog.Logger, trello trelloClient, wh Webhook) {
primary.Id = wh.Action.Data.Attachment.Id

// save the primary as a backup to the secondary
saveBackupData(secondary.Id, primary)
saveBackupData(b, secondary.Id, primary)

// and vice-versa
saveBackupData(primary.Id, secondary)
saveBackupData(b, primary.Id, secondary)
}
} else {
// just save the primary data as a backup to itself
saveBackupData(wh.Action.Data.Attachment.Id, primary)
saveBackupData(b, wh.Action.Data.Attachment.Id, primary)
}
case "deleteAttachmentFromCard":
err = deleteBackupData(wh.Action.Data.Attachment.Id)
err = deleteBackupData(b, wh.Action.Data.Attachment.Id)
}

if err != nil {
if perr, ok := err.(*pq.Error); ok {
log.Print(perr.Where)
log.Print(perr.Position)
log.Print(perr.Hint)
log.Print(perr.Column)
log.Print(perr.Message)
pretty.Log(perr)
}

logger.Warn().
Expand Down
50 changes: 28 additions & 22 deletions helpers.go
Expand Up @@ -110,22 +110,22 @@ func toJSONText(data interface{}) (v types.JSONText, err error) {
return
}

func saveBackupData(id string, data interface{}) (err error) {
func saveBackupData(boardId, id string, data interface{}) (err error) {
v, err := toJSONText(data)
if err != nil {
return
}

_, err = pg.Exec(`
INSERT INTO backups VALUES ($1, $2)
ON CONFLICT (id) DO UPDATE SET data = backups.data || $2
`, id, v)
INSERT INTO backups (id, board, data) VALUES ($1, $2, $3)
ON CONFLICT (id) DO UPDATE SET board = $2, data = backups.data || $3
`, id, boardId, v)
return
}

func updateBackupData(
id string, initData interface{},
preupdate, updatefun string, value interface{},
boardId, id string, initData interface{},
initialize, updatefun string, value interface{},
) (err error) {
d, err := toJSONText(initData)
if err != nil {
Expand All @@ -138,27 +138,33 @@ func updateBackupData(
}

updatefun = strings.Replace(
strings.Replace(updatefun, "$init", "$2", -1),
"$arg", "$3", -1)
strings.Replace(updatefun, "$init", "$3", -1),
"$arg", "$4", -1)

preupdate = strings.Replace(
strings.Replace(preupdate, "$init", "$2", -1),
"$arg", "$3", -1)
initialize = strings.Replace(
strings.Replace(initialize, "$init", "$3", -1),
"$arg", "$4", -1)

_, err = pg.Exec(`
WITH
ins AS (
INSERT INTO backups VALUES ($1, $2)
ON CONFLICT (id) DO NOTHING
init AS (
SELECT (`+initialize+`) AS data
FROM (
SELECT 0 AS idx, data FROM backups WHERE id = $1
UNION ALL
SELECT 1 AS idx, '{}'::jsonb AS data
) AS whatever
ORDER BY idx LIMIT 1
),
new AS (
SELECT (`+preupdate+`) AS data
FROM backups WHERE id = $1
SELECT (`+updatefun+`) AS data
FROM init
)
UPDATE backups SET data = `+updatefun+`
FROM new
WHERE id = $1
`, id, d, v)
INSERT INTO backups (id, board, data) VALUES ($1, $2, (SELECT data FROM new))
ON CONFLICT (id) DO UPDATE
SET data = (SELECT data FROM new),
board = $2
`, id, boardId, d, v)
return
}

Expand All @@ -176,7 +182,7 @@ func fetchBackupData(id string, data interface{}) (err error) {
return
}

func deleteBackupData(id string) (err error) {
_, err = pg.Exec(`DELETE FROM backups WHERE id = $1`, id)
func deleteBackupData(boardId, id string) (err error) {
_, err = pg.Exec(`DELETE FROM backups WHERE id = $1 AND board = $2`, id, boardId)
return
}
24 changes: 24 additions & 0 deletions postgres.sql
Expand Up @@ -8,10 +8,34 @@ CREATE TABLE boards (

CREATE TABLE backups (
id text PRIMARY KEY,
board text,
data jsonb NOT NULL,

CHECK (id != '')
);

table boards;
table backups;
delete from backups;

WITH
init AS (
SELECT ('{"id":"5b4a910f0aa8cfb949529fb9","name":"Checklist"}' || '{"idCheckItems": []}'::jsonb || data) AS data
FROM (
SELECT 0 AS idx, data FROM backups WHERE id = '5b4a910f0aa8cfb949529fb9'
UNION ALL
SELECT 1 AS idx, '{}'::jsonb
) AS whatever
ORDER BY idx LIMIT 1
),
new AS (
SELECT jsonb_set(
data,
'{idCheckItems}',
data->'idCheckItems' || '"5b4a9232a495da35ccca80ea"'
) AS data
FROM init
)
INSERT INTO backups (id, board, data) VALUES ('5b4a910f0aa8cfb949529fb9', '5b1980e92c9e71f5e06ad718', (SELECT data FROM new))
ON CONFLICT (id) DO UPDATE
SET data = (SELECT data FROM new);
12 changes: 7 additions & 5 deletions types.go
Expand Up @@ -33,6 +33,8 @@ type Label struct {
type Card struct {
Id string `json:"id,omitempty"`
ShortLink string `json:"shortLink,omitempty"`
IdBoard string `json:"idBoard,omitempty"`
IdList string `json:"idList,omitempty"`
Name string `json:"name,omitempty"`
Desc string `json:"desc,omitempty"`
Due string `json:"due,omitempty"`
Expand All @@ -41,17 +43,17 @@ type Card struct {
IdAttachmentCover string `json:"idAttachmentCover,omitempty"`
IdMembers []string `json:"idMembers,omitempty"`
IdLabels []string `json:"idLabels,omitempty"`
IdChecklists []string `json:"idChecklists,omitempty"`
Checklists []Checklist `json:"checklists,omitempty"`
Attachments []Attachment `json:"attachments,omitempty"`
IdBoard string `json:"idBoard,omitempty"`
IdList string `json:"idList,omitempty"`
CustomFieldItems []CustomFieldItem `json:"customFieldItems,omitempty"`
}

type Checklist struct {
Id string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
CheckItems []CheckItem `json:"checkItems,omitempty"`
Id string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
CheckItems []CheckItem `json:"checkItems,omitempty"`
IdCheckItems []string `json:"idCheckItems,omitempty"`
}

type CheckItem struct {
Expand Down

0 comments on commit aba74f6

Please sign in to comment.