diff --git a/internal/modules/storage/interface.go b/internal/modules/storage/interface.go index bf32db7..a471a5c 100644 --- a/internal/modules/storage/interface.go +++ b/internal/modules/storage/interface.go @@ -5,12 +5,12 @@ import "context" //go:generate mockgen -source=$GOFILE -destination=mocks/$GOFILE -package=mocks type User struct { - ChatID string - UserID string + ChatID string `sql:"chat_id"` + UserID string `sql:"user_id"` } type IStorage interface { - UpsertUser(ctx context.Context, user User) error - GetAllUsersByChatID(ctx context.Context, chatID string) ([]User, error) + UpsertUser(ctx context.Context, user *User) error + GetAllUsersByChatID(ctx context.Context, chatID string) ([]*User, error) Close() } diff --git a/internal/modules/storage/mocks/interface.go b/internal/modules/storage/mocks/interface.go index c4f56db..811e257 100644 --- a/internal/modules/storage/mocks/interface.go +++ b/internal/modules/storage/mocks/interface.go @@ -48,10 +48,10 @@ func (mr *MockIStorageMockRecorder) Close() *gomock.Call { } // GetAllUsersByChatID mocks base method. -func (m *MockIStorage) GetAllUsersByChatID(ctx context.Context, chatID string) ([]storage.User, error) { +func (m *MockIStorage) GetAllUsersByChatID(ctx context.Context, chatID string) ([]*storage.User, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAllUsersByChatID", ctx, chatID) - ret0, _ := ret[0].([]storage.User) + ret0, _ := ret[0].([]*storage.User) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -63,7 +63,7 @@ func (mr *MockIStorageMockRecorder) GetAllUsersByChatID(ctx, chatID interface{}) } // UpsertUser mocks base method. -func (m *MockIStorage) UpsertUser(ctx context.Context, user storage.User) error { +func (m *MockIStorage) UpsertUser(ctx context.Context, user *storage.User) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UpsertUser", ctx, user) ret0, _ := ret[0].(error) diff --git a/internal/modules/storage/postgres/postgres.go b/internal/modules/storage/postgres/postgres.go index af8a371..21d2989 100644 --- a/internal/modules/storage/postgres/postgres.go +++ b/internal/modules/storage/postgres/postgres.go @@ -21,13 +21,36 @@ func NewStoragePostgres(urlConnect string) (storage.IStorage, error) { return &storagePostgres{db: db}, nil } -func (s *storagePostgres) GetAllUsersByChatID(ctx context.Context, chatID string) ([]storage.User, error) { - // TODO: imptement - return nil, nil +func (s *storagePostgres) GetAllUsersByChatID(ctx context.Context, chatID string) ([]*storage.User, error) { + rows, err := s.db.Query(`select chat_id, user_id from users where chat_id = $1`, chatID) + if err != nil { + return nil, err + } + defer rows.Close() + var users []*storage.User + for rows.Next() { + user := &storage.User{} + err := rows.Scan(&user.ChatID, &user.UserID) + if err != nil { + return nil, err + } + users = append(users, user) + } + err = rows.Err() + if err != nil { + return nil, err + } + return users, nil } -func (s *storagePostgres) UpsertUser(ctx context.Context, user storage.User) error { - // TODO: imptement +func (s *storagePostgres) UpsertUser(ctx context.Context, user *storage.User) error { + stmt, err := s.db.Prepare(`insert into users (chat_id, user_id) select $1, $2 where not exists (select * FROM users WHERE chat_id = $1 and user_id = $2);`) + if err != nil { + return err + } + if _, err := stmt.Exec(user.ChatID, user.UserID); err != nil { + return err + } return nil } diff --git a/internal/services/bot/bot_all/bot.go b/internal/services/bot/bot_all/bot.go index 2160730..e7e2aa8 100644 --- a/internal/services/bot/bot_all/bot.go +++ b/internal/services/bot/bot_all/bot.go @@ -2,6 +2,7 @@ package bot_all import ( "context" + "fmt" "strings" "github.com/samber/lo" @@ -27,21 +28,21 @@ func NewBotAll( } func (bot *botAll) Process(ctx context.Context, msg *messenger.Message) error { - if err := bot.storage.UpsertUser(ctx, storage.User{ChatID: msg.ChatID, UserID: msg.UserID}); err != nil { + if err := bot.storage.UpsertUser(ctx, &storage.User{ChatID: msg.ChatID, UserID: msg.UserID}); err != nil { return err } - if !strings.Contains(msg.Text, "@all") { + if !strings.Contains(msg.Text, "@all") && !strings.Contains(msg.Text, "@все") && strings.ToLower(msg.Text) != "ау" { return nil } users, err := bot.storage.GetAllUsersByChatID(ctx, msg.ChatID) if err != nil { return err } - usernames := lo.FilterMap(users, func(item storage.User, _ int) (string, bool) { + usernames := lo.FilterMap(users, func(item *storage.User, _ int) (string, bool) { if item.UserID == msg.UserID { return "", false } - return item.UserID, true + return fmt.Sprintf("@%s", item.UserID), true }) if len(usernames) > 0 { bot.messenger.SendMessage( diff --git a/migrations/init.sql b/migrations/init.sql new file mode 100644 index 0000000..e7c4f4d --- /dev/null +++ b/migrations/init.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS users; +CREATE TABLE users ( + id SERIAL PRIMARY KEY, + chat_id TEXT NOT NULL, + user_id TEXT NOT NULL, + CONSTRAINT unique__chat_id__user_id UNIQUE (chat_id, user_id) +); \ No newline at end of file