mirror of
https://github.com/usememos/memos.git
synced 2025-06-05 22:09:59 +02:00
chore: impl inbox store methods
This commit is contained in:
9
store/db/sqlite/common.go
Normal file
9
store/db/sqlite/common.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package sqlite
|
||||
|
||||
import "google.golang.org/protobuf/encoding/protojson"
|
||||
|
||||
var (
|
||||
protojsonUnmarshaler = protojson.UnmarshalOptions{
|
||||
DiscardUnknown: true,
|
||||
}
|
||||
)
|
@@ -2,26 +2,124 @@ package sqlite
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
// nolint
|
||||
func (d *DB) CreateInbox(ctx context.Context, create *store.Inbox) (*store.Inbox, error) {
|
||||
return nil, nil
|
||||
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}
|
||||
|
||||
stmt := "INSERT INTO inbox (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ") RETURNING `id`, `created_ts`"
|
||||
if err := d.db.QueryRowContext(ctx, stmt, args...).Scan(
|
||||
&create.ID,
|
||||
&create.CreatedTs,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return create, nil
|
||||
}
|
||||
|
||||
// nolint
|
||||
func (d *DB) ListInboxes(ctx context.Context, find *store.FindInbox) ([]*store.Inbox, error) {
|
||||
return nil, nil
|
||||
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)
|
||||
}
|
||||
|
||||
query := "SELECT `id`, `created_ts`, `sender_id`, `receiver_id`, `status`, `message` FROM `inbox` WHERE " + strings.Join(where, " AND ")
|
||||
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
|
||||
}
|
||||
|
||||
// nolint
|
||||
func (d *DB) UpdateInbox(ctx context.Context, update *store.UpdateInbox) (*store.Inbox, error) {
|
||||
return nil, nil
|
||||
set, args := []string{"status"}, []any{update.Status}
|
||||
args = append(args, update.ID)
|
||||
query := "UPDATE inbox SET " + strings.Join(set, " = ?, ") + " = ? WHERE id = ? RETURNING `id`, `created_ts`, `sender_id`, `receiver_id`, `status`, `message`"
|
||||
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
|
||||
}
|
||||
|
||||
// nolint
|
||||
func (d *DB) DeleteInbox(ctx context.Context, delete *store.DeleteInbox) error {
|
||||
result, err := d.db.ExecContext(ctx, "DELETE FROM inbox WHERE id = ?", delete.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := result.RowsAffected(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@@ -141,6 +141,6 @@ CREATE TABLE inbox (
|
||||
created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
|
||||
sender_id INTEGER NOT NULL,
|
||||
receiver_id INTEGER NOT NULL,
|
||||
status TEXT NOT NULL CHECK (status IN ('UNREAD', 'READ', 'ARCHIVED')) DEFAULT 'UNREAD',
|
||||
status TEXT NOT NULL,
|
||||
message TEXT NOT NULL DEFAULT '{}'
|
||||
);
|
||||
|
55
test/store/inbox_test.go
Normal file
55
test/store/inbox_test.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package teststore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
func TestInboxStore(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ts := NewTestingStore(ctx, t)
|
||||
user, err := createTestingHostUser(ctx, ts)
|
||||
require.NoError(t, err)
|
||||
const systemBotID int32 = 0
|
||||
create := &store.Inbox{
|
||||
SenderID: systemBotID,
|
||||
ReceiverID: user.ID,
|
||||
Status: store.UNREAD,
|
||||
Message: &storepb.InboxMessage{
|
||||
Title: "title",
|
||||
Content: "content",
|
||||
Link: "link",
|
||||
},
|
||||
}
|
||||
inbox, err := ts.CreateInbox(ctx, create)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, inbox)
|
||||
require.Equal(t, create.Message, inbox.Message)
|
||||
inboxes, err := ts.ListInboxes(ctx, &store.FindInbox{
|
||||
ReceiverID: &user.ID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(inboxes))
|
||||
require.Equal(t, inbox, inboxes[0])
|
||||
updatedInbox, err := ts.UpdateInbox(ctx, &store.UpdateInbox{
|
||||
ID: inbox.ID,
|
||||
Status: store.READ,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, updatedInbox)
|
||||
require.Equal(t, store.READ, updatedInbox.Status)
|
||||
err = ts.DeleteInbox(ctx, &store.DeleteInbox{
|
||||
ID: inbox.ID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
inboxes, err = ts.ListInboxes(ctx, &store.FindInbox{
|
||||
ReceiverID: &user.ID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(inboxes))
|
||||
}
|
Reference in New Issue
Block a user