From 79150418e5985b15a955c30a49d3d2eb3dfce538 Mon Sep 17 00:00:00 2001 From: Kevin Lyda <kevin@lyda.ie> Date: Mon, 26 May 2025 18:09:55 +0100 Subject: [PATCH] Add docs to the storage functions Remove excess storage routines. Change sqlc configs which changes how params work. --- batch/batch.go | 6 +- folders/folders.go | 15 +- folders/messages.go | 57 +---- repl/accounts.go | 21 +- repl/command.go | 2 +- repl/messages.go | 49 +--- repl/set.go | 65 +---- repl/show.go | 12 +- storage/batch.sql.go | 11 + storage/broadcast.sql.go | 44 ++-- storage/folders.sql.go | 160 +++++-------- storage/messages.sql.go | 333 +++++++++++++------------- storage/queries/batch.sql | 5 + storage/queries/broadcast.sql | 8 +- storage/queries/folders.sql | 22 +- storage/queries/messages.sql | 49 ++-- storage/queries/seed.sql | 3 + storage/queries/standard.sql | 60 ++--- storage/queries/system.sql | 3 + storage/queries/users.sql | 21 ++ storage/seed.sql.go | 15 ++ storage/sqlc.yaml | 2 + storage/standard.sql.go | 433 +++++----------------------------- storage/system.sql.go | 9 + storage/users.sql.go | 110 +++++---- this/alert.go | 16 +- this/this.go | 16 +- 27 files changed, 571 insertions(+), 976 deletions(-) diff --git a/batch/batch.go b/batch/batch.go index e8b65b7..6de3eef 100644 --- a/batch/batch.go +++ b/batch/batch.go @@ -95,11 +95,7 @@ the first user.`) if err != nil { system.ExpireLimit = 365 } - err = q.SetSystem(ctx, storage.SetSystemParams{ - Name: system.Name, - DefaultExpire: system.DefaultExpire, - ExpireLimit: system.ExpireLimit, - }) + err = q.SetSystem(ctx, system.Name, system.DefaultExpire, system.ExpireLimit) ask.CheckErr(err) login, err := ask.GetLine("Enter login of initial user: ") diff --git a/folders/folders.go b/folders/folders.go index fef08be..1317b10 100644 --- a/folders/folders.go +++ b/folders/folders.go @@ -78,10 +78,7 @@ func IsFolderReadable(name, login string) bool { if admin == 1 { return true } - found, _ := this.Q.IsFolderReadable(ctx, storage.IsFolderReadableParams{ - Name: name, - Owner: login, - }) + found, _ := this.Q.IsFolderReadable(ctx, name, login) return found == 1 } @@ -92,10 +89,7 @@ func IsFolderWriteable(name, login string) bool { if admin == 1 { return true } - found, _ := this.Q.IsFolderWriteable(ctx, storage.IsFolderWriteableParams{ - Name: name, - Owner: login, - }) + found, _ := this.Q.IsFolderWriteable(ctx, name, login) return found == 1 } @@ -106,10 +100,7 @@ func IsFolderOwner(folder, login string) bool { if admin == 1 { return true } - found, _ := this.Q.IsFolderOwner(ctx, storage.IsFolderOwnerParams{ - Name: folder, - Owner: login, - }) + found, _ := this.Q.IsFolderOwner(ctx, folder, login) return found == 1 } diff --git a/folders/messages.go b/folders/messages.go index 07a6645..34d1a70 100644 --- a/folders/messages.go +++ b/folders/messages.go @@ -40,10 +40,7 @@ func CreateMessage(author, subject, message, folder string, permanent, shutdown // GetMessage reads a message for a user. func GetMessage(login, folder string, msgid int64) (*storage.Message, error) { ctx := storage.Context() - msg, err := this.Q.ReadMessage(ctx, storage.ReadMessageParams{ - Folder: folder, - ID: msgid, - }) + msg, err := this.Q.ReadMessage(ctx, folder, msgid) if err != nil { return nil, err } @@ -60,11 +57,7 @@ func MarkSeen(msgids []int64) error { ctx := storage.Context() for _, msgid := range msgids { - this.Q.SetMessageSeen(ctx, storage.SetMessageSeenParams{ - Login: this.User.Login, - Folder: this.Folder.Name, - Msgid: msgid, - }) + this.Q.SetMessageSeen(ctx, this.User.Login, this.Folder.Name, msgid) } return nil } @@ -74,11 +67,7 @@ func MarkUnseen(msgids []int64) error { ctx := storage.Context() for _, msgid := range msgids { - this.Q.UnsetMessageSeen(ctx, storage.UnsetMessageSeenParams{ - Login: this.User.Login, - Folder: this.Folder.Name, - Msgid: msgid, - }) + this.Q.UnsetMessageSeen(ctx, this.User.Login, this.Folder.Name, msgid) } return nil } @@ -86,11 +75,7 @@ func MarkUnseen(msgids []int64) error { // NextMsgid gets the next message id. func NextMsgid(login, folder string, msgid int64) int64 { ctx := storage.Context() - newid, err := this.Q.NextMsgid(ctx, storage.NextMsgidParams{ - Folder: folder, - Login: login, - ID: msgid, - }) + newid, err := this.Q.NextMsgid(ctx, folder, msgid, login) if err != nil { return 0 } @@ -100,11 +85,7 @@ func NextMsgid(login, folder string, msgid int64) int64 { // PrevMsgid gets the next message id. func PrevMsgid(login, folder string, msgid int64) int64 { ctx := storage.Context() - newid, err := this.Q.PrevMsgid(ctx, storage.PrevMsgidParams{ - Folder: folder, - Login: login, - ID: msgid, - }) + newid, err := this.Q.PrevMsgid(ctx, folder, msgid, login) if err != nil { return 0 } @@ -114,11 +95,7 @@ func PrevMsgid(login, folder string, msgid int64) int64 { // FirstMessage gets the first message in a folder. func FirstMessage(folder string) int64 { ctx := storage.Context() - first, err := this.Q.NextMsgidIgnoringSeen(ctx, - storage.NextMsgidIgnoringSeenParams{ - Folder: folder, - ID: 0, - }) + first, err := this.Q.NextMsgidIgnoringSeen(ctx, folder, 0) if err != nil { return 0 } @@ -147,10 +124,7 @@ func WroteAllMessages(login string, msgids []int64) bool { ctx := storage.Context() for _, msgid := range msgids { - msg, err := this.Q.GetMessage(ctx, storage.GetMessageParams{ - ID: msgid, - Folder: this.Folder.Name, - }) + msg, err := this.Q.GetMessage(ctx, msgid, this.Folder.Name) if err != nil { return false } @@ -166,10 +140,7 @@ func DeleteMessages(msgids []int64) error { ctx := storage.Context() for _, msgid := range msgids { - this.Q.DeleteMessage(ctx, storage.DeleteMessageParams{ - Folder: this.Folder.Name, - ID: msgid, - }) + this.Q.DeleteMessage(ctx, msgid, this.Folder.Name) } return nil } @@ -187,11 +158,7 @@ func SetMark(msgids []int64) error { ctx := storage.Context() for _, msgid := range msgids { - this.Q.AddMark(ctx, storage.AddMarkParams{ - Folder: this.Folder.Name, - Login: this.User.Login, - Msgid: msgid, - }) + this.Q.AddMark(ctx, this.Folder.Name, this.User.Login, msgid) } return nil } @@ -201,11 +168,7 @@ func UnsetMark(msgids []int64) error { ctx := storage.Context() for _, msgid := range msgids { - this.Q.DeleteMark(ctx, storage.DeleteMarkParams{ - Folder: this.Folder.Name, - Login: this.User.Login, - Msgid: msgid, - }) + this.Q.DeleteMark(ctx, this.Folder.Name, this.User.Login, msgid) } return nil } diff --git a/repl/accounts.go b/repl/accounts.go index 09f0b73..f6478d6 100644 --- a/repl/accounts.go +++ b/repl/accounts.go @@ -100,10 +100,7 @@ func actionUserEnable(cmd *dclish.Command, disabled int64, doing string) error { return nil } ctx := storage.Context() - err = this.Q.UpdateUserDisabled(ctx, storage.UpdateUserDisabledParams{ - Login: u.Login, - Disabled: disabled, - }) + err = this.Q.UpdateUserDisabled(ctx, disabled, u.Login) if err != nil { fmt.Printf("ERROR: Failed to %s user (%s).\n", doing, err) return nil @@ -137,10 +134,7 @@ func actionUserAdmin(cmd *dclish.Command, admin int64, doing string) error { return nil } ctx := storage.Context() - err = this.Q.UpdateUserAdmin(ctx, storage.UpdateUserAdminParams{ - Login: u.Login, - Admin: admin, - }) + err = this.Q.UpdateUserAdmin(ctx, admin, u.Login) if err != nil { fmt.Printf("ERROR: Failed to make user %s (%s).\n", doing, err) return nil @@ -174,10 +168,7 @@ func actionUserMod(cmd *dclish.Command, mod int64, doing string) error { return nil } ctx := storage.Context() - err = this.Q.UpdateUserMod(ctx, storage.UpdateUserModParams{ - Login: u.Login, - Moderator: mod, - }) + err = this.Q.UpdateUserMod(ctx, mod, u.Login) if err != nil { fmt.Printf("ERROR: Failed to make user %s (%s).\n", doing, err) return nil @@ -214,11 +205,7 @@ func ActionUserName(cmd *dclish.Command) error { } } ctx := storage.Context() - err := this.Q.UpdateUserName(ctx, - storage.UpdateUserNameParams{ - Login: login, - Name: name, - }) + err := this.Q.UpdateUserName(ctx, name, login) if err != nil { fmt.Printf("ERROR: Failed to update user name (%s).\n", err) } diff --git a/repl/command.go b/repl/command.go index 1508942..316875b 100644 --- a/repl/command.go +++ b/repl/command.go @@ -859,7 +859,7 @@ header. If a "search-string" is not specified, a search is made using the previously specified string, starting with the message following the one you are currently reading (or have just read). Once started, a search can be aborted by typing a CTRL-C.`, - MinArgs: 0, + MinArgs: 1, MaxArgs: 1, Action: ActionSearch, Flags: dclish.Flags{ diff --git a/repl/messages.go b/repl/messages.go index ee62116..7e2dc32 100644 --- a/repl/messages.go +++ b/repl/messages.go @@ -703,21 +703,16 @@ func ActionSearch(cmd *dclish.Command) error { optSubject = true } - var searchTerm string + subject := "" if optReply { - if optSubject || len(cmd.Args) == 1 { - return errors.New("Can't specify /REPLY and a search term or /SUBJECT") + if optSubject { + return errors.New("Can't specify /REPLY and /SUBJECT") } - msg, err := this.Q.ReadMessage(ctx, storage.ReadMessageParams{ - Folder: this.Folder.Name, - ID: this.MsgID, - }) + msg, err := this.Q.ReadMessage(ctx, this.Folder.Name, this.MsgID) if err != nil { return err } - searchTerm = "Re: " + msg.Subject - } else { - searchTerm = cmd.Args[0] + subject = "Re: " + msg.Subject } allMsgs := []storage.Message{} @@ -739,49 +734,31 @@ func ActionSearch(cmd *dclish.Command) error { if optReverse { msgs, err = this.Q.SearchReplyReverse(ctx, storage.SearchReplyReverseParams{ - Subject: searchTerm, + Column1: nullStr(cmd.Args[0]), + Subject: subject, ID: start, Folder: optFolders[i], }) } else { msgs, err = this.Q.SearchReply(ctx, storage.SearchReplyParams{ - Subject: searchTerm, + Column1: nullStr(cmd.Args[0]), + Subject: subject, ID: start, Folder: optFolders[i], }) } } else if optSubject { if optReverse { - msgs, err = this.Q.SearchSubjectReverse(ctx, - storage.SearchSubjectReverseParams{ - Column1: nullStr(searchTerm), - ID: start, - Folder: optFolders[i], - }) + msgs, err = this.Q.SearchSubjectReverse(ctx, nullStr(cmd.Args[0]), start, optFolders[i]) } else { - msgs, err = this.Q.SearchSubject(ctx, - storage.SearchSubjectParams{ - Column1: nullStr(searchTerm), - ID: start, - Folder: optFolders[i], - }) + msgs, err = this.Q.SearchSubject(ctx, nullStr(cmd.Args[0]), start, optFolders[i]) } } else { if optReverse { - msgs, err = this.Q.SearchReverse(ctx, - storage.SearchReverseParams{ - Column1: nullStr(searchTerm), - ID: start, - Folder: optFolders[i], - }) + msgs, err = this.Q.SearchReverse(ctx, nullStr(cmd.Args[0]), start, optFolders[i]) } else { - msgs, err = this.Q.Search(ctx, - storage.SearchParams{ - Column1: nullStr(searchTerm), - ID: start, - Folder: optFolders[i], - }) + msgs, err = this.Q.Search(ctx, nullStr(cmd.Args[0]), start, optFolders[i]) } } if err != nil { diff --git a/repl/set.go b/repl/set.go index 249452d..6a9d2a8 100644 --- a/repl/set.go +++ b/repl/set.go @@ -36,22 +36,12 @@ func setAlert(cmd *dclish.Command, alert int64) error { ctx := storage.Context() if optAll && optPerm { - return this.Q.UpdateFolderAlert(ctx, storage.UpdateFolderAlertParams{ - Alert: alert + 3, - Name: folder.Name, - }) + return this.Q.UpdateFolderAlert(ctx, alert+3, folder.Name) } if optAll { - return this.Q.UpdateFolderAlert(ctx, storage.UpdateFolderAlertParams{ - Alert: alert, - Name: folder.Name, - }) + return this.Q.UpdateFolderAlert(ctx, alert, folder.Name) } - return this.Q.UpdateUserAlert(ctx, storage.UpdateUserAlertParams{ - Login: this.User.Login, - Folder: folder.Name, - Alert: alert, - }) + return this.Q.UpdateUserAlert(ctx, this.User.Login, folder.Name, alert) } // ActionSet handles the `SET` command. @@ -74,11 +64,7 @@ func ActionSetNoaccess(cmd *dclish.Command) error { if this.User.Admin == 0 || folder.Owner != this.User.Login { return errors.New("Must be an admin or folder owner") } - this.Q.DeleteFolderAccess(ctx, - storage.DeleteFolderAccessParams{ - Login: login, - Folder: folder.Name, - }) + this.Q.DeleteFolderAccess(ctx, login, folder.Name) return nil } @@ -115,11 +101,7 @@ func ActionSetAccess(cmd *dclish.Command) error { if optRead { visibility = 1 } - this.Q.UpdateFolderVisibility(ctx, - storage.UpdateFolderVisibilityParams{ - Visibility: visibility, - Name: folder.Name, - }) + this.Q.UpdateFolderVisibility(ctx, visibility, folder.Name) return nil } if len(cmd.Args) == 0 { @@ -140,32 +122,21 @@ func ActionSetAccess(cmd *dclish.Command) error { if optRead { visibility = 1 } - this.Q.UpdateFolderAccess(ctx, - storage.UpdateFolderAccessParams{ - Login: login, - Folder: folder.Name, - Visibility: visibility, - }) + this.Q.UpdateFolderAccess(ctx, login, folder.Name, visibility) return nil } // ActionSetAlways handles the `SET ALWAYS` command. func ActionSetAlways(_ *dclish.Command) error { ctx := storage.Context() - this.Q.UpdateFolderAlways(ctx, storage.UpdateFolderAlwaysParams{ - Always: 1, - Name: this.Folder.Name, - }) + this.Q.UpdateFolderAlways(ctx, 1, this.Folder.Name) return nil } // ActionSetNoalways handles the `SET NOALWAYS` command. func ActionSetNoalways(_ *dclish.Command) error { ctx := storage.Context() - this.Q.UpdateFolderAlways(ctx, storage.UpdateFolderAlwaysParams{ - Always: 0, - Name: this.Folder.Name, - }) + this.Q.UpdateFolderAlways(ctx, 0, this.Folder.Name) return nil } @@ -208,20 +179,14 @@ func ActionSetExpireLimit(cmd *dclish.Command) error { // ActionSetPromptExpire handles the `SET PROMPT_EXPIRE` command. func ActionSetPromptExpire(_ *dclish.Command) error { ctx := storage.Context() - this.Q.UpdateUserPrompt(ctx, storage.UpdateUserPromptParams{ - Login: this.User.Login, - Prompt: 1, - }) + this.Q.UpdateUserPrompt(ctx, 1, this.User.Login) return nil } // ActionSetNoPromptExpire handles the `SET NOPROMPT_EXPIRE` command. func ActionSetNoPromptExpire(_ *dclish.Command) error { ctx := storage.Context() - this.Q.UpdateUserPrompt(ctx, storage.UpdateUserPromptParams{ - Login: this.User.Login, - Prompt: 0, - }) + this.Q.UpdateUserPrompt(ctx, 0, this.User.Login) return nil } @@ -251,10 +216,7 @@ func ActionSetSystem(_ *dclish.Command) error { return errors.New("You are not an admin") } ctx := storage.Context() - this.Q.UpdateFolderSystem(ctx, storage.UpdateFolderSystemParams{ - System: 1, - Name: this.Folder.Name, - }) + this.Q.UpdateFolderSystem(ctx, 1, this.Folder.Name) return nil } @@ -268,9 +230,6 @@ func ActionSetNosystem(_ *dclish.Command) error { return nil } ctx := storage.Context() - this.Q.UpdateFolderSystem(ctx, storage.UpdateFolderSystemParams{ - System: 1, - Name: this.Folder.Name, - }) + this.Q.UpdateFolderSystem(ctx, 1, this.Folder.Name) return nil } diff --git a/repl/show.go b/repl/show.go index e3852ee..639b504 100644 --- a/repl/show.go +++ b/repl/show.go @@ -161,11 +161,7 @@ func ActionShowUser(cmd *dclish.Command) error { // Actually do the thing. ctx := storage.Context() if cmd.Flags["/LOGIN"].Set && cmd.Flags["/FOLDER"].Set { - rows, err := this.Q.GetLastReadByEnabled(ctx, - storage.GetLastReadByEnabledParams{ - Folder: folder.Name, - Disabled: showLogin, - }) + rows, err := this.Q.GetLastReadByEnabled(ctx, folder.Name, showLogin) if err != nil { fmt.Printf("ERROR: Failed to get list (%s).\n", err) return nil @@ -185,11 +181,7 @@ func ActionShowUser(cmd *dclish.Command) error { fmt.Printf("%-12s %-25s % 4d\n", r.Author, folder.Name, r.ID) } } else if cmd.Flags["/FOLDER"].Set { - r, err := this.Q.GetLastReadByUser(ctx, - storage.GetLastReadByUserParams{ - Folder: folder.Name, - Author: login, - }) + r, err := this.Q.GetLastReadByUser(ctx, folder.Name, login) if err != nil { fmt.Printf("ERROR: Failed to get list (%s).\n", err) return nil diff --git a/storage/batch.sql.go b/storage/batch.sql.go index a8c8113..fe96c7d 100644 --- a/storage/batch.sql.go +++ b/storage/batch.sql.go @@ -14,6 +14,12 @@ DELETE FROM messages WHERE permanent != 1 AND expiration < CURRENT_TIMESTAMP ` +// DeleteAllExpiredMessages deletes all messages that are not permanent +// and have an expiration timestamp less than the `CURRENT_TIMESTAMP`. +// This works on all folders. +// +// DELETE FROM messages +// WHERE permanent != 1 AND expiration < CURRENT_TIMESTAMP func (q *Queries) DeleteAllExpiredMessages(ctx context.Context) (int64, error) { result, err := q.db.ExecContext(ctx, deleteAllExpiredMessages) if err != nil { @@ -27,6 +33,11 @@ DELETE FROM messages WHERE permanent != 1 AND shutdown > 0 ` +// DeleteAllShutdownMessages removes all shutdown that are not permanent. +// This works on all folders. +// +// DELETE FROM messages +// WHERE permanent != 1 AND shutdown > 0 func (q *Queries) DeleteAllShutdownMessages(ctx context.Context) (int64, error) { result, err := q.db.ExecContext(ctx, deleteAllShutdownMessages) if err != nil { diff --git a/storage/broadcast.sql.go b/storage/broadcast.sql.go index 9c61b1f..3fc9ba5 100644 --- a/storage/broadcast.sql.go +++ b/storage/broadcast.sql.go @@ -10,15 +10,6 @@ import ( "time" ) -const clearBroadcasts = `-- name: ClearBroadcasts :exec -DELETE FROM broadcast -` - -func (q *Queries) ClearBroadcasts(ctx context.Context) error { - _, err := q.db.ExecContext(ctx, clearBroadcasts) - return err -} - const createBroadcast = `-- name: CreateBroadcast :exec INSERT INTO broadcast (author, bell, message) @@ -26,14 +17,14 @@ INSERT INTO broadcast (?, ?, ?) ` -type CreateBroadcastParams struct { - Author string - Bell int64 - Message string -} - -func (q *Queries) CreateBroadcast(ctx context.Context, arg CreateBroadcastParams) error { - _, err := q.db.ExecContext(ctx, createBroadcast, arg.Author, arg.Bell, arg.Message) +// CreateBroadcast adds a new broadcast message. +// +// INSERT INTO broadcast +// (author, bell, message) +// VALUES +// (?, ?, ?) +func (q *Queries) CreateBroadcast(ctx context.Context, author string, bell int64, message string) error { + _, err := q.db.ExecContext(ctx, createBroadcast, author, bell, message) return err } @@ -41,6 +32,10 @@ const getBroadcasts = `-- name: GetBroadcasts :many SELECT author, bell, message, create_at FROM broadcast WHERE create_at > ? ORDER BY create_at ` +// GetBroadcasts gets new broadcast messages newer than a passed +// time.Time() value and returns them in create_at order. +// +// SELECT author, bell, message, create_at FROM broadcast WHERE create_at > ? ORDER BY create_at func (q *Queries) GetBroadcasts(ctx context.Context, createAt time.Time) ([]Broadcast, error) { rows, err := q.db.QueryContext(ctx, getBroadcasts, createAt) if err != nil { @@ -73,6 +68,9 @@ const reapBroadcasts = `-- name: ReapBroadcasts :exec DELETE FROM broadcast WHERE julianday(current_timestamp) - julianday(create_at) > 3 ` +// ReapBroadcasts deletes broadcast messages over 3 days old. +// +// DELETE FROM broadcast WHERE julianday(current_timestamp) - julianday(create_at) > 3 func (q *Queries) ReapBroadcasts(ctx context.Context) error { _, err := q.db.ExecContext(ctx, reapBroadcasts) return err @@ -82,12 +80,10 @@ const updateLastActivity = `-- name: UpdateLastActivity :exec UPDATE users SET last_activity = ? WHERE login = ? ` -type UpdateLastActivityParams struct { - LastActivity time.Time - Login string -} - -func (q *Queries) UpdateLastActivity(ctx context.Context, arg UpdateLastActivityParams) error { - _, err := q.db.ExecContext(ctx, updateLastActivity, arg.LastActivity, arg.Login) +// UpdateLastActivity updates the user's last_activity time. +// +// UPDATE users SET last_activity = ? WHERE login = ? +func (q *Queries) UpdateLastActivity(ctx context.Context, lastActivity time.Time, login string) error { + _, err := q.db.ExecContext(ctx, updateLastActivity, lastActivity, login) return err } diff --git a/storage/folders.sql.go b/storage/folders.sql.go index b479c9e..3970325 100644 --- a/storage/folders.sql.go +++ b/storage/folders.sql.go @@ -28,6 +28,12 @@ type CreateFolderParams struct { Visibility int64 } +// CreateFolder creates a new folder. +// +// INSERT INTO folders +// (name, always, alert, description, owner, system, expire, visibility) +// VALUES +// (?, ?, ?, ?, ?, ?, ?, ?) func (q *Queries) CreateFolder(ctx context.Context, arg CreateFolderParams) error { _, err := q.db.ExecContext(ctx, createFolder, arg.Name, @@ -46,6 +52,9 @@ const findFolderExact = `-- name: FindFolderExact :one SELECT name, "always", alert, description, owner, system, expire, visibility, create_at, update_at FROM folders where name = ? ` +// FindFolderExact finds a folder with an exact match. +// +// SELECT name, "always", alert, description, owner, system, expire, visibility, create_at, update_at FROM folders where name = ? func (q *Queries) FindFolderExact(ctx context.Context, name string) (Folder, error) { row := q.db.QueryRowContext(ctx, findFolderExact, name) var i Folder @@ -70,6 +79,11 @@ ORDER BY name LIMIT 1 ` +// FindFolderPrefix finds a folder based on a prefix. +// +// SELECT name, "always", alert, description, owner, system, expire, visibility, create_at, update_at FROM folders where name LIKE ?1 || '%' +// ORDER BY name +// LIMIT 1 func (q *Queries) FindFolderPrefix(ctx context.Context, name sql.NullString) (Folder, error) { row := q.db.QueryRowContext(ctx, findFolderPrefix, name) var i Folder @@ -92,6 +106,9 @@ const getFolderExpire = `-- name: GetFolderExpire :one SELECT expire FROM folders WHERE name = ? ` +// GetFolderExpire gets the default expiration (in days) for a folder. +// +// SELECT expire FROM folders WHERE name = ? func (q *Queries) GetFolderExpire(ctx context.Context, name string) (int64, error) { row := q.db.QueryRowContext(ctx, getFolderExpire, name) var expire int64 @@ -103,13 +120,11 @@ const isFolderOwner = `-- name: IsFolderOwner :one SELECT 1 FROM folders WHERE name = ? AND owner = ? ` -type IsFolderOwnerParams struct { - Name string - Owner string -} - -func (q *Queries) IsFolderOwner(ctx context.Context, arg IsFolderOwnerParams) (int64, error) { - row := q.db.QueryRowContext(ctx, isFolderOwner, arg.Name, arg.Owner) +// IsFolderOwner returns true if a user is a folder owner. +// +// SELECT 1 FROM folders WHERE name = ? AND owner = ? +func (q *Queries) IsFolderOwner(ctx context.Context, name string, owner string) (int64, error) { + row := q.db.QueryRowContext(ctx, isFolderOwner, name, owner) var column_1 int64 err := row.Scan(&column_1) return column_1, err @@ -119,13 +134,11 @@ const isFolderReadable = `-- name: IsFolderReadable :one SELECT 1 FROM folders WHERE name = ? AND (visibility <= 1 OR owner = ?) ` -type IsFolderReadableParams struct { - Name string - Owner string -} - -func (q *Queries) IsFolderReadable(ctx context.Context, arg IsFolderReadableParams) (int64, error) { - row := q.db.QueryRowContext(ctx, isFolderReadable, arg.Name, arg.Owner) +// IsFolderReadable checks if a folder is readable for a given user. +// +// SELECT 1 FROM folders WHERE name = ? AND (visibility <= 1 OR owner = ?) +func (q *Queries) IsFolderReadable(ctx context.Context, name string, owner string) (int64, error) { + row := q.db.QueryRowContext(ctx, isFolderReadable, name, owner) var column_1 int64 err := row.Scan(&column_1) return column_1, err @@ -135,13 +148,11 @@ const isFolderWriteable = `-- name: IsFolderWriteable :one SELECT 1 FROM folders WHERE name = ? AND (visibility = 0 OR owner = ?) ` -type IsFolderWriteableParams struct { - Name string - Owner string -} - -func (q *Queries) IsFolderWriteable(ctx context.Context, arg IsFolderWriteableParams) (int64, error) { - row := q.db.QueryRowContext(ctx, isFolderWriteable, arg.Name, arg.Owner) +// IsFolderWriteable checks if a folder is writeable for a given user. +// +// SELECT 1 FROM folders WHERE name = ? AND (visibility = 0 OR owner = ?) +func (q *Queries) IsFolderWriteable(ctx context.Context, name string, owner string) (int64, error) { + row := q.db.QueryRowContext(ctx, isFolderWriteable, name, owner) var column_1 int64 err := row.Scan(&column_1) return column_1, err @@ -160,6 +171,12 @@ type ListFolderRow struct { Description string } +// ListFolder lists folders and their message counts. +// +// SELECT f.name, count(m.id) as count, f.description +// FROM folders AS f LEFT JOIN messages AS m ON f.name = m.folder +// GROUP By f.name +// ORDER BY f.name func (q *Queries) ListFolder(ctx context.Context) ([]ListFolderRow, error) { rows, err := q.db.QueryContext(ctx, listFolder) if err != nil { @@ -183,53 +200,15 @@ func (q *Queries) ListFolder(ctx context.Context) ([]ListFolderRow, error) { return items, nil } -const listFolderForAdmin = `-- name: ListFolderForAdmin :many -SELECT f.name, count(m.id) as count, f.description -FROM folders AS f LEFT JOIN messages AS m ON f.name = m.folder -GROUP By f.name -ORDER BY f.name -` - -type ListFolderForAdminRow struct { - Name string - Count int64 - Description string -} - -func (q *Queries) ListFolderForAdmin(ctx context.Context) ([]ListFolderForAdminRow, error) { - rows, err := q.db.QueryContext(ctx, listFolderForAdmin) - if err != nil { - return nil, err - } - defer rows.Close() - var items []ListFolderForAdminRow - for rows.Next() { - var i ListFolderForAdminRow - if err := rows.Scan(&i.Name, &i.Count, &i.Description); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Close(); err != nil { - return nil, err - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - const updateFolderAlert = `-- name: UpdateFolderAlert :exec UPDATE folders SET alert = ? WHERE name = ? ` -type UpdateFolderAlertParams struct { - Alert int64 - Name string -} - -func (q *Queries) UpdateFolderAlert(ctx context.Context, arg UpdateFolderAlertParams) error { - _, err := q.db.ExecContext(ctx, updateFolderAlert, arg.Alert, arg.Name) +// UpdateFolderAlert updates the alert setting for a folder. +// +// UPDATE folders SET alert = ? WHERE name = ? +func (q *Queries) UpdateFolderAlert(ctx context.Context, alert int64, name string) error { + _, err := q.db.ExecContext(ctx, updateFolderAlert, alert, name) return err } @@ -237,27 +216,11 @@ const updateFolderAlways = `-- name: UpdateFolderAlways :exec UPDATE folders SET always = ? WHERE name = ? ` -type UpdateFolderAlwaysParams struct { - Always int64 - Name string -} - -func (q *Queries) UpdateFolderAlways(ctx context.Context, arg UpdateFolderAlwaysParams) error { - _, err := q.db.ExecContext(ctx, updateFolderAlways, arg.Always, arg.Name) - return err -} - -const updateFolderExpire = `-- name: UpdateFolderExpire :exec -UPDATE folders SET expire = ? WHERE name = ? -` - -type UpdateFolderExpireParams struct { - Expire int64 - Name string -} - -func (q *Queries) UpdateFolderExpire(ctx context.Context, arg UpdateFolderExpireParams) error { - _, err := q.db.ExecContext(ctx, updateFolderExpire, arg.Expire, arg.Name) +// UpdateFolderAlways updates the always setting for a folder. +// +// UPDATE folders SET always = ? WHERE name = ? +func (q *Queries) UpdateFolderAlways(ctx context.Context, always int64, name string) error { + _, err := q.db.ExecContext(ctx, updateFolderAlways, always, name) return err } @@ -272,6 +235,9 @@ type UpdateFolderMainParams struct { OldName string } +// UpdateFolderMain updates the description, owner and name of a folder. +// +// UPDATE folders SET description = ?, owner = ?, name = ?3 WHERE name = ?4 func (q *Queries) UpdateFolderMain(ctx context.Context, arg UpdateFolderMainParams) error { _, err := q.db.ExecContext(ctx, updateFolderMain, arg.Description, @@ -286,13 +252,11 @@ const updateFolderSystem = `-- name: UpdateFolderSystem :exec UPDATE folders SET system = ? WHERE name = ? ` -type UpdateFolderSystemParams struct { - System int64 - Name string -} - -func (q *Queries) UpdateFolderSystem(ctx context.Context, arg UpdateFolderSystemParams) error { - _, err := q.db.ExecContext(ctx, updateFolderSystem, arg.System, arg.Name) +// UpdateFolderSystem updates the system setting for a folder. +// +// UPDATE folders SET system = ? WHERE name = ? +func (q *Queries) UpdateFolderSystem(ctx context.Context, system int64, name string) error { + _, err := q.db.ExecContext(ctx, updateFolderSystem, system, name) return err } @@ -300,12 +264,10 @@ const updateFolderVisibility = `-- name: UpdateFolderVisibility :exec UPDATE folders SET visibility = ? WHERE name = ? ` -type UpdateFolderVisibilityParams struct { - Visibility int64 - Name string -} - -func (q *Queries) UpdateFolderVisibility(ctx context.Context, arg UpdateFolderVisibilityParams) error { - _, err := q.db.ExecContext(ctx, updateFolderVisibility, arg.Visibility, arg.Name) +// UpdateFolderVisibility updates the visibility setting for a folder. +// +// UPDATE folders SET visibility = ? WHERE name = ? +func (q *Queries) UpdateFolderVisibility(ctx context.Context, visibility int64, name string) error { + _, err := q.db.ExecContext(ctx, updateFolderVisibility, visibility, name) return err } diff --git a/storage/messages.sql.go b/storage/messages.sql.go index 84d85a8..b93a7b6 100644 --- a/storage/messages.sql.go +++ b/storage/messages.sql.go @@ -29,6 +29,13 @@ type CreateMessageParams struct { Expiration time.Time } +// CreateMessage creates a new message. +// +// INSERT INTO messages ( +// id, folder, author, subject, message, permanent, shutdown, expiration +// ) VALUES ( +// (SELECT COALESCE(MAX(id), 0) + 1 FROM messages AS m WHERE m.folder = ?1), +// ?1, ?2, ?3, ?4, ?5, ?6, ?7) func (q *Queries) CreateMessage(ctx context.Context, arg CreateMessageParams) error { _, err := q.db.ExecContext(ctx, createMessage, arg.Folder, @@ -46,6 +53,9 @@ const deleteAllMessages = `-- name: DeleteAllMessages :exec DELETE FROM messages WHERE folder = ? ` +// DeleteAllMessages delete all messages in a folder. +// +// DELETE FROM messages WHERE folder = ? func (q *Queries) DeleteAllMessages(ctx context.Context, folder string) error { _, err := q.db.ExecContext(ctx, deleteAllMessages, folder) return err @@ -64,19 +74,27 @@ SELECT CAST(f.alert AS INT) AS folder_alert, ORDER BY m.folder, m.id ` -type GetAlertMessagesParams struct { - Login string - CreateAt time.Time -} - type GetAlertMessagesRow struct { FolderAlert int64 UserAlert int64 Message Message } -func (q *Queries) GetAlertMessages(ctx context.Context, arg GetAlertMessagesParams) ([]GetAlertMessagesRow, error) { - rows, err := q.db.QueryContext(ctx, getAlertMessages, arg.Login, arg.CreateAt) +// GetAlertMessages get all alert messages for a user older than a +// certain date that are brief, readnew, or shownew. +// +// SELECT CAST(f.alert AS INT) AS folder_alert, +// CAST(COALESCE(fc.alert, 0) AS INT) AS user_alert, +// m.id, m.folder, m.author, m.subject, m.message, m.permanent, m.system, m.shutdown, m.expiration, m.create_at, m.update_at +// FROM messages AS m +// LEFT OUTER JOIN folders AS f ON m.folder = f.name +// LEFT OUTER JOIN folder_configs AS fc ON f.name = fc.folder AND fc.login = ? +// WHERE m.create_at >= ? +// AND (f.alert > 4 OR fc.alert > 1 +// OR (f.alert > 1 AND COALESCE(fc.alert, 0) != 1)) +// ORDER BY m.folder, m.id +func (q *Queries) GetAlertMessages(ctx context.Context, login string, createAt time.Time) ([]GetAlertMessagesRow, error) { + rows, err := q.db.QueryContext(ctx, getAlertMessages, login, createAt) if err != nil { return nil, err } @@ -125,6 +143,11 @@ type GetLastReadRow struct { } // GetLastRead gets the last message read by a login in a folder. +// +// SELECT CAST(MAX(m.id) AS INT) AS id, m.author FROM messages AS m, users AS u +// WHERE folder = ? AND u.login == m.author +// GROUP BY m.author +// ORDER BY m.author func (q *Queries) GetLastRead(ctx context.Context, folder string) ([]GetLastReadRow, error) { rows, err := q.db.QueryContext(ctx, getLastRead, folder) if err != nil { @@ -155,18 +178,19 @@ SELECT CAST(MAX(m.id) AS INT) AS id, m.author FROM messages AS m, users AS u ORDER BY m.author ` -type GetLastReadByEnabledParams struct { - Folder string - Disabled int64 -} - type GetLastReadByEnabledRow struct { ID int64 Author string } -func (q *Queries) GetLastReadByEnabled(ctx context.Context, arg GetLastReadByEnabledParams) ([]GetLastReadByEnabledRow, error) { - rows, err := q.db.QueryContext(ctx, getLastReadByEnabled, arg.Folder, arg.Disabled) +// GetLastReadByEnabled gets the last message for a user that's enabled. +// +// SELECT CAST(MAX(m.id) AS INT) AS id, m.author FROM messages AS m, users AS u +// WHERE folder = ? AND u.login == m.author AND u.disabled = ? +// GROUP BY m.author +// ORDER BY m.author +func (q *Queries) GetLastReadByEnabled(ctx context.Context, folder string, disabled int64) ([]GetLastReadByEnabledRow, error) { + rows, err := q.db.QueryContext(ctx, getLastReadByEnabled, folder, disabled) if err != nil { return nil, err } @@ -193,66 +217,30 @@ SELECT CAST(MAX(m.id) AS INT) AS id, m.author FROM messages AS m, users AS u WHERE folder = ? AND u.login == m.author AND m.author = ? ` -type GetLastReadByUserParams struct { - Folder string - Author string -} - type GetLastReadByUserRow struct { ID int64 Author string } -func (q *Queries) GetLastReadByUser(ctx context.Context, arg GetLastReadByUserParams) (GetLastReadByUserRow, error) { - row := q.db.QueryRowContext(ctx, getLastReadByUser, arg.Folder, arg.Author) +// GetLastReadByUser get last message read by a user in a folder. +// +// SELECT CAST(MAX(m.id) AS INT) AS id, m.author FROM messages AS m, users AS u +// WHERE folder = ? AND u.login == m.author AND m.author = ? +func (q *Queries) GetLastReadByUser(ctx context.Context, folder string, author string) (GetLastReadByUserRow, error) { + row := q.db.QueryRowContext(ctx, getLastReadByUser, folder, author) var i GetLastReadByUserRow err := row.Scan(&i.ID, &i.Author) return i, err } -const getShutdownMessages = `-- name: GetShutdownMessages :many -SELECT id, folder, author, subject, message, permanent, system, shutdown, expiration, create_at, update_at FROM messages WHERE create_at >= ? AND shutdown = 1 -` - -func (q *Queries) GetShutdownMessages(ctx context.Context, createAt time.Time) ([]Message, error) { - rows, err := q.db.QueryContext(ctx, getShutdownMessages, createAt) - if err != nil { - return nil, err - } - defer rows.Close() - var items []Message - for rows.Next() { - var i Message - if err := rows.Scan( - &i.ID, - &i.Folder, - &i.Author, - &i.Subject, - &i.Message, - &i.Permanent, - &i.System, - &i.Shutdown, - &i.Expiration, - &i.CreateAt, - &i.UpdateAt, - ); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Close(); err != nil { - return nil, err - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - const lastMsgidIgnoringSeen = `-- name: LastMsgidIgnoringSeen :one SELECT CAST(MAX(id) AS INT) FROM messages AS m WHERE m.folder = ?1 ` +// LastMsgidIgnoringSeen last message id in a folder without factoring in +// if the message has been seen. +// +// SELECT CAST(MAX(id) AS INT) FROM messages AS m WHERE m.folder = ?1 func (q *Queries) LastMsgidIgnoringSeen(ctx context.Context, folder string) (int64, error) { row := q.db.QueryRowContext(ctx, lastMsgidIgnoringSeen, folder) var column_1 int64 @@ -266,14 +254,13 @@ SELECT CAST(COALESCE(MIN(id), 0) AS INT) FROM messages AS m AND id NOT IN (SELECT msgid FROM seen AS s WHERE s.folder = ?1 AND s.login = ?3) ` -type NextMsgidParams struct { - Folder string - ID int64 - Login string -} - -func (q *Queries) NextMsgid(ctx context.Context, arg NextMsgidParams) (int64, error) { - row := q.db.QueryRowContext(ctx, nextMsgid, arg.Folder, arg.ID, arg.Login) +// NextMsgid gets the next unread message id. +// +// SELECT CAST(COALESCE(MIN(id), 0) AS INT) FROM messages AS m +// WHERE m.folder = ?1 AND m.id > ?2 +// AND id NOT IN (SELECT msgid FROM seen AS s WHERE s.folder = ?1 AND s.login = ?3) +func (q *Queries) NextMsgid(ctx context.Context, folder string, iD int64, login string) (int64, error) { + row := q.db.QueryRowContext(ctx, nextMsgid, folder, iD, login) var column_1 int64 err := row.Scan(&column_1) return column_1, err @@ -284,13 +271,12 @@ SELECT CAST(MIN(id) AS INT) FROM messages AS m WHERE m.folder = ?1 AND m.id > ?2 ` -type NextMsgidIgnoringSeenParams struct { - Folder string - ID int64 -} - -func (q *Queries) NextMsgidIgnoringSeen(ctx context.Context, arg NextMsgidIgnoringSeenParams) (int64, error) { - row := q.db.QueryRowContext(ctx, nextMsgidIgnoringSeen, arg.Folder, arg.ID) +// NextMsgidIgnoringSeen gets the next message id. +// +// SELECT CAST(MIN(id) AS INT) FROM messages AS m +// WHERE m.folder = ?1 AND m.id > ?2 +func (q *Queries) NextMsgidIgnoringSeen(ctx context.Context, folder string, iD int64) (int64, error) { + row := q.db.QueryRowContext(ctx, nextMsgidIgnoringSeen, folder, iD) var column_1 int64 err := row.Scan(&column_1) return column_1, err @@ -302,31 +288,13 @@ SELECT CAST(COALESCE(MAX(id), 0) AS INT) FROM messages AS m AND id NOT IN (SELECT msgid FROM seen AS s WHERE s.folder = ?1 AND s.login = ?3) ` -type PrevMsgidParams struct { - Folder string - ID int64 - Login string -} - -func (q *Queries) PrevMsgid(ctx context.Context, arg PrevMsgidParams) (int64, error) { - row := q.db.QueryRowContext(ctx, prevMsgid, arg.Folder, arg.ID, arg.Login) - var column_1 int64 - err := row.Scan(&column_1) - return column_1, err -} - -const prevMsgidIgnoringSeen = `-- name: PrevMsgidIgnoringSeen :one -SELECT CAST(MAX(id) AS INT) FROM messages AS m - WHERE m.folder = ?1 AND m.id < ?2 -` - -type PrevMsgidIgnoringSeenParams struct { - Folder string - ID int64 -} - -func (q *Queries) PrevMsgidIgnoringSeen(ctx context.Context, arg PrevMsgidIgnoringSeenParams) (int64, error) { - row := q.db.QueryRowContext(ctx, prevMsgidIgnoringSeen, arg.Folder, arg.ID) +// PrevMsgid get the previous message id. +// +// SELECT CAST(COALESCE(MAX(id), 0) AS INT) FROM messages AS m +// WHERE m.folder = ?1 AND m.id < ?2 +// AND id NOT IN (SELECT msgid FROM seen AS s WHERE s.folder = ?1 AND s.login = ?3) +func (q *Queries) PrevMsgid(ctx context.Context, folder string, iD int64, login string) (int64, error) { + row := q.db.QueryRowContext(ctx, prevMsgid, folder, iD, login) var column_1 int64 err := row.Scan(&column_1) return column_1, err @@ -336,13 +304,11 @@ const readMessage = `-- name: ReadMessage :one SELECT id, folder, author, subject, message, permanent, system, shutdown, expiration, create_at, update_at FROM messages WHERE folder = ? AND id = ? ` -type ReadMessageParams struct { - Folder string - ID int64 -} - -func (q *Queries) ReadMessage(ctx context.Context, arg ReadMessageParams) (Message, error) { - row := q.db.QueryRowContext(ctx, readMessage, arg.Folder, arg.ID) +// ReadMessage returns a specified message id from a folder. +// +// SELECT id, folder, author, subject, message, permanent, system, shutdown, expiration, create_at, update_at FROM messages WHERE folder = ? AND id = ? +func (q *Queries) ReadMessage(ctx context.Context, folder string, iD int64) (Message, error) { + row := q.db.QueryRowContext(ctx, readMessage, folder, iD) var i Message err := row.Scan( &i.ID, @@ -366,16 +332,19 @@ SELECT id, folder, author, subject, message, permanent, system, shutdown, expira OR subject LIKE '%' || ?1 || '%') AND id >= ?2 AND folder = ?3 + ORDER BY id ASC ` -type SearchParams struct { - Column1 sql.NullString - ID int64 - Folder string -} - -func (q *Queries) Search(ctx context.Context, arg SearchParams) ([]Message, error) { - rows, err := q.db.QueryContext(ctx, search, arg.Column1, arg.ID, arg.Folder) +// Search find messages that match subject or message text. +// +// SELECT id, folder, author, subject, message, permanent, system, shutdown, expiration, create_at, update_at FROM messages +// WHERE (message LIKE '%' || ?1 || '%' +// OR subject LIKE '%' || ?1 || '%') +// AND id >= ?2 +// AND folder = ?3 +// ORDER BY id ASC +func (q *Queries) Search(ctx context.Context, column1 sql.NullString, iD int64, folder string) ([]Message, error) { + rows, err := q.db.QueryContext(ctx, search, column1, iD, folder) if err != nil { return nil, err } @@ -411,19 +380,36 @@ func (q *Queries) Search(ctx context.Context, arg SearchParams) ([]Message, erro const searchReply = `-- name: SearchReply :many SELECT id, folder, author, subject, message, permanent, system, shutdown, expiration, create_at, update_at FROM messages - WHERE subject = ? + WHERE message LIKE '%' || ? || '%' + AND subject = ? AND id >= ? AND folder = ? + ORDER BY id ASC ` type SearchReplyParams struct { + Column1 sql.NullString Subject string ID int64 Folder string } +// SearchReply find messages that match a specific subject and a different +// message text. +// +// SELECT id, folder, author, subject, message, permanent, system, shutdown, expiration, create_at, update_at FROM messages +// WHERE message LIKE '%' || ? || '%' +// AND subject = ? +// AND id >= ? +// AND folder = ? +// ORDER BY id ASC func (q *Queries) SearchReply(ctx context.Context, arg SearchReplyParams) ([]Message, error) { - rows, err := q.db.QueryContext(ctx, searchReply, arg.Subject, arg.ID, arg.Folder) + rows, err := q.db.QueryContext(ctx, searchReply, + arg.Column1, + arg.Subject, + arg.ID, + arg.Folder, + ) if err != nil { return nil, err } @@ -459,20 +445,36 @@ func (q *Queries) SearchReply(ctx context.Context, arg SearchReplyParams) ([]Mes const searchReplyReverse = `-- name: SearchReplyReverse :many SELECT id, folder, author, subject, message, permanent, system, shutdown, expiration, create_at, update_at FROM messages - WHERE subject = ? + WHERE message LIKE '%' || ? || '%' + AND subject = ? AND id <= ? AND folder = ? ORDER BY DESC ` type SearchReplyReverseParams struct { + Column1 sql.NullString Subject string ID int64 Folder string } +// SearchReplyReverse find messages that match a specific subject and +// a different message text in reverse order. +// +// SELECT id, folder, author, subject, message, permanent, system, shutdown, expiration, create_at, update_at FROM messages +// WHERE message LIKE '%' || ? || '%' +// AND subject = ? +// AND id <= ? +// AND folder = ? +// ORDER BY DESC func (q *Queries) SearchReplyReverse(ctx context.Context, arg SearchReplyReverseParams) ([]Message, error) { - rows, err := q.db.QueryContext(ctx, searchReplyReverse, arg.Subject, arg.ID, arg.Folder) + rows, err := q.db.QueryContext(ctx, searchReplyReverse, + arg.Column1, + arg.Subject, + arg.ID, + arg.Folder, + ) if err != nil { return nil, err } @@ -512,17 +514,19 @@ SELECT id, folder, author, subject, message, permanent, system, shutdown, expira OR subject LIKE '%' || ?1 || '%') AND id <= ?2 AND folder = ?3 - ORDER BY DESC + ORDER BY id DESC ` -type SearchReverseParams struct { - Column1 sql.NullString - ID int64 - Folder string -} - -func (q *Queries) SearchReverse(ctx context.Context, arg SearchReverseParams) ([]Message, error) { - rows, err := q.db.QueryContext(ctx, searchReverse, arg.Column1, arg.ID, arg.Folder) +// SearchReverse find messages that match subject or message text in reverse order. +// +// SELECT id, folder, author, subject, message, permanent, system, shutdown, expiration, create_at, update_at FROM messages +// WHERE (message LIKE '%' || ?1 || '%' +// OR subject LIKE '%' || ?1 || '%') +// AND id <= ?2 +// AND folder = ?3 +// ORDER BY id DESC +func (q *Queries) SearchReverse(ctx context.Context, column1 sql.NullString, iD int64, folder string) ([]Message, error) { + rows, err := q.db.QueryContext(ctx, searchReverse, column1, iD, folder) if err != nil { return nil, err } @@ -561,16 +565,18 @@ SELECT id, folder, author, subject, message, permanent, system, shutdown, expira WHERE subject LIKE '%' || ? || '%' AND id >= ? AND folder = ? + ORDER BY id ASC ` -type SearchSubjectParams struct { - Column1 sql.NullString - ID int64 - Folder string -} - -func (q *Queries) SearchSubject(ctx context.Context, arg SearchSubjectParams) ([]Message, error) { - rows, err := q.db.QueryContext(ctx, searchSubject, arg.Column1, arg.ID, arg.Folder) +// SearchSubject find messages that match the subject. +// +// SELECT id, folder, author, subject, message, permanent, system, shutdown, expiration, create_at, update_at FROM messages +// WHERE subject LIKE '%' || ? || '%' +// AND id >= ? +// AND folder = ? +// ORDER BY id ASC +func (q *Queries) SearchSubject(ctx context.Context, column1 sql.NullString, iD int64, folder string) ([]Message, error) { + rows, err := q.db.QueryContext(ctx, searchSubject, column1, iD, folder) if err != nil { return nil, err } @@ -609,17 +615,18 @@ SELECT id, folder, author, subject, message, permanent, system, shutdown, expira WHERE subject LIKE '%' || ? || '%' AND id <= ? AND folder = ? - ORDER BY DESC + ORDER BY id DESC ` -type SearchSubjectReverseParams struct { - Column1 sql.NullString - ID int64 - Folder string -} - -func (q *Queries) SearchSubjectReverse(ctx context.Context, arg SearchSubjectReverseParams) ([]Message, error) { - rows, err := q.db.QueryContext(ctx, searchSubjectReverse, arg.Column1, arg.ID, arg.Folder) +// SearchSubjectReverse find messages that match the subject in reverse order. +// +// SELECT id, folder, author, subject, message, permanent, system, shutdown, expiration, create_at, update_at FROM messages +// WHERE subject LIKE '%' || ? || '%' +// AND id <= ? +// AND folder = ? +// ORDER BY id DESC +func (q *Queries) SearchSubjectReverse(ctx context.Context, column1 sql.NullString, iD int64, folder string) ([]Message, error) { + rows, err := q.db.QueryContext(ctx, searchSubjectReverse, column1, iD, folder) if err != nil { return nil, err } @@ -657,14 +664,11 @@ const setMessageSeen = `-- name: SetMessageSeen :exec INSERT INTO seen (login, folder, msgid) VALUES (?, ?, ?) ` -type SetMessageSeenParams struct { - Login string - Folder string - Msgid int64 -} - -func (q *Queries) SetMessageSeen(ctx context.Context, arg SetMessageSeenParams) error { - _, err := q.db.ExecContext(ctx, setMessageSeen, arg.Login, arg.Folder, arg.Msgid) +// SetMessageSeen mark a message as seen for a user. +// +// INSERT INTO seen (login, folder, msgid) VALUES (?, ?, ?) +func (q *Queries) SetMessageSeen(ctx context.Context, login string, folder string, msgid int64) error { + _, err := q.db.ExecContext(ctx, setMessageSeen, login, folder, msgid) return err } @@ -672,14 +676,11 @@ const unsetMessageSeen = `-- name: UnsetMessageSeen :exec DELETE FROM seen WHERE login = ? AND folder = ? AND msgid = ? ` -type UnsetMessageSeenParams struct { - Login string - Folder string - Msgid int64 -} - -func (q *Queries) UnsetMessageSeen(ctx context.Context, arg UnsetMessageSeenParams) error { - _, err := q.db.ExecContext(ctx, unsetMessageSeen, arg.Login, arg.Folder, arg.Msgid) +// UnsetMessageSeen unmark a message as seen for a user. +// +// DELETE FROM seen WHERE login = ? AND folder = ? AND msgid = ? +func (q *Queries) UnsetMessageSeen(ctx context.Context, login string, folder string, msgid int64) error { + _, err := q.db.ExecContext(ctx, unsetMessageSeen, login, folder, msgid) return err } @@ -704,6 +705,16 @@ type UpdateMessageParams struct { ID int64 } +// UpdateMessage updates a message. +// +// UPDATE messages SET +// subject = ?, +// message = ?, +// permanent = ?, +// system = ?, +// shutdown = ?, +// expiration = ? +// WHERE id = ? func (q *Queries) UpdateMessage(ctx context.Context, arg UpdateMessageParams) error { _, err := q.db.ExecContext(ctx, updateMessage, arg.Subject, diff --git a/storage/queries/batch.sql b/storage/queries/batch.sql index 5eb8127..44dfdc8 100644 --- a/storage/queries/batch.sql +++ b/storage/queries/batch.sql @@ -1,7 +1,12 @@ +-- DeleteAllExpiredMessages deletes all messages that are not permanent +-- and have an expiration timestamp less than the `CURRENT_TIMESTAMP`. +-- This works on all folders. -- name: DeleteAllExpiredMessages :execrows DELETE FROM messages WHERE permanent != 1 AND expiration < CURRENT_TIMESTAMP; +-- DeleteAllShutdownMessages removes all shutdown that are not permanent. +-- This works on all folders. -- name: DeleteAllShutdownMessages :execrows DELETE FROM messages WHERE permanent != 1 AND shutdown > 0; diff --git a/storage/queries/broadcast.sql b/storage/queries/broadcast.sql index 311ae1c..d9bdb4c 100644 --- a/storage/queries/broadcast.sql +++ b/storage/queries/broadcast.sql @@ -1,17 +1,19 @@ +-- CreateBroadcast adds a new broadcast message. -- name: CreateBroadcast :exec INSERT INTO broadcast (author, bell, message) VALUES (?, ?, ?); +-- GetBroadcasts gets new broadcast messages newer than a passed +-- time.Time() value and returns them in create_at order. -- name: GetBroadcasts :many SELECT * FROM broadcast WHERE create_at > ? ORDER BY create_at; +-- UpdateLastActivity updates the user's last_activity time. -- name: UpdateLastActivity :exec UPDATE users SET last_activity = ? WHERE login = ?; --- name: ClearBroadcasts :exec -DELETE FROM broadcast; - +-- ReapBroadcasts deletes broadcast messages over 3 days old. -- name: ReapBroadcasts :exec DELETE FROM broadcast WHERE julianday(current_timestamp) - julianday(create_at) > 3; diff --git a/storage/queries/folders.sql b/storage/queries/folders.sql index 6c8aba9..ce859e7 100644 --- a/storage/queries/folders.sql +++ b/storage/queries/folders.sql @@ -1,55 +1,59 @@ +-- CreateFolder creates a new folder. -- name: CreateFolder :exec INSERT INTO folders (name, always, alert, description, owner, system, expire, visibility) VALUES (?, ?, ?, ?, ?, ?, ?, ?); --- name: ListFolderForAdmin :many -SELECT f.name, count(m.id) as count, f.description -FROM folders AS f LEFT JOIN messages AS m ON f.name = m.folder -GROUP By f.name -ORDER BY f.name; - +-- ListFolder lists folders and their message counts. -- name: ListFolder :many SELECT f.name, count(m.id) as count, f.description FROM folders AS f LEFT JOIN messages AS m ON f.name = m.folder GROUP By f.name ORDER BY f.name; +-- FindFolderExact finds a folder with an exact match. -- name: FindFolderExact :one SELECT * FROM folders where name = ?; +-- FindFolderPrefix finds a folder based on a prefix. -- name: FindFolderPrefix :one SELECT * FROM folders where name LIKE sqlc.arg(name) || '%' ORDER BY name LIMIT 1; +-- IsFolderReadable checks if a folder is readable for a given user. -- name: IsFolderReadable :one SELECT 1 FROM folders WHERE name = ? AND (visibility <= 1 OR owner = ?); +-- IsFolderWriteable checks if a folder is writeable for a given user. -- name: IsFolderWriteable :one SELECT 1 FROM folders WHERE name = ? AND (visibility = 0 OR owner = ?); +-- IsFolderOwner returns true if a user is a folder owner. -- name: IsFolderOwner :one SELECT 1 FROM folders WHERE name = ? AND owner = ?; +-- GetFolderExpire gets the default expiration (in days) for a folder. -- name: GetFolderExpire :one SELECT expire FROM folders WHERE name = ?; +-- UpdateFolderAlways updates the always setting for a folder. -- name: UpdateFolderAlways :exec UPDATE folders SET always = ? WHERE name = ?; +-- UpdateFolderSystem updates the system setting for a folder. -- name: UpdateFolderSystem :exec UPDATE folders SET system = ? WHERE name = ?; +-- UpdateFolderAlert updates the alert setting for a folder. -- name: UpdateFolderAlert :exec UPDATE folders SET alert = ? WHERE name = ?; +-- UpdateFolderVisibility updates the visibility setting for a folder. -- name: UpdateFolderVisibility :exec UPDATE folders SET visibility = ? WHERE name = ?; --- name: UpdateFolderExpire :exec -UPDATE folders SET expire = ? WHERE name = ?; - +-- UpdateFolderMain updates the description, owner and name of a folder. -- name: UpdateFolderMain :exec UPDATE folders SET description = ?, owner = ?, name = sqlc.arg(new_name) WHERE name = sqlc.arg(old_name); diff --git a/storage/queries/messages.sql b/storage/queries/messages.sql index 5a49f81..5e68548 100644 --- a/storage/queries/messages.sql +++ b/storage/queries/messages.sql @@ -1,3 +1,4 @@ +-- CreateMessage creates a new message. -- name: CreateMessage :exec INSERT INTO messages ( id, folder, author, subject, message, permanent, shutdown, expiration @@ -5,36 +6,41 @@ INSERT INTO messages ( (SELECT COALESCE(MAX(id), 0) + 1 FROM messages AS m WHERE m.folder = ?1), ?1, ?2, ?3, ?4, ?5, ?6, ?7); +-- SetMessageSeen mark a message as seen for a user. -- name: SetMessageSeen :exec INSERT INTO seen (login, folder, msgid) VALUES (?, ?, ?); +-- UnsetMessageSeen unmark a message as seen for a user. -- name: UnsetMessageSeen :exec DELETE FROM seen WHERE login = ? AND folder = ? AND msgid = ?; +-- ReadMessage returns a specified message id from a folder. -- name: ReadMessage :one SELECT * FROM messages WHERE folder = ? AND id = ?; +-- NextMsgid gets the next unread message id. -- name: NextMsgid :one SELECT CAST(COALESCE(MIN(id), 0) AS INT) FROM messages AS m WHERE m.folder = ?1 AND m.id > ?2 AND id NOT IN (SELECT msgid FROM seen AS s WHERE s.folder = ?1 AND s.login = ?3); +-- NextMsgidIgnoringSeen gets the next message id. -- name: NextMsgidIgnoringSeen :one SELECT CAST(MIN(id) AS INT) FROM messages AS m WHERE m.folder = ?1 AND m.id > ?2; +-- PrevMsgid get the previous message id. -- name: PrevMsgid :one SELECT CAST(COALESCE(MAX(id), 0) AS INT) FROM messages AS m WHERE m.folder = ?1 AND m.id < ?2 AND id NOT IN (SELECT msgid FROM seen AS s WHERE s.folder = ?1 AND s.login = ?3); --- name: PrevMsgidIgnoringSeen :one -SELECT CAST(MAX(id) AS INT) FROM messages AS m - WHERE m.folder = ?1 AND m.id < ?2; - +-- DeleteAllMessages delete all messages in a folder. -- name: DeleteAllMessages :exec DELETE FROM messages WHERE folder = ?; +-- LastMsgidIgnoringSeen last message id in a folder without factoring in +-- if the message has been seen. -- name: LastMsgidIgnoringSeen :one SELECT CAST(MAX(id) AS INT) FROM messages AS m WHERE m.folder = ?1; @@ -45,57 +51,73 @@ SELECT CAST(MAX(m.id) AS INT) AS id, m.author FROM messages AS m, users AS u GROUP BY m.author ORDER BY m.author; +-- GetLastReadByEnabled gets the last message for a user that's enabled. -- name: GetLastReadByEnabled :many SELECT CAST(MAX(m.id) AS INT) AS id, m.author FROM messages AS m, users AS u WHERE folder = ? AND u.login == m.author AND u.disabled = ? GROUP BY m.author ORDER BY m.author; +-- GetLastReadByUser get last message read by a user in a folder. -- name: GetLastReadByUser :one SELECT CAST(MAX(m.id) AS INT) AS id, m.author FROM messages AS m, users AS u WHERE folder = ? AND u.login == m.author AND m.author = ?; +-- Search find messages that match subject or message text. -- name: Search :many SELECT * FROM messages WHERE (message LIKE '%' || ?1 || '%' OR subject LIKE '%' || ?1 || '%') AND id >= ?2 - AND folder = ?3; + AND folder = ?3 + ORDER BY id ASC; +-- SearchReverse find messages that match subject or message text in reverse order. -- name: SearchReverse :many SELECT * FROM messages WHERE (message LIKE '%' || ?1 || '%' OR subject LIKE '%' || ?1 || '%') AND id <= ?2 AND folder = ?3 - ORDER BY DESC; + ORDER BY id DESC; +-- SearchSubject find messages that match the subject. -- name: SearchSubject :many SELECT * FROM messages WHERE subject LIKE '%' || ? || '%' AND id >= ? - AND folder = ?; + AND folder = ? + ORDER BY id ASC; +-- SearchSubjectReverse find messages that match the subject in reverse order. -- name: SearchSubjectReverse :many SELECT * FROM messages WHERE subject LIKE '%' || ? || '%' AND id <= ? AND folder = ? - ORDER BY DESC; + ORDER BY id DESC; +-- SearchReply find messages that match a specific subject and a different +-- message text. -- name: SearchReply :many SELECT * FROM messages - WHERE subject = ? + WHERE message LIKE '%' || ? || '%' + AND subject = ? AND id >= ? - AND folder = ?; + AND folder = ? + ORDER BY id ASC; +-- SearchReplyReverse find messages that match a specific subject and +-- a different message text in reverse order. -- name: SearchReplyReverse :many SELECT * FROM messages - WHERE subject = ? + WHERE message LIKE '%' || ? || '%' + AND subject = ? AND id <= ? AND folder = ? ORDER BY DESC; +-- UpdateMessage updates a message. -- name: UpdateMessage :exec UPDATE messages SET subject = ?, @@ -106,9 +128,8 @@ UPDATE messages SET expiration = ? WHERE id = ?; --- name: GetShutdownMessages :many -SELECT * FROM messages WHERE create_at >= ? AND shutdown = 1; - +-- GetAlertMessages get all alert messages for a user older than a +-- certain date that are brief, readnew, or shownew. -- name: GetAlertMessages :many SELECT CAST(f.alert AS INT) AS folder_alert, CAST(COALESCE(fc.alert, 0) AS INT) AS user_alert, diff --git a/storage/queries/seed.sql b/storage/queries/seed.sql index 07ca474..1d45b10 100644 --- a/storage/queries/seed.sql +++ b/storage/queries/seed.sql @@ -1,11 +1,14 @@ +-- SeedUserSystem adds the SYSTEM user. -- name: SeedUserSystem :exec INSERT INTO users (login, name, admin, moderator) VALUES ('SYSTEM', 'System User', 1, 1); +-- SeedFolderGeneral adds the GENERAL folder. -- name: SeedFolderGeneral :exec INSERT INTO folders (name, owner, description, system, alert) VALUES ('GENERAL', 'SYSTEM', 'Default general bulletin folder.', 1, 2); +-- SeedCreateMessage add in the initial messages. -- name: SeedCreateMessage :exec INSERT INTO messages (id, folder, author, subject, message, permanent, create_at, update_at, expiration) diff --git a/storage/queries/standard.sql b/storage/queries/standard.sql index 34ef417..0bf127c 100644 --- a/storage/queries/standard.sql +++ b/storage/queries/standard.sql @@ -1,91 +1,61 @@ +-- ListUsers get a list of all users. -- name: ListUsers :many SELECT * FROM users; +-- DeleteUser removes the user (as long as the user isn't SYSTEM). -- name: DeleteUser :exec DELETE FROM users WHERE login = ? AND login != 'SYSTEM'; --- name: AddFolder :exec -INSERT INTO folders (name) VALUES (?); - --- name: ListFolders :many -SELECT * FROM folders; - +-- GetFolder get a folder by name. -- name: GetFolder :one SELECT * FROM folders WHERE name = ?; +-- DeleteFolder remove a folder by name. -- name: DeleteFolder :exec DELETE FROM folders WHERE name = ?; --- name: AddMessage :exec -INSERT INTO messages (id, folder) VALUES (?, ?); - +-- ListMessages list all messages in a specific folder. -- name: ListMessages :many SELECT * FROM messages WHERE folder = ? ORDER BY id; +-- ListMessageIDs list all message IDs in a specific folder. -- name: ListMessageIDs :many SELECT id FROM messages WHERE folder = ? ORDER BY id; +-- GetMessage gets a message by id and by folder. -- name: GetMessage :one SELECT * FROM messages WHERE id = ? AND folder = ?; +-- DeleteMessage removes a message by id and by folder. -- name: DeleteMessage :exec DELETE FROM messages WHERE id = ? AND folder = ?; --- name: AddSeen :exec -INSERT INTO seen (folder, login, msgid) VALUES (?, ?, ?); - --- name: ListSeen :many -SELECT * FROM seen; - --- name: GetSeen :one -SELECT * FROM seen WHERE folder = ? AND login = ? AND msgid = ?; - --- name: DeleteSeen :exec -DELETE FROM seen WHERE folder = ? AND login = ? AND msgid = ?; - +-- AddMark mark a message id for a login in a folder. -- name: AddMark :exec INSERT INTO marks (folder, login, msgid) VALUES (?, ?, ?); --- name: ListMark :many -SELECT * FROM marks WHERE folder = ? AND login = ?; - --- name: GetMark :one -SELECT * FROM marks WHERE folder = ? AND login = ? AND msgid = ?; - +-- DeleteMark unmark a message id for a login in a folder. -- name: DeleteMark :exec DELETE FROM marks WHERE folder = ? AND login = ? AND msgid = ?; +-- UpdateFolderAccess update folder visibility for a given login and +-- folder. -- name: UpdateFolderAccess :exec INSERT INTO folder_access (login, folder, visibility) VALUES (?1, ?2, ?3) ON CONFLICT(login, folder) DO UPDATE SET visibility = ?3; --- name: ListFolderAccess :many -SELECT * FROM folder_access WHERE folder = ?; - --- name: GetFolderAccess :one -SELECT visibility FROM folder_access WHERE login = ? AND folder = ?; - +-- DeleteFolderAccess remove access for a folder for a given login. -- name: DeleteFolderAccess :exec DELETE FROM folder_access WHERE login = ? AND folder = ?; --- name: AddFolderConfig :exec -INSERT INTO folder_configs (login, folder) VALUES (?, ?); - --- name: ListFolderConfig :many -SELECT * FROM folder_configs; - --- name: GetFolderConfig :one -SELECT * FROM folder_configs WHERE login = ? AND folder = ?; - --- name: DeleteFolderConfig :exec -DELETE FROM folder_configs WHERE login = ? AND folder = ?; - +-- SetSystem sets the system info. The system folder only has a single row. -- name: SetSystem :exec INSERT INTO system (rowid, name, default_expire, expire_limit) VALUES (1, ?1, ?2, ?3) ON CONFLICT(rowid) DO UPDATE SET name = ?1, default_expire = ?2, expire_limit = ?3; +-- GetSystem gets the row from the system folder. -- name: GetSystem :one SELECT * FROM system LIMIT 1; diff --git a/storage/queries/system.sql b/storage/queries/system.sql index 3196183..adc71c0 100644 --- a/storage/queries/system.sql +++ b/storage/queries/system.sql @@ -1,8 +1,11 @@ +-- UpdateDefaultExpire update the default expiration value for the system. -- name: UpdateDefaultExpire :exec UPDATE system SET default_expire = ? WHERE rowid = 1; +-- UpdateExpireLimit update the default expiration limit for the system. -- name: UpdateExpireLimit :exec UPDATE system SET expire_limit = ? WHERE rowid = 1; +-- GetExpire get the default expiration value and limit for the system. -- name: GetExpire :one SELECT default_expire, expire_limit FROM system WHERE rowid = 1; diff --git a/storage/queries/users.sql b/storage/queries/users.sql index cd6d7ff..818d0a0 100644 --- a/storage/queries/users.sql +++ b/storage/queries/users.sql @@ -1,6 +1,8 @@ +-- GetUser gets the user by login. -- name: GetUser :one SELECT * FROM users WHERE login = ?; +-- AddUser adds the user. -- name: AddUser :one INSERT INTO users (login, name, admin, disabled, last_activity, last_login) @@ -8,39 +10,58 @@ INSERT INTO users (?, ?, ?, ?, '1970-01-01', '1970-01-01') RETURNING *; +-- IsUserAdmin returns the admin setting for the user. -- name: IsUserAdmin :one SELECT admin FROM users WHERE login = ?; +-- UpdateUserDisabled updates the disabled setting for the user (excluding +-- the SYSTEM user). -- name: UpdateUserDisabled :exec UPDATE users SET disabled = ? WHERE login = ? AND login != 'SYSTEM'; +-- UpdateUserAdmin updates the admin setting for the user (excluding +-- the SYSTEM user). -- name: UpdateUserAdmin :exec UPDATE users SET admin = ? WHERE login = ? AND login != 'SYSTEM'; +-- UpdateUserAlert set user's alert setting for a folder. -- name: UpdateUserAlert :exec INSERT INTO folder_configs (login, folder, alert) VALUES (?1, ?2, ?3) ON CONFLICT(login, folder) DO UPDATE SET login = ?1, folder = ?2, alert = ?3; +-- UpdateUserName update user's name for a given login (excluding the +-- SYSTEM user). -- name: UpdateUserName :exec UPDATE users SET name = ? WHERE login = ? AND login != 'SYSTEM'; +-- UpdateUserMod set user's moderator setting for the user (excluding +-- the SYSTEM user). -- name: UpdateUserMod :exec UPDATE users SET moderator = ? WHERE login = ? AND login != 'SYSTEM'; +-- UpdateUserPrompt set user's prompt setting for the user (excluding +-- the SYSTEM user). -- name: UpdateUserPrompt :exec UPDATE users SET prompt = ? WHERE login = ? AND login != 'SYSTEM'; +-- UpdateUserLastLogin set user's last_login time for the user (excluding +-- the SYSTEM user). -- name: UpdateUserLastLogin :one UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE login = ? AND login != 'SYSTEM' RETURNING last_login; +-- GetLastLogin gets the login and last_login time for all users. -- name: GetLastLogin :many SELECT login, last_login FROM users ORDER BY login; +-- GetLastLoginByLogin gets the login and last_login time for all users +-- ordered by login. -- name: GetLastLoginByLogin :one SELECT login, last_login FROM users WHERE login = ? ORDER BY login; +-- GetLastLoginByEnabled gets the login and last_login time for all users +-- with a given disabled setting ordered by login. -- name: GetLastLoginByEnabled :many SELECT login, last_login FROM users WHERE disabled = ? ORDER BY login; diff --git a/storage/seed.sql.go b/storage/seed.sql.go index 76bb10e..cbe49af 100644 --- a/storage/seed.sql.go +++ b/storage/seed.sql.go @@ -27,6 +27,13 @@ type SeedCreateMessageParams struct { Expiration time.Time } +// SeedCreateMessage add in the initial messages. +// +// INSERT INTO messages +// (id, folder, author, subject, message, permanent, create_at, update_at, expiration) +// VALUES +// ((SELECT COALESCE(MAX(id), 0) + 1 FROM messages AS m WHERE m.folder = ?1), +// ?1, ?2, ?3, ?4, 1, ?5, ?5, ?6) func (q *Queries) SeedCreateMessage(ctx context.Context, arg SeedCreateMessageParams) error { _, err := q.db.ExecContext(ctx, seedCreateMessage, arg.Folder, @@ -44,6 +51,10 @@ INSERT INTO folders (name, owner, description, system, alert) VALUES ('GENERAL', 'SYSTEM', 'Default general bulletin folder.', 1, 2) ` +// SeedFolderGeneral adds the GENERAL folder. +// +// INSERT INTO folders (name, owner, description, system, alert) +// VALUES ('GENERAL', 'SYSTEM', 'Default general bulletin folder.', 1, 2) func (q *Queries) SeedFolderGeneral(ctx context.Context) error { _, err := q.db.ExecContext(ctx, seedFolderGeneral) return err @@ -54,6 +65,10 @@ INSERT INTO users (login, name, admin, moderator) VALUES ('SYSTEM', 'System User', 1, 1) ` +// SeedUserSystem adds the SYSTEM user. +// +// INSERT INTO users (login, name, admin, moderator) +// VALUES ('SYSTEM', 'System User', 1, 1) func (q *Queries) SeedUserSystem(ctx context.Context) error { _, err := q.db.ExecContext(ctx, seedUserSystem) return err diff --git a/storage/sqlc.yaml b/storage/sqlc.yaml index a870855..d8c0c6f 100644 --- a/storage/sqlc.yaml +++ b/storage/sqlc.yaml @@ -6,5 +6,7 @@ sql: schema: "migrations/" gen: go: + emit_sql_as_comment: true + query_parameter_limit: 3 package: "storage" out: "." diff --git a/storage/standard.sql.go b/storage/standard.sql.go index f26c1e2..54ec480 100644 --- a/storage/standard.sql.go +++ b/storage/standard.sql.go @@ -9,70 +9,15 @@ import ( "context" ) -const addFolder = `-- name: AddFolder :exec -INSERT INTO folders (name) VALUES (?) -` - -func (q *Queries) AddFolder(ctx context.Context, name string) error { - _, err := q.db.ExecContext(ctx, addFolder, name) - return err -} - -const addFolderConfig = `-- name: AddFolderConfig :exec -INSERT INTO folder_configs (login, folder) VALUES (?, ?) -` - -type AddFolderConfigParams struct { - Login string - Folder string -} - -func (q *Queries) AddFolderConfig(ctx context.Context, arg AddFolderConfigParams) error { - _, err := q.db.ExecContext(ctx, addFolderConfig, arg.Login, arg.Folder) - return err -} - const addMark = `-- name: AddMark :exec INSERT INTO marks (folder, login, msgid) VALUES (?, ?, ?) ` -type AddMarkParams struct { - Folder string - Login string - Msgid int64 -} - -func (q *Queries) AddMark(ctx context.Context, arg AddMarkParams) error { - _, err := q.db.ExecContext(ctx, addMark, arg.Folder, arg.Login, arg.Msgid) - return err -} - -const addMessage = `-- name: AddMessage :exec -INSERT INTO messages (id, folder) VALUES (?, ?) -` - -type AddMessageParams struct { - ID int64 - Folder string -} - -func (q *Queries) AddMessage(ctx context.Context, arg AddMessageParams) error { - _, err := q.db.ExecContext(ctx, addMessage, arg.ID, arg.Folder) - return err -} - -const addSeen = `-- name: AddSeen :exec -INSERT INTO seen (folder, login, msgid) VALUES (?, ?, ?) -` - -type AddSeenParams struct { - Folder string - Login string - Msgid int64 -} - -func (q *Queries) AddSeen(ctx context.Context, arg AddSeenParams) error { - _, err := q.db.ExecContext(ctx, addSeen, arg.Folder, arg.Login, arg.Msgid) +// AddMark mark a message id for a login in a folder. +// +// INSERT INTO marks (folder, login, msgid) VALUES (?, ?, ?) +func (q *Queries) AddMark(ctx context.Context, folder string, login string, msgid int64) error { + _, err := q.db.ExecContext(ctx, addMark, folder, login, msgid) return err } @@ -80,6 +25,9 @@ const deleteFolder = `-- name: DeleteFolder :exec DELETE FROM folders WHERE name = ? ` +// DeleteFolder remove a folder by name. +// +// DELETE FROM folders WHERE name = ? func (q *Queries) DeleteFolder(ctx context.Context, name string) error { _, err := q.db.ExecContext(ctx, deleteFolder, name) return err @@ -89,27 +37,11 @@ const deleteFolderAccess = `-- name: DeleteFolderAccess :exec DELETE FROM folder_access WHERE login = ? AND folder = ? ` -type DeleteFolderAccessParams struct { - Login string - Folder string -} - -func (q *Queries) DeleteFolderAccess(ctx context.Context, arg DeleteFolderAccessParams) error { - _, err := q.db.ExecContext(ctx, deleteFolderAccess, arg.Login, arg.Folder) - return err -} - -const deleteFolderConfig = `-- name: DeleteFolderConfig :exec -DELETE FROM folder_configs WHERE login = ? AND folder = ? -` - -type DeleteFolderConfigParams struct { - Login string - Folder string -} - -func (q *Queries) DeleteFolderConfig(ctx context.Context, arg DeleteFolderConfigParams) error { - _, err := q.db.ExecContext(ctx, deleteFolderConfig, arg.Login, arg.Folder) +// DeleteFolderAccess remove access for a folder for a given login. +// +// DELETE FROM folder_access WHERE login = ? AND folder = ? +func (q *Queries) DeleteFolderAccess(ctx context.Context, login string, folder string) error { + _, err := q.db.ExecContext(ctx, deleteFolderAccess, login, folder) return err } @@ -117,14 +49,11 @@ const deleteMark = `-- name: DeleteMark :exec DELETE FROM marks WHERE folder = ? AND login = ? AND msgid = ? ` -type DeleteMarkParams struct { - Folder string - Login string - Msgid int64 -} - -func (q *Queries) DeleteMark(ctx context.Context, arg DeleteMarkParams) error { - _, err := q.db.ExecContext(ctx, deleteMark, arg.Folder, arg.Login, arg.Msgid) +// DeleteMark unmark a message id for a login in a folder. +// +// DELETE FROM marks WHERE folder = ? AND login = ? AND msgid = ? +func (q *Queries) DeleteMark(ctx context.Context, folder string, login string, msgid int64) error { + _, err := q.db.ExecContext(ctx, deleteMark, folder, login, msgid) return err } @@ -132,28 +61,11 @@ const deleteMessage = `-- name: DeleteMessage :exec DELETE FROM messages WHERE id = ? AND folder = ? ` -type DeleteMessageParams struct { - ID int64 - Folder string -} - -func (q *Queries) DeleteMessage(ctx context.Context, arg DeleteMessageParams) error { - _, err := q.db.ExecContext(ctx, deleteMessage, arg.ID, arg.Folder) - return err -} - -const deleteSeen = `-- name: DeleteSeen :exec -DELETE FROM seen WHERE folder = ? AND login = ? AND msgid = ? -` - -type DeleteSeenParams struct { - Folder string - Login string - Msgid int64 -} - -func (q *Queries) DeleteSeen(ctx context.Context, arg DeleteSeenParams) error { - _, err := q.db.ExecContext(ctx, deleteSeen, arg.Folder, arg.Login, arg.Msgid) +// DeleteMessage removes a message by id and by folder. +// +// DELETE FROM messages WHERE id = ? AND folder = ? +func (q *Queries) DeleteMessage(ctx context.Context, iD int64, folder string) error { + _, err := q.db.ExecContext(ctx, deleteMessage, iD, folder) return err } @@ -161,6 +73,9 @@ const deleteUser = `-- name: DeleteUser :exec DELETE FROM users WHERE login = ? AND login != 'SYSTEM' ` +// DeleteUser removes the user (as long as the user isn't SYSTEM). +// +// DELETE FROM users WHERE login = ? AND login != 'SYSTEM' func (q *Queries) DeleteUser(ctx context.Context, login string) error { _, err := q.db.ExecContext(ctx, deleteUser, login) return err @@ -170,6 +85,9 @@ const getFolder = `-- name: GetFolder :one SELECT name, "always", alert, description, owner, system, expire, visibility, create_at, update_at FROM folders WHERE name = ? ` +// GetFolder get a folder by name. +// +// SELECT name, "always", alert, description, owner, system, expire, visibility, create_at, update_at FROM folders WHERE name = ? func (q *Queries) GetFolder(ctx context.Context, name string) (Folder, error) { row := q.db.QueryRowContext(ctx, getFolder, name) var i Folder @@ -188,71 +106,15 @@ func (q *Queries) GetFolder(ctx context.Context, name string) (Folder, error) { return i, err } -const getFolderAccess = `-- name: GetFolderAccess :one -SELECT visibility FROM folder_access WHERE login = ? AND folder = ? -` - -type GetFolderAccessParams struct { - Login string - Folder string -} - -func (q *Queries) GetFolderAccess(ctx context.Context, arg GetFolderAccessParams) (int64, error) { - row := q.db.QueryRowContext(ctx, getFolderAccess, arg.Login, arg.Folder) - var visibility int64 - err := row.Scan(&visibility) - return visibility, err -} - -const getFolderConfig = `-- name: GetFolderConfig :one -SELECT login, folder, "always", alert FROM folder_configs WHERE login = ? AND folder = ? -` - -type GetFolderConfigParams struct { - Login string - Folder string -} - -func (q *Queries) GetFolderConfig(ctx context.Context, arg GetFolderConfigParams) (FolderConfig, error) { - row := q.db.QueryRowContext(ctx, getFolderConfig, arg.Login, arg.Folder) - var i FolderConfig - err := row.Scan( - &i.Login, - &i.Folder, - &i.Always, - &i.Alert, - ) - return i, err -} - -const getMark = `-- name: GetMark :one -SELECT login, folder, msgid FROM marks WHERE folder = ? AND login = ? AND msgid = ? -` - -type GetMarkParams struct { - Folder string - Login string - Msgid int64 -} - -func (q *Queries) GetMark(ctx context.Context, arg GetMarkParams) (Mark, error) { - row := q.db.QueryRowContext(ctx, getMark, arg.Folder, arg.Login, arg.Msgid) - var i Mark - err := row.Scan(&i.Login, &i.Folder, &i.Msgid) - return i, err -} - const getMessage = `-- name: GetMessage :one SELECT id, folder, author, subject, message, permanent, system, shutdown, expiration, create_at, update_at FROM messages WHERE id = ? AND folder = ? ` -type GetMessageParams struct { - ID int64 - Folder string -} - -func (q *Queries) GetMessage(ctx context.Context, arg GetMessageParams) (Message, error) { - row := q.db.QueryRowContext(ctx, getMessage, arg.ID, arg.Folder) +// GetMessage gets a message by id and by folder. +// +// SELECT id, folder, author, subject, message, permanent, system, shutdown, expiration, create_at, update_at FROM messages WHERE id = ? AND folder = ? +func (q *Queries) GetMessage(ctx context.Context, iD int64, folder string) (Message, error) { + row := q.db.QueryRowContext(ctx, getMessage, iD, folder) var i Message err := row.Scan( &i.ID, @@ -270,32 +132,13 @@ func (q *Queries) GetMessage(ctx context.Context, arg GetMessageParams) (Message return i, err } -const getSeen = `-- name: GetSeen :one -SELECT login, folder, msgid, create_at FROM seen WHERE folder = ? AND login = ? AND msgid = ? -` - -type GetSeenParams struct { - Folder string - Login string - Msgid int64 -} - -func (q *Queries) GetSeen(ctx context.Context, arg GetSeenParams) (Seen, error) { - row := q.db.QueryRowContext(ctx, getSeen, arg.Folder, arg.Login, arg.Msgid) - var i Seen - err := row.Scan( - &i.Login, - &i.Folder, - &i.Msgid, - &i.CreateAt, - ) - return i, err -} - const getSystem = `-- name: GetSystem :one SELECT name, default_expire, expire_limit FROM system LIMIT 1 ` +// GetSystem gets the row from the system folder. +// +// SELECT name, default_expire, expire_limit FROM system LIMIT 1 func (q *Queries) GetSystem(ctx context.Context) (System, error) { row := q.db.QueryRowContext(ctx, getSystem) var i System @@ -303,139 +146,13 @@ func (q *Queries) GetSystem(ctx context.Context) (System, error) { return i, err } -const listFolderAccess = `-- name: ListFolderAccess :many -SELECT login, folder, visibility FROM folder_access WHERE folder = ? -` - -func (q *Queries) ListFolderAccess(ctx context.Context, folder string) ([]FolderAccess, error) { - rows, err := q.db.QueryContext(ctx, listFolderAccess, folder) - if err != nil { - return nil, err - } - defer rows.Close() - var items []FolderAccess - for rows.Next() { - var i FolderAccess - if err := rows.Scan(&i.Login, &i.Folder, &i.Visibility); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Close(); err != nil { - return nil, err - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - -const listFolderConfig = `-- name: ListFolderConfig :many -SELECT login, folder, "always", alert FROM folder_configs -` - -func (q *Queries) ListFolderConfig(ctx context.Context) ([]FolderConfig, error) { - rows, err := q.db.QueryContext(ctx, listFolderConfig) - if err != nil { - return nil, err - } - defer rows.Close() - var items []FolderConfig - for rows.Next() { - var i FolderConfig - if err := rows.Scan( - &i.Login, - &i.Folder, - &i.Always, - &i.Alert, - ); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Close(); err != nil { - return nil, err - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - -const listFolders = `-- name: ListFolders :many -SELECT name, "always", alert, description, owner, system, expire, visibility, create_at, update_at FROM folders -` - -func (q *Queries) ListFolders(ctx context.Context) ([]Folder, error) { - rows, err := q.db.QueryContext(ctx, listFolders) - if err != nil { - return nil, err - } - defer rows.Close() - var items []Folder - for rows.Next() { - var i Folder - if err := rows.Scan( - &i.Name, - &i.Always, - &i.Alert, - &i.Description, - &i.Owner, - &i.System, - &i.Expire, - &i.Visibility, - &i.CreateAt, - &i.UpdateAt, - ); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Close(); err != nil { - return nil, err - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - -const listMark = `-- name: ListMark :many -SELECT login, folder, msgid FROM marks WHERE folder = ? AND login = ? -` - -type ListMarkParams struct { - Folder string - Login string -} - -func (q *Queries) ListMark(ctx context.Context, arg ListMarkParams) ([]Mark, error) { - rows, err := q.db.QueryContext(ctx, listMark, arg.Folder, arg.Login) - if err != nil { - return nil, err - } - defer rows.Close() - var items []Mark - for rows.Next() { - var i Mark - if err := rows.Scan(&i.Login, &i.Folder, &i.Msgid); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Close(); err != nil { - return nil, err - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - const listMessageIDs = `-- name: ListMessageIDs :many SELECT id FROM messages WHERE folder = ? ORDER BY id ` +// ListMessageIDs list all message IDs in a specific folder. +// +// SELECT id FROM messages WHERE folder = ? ORDER BY id func (q *Queries) ListMessageIDs(ctx context.Context, folder string) ([]int64, error) { rows, err := q.db.QueryContext(ctx, listMessageIDs, folder) if err != nil { @@ -463,6 +180,9 @@ const listMessages = `-- name: ListMessages :many SELECT id, folder, author, subject, message, permanent, system, shutdown, expiration, create_at, update_at FROM messages WHERE folder = ? ORDER BY id ` +// ListMessages list all messages in a specific folder. +// +// SELECT id, folder, author, subject, message, permanent, system, shutdown, expiration, create_at, update_at FROM messages WHERE folder = ? ORDER BY id func (q *Queries) ListMessages(ctx context.Context, folder string) ([]Message, error) { rows, err := q.db.QueryContext(ctx, listMessages, folder) if err != nil { @@ -498,42 +218,13 @@ func (q *Queries) ListMessages(ctx context.Context, folder string) ([]Message, e return items, nil } -const listSeen = `-- name: ListSeen :many -SELECT login, folder, msgid, create_at FROM seen -` - -func (q *Queries) ListSeen(ctx context.Context) ([]Seen, error) { - rows, err := q.db.QueryContext(ctx, listSeen) - if err != nil { - return nil, err - } - defer rows.Close() - var items []Seen - for rows.Next() { - var i Seen - if err := rows.Scan( - &i.Login, - &i.Folder, - &i.Msgid, - &i.CreateAt, - ); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Close(); err != nil { - return nil, err - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - const listUsers = `-- name: ListUsers :many SELECT login, name, admin, moderator, disabled, prompt, signature, last_activity, last_login, create_at, update_at FROM users ` +// ListUsers get a list of all users. +// +// SELECT login, name, admin, moderator, disabled, prompt, signature, last_activity, last_login, create_at, update_at FROM users func (q *Queries) ListUsers(ctx context.Context) ([]User, error) { rows, err := q.db.QueryContext(ctx, listUsers) if err != nil { @@ -576,14 +267,14 @@ INSERT INTO system (rowid, name, default_expire, expire_limit) SET name = ?1, default_expire = ?2, expire_limit = ?3 ` -type SetSystemParams struct { - Name string - DefaultExpire int64 - ExpireLimit int64 -} - -func (q *Queries) SetSystem(ctx context.Context, arg SetSystemParams) error { - _, err := q.db.ExecContext(ctx, setSystem, arg.Name, arg.DefaultExpire, arg.ExpireLimit) +// SetSystem sets the system info. The system folder only has a single row. +// +// INSERT INTO system (rowid, name, default_expire, expire_limit) +// VALUES (1, ?1, ?2, ?3) +// ON CONFLICT(rowid) DO UPDATE +// SET name = ?1, default_expire = ?2, expire_limit = ?3 +func (q *Queries) SetSystem(ctx context.Context, name string, defaultExpire int64, expireLimit int64) error { + _, err := q.db.ExecContext(ctx, setSystem, name, defaultExpire, expireLimit) return err } @@ -593,13 +284,13 @@ INSERT INTO folder_access (login, folder, visibility) VALUES (?1, ?2, ?3) SET visibility = ?3 ` -type UpdateFolderAccessParams struct { - Login string - Folder string - Visibility int64 -} - -func (q *Queries) UpdateFolderAccess(ctx context.Context, arg UpdateFolderAccessParams) error { - _, err := q.db.ExecContext(ctx, updateFolderAccess, arg.Login, arg.Folder, arg.Visibility) +// UpdateFolderAccess update folder visibility for a given login and +// folder. +// +// INSERT INTO folder_access (login, folder, visibility) VALUES (?1, ?2, ?3) +// ON CONFLICT(login, folder) DO UPDATE +// SET visibility = ?3 +func (q *Queries) UpdateFolderAccess(ctx context.Context, login string, folder string, visibility int64) error { + _, err := q.db.ExecContext(ctx, updateFolderAccess, login, folder, visibility) return err } diff --git a/storage/system.sql.go b/storage/system.sql.go index 91aebac..6f82ad6 100644 --- a/storage/system.sql.go +++ b/storage/system.sql.go @@ -18,6 +18,9 @@ type GetExpireRow struct { ExpireLimit int64 } +// GetExpire get the default expiration value and limit for the system. +// +// SELECT default_expire, expire_limit FROM system WHERE rowid = 1 func (q *Queries) GetExpire(ctx context.Context) (GetExpireRow, error) { row := q.db.QueryRowContext(ctx, getExpire) var i GetExpireRow @@ -29,6 +32,9 @@ const updateDefaultExpire = `-- name: UpdateDefaultExpire :exec UPDATE system SET default_expire = ? WHERE rowid = 1 ` +// UpdateDefaultExpire update the default expiration value for the system. +// +// UPDATE system SET default_expire = ? WHERE rowid = 1 func (q *Queries) UpdateDefaultExpire(ctx context.Context, defaultExpire int64) error { _, err := q.db.ExecContext(ctx, updateDefaultExpire, defaultExpire) return err @@ -38,6 +44,9 @@ const updateExpireLimit = `-- name: UpdateExpireLimit :exec UPDATE system SET expire_limit = ? WHERE rowid = 1 ` +// UpdateExpireLimit update the default expiration limit for the system. +// +// UPDATE system SET expire_limit = ? WHERE rowid = 1 func (q *Queries) UpdateExpireLimit(ctx context.Context, expireLimit int64) error { _, err := q.db.ExecContext(ctx, updateExpireLimit, expireLimit) return err diff --git a/storage/users.sql.go b/storage/users.sql.go index 8ca3608..ac8fff5 100644 --- a/storage/users.sql.go +++ b/storage/users.sql.go @@ -25,6 +25,13 @@ type AddUserParams struct { Disabled int64 } +// AddUser adds the user. +// +// INSERT INTO users +// (login, name, admin, disabled, last_activity, last_login) +// VALUES +// (?, ?, ?, ?, '1970-01-01', '1970-01-01') +// RETURNING login, name, admin, moderator, disabled, prompt, signature, last_activity, last_login, create_at, update_at func (q *Queries) AddUser(ctx context.Context, arg AddUserParams) (User, error) { row := q.db.QueryRowContext(ctx, addUser, arg.Login, @@ -58,6 +65,9 @@ type GetLastLoginRow struct { LastLogin time.Time } +// GetLastLogin gets the login and last_login time for all users. +// +// SELECT login, last_login FROM users ORDER BY login func (q *Queries) GetLastLogin(ctx context.Context) ([]GetLastLoginRow, error) { rows, err := q.db.QueryContext(ctx, getLastLogin) if err != nil { @@ -90,6 +100,10 @@ type GetLastLoginByEnabledRow struct { LastLogin time.Time } +// GetLastLoginByEnabled gets the login and last_login time for all users +// with a given disabled setting ordered by login. +// +// SELECT login, last_login FROM users WHERE disabled = ? ORDER BY login func (q *Queries) GetLastLoginByEnabled(ctx context.Context, disabled int64) ([]GetLastLoginByEnabledRow, error) { rows, err := q.db.QueryContext(ctx, getLastLoginByEnabled, disabled) if err != nil { @@ -122,6 +136,10 @@ type GetLastLoginByLoginRow struct { LastLogin time.Time } +// GetLastLoginByLogin gets the login and last_login time for all users +// ordered by login. +// +// SELECT login, last_login FROM users WHERE login = ? ORDER BY login func (q *Queries) GetLastLoginByLogin(ctx context.Context, login string) (GetLastLoginByLoginRow, error) { row := q.db.QueryRowContext(ctx, getLastLoginByLogin, login) var i GetLastLoginByLoginRow @@ -133,6 +151,9 @@ const getUser = `-- name: GetUser :one SELECT login, name, admin, moderator, disabled, prompt, signature, last_activity, last_login, create_at, update_at FROM users WHERE login = ? ` +// GetUser gets the user by login. +// +// SELECT login, name, admin, moderator, disabled, prompt, signature, last_activity, last_login, create_at, update_at FROM users WHERE login = ? func (q *Queries) GetUser(ctx context.Context, login string) (User, error) { row := q.db.QueryRowContext(ctx, getUser, login) var i User @@ -156,6 +177,9 @@ const isUserAdmin = `-- name: IsUserAdmin :one SELECT admin FROM users WHERE login = ? ` +// IsUserAdmin returns the admin setting for the user. +// +// SELECT admin FROM users WHERE login = ? func (q *Queries) IsUserAdmin(ctx context.Context, login string) (int64, error) { row := q.db.QueryRowContext(ctx, isUserAdmin, login) var admin int64 @@ -167,13 +191,12 @@ const updateUserAdmin = `-- name: UpdateUserAdmin :exec UPDATE users SET admin = ? WHERE login = ? AND login != 'SYSTEM' ` -type UpdateUserAdminParams struct { - Admin int64 - Login string -} - -func (q *Queries) UpdateUserAdmin(ctx context.Context, arg UpdateUserAdminParams) error { - _, err := q.db.ExecContext(ctx, updateUserAdmin, arg.Admin, arg.Login) +// UpdateUserAdmin updates the admin setting for the user (excluding +// the SYSTEM user). +// +// UPDATE users SET admin = ? WHERE login = ? AND login != 'SYSTEM' +func (q *Queries) UpdateUserAdmin(ctx context.Context, admin int64, login string) error { + _, err := q.db.ExecContext(ctx, updateUserAdmin, admin, login) return err } @@ -184,14 +207,14 @@ INSERT INTO folder_configs (login, folder, alert) SET login = ?1, folder = ?2, alert = ?3 ` -type UpdateUserAlertParams struct { - Login string - Folder string - Alert int64 -} - -func (q *Queries) UpdateUserAlert(ctx context.Context, arg UpdateUserAlertParams) error { - _, err := q.db.ExecContext(ctx, updateUserAlert, arg.Login, arg.Folder, arg.Alert) +// UpdateUserAlert set user's alert setting for a folder. +// +// INSERT INTO folder_configs (login, folder, alert) +// VALUES (?1, ?2, ?3) +// ON CONFLICT(login, folder) DO UPDATE +// SET login = ?1, folder = ?2, alert = ?3 +func (q *Queries) UpdateUserAlert(ctx context.Context, login string, folder string, alert int64) error { + _, err := q.db.ExecContext(ctx, updateUserAlert, login, folder, alert) return err } @@ -199,13 +222,12 @@ const updateUserDisabled = `-- name: UpdateUserDisabled :exec UPDATE users SET disabled = ? WHERE login = ? AND login != 'SYSTEM' ` -type UpdateUserDisabledParams struct { - Disabled int64 - Login string -} - -func (q *Queries) UpdateUserDisabled(ctx context.Context, arg UpdateUserDisabledParams) error { - _, err := q.db.ExecContext(ctx, updateUserDisabled, arg.Disabled, arg.Login) +// UpdateUserDisabled updates the disabled setting for the user (excluding +// the SYSTEM user). +// +// UPDATE users SET disabled = ? WHERE login = ? AND login != 'SYSTEM' +func (q *Queries) UpdateUserDisabled(ctx context.Context, disabled int64, login string) error { + _, err := q.db.ExecContext(ctx, updateUserDisabled, disabled, login) return err } @@ -214,6 +236,11 @@ UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE login = ? AND login != 'SY RETURNING last_login ` +// UpdateUserLastLogin set user's last_login time for the user (excluding +// the SYSTEM user). +// +// UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE login = ? AND login != 'SYSTEM' +// RETURNING last_login func (q *Queries) UpdateUserLastLogin(ctx context.Context, login string) (time.Time, error) { row := q.db.QueryRowContext(ctx, updateUserLastLogin, login) var last_login time.Time @@ -225,13 +252,12 @@ const updateUserMod = `-- name: UpdateUserMod :exec UPDATE users SET moderator = ? WHERE login = ? AND login != 'SYSTEM' ` -type UpdateUserModParams struct { - Moderator int64 - Login string -} - -func (q *Queries) UpdateUserMod(ctx context.Context, arg UpdateUserModParams) error { - _, err := q.db.ExecContext(ctx, updateUserMod, arg.Moderator, arg.Login) +// UpdateUserMod set user's moderator setting for the user (excluding +// the SYSTEM user). +// +// UPDATE users SET moderator = ? WHERE login = ? AND login != 'SYSTEM' +func (q *Queries) UpdateUserMod(ctx context.Context, moderator int64, login string) error { + _, err := q.db.ExecContext(ctx, updateUserMod, moderator, login) return err } @@ -239,13 +265,12 @@ const updateUserName = `-- name: UpdateUserName :exec UPDATE users SET name = ? WHERE login = ? AND login != 'SYSTEM' ` -type UpdateUserNameParams struct { - Name string - Login string -} - -func (q *Queries) UpdateUserName(ctx context.Context, arg UpdateUserNameParams) error { - _, err := q.db.ExecContext(ctx, updateUserName, arg.Name, arg.Login) +// UpdateUserName update user's name for a given login (excluding the +// SYSTEM user). +// +// UPDATE users SET name = ? WHERE login = ? AND login != 'SYSTEM' +func (q *Queries) UpdateUserName(ctx context.Context, name string, login string) error { + _, err := q.db.ExecContext(ctx, updateUserName, name, login) return err } @@ -253,12 +278,11 @@ const updateUserPrompt = `-- name: UpdateUserPrompt :exec UPDATE users SET prompt = ? WHERE login = ? AND login != 'SYSTEM' ` -type UpdateUserPromptParams struct { - Prompt int64 - Login string -} - -func (q *Queries) UpdateUserPrompt(ctx context.Context, arg UpdateUserPromptParams) error { - _, err := q.db.ExecContext(ctx, updateUserPrompt, arg.Prompt, arg.Login) +// UpdateUserPrompt set user's prompt setting for the user (excluding +// the SYSTEM user). +// +// UPDATE users SET prompt = ? WHERE login = ? AND login != 'SYSTEM' +func (q *Queries) UpdateUserPrompt(ctx context.Context, prompt int64, login string) error { + _, err := q.db.ExecContext(ctx, updateUserPrompt, prompt, login) return err } diff --git a/this/alert.go b/this/alert.go index 456802f..5f405ba 100644 --- a/this/alert.go +++ b/this/alert.go @@ -22,20 +22,14 @@ func ShowBroadcast() { } fmt.Println("BROADCAST MSG END") } - Q.UpdateLastActivity(ctx, storage.UpdateLastActivityParams{ - LastActivity: User.LastActivity, - Login: User.Login, - }) + Q.UpdateLastActivity(ctx, User.LastActivity, User.Login) Q.ReapBroadcasts(ctx) } // ShowAlerts print alert messages. func ShowAlerts(doReadNew bool) { ctx := storage.Context() - alerts, err := Q.GetAlertMessages(ctx, storage.GetAlertMessagesParams{ - CreateAt: User.LastActivity, - Login: User.Name, - }) + alerts, err := Q.GetAlertMessages(ctx, User.Name, User.LastActivity) if err != nil { fmt.Printf("ERROR: failed to get alerts: %s.\n", err) } @@ -50,11 +44,7 @@ func ShowAlerts(doReadNew bool) { fmt.Fprintf(shownew, "%s", alerts[i].Message.AlertLine()) case storage.AlertReadNew: if doReadNew { - Q.SetMessageSeen(ctx, storage.SetMessageSeenParams{ - Login: User.Login, - Folder: Folder.Name, - Msgid: alerts[i].Message.ID, - }) + Q.SetMessageSeen(ctx, User.Login, Folder.Name, alerts[i].Message.ID) fmt.Fprintf(readnew, "%s\n", alerts[i].Message.String()) } } diff --git a/this/this.go b/this/this.go index cc795cd..548bfee 100644 --- a/this/this.go +++ b/this/this.go @@ -90,10 +90,7 @@ func StartThis(login string) error { return err } User.Name = name - Q.UpdateUserName(ctx, storage.UpdateUserNameParams{ - Name: User.Name, - Login: User.Login, - }) + Q.UpdateUserName(ctx, User.Name, User.Login) } if User.Disabled == 1 { return errors.New("User is disabled") @@ -105,16 +102,9 @@ func StartThis(login string) error { } ReadFirstCall = true - MsgID, err = Q.NextMsgid(ctx, storage.NextMsgidParams{ - Folder: Folder.Name, - ID: 0, - Login: User.Login, - }) + MsgID, err = Q.NextMsgid(ctx, Folder.Name, 0, User.Login) if MsgID == 0 { - MsgID, err = Q.NextMsgidIgnoringSeen(ctx, storage.NextMsgidIgnoringSeenParams{ - Folder: Folder.Name, - ID: 0, - }) + MsgID, err = Q.NextMsgidIgnoringSeen(ctx, Folder.Name, 0) } ShowAlerts(true) -- GitLab