inbox.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package postgres
  2. import (
  3. "context"
  4. "strings"
  5. "github.com/pkg/errors"
  6. "google.golang.org/protobuf/encoding/protojson"
  7. storepb "github.com/usememos/memos/proto/gen/store"
  8. "github.com/usememos/memos/store"
  9. )
  10. func (d *DB) CreateInbox(ctx context.Context, create *store.Inbox) (*store.Inbox, error) {
  11. messageString := "{}"
  12. if create.Message != nil {
  13. bytes, err := protojson.Marshal(create.Message)
  14. if err != nil {
  15. return nil, errors.Wrap(err, "failed to marshal inbox message")
  16. }
  17. messageString = string(bytes)
  18. }
  19. fields := []string{"sender_id", "receiver_id", "status", "message"}
  20. args := []any{create.SenderID, create.ReceiverID, create.Status, messageString}
  21. stmt := "INSERT INTO inbox (" + strings.Join(fields, ", ") + ") VALUES (" + placeholders(len(args)) + ") RETURNING id, created_ts"
  22. if err := d.db.QueryRowContext(ctx, stmt, args...).Scan(
  23. &create.ID,
  24. &create.CreatedTs,
  25. ); err != nil {
  26. return nil, err
  27. }
  28. return create, nil
  29. }
  30. func (d *DB) ListInboxes(ctx context.Context, find *store.FindInbox) ([]*store.Inbox, error) {
  31. where, args := []string{"1 = 1"}, []any{}
  32. if find.ID != nil {
  33. where, args = append(where, "id = "+placeholder(len(args)+1)), append(args, *find.ID)
  34. }
  35. if find.SenderID != nil {
  36. where, args = append(where, "sender_id = "+placeholder(len(args)+1)), append(args, *find.SenderID)
  37. }
  38. if find.ReceiverID != nil {
  39. where, args = append(where, "receiver_id = "+placeholder(len(args)+1)), append(args, *find.ReceiverID)
  40. }
  41. if find.Status != nil {
  42. where, args = append(where, "status = "+placeholder(len(args)+1)), append(args, *find.Status)
  43. }
  44. query := "SELECT id, created_ts, sender_id, receiver_id, status, message FROM inbox WHERE " + strings.Join(where, " AND ") + " ORDER BY created_ts DESC"
  45. rows, err := d.db.QueryContext(ctx, query, args...)
  46. if err != nil {
  47. return nil, err
  48. }
  49. defer rows.Close()
  50. list := []*store.Inbox{}
  51. for rows.Next() {
  52. inbox := &store.Inbox{}
  53. var messageBytes []byte
  54. if err := rows.Scan(
  55. &inbox.ID,
  56. &inbox.CreatedTs,
  57. &inbox.SenderID,
  58. &inbox.ReceiverID,
  59. &inbox.Status,
  60. &messageBytes,
  61. ); err != nil {
  62. return nil, err
  63. }
  64. message := &storepb.InboxMessage{}
  65. if err := protojsonUnmarshaler.Unmarshal(messageBytes, message); err != nil {
  66. return nil, err
  67. }
  68. inbox.Message = message
  69. list = append(list, inbox)
  70. }
  71. if err := rows.Err(); err != nil {
  72. return nil, err
  73. }
  74. return list, nil
  75. }
  76. func (d *DB) GetInbox(ctx context.Context, find *store.FindInbox) (*store.Inbox, error) {
  77. list, err := d.ListInboxes(ctx, find)
  78. if err != nil {
  79. return nil, errors.Wrap(err, "failed to get inbox")
  80. }
  81. if len(list) != 1 {
  82. return nil, errors.Wrapf(nil, "unexpected inbox count: %d", len(list))
  83. }
  84. return list[0], nil
  85. }
  86. func (d *DB) UpdateInbox(ctx context.Context, update *store.UpdateInbox) (*store.Inbox, error) {
  87. set, args := []string{"status = $1"}, []any{update.Status.String()}
  88. args = append(args, update.ID)
  89. query := "UPDATE inbox SET " + strings.Join(set, ", ") + " WHERE id = $2 RETURNING id, created_ts, sender_id, receiver_id, status, message"
  90. inbox := &store.Inbox{}
  91. var messageBytes []byte
  92. if err := d.db.QueryRowContext(ctx, query, args...).Scan(
  93. &inbox.ID,
  94. &inbox.CreatedTs,
  95. &inbox.SenderID,
  96. &inbox.ReceiverID,
  97. &inbox.Status,
  98. &messageBytes,
  99. ); err != nil {
  100. return nil, err
  101. }
  102. message := &storepb.InboxMessage{}
  103. if err := protojsonUnmarshaler.Unmarshal(messageBytes, message); err != nil {
  104. return nil, err
  105. }
  106. inbox.Message = message
  107. return inbox, nil
  108. }
  109. func (d *DB) DeleteInbox(ctx context.Context, delete *store.DeleteInbox) error {
  110. result, err := d.db.ExecContext(ctx, "DELETE FROM inbox WHERE id = $1", delete.ID)
  111. if err != nil {
  112. return err
  113. }
  114. if _, err := result.RowsAffected(); err != nil {
  115. return err
  116. }
  117. return nil
  118. }