Store role list in database and convert role mentions into a readable format

This commit is contained in:
Tulir Asokan
2022-07-08 15:31:03 +03:00
parent 668a77e30d
commit 2611cbfa34
8 changed files with 246 additions and 9 deletions

View File

@@ -22,6 +22,7 @@ type Database struct {
Reaction *ReactionQuery
Emoji *EmojiQuery
Guild *GuildQuery
Role *RoleQuery
}
func New(baseDB *dbutil.Database) *Database {
@@ -59,6 +60,10 @@ func New(baseDB *dbutil.Database) *Database {
db: db,
log: db.Log.Sub("Guild"),
}
db.Role = &RoleQuery{
db: db,
log: db.Log.Sub("Role"),
}
return db
}

114
database/role.go Normal file
View File

@@ -0,0 +1,114 @@
package database
import (
"database/sql"
"errors"
log "maunium.net/go/maulogger/v2"
"maunium.net/go/mautrix/util/dbutil"
"github.com/bwmarrin/discordgo"
)
type RoleQuery struct {
db *Database
log log.Logger
}
// language=postgresql
const (
roleSelect = "SELECT dc_guild_id, dcid, name, icon, mentionable, managed, hoist, color, position, permissions FROM role"
roleUpsert = `
INSERT INTO role (dc_guild_id, dcid, name, icon, mentionable, managed, hoist, color, position, permissions)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
ON CONFLICT (dc_guild_id, dcid) DO UPDATE
SET name=excluded.name, icon=excluded.icon, mentionable=excluded.mentionable, managed=excluded.managed,
hoist=excluded.hoist, color=excluded.color, position=excluded.position, permissions=excluded.permissions
`
roleDelete = "DELETE FROM role WHERE dc_guild_id=$1 AND dcid=$2"
)
func (rq *RoleQuery) New() *Role {
return &Role{
db: rq.db,
log: rq.log,
}
}
func (rq *RoleQuery) GetByID(guildID, dcid string) *Role {
query := roleSelect + " WHERE dc_guild_id=$1 AND dcid=$2"
return rq.New().Scan(rq.db.QueryRow(query, guildID, dcid))
}
func (rq *RoleQuery) DeleteByID(guildID, dcid string) {
_, err := rq.db.Exec("DELETE FROM role WHERE dc_guild_id=$1 AND dcid=$2", guildID, dcid)
if err != nil {
rq.log.Warnfln("Failed to delete %s/%s: %v", guildID, dcid, err)
panic(err)
}
}
func (rq *RoleQuery) GetAll(guildID string) []*Role {
rows, err := rq.db.Query(roleSelect+" WHERE dc_guild_id=$1", guildID)
if err != nil {
rq.log.Errorfln("Failed to query roles of %s: %v", guildID, err)
return nil
}
var roles []*Role
for rows.Next() {
role := rq.New().Scan(rows)
if role != nil {
roles = append(roles, role)
}
}
return roles
}
type Role struct {
db *Database
log log.Logger
GuildID string
discordgo.Role
}
func (r *Role) Scan(row dbutil.Scannable) *Role {
var icon sql.NullString
err := row.Scan(&r.GuildID, &r.ID, &r.Name, &icon, &r.Mentionable, &r.Managed, &r.Hoist, &r.Color, &r.Position, &r.Permissions)
if err != nil {
if !errors.Is(err, sql.ErrNoRows) {
r.log.Errorln("Database scan failed:", err)
panic(err)
}
return nil
}
r.Icon = icon.String
return r
}
func (r *Role) Upsert(txn dbutil.Execable) {
if txn == nil {
txn = r.db
}
_, err := txn.Exec(roleUpsert, r.GuildID, r.ID, r.Name, strPtr(r.Icon), r.Mentionable, r.Managed, r.Hoist, r.Color, r.Position, r.Permissions)
if err != nil {
r.log.Warnfln("Failed to insert %s/%s: %v", r.GuildID, r.ID, err)
panic(err)
}
}
func (r *Role) Delete(txn dbutil.Execable) {
if txn == nil {
txn = r.db
}
_, err := txn.Exec(roleDelete, r.GuildID, r.Icon)
if err != nil {
r.log.Warnfln("Failed to delete %s/%s: %v", r.GuildID, r.ID, err)
panic(err)
}
}

View File

@@ -1,4 +1,4 @@
-- v0 -> v5: Latest revision
-- v0 -> v7: Latest revision
CREATE TABLE guild (
dcid TEXT PRIMARY KEY,
@@ -74,7 +74,9 @@ CREATE TABLE "user" (
discord_token TEXT,
management_room TEXT,
space_room TEXT,
dm_space_room TEXT
dm_space_room TEXT,
read_state_version INTEGER NOT NULL DEFAULT 0
);
CREATE TABLE user_portal (
@@ -126,3 +128,22 @@ CREATE TABLE emoji (
discord_name TEXT,
matrix_url TEXT
);
CREATE TABLE role (
dc_guild_id TEXT,
dcid TEXT,
name TEXT NOT NULL,
icon TEXT,
mentionable BOOLEAN NOT NULL,
managed BOOLEAN NOT NULL,
hoist BOOLEAN NOT NULL,
color INTEGER NOT NULL,
position INTEGER NOT NULL,
permissions BIGINT NOT NULL,
PRIMARY KEY (dc_guild_id, dcid),
CONSTRAINT role_guild_fkey FOREIGN KEY (dc_guild_id) REFERENCES guild (dcid) ON DELETE CASCADE
);

View File

@@ -0,0 +1,19 @@
-- v7: Store role info
CREATE TABLE role (
dc_guild_id TEXT,
dcid TEXT,
name TEXT NOT NULL,
icon TEXT,
mentionable BOOLEAN NOT NULL,
managed BOOLEAN NOT NULL,
hoist BOOLEAN NOT NULL,
color INTEGER NOT NULL,
position INTEGER NOT NULL,
permissions BIGINT NOT NULL,
PRIMARY KEY (dc_guild_id, dcid),
CONSTRAINT role_guild_fkey FOREIGN KEY (dc_guild_id) REFERENCES guild (dcid) ON DELETE CASCADE
);