2021-06-10 16:51:56 +01:00
|
|
|
package state
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
|
|
"github.com/lib/pq"
|
|
|
|
)
|
|
|
|
|
|
|
|
// TypingTable stores who is currently typing
|
|
|
|
// TODO: If 2 users are in the same room and 1 is on a laggy synchotron, we'll flip flop who is
|
|
|
|
// typing with live / stale data. Maybe do this per user per room?
|
|
|
|
type TypingTable struct {
|
|
|
|
db *sqlx.DB
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewTypingTable(db *sqlx.DB) *TypingTable {
|
|
|
|
// make sure tables are made
|
|
|
|
db.MustExec(`
|
2021-06-10 17:08:06 +01:00
|
|
|
CREATE SEQUENCE IF NOT EXISTS syncv3_typing_seq;
|
2021-06-10 16:51:56 +01:00
|
|
|
CREATE TABLE IF NOT EXISTS syncv3_typing (
|
2021-06-10 17:08:06 +01:00
|
|
|
stream_id BIGINT NOT NULL DEFAULT nextval('syncv3_typing_seq'),
|
2021-06-10 16:51:56 +01:00
|
|
|
room_id TEXT NOT NULL PRIMARY KEY,
|
|
|
|
user_ids TEXT[] NOT NULL
|
|
|
|
);
|
|
|
|
`)
|
|
|
|
return &TypingTable{db}
|
|
|
|
}
|
|
|
|
|
2021-07-23 14:06:18 +01:00
|
|
|
func (t *TypingTable) SelectHighestID() (id int64, err error) {
|
|
|
|
var result sql.NullInt64
|
|
|
|
err = t.db.QueryRow(
|
|
|
|
`SELECT MAX(stream_id) FROM syncv3_typing`,
|
|
|
|
).Scan(&result)
|
|
|
|
if result.Valid {
|
|
|
|
id = result.Int64
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-08-03 16:25:57 +01:00
|
|
|
func (t *TypingTable) SetTyping(roomID string, userIDs []string) (position int64, err error) {
|
2021-06-10 16:51:56 +01:00
|
|
|
if userIDs == nil {
|
|
|
|
userIDs = []string{}
|
|
|
|
}
|
2021-06-10 17:08:06 +01:00
|
|
|
err = t.db.QueryRow(`
|
|
|
|
INSERT INTO syncv3_typing(room_id, user_ids) VALUES($1, $2)
|
|
|
|
ON CONFLICT (room_id) DO UPDATE SET user_ids = $2, stream_id = nextval('syncv3_typing_seq') RETURNING stream_id`,
|
|
|
|
roomID, pq.Array(userIDs),
|
2021-08-03 16:25:57 +01:00
|
|
|
).Scan(&position)
|
|
|
|
return position, err
|
2021-06-10 16:51:56 +01:00
|
|
|
}
|
|
|
|
|
2021-08-03 17:43:41 +01:00
|
|
|
func (t *TypingTable) Typing(roomID string, fromStreamIDExcl, toStreamIDIncl int64) (userIDs []string, latest int64, err error) {
|
2021-06-10 16:51:56 +01:00
|
|
|
var userIDsArray pq.StringArray
|
2021-06-10 17:08:06 +01:00
|
|
|
err = t.db.QueryRow(
|
2021-08-03 17:43:41 +01:00
|
|
|
`SELECT stream_id, user_ids FROM syncv3_typing WHERE room_id=$1 AND stream_id > $2 AND stream_id <= $3`,
|
|
|
|
roomID, fromStreamIDExcl, toStreamIDIncl,
|
2021-07-23 11:37:33 +01:00
|
|
|
).Scan(&latest, &userIDsArray)
|
2021-06-10 16:51:56 +01:00
|
|
|
if err == sql.ErrNoRows {
|
|
|
|
err = nil
|
|
|
|
}
|
2021-07-23 11:37:33 +01:00
|
|
|
return userIDsArray, latest, err
|
2021-06-10 16:51:56 +01:00
|
|
|
}
|