user.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package postgres
  2. import (
  3. "context"
  4. "fmt"
  5. "slices"
  6. "strings"
  7. "github.com/usememos/memos/store"
  8. )
  9. func (d *DB) CreateUser(ctx context.Context, create *store.User) (*store.User, error) {
  10. fields := []string{"username", "role", "email", "nickname", "password_hash", "avatar_url"}
  11. args := []any{create.Username, create.Role, create.Email, create.Nickname, create.PasswordHash, create.AvatarURL}
  12. stmt := "INSERT INTO \"user\" (" + strings.Join(fields, ", ") + ") VALUES (" + placeholders(len(args)) + ") RETURNING id, avatar_url, description, created_ts, updated_ts, row_status"
  13. if err := d.db.QueryRowContext(ctx, stmt, args...).Scan(
  14. &create.ID,
  15. &create.AvatarURL,
  16. &create.Description,
  17. &create.CreatedTs,
  18. &create.UpdatedTs,
  19. &create.RowStatus,
  20. ); err != nil {
  21. return nil, err
  22. }
  23. return create, nil
  24. }
  25. func (d *DB) UpdateUser(ctx context.Context, update *store.UpdateUser) (*store.User, error) {
  26. set, args := []string{}, []any{}
  27. if v := update.UpdatedTs; v != nil {
  28. set, args = append(set, "updated_ts = "+placeholder(len(args)+1)), append(args, *v)
  29. }
  30. if v := update.RowStatus; v != nil {
  31. set, args = append(set, "row_status = "+placeholder(len(args)+1)), append(args, *v)
  32. }
  33. if v := update.Username; v != nil {
  34. set, args = append(set, "username = "+placeholder(len(args)+1)), append(args, *v)
  35. }
  36. if v := update.Email; v != nil {
  37. set, args = append(set, "email = "+placeholder(len(args)+1)), append(args, *v)
  38. }
  39. if v := update.Nickname; v != nil {
  40. set, args = append(set, "nickname = "+placeholder(len(args)+1)), append(args, *v)
  41. }
  42. if v := update.AvatarURL; v != nil {
  43. set, args = append(set, "avatar_url = "+placeholder(len(args)+1)), append(args, *v)
  44. }
  45. if v := update.PasswordHash; v != nil {
  46. set, args = append(set, "password_hash = "+placeholder(len(args)+1)), append(args, *v)
  47. }
  48. if v := update.Description; v != nil {
  49. set, args = append(set, "description = "+placeholder(len(args)+1)), append(args, *v)
  50. }
  51. query := `
  52. UPDATE "user"
  53. SET ` + strings.Join(set, ", ") + `
  54. WHERE id = ` + placeholder(len(args)+1) + `
  55. RETURNING id, username, role, email, nickname, password_hash, avatar_url, description, created_ts, updated_ts, row_status
  56. `
  57. args = append(args, update.ID)
  58. user := &store.User{}
  59. if err := d.db.QueryRowContext(ctx, query, args...).Scan(
  60. &user.ID,
  61. &user.Username,
  62. &user.Role,
  63. &user.Email,
  64. &user.Nickname,
  65. &user.PasswordHash,
  66. &user.AvatarURL,
  67. &user.Description,
  68. &user.CreatedTs,
  69. &user.UpdatedTs,
  70. &user.RowStatus,
  71. ); err != nil {
  72. return nil, err
  73. }
  74. return user, nil
  75. }
  76. func (d *DB) ListUsers(ctx context.Context, find *store.FindUser) ([]*store.User, error) {
  77. where, args := []string{"1 = 1"}, []any{}
  78. if v := find.ID; v != nil {
  79. where, args = append(where, "id = "+placeholder(len(args)+1)), append(args, *v)
  80. }
  81. if v := find.Username; v != nil {
  82. where, args = append(where, "username = "+placeholder(len(args)+1)), append(args, *v)
  83. }
  84. if v := find.Role; v != nil {
  85. where, args = append(where, "role = "+placeholder(len(args)+1)), append(args, *v)
  86. }
  87. if v := find.Email; v != nil {
  88. where, args = append(where, "email = "+placeholder(len(args)+1)), append(args, *v)
  89. }
  90. if v := find.Nickname; v != nil {
  91. where, args = append(where, "nickname = "+placeholder(len(args)+1)), append(args, *v)
  92. }
  93. orderBy := []string{"created_ts DESC", "row_status DESC"}
  94. if find.Random {
  95. orderBy = slices.Concat([]string{"RANDOM()"}, orderBy)
  96. }
  97. query := `
  98. SELECT
  99. id,
  100. username,
  101. role,
  102. email,
  103. nickname,
  104. password_hash,
  105. avatar_url,
  106. description,
  107. created_ts,
  108. updated_ts,
  109. row_status
  110. FROM "user"
  111. WHERE ` + strings.Join(where, " AND ") + ` ORDER BY ` + strings.Join(orderBy, ", ")
  112. if v := find.Limit; v != nil {
  113. query += fmt.Sprintf(" LIMIT %d", *v)
  114. }
  115. rows, err := d.db.QueryContext(ctx, query, args...)
  116. if err != nil {
  117. return nil, err
  118. }
  119. defer rows.Close()
  120. list := make([]*store.User, 0)
  121. for rows.Next() {
  122. var user store.User
  123. if err := rows.Scan(
  124. &user.ID,
  125. &user.Username,
  126. &user.Role,
  127. &user.Email,
  128. &user.Nickname,
  129. &user.PasswordHash,
  130. &user.AvatarURL,
  131. &user.Description,
  132. &user.CreatedTs,
  133. &user.UpdatedTs,
  134. &user.RowStatus,
  135. ); err != nil {
  136. return nil, err
  137. }
  138. list = append(list, &user)
  139. }
  140. if err := rows.Err(); err != nil {
  141. return nil, err
  142. }
  143. return list, nil
  144. }
  145. func (d *DB) DeleteUser(ctx context.Context, delete *store.DeleteUser) error {
  146. result, err := d.db.ExecContext(ctx, `DELETE FROM "user" WHERE id = $1`, delete.ID)
  147. if err != nil {
  148. return err
  149. }
  150. if _, err := result.RowsAffected(); err != nil {
  151. return err
  152. }
  153. return nil
  154. }