2023-10-27 01:10:19 +08:00
package sqlite
import (
"context"
2024-01-11 21:29:22 +08:00
"database/sql"
2023-10-27 08:17:58 +08:00
"strings"
2023-10-27 01:10:19 +08:00
2023-10-27 08:17:58 +08:00
"github.com/pkg/errors"
"google.golang.org/protobuf/encoding/protojson"
storepb "github.com/usememos/memos/proto/gen/store"
2023-10-27 01:10:19 +08:00
"github.com/usememos/memos/store"
)
func ( d * DB ) CreateInbox ( ctx context . Context , create * store . Inbox ) ( * store . Inbox , error ) {
2023-10-27 08:17:58 +08:00
messageString := "{}"
if create . Message != nil {
bytes , err := protojson . Marshal ( create . Message )
if err != nil {
return nil , errors . Wrap ( err , "failed to marshal inbox message" )
}
messageString = string ( bytes )
}
fields := [ ] string { "`sender_id`" , "`receiver_id`" , "`status`" , "`message`" }
placeholder := [ ] string { "?" , "?" , "?" , "?" }
args := [ ] any { create . SenderID , create . ReceiverID , create . Status , messageString }
2023-10-28 09:44:52 +08:00
stmt := "INSERT INTO `inbox` (" + strings . Join ( fields , ", " ) + ") VALUES (" + strings . Join ( placeholder , ", " ) + ") RETURNING `id`, `created_ts`"
2023-10-27 08:17:58 +08:00
if err := d . db . QueryRowContext ( ctx , stmt , args ... ) . Scan (
& create . ID ,
& create . CreatedTs ,
) ; err != nil {
return nil , err
}
return create , nil
2023-10-27 01:10:19 +08:00
}
2023-10-28 00:08:42 +08:00
func ( d * DB ) ListInboxes ( ctx context . Context , find * store . FindInbox ) ( [ ] * store . Inbox , error ) {
2023-10-27 08:17:58 +08:00
where , args := [ ] string { "1 = 1" } , [ ] any { }
if find . ID != nil {
where , args = append ( where , "`id` = ?" ) , append ( args , * find . ID )
}
if find . SenderID != nil {
where , args = append ( where , "`sender_id` = ?" ) , append ( args , * find . SenderID )
}
if find . ReceiverID != nil {
where , args = append ( where , "`receiver_id` = ?" ) , append ( args , * find . ReceiverID )
}
if find . Status != nil {
where , args = append ( where , "`status` = ?" ) , append ( args , * find . Status )
}
2023-10-28 09:44:52 +08:00
query := "SELECT `id`, `created_ts`, `sender_id`, `receiver_id`, `status`, `message` FROM `inbox` WHERE " + strings . Join ( where , " AND " ) + " ORDER BY `created_ts` DESC"
2023-10-27 08:17:58 +08:00
rows , err := d . db . QueryContext ( ctx , query , args ... )
if err != nil {
return nil , err
}
defer rows . Close ( )
list := [ ] * store . Inbox { }
for rows . Next ( ) {
inbox := & store . Inbox { }
var messageBytes [ ] byte
if err := rows . Scan (
& inbox . ID ,
& inbox . CreatedTs ,
& inbox . SenderID ,
& inbox . ReceiverID ,
& inbox . Status ,
& messageBytes ,
) ; err != nil {
return nil , err
}
message := & storepb . InboxMessage { }
if err := protojsonUnmarshaler . Unmarshal ( messageBytes , message ) ; err != nil {
return nil , err
}
inbox . Message = message
list = append ( list , inbox )
}
if err := rows . Err ( ) ; err != nil {
return nil , err
}
return list , nil
2023-10-27 01:10:19 +08:00
}
func ( d * DB ) UpdateInbox ( ctx context . Context , update * store . UpdateInbox ) ( * store . Inbox , error ) {
2023-10-28 09:44:52 +08:00
set , args := [ ] string { "`status` = ?" } , [ ] any { update . Status . String ( ) }
2023-10-27 08:17:58 +08:00
args = append ( args , update . ID )
2023-10-28 09:44:52 +08:00
query := "UPDATE `inbox` SET " + strings . Join ( set , ", " ) + " WHERE `id` = ? RETURNING `id`, `created_ts`, `sender_id`, `receiver_id`, `status`, `message`"
2023-10-27 08:17:58 +08:00
inbox := & store . Inbox { }
var messageBytes [ ] byte
if err := d . db . QueryRowContext ( ctx , query , args ... ) . Scan (
& inbox . ID ,
& inbox . CreatedTs ,
& inbox . SenderID ,
& inbox . ReceiverID ,
& inbox . Status ,
& messageBytes ,
) ; err != nil {
return nil , err
}
message := & storepb . InboxMessage { }
if err := protojsonUnmarshaler . Unmarshal ( messageBytes , message ) ; err != nil {
return nil , err
}
inbox . Message = message
return inbox , nil
2023-10-27 01:10:19 +08:00
}
func ( d * DB ) DeleteInbox ( ctx context . Context , delete * store . DeleteInbox ) error {
2023-10-28 09:44:52 +08:00
result , err := d . db . ExecContext ( ctx , "DELETE FROM `inbox` WHERE `id` = ?" , delete . ID )
2023-10-27 08:17:58 +08:00
if err != nil {
return err
}
if _ , err := result . RowsAffected ( ) ; err != nil {
return err
}
2023-10-27 01:10:19 +08:00
return nil
}
2024-01-11 21:29:22 +08:00
func vacuumInbox ( ctx context . Context , tx * sql . Tx ) error {
stmt := `
DELETE FROM
inbox
WHERE
sender_id NOT IN (
SELECT
id
FROM
user
) `
_ , err := tx . ExecContext ( ctx , stmt )
if err != nil {
return err
}
return nil
}