memo_organizer.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package store
  2. import (
  3. "context"
  4. "database/sql"
  5. "fmt"
  6. "strings"
  7. )
  8. type MemoOrganizer struct {
  9. MemoID int
  10. UserID int
  11. Pinned bool
  12. }
  13. type FindMemoOrganizer struct {
  14. MemoID int
  15. UserID int
  16. }
  17. type DeleteMemoOrganizer struct {
  18. MemoID *int
  19. UserID *int
  20. }
  21. func (s *Store) UpsertMemoOrganizer(ctx context.Context, upsert *MemoOrganizer) (*MemoOrganizer, error) {
  22. tx, err := s.db.BeginTx(ctx, nil)
  23. if err != nil {
  24. return nil, err
  25. }
  26. defer tx.Rollback()
  27. query := `
  28. INSERT INTO memo_organizer (
  29. memo_id,
  30. user_id,
  31. pinned
  32. )
  33. VALUES (?, ?, ?)
  34. ON CONFLICT(memo_id, user_id) DO UPDATE
  35. SET
  36. pinned = EXCLUDED.pinned
  37. `
  38. if _, err := tx.ExecContext(ctx, query, upsert.MemoID, upsert.UserID, upsert.Pinned); err != nil {
  39. return nil, err
  40. }
  41. if err := tx.Commit(); err != nil {
  42. return nil, err
  43. }
  44. memoOrganizer := upsert
  45. return memoOrganizer, nil
  46. }
  47. func (s *Store) GetMemoOrganizer(ctx context.Context, find *FindMemoOrganizer) (*MemoOrganizer, error) {
  48. tx, err := s.db.BeginTx(ctx, nil)
  49. if err != nil {
  50. return nil, err
  51. }
  52. defer tx.Rollback()
  53. where, args := []string{}, []any{}
  54. if find.MemoID != 0 {
  55. where = append(where, "memo_id = ?")
  56. args = append(args, find.MemoID)
  57. }
  58. if find.UserID != 0 {
  59. where = append(where, "user_id = ?")
  60. args = append(args, find.UserID)
  61. }
  62. query := fmt.Sprintf(`
  63. SELECT
  64. memo_id,
  65. user_id,
  66. pinned
  67. FROM memo_organizer
  68. WHERE %s
  69. `, strings.Join(where, " AND "))
  70. row := tx.QueryRowContext(ctx, query, args...)
  71. if err := row.Err(); err != nil {
  72. return nil, err
  73. }
  74. if row == nil {
  75. return nil, nil
  76. }
  77. memoOrganizer := &MemoOrganizer{}
  78. if err := row.Scan(
  79. &memoOrganizer.MemoID,
  80. &memoOrganizer.UserID,
  81. &memoOrganizer.Pinned,
  82. ); err != nil {
  83. return nil, err
  84. }
  85. if err := tx.Commit(); err != nil {
  86. return nil, err
  87. }
  88. return memoOrganizer, nil
  89. }
  90. func (s *Store) DeleteMemoOrganizer(ctx context.Context, delete *DeleteMemoOrganizer) error {
  91. tx, err := s.db.BeginTx(ctx, nil)
  92. if err != nil {
  93. return err
  94. }
  95. defer tx.Rollback()
  96. where, args := []string{}, []any{}
  97. if v := delete.MemoID; v != nil {
  98. where, args = append(where, "memo_id = ?"), append(args, *v)
  99. }
  100. if v := delete.UserID; v != nil {
  101. where, args = append(where, "user_id = ?"), append(args, *v)
  102. }
  103. stmt := `DELETE FROM memo_organizer WHERE ` + strings.Join(where, " AND ")
  104. _, err = tx.ExecContext(ctx, stmt, args...)
  105. if err != nil {
  106. return err
  107. }
  108. if err := tx.Commit(); err != nil {
  109. // Prevent linter warning.
  110. return err
  111. }
  112. return nil
  113. }
  114. func vacuumMemoOrganizer(ctx context.Context, tx *sql.Tx) error {
  115. stmt := `
  116. DELETE FROM
  117. memo_organizer
  118. WHERE
  119. memo_id NOT IN (
  120. SELECT
  121. id
  122. FROM
  123. memo
  124. )
  125. OR user_id NOT IN (
  126. SELECT
  127. id
  128. FROM
  129. user
  130. )`
  131. _, err := tx.ExecContext(ctx, stmt)
  132. if err != nil {
  133. return err
  134. }
  135. return nil
  136. }