144 lines
3.7 KiB
Go
144 lines
3.7 KiB
Go
package postgres
|
|
|
|
import (
|
|
"slices"
|
|
"time"
|
|
|
|
"git.tek.govt.hu/dowerx/chat/server/model"
|
|
"git.tek.govt.hu/dowerx/chat/server/util"
|
|
"github.com/jmoiron/sqlx"
|
|
)
|
|
|
|
type MessageDAO struct {
|
|
pgDAO
|
|
}
|
|
|
|
// Create a new message
|
|
func (d MessageDAO) Create(message model.Message) (int, *util.ChatError) {
|
|
rows, err := d.db.NamedQuery(`insert into "message" ("sender_id", "channel_id", "time", "content") values (:sender_id, :channel_id, :time, :content) returning "id"`, &message)
|
|
if err != nil {
|
|
return 0, util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
|
}
|
|
|
|
if !rows.Next() {
|
|
return 0, &util.ChatError{Message: "failed to insert new message", Code: util.DATABASE_QUERY_FAULT}
|
|
}
|
|
|
|
var id int
|
|
if rows.Scan(&id) != nil {
|
|
return 0, &util.ChatError{Message: "failed to return new message id", Code: util.DATABASE_QUERY_FAULT}
|
|
}
|
|
|
|
return int(id), util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
|
}
|
|
|
|
// Read returns a message by ID
|
|
func (d MessageDAO) Read(id int) (model.Message, *util.ChatError) {
|
|
message := model.Message{}
|
|
|
|
var rows *sqlx.Rows
|
|
var err error
|
|
rows, err = d.db.NamedQuery(`select * from "message" where "id" = $1`, id)
|
|
if err != nil {
|
|
return message, util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
|
}
|
|
defer rows.Close()
|
|
|
|
if !rows.Next() {
|
|
return message, &util.ChatError{Message: "", Code: util.NOT_FOUND}
|
|
}
|
|
|
|
err = rows.StructScan(&message)
|
|
return message, util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
|
}
|
|
|
|
// List all messages in channel by ID or name
|
|
func (d MessageDAO) List(channel model.Channel, from time.Time, limit int) ([]model.Message, *util.ChatError) {
|
|
|
|
type queryInfo struct {
|
|
ID int `db:"id"`
|
|
Name string `db:"name"`
|
|
From time.Time `db:"from"`
|
|
Limit int `db:"limit"`
|
|
}
|
|
|
|
var rows *sqlx.Rows
|
|
var err error
|
|
|
|
if channel.ID != 0 {
|
|
rows, err = d.db.NamedQuery(
|
|
`select
|
|
"m"."id" as "id",
|
|
"u"."username" as "sender_name",
|
|
"m"."channel_id" as "channel_id",
|
|
"m"."time" as "time",
|
|
"m"."content" as "content"
|
|
from "message" as "m"
|
|
inner join "user" "u" on "u"."id" = "m"."sender_id"
|
|
where "m"."channel_id" = :id and "m"."time" < :from
|
|
order by "time" desc
|
|
limit :limit`,
|
|
&queryInfo{ID: channel.ID, From: from, Limit: limit})
|
|
} else {
|
|
rows, err = d.db.NamedQuery(
|
|
`select
|
|
"m"."id" as "id",
|
|
"u"."username" as "sender_name",
|
|
"m"."channel_id" as "channel_id",
|
|
"m"."time" as "time",
|
|
"m"."content" as "content"
|
|
from "message" as "m"
|
|
inner join "user" "u" on "u"."id" = "m"."sender_id"
|
|
inner join "channel" "c" on "c"."id" = "m"."channel_id"
|
|
where "c"."name" = :name and "m"."time" < :from
|
|
order by "time" desc
|
|
limit :limit`,
|
|
&queryInfo{Name: channel.Name, From: from, Limit: limit})
|
|
}
|
|
|
|
if err != nil {
|
|
return nil, util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
|
}
|
|
defer rows.Close()
|
|
|
|
messages := make([]model.Message, 0)
|
|
|
|
for rows.Next() {
|
|
message := model.Message{}
|
|
|
|
err = rows.StructScan(&message)
|
|
if err != nil {
|
|
break
|
|
}
|
|
|
|
messages = append(messages, message)
|
|
}
|
|
|
|
slices.Reverse(messages)
|
|
return messages, util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
|
}
|
|
|
|
// Update the contents and time of a Message with the given ID
|
|
func (d MessageDAO) Update(message model.Message) *util.ChatError {
|
|
_, err := d.db.NamedExec(`update "message" set "content" = :content, "time" = :time where "id" = :id`, &message)
|
|
return util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
|
}
|
|
|
|
// Delete a message by ID
|
|
func (d MessageDAO) Delete(id int) *util.ChatError {
|
|
var err error
|
|
_, err = d.db.NamedExec(`delete from "message" where "id" = $1`, id)
|
|
return util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
|
}
|
|
|
|
func MakeMessageDAO() (MessageDAO, *util.ChatError) {
|
|
dao := MessageDAO{}
|
|
conn, err := getDatabase()
|
|
if err != nil {
|
|
return dao, err
|
|
}
|
|
|
|
dao.db = conn
|
|
return dao, nil
|
|
}
|