chore: impl inbox store methods

pull/2450/head
Steven 2 years ago
parent 93b8e2211c
commit 4ea78fa1a2

@ -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 '{}'
);

@ -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))
}
Loading…
Cancel
Save