switch mentions from _inbox tags to mentions relation
This commit is contained in:
90
db/node.go
90
db/node.go
@@ -67,6 +67,18 @@ func (db *DB) resolveUserRef(tx *sql.Tx, ref string) (string, error) {
|
||||
return db.ensureUser(tx, ref)
|
||||
}
|
||||
|
||||
func (db *DB) GetUserByUsername(username string) (string, error) {
|
||||
var id string
|
||||
err := db.QueryRow(`
|
||||
SELECT n.id FROM nodes n
|
||||
JOIN tags t ON n.id = t.node_id
|
||||
WHERE n.title = ? AND t.tag = '_type::user'`, username).Scan(&id)
|
||||
if err == sql.ErrNoRows {
|
||||
return "", nil
|
||||
}
|
||||
return id, err
|
||||
}
|
||||
|
||||
func (db *DB) ensureNamespace(tx *sql.Tx, name string) (string, error) {
|
||||
var existingID string
|
||||
err := tx.QueryRow(`
|
||||
@@ -123,8 +135,9 @@ type UpdateParams struct {
|
||||
AddRels, RemoveRels map[models.RelType][]string
|
||||
}
|
||||
type ListFilter struct {
|
||||
TagPrefixes []string
|
||||
Assignee string
|
||||
TagPrefixes []string
|
||||
Assignee string
|
||||
MentionsUser string
|
||||
}
|
||||
|
||||
func (db *DB) CreateNode(p CreateParams) (*models.Node, error) {
|
||||
@@ -142,17 +155,17 @@ func (db *DB) CreateNode(p CreateParams) (*models.Node, error) {
|
||||
}
|
||||
|
||||
for _, m := range parse.Mentions(p.Title + " " + p.Content) {
|
||||
if _, err := db.ensureUser(tx, m); err != nil {
|
||||
userID, err := db.resolveUserRef(tx, m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := tx.Exec("INSERT INTO rels (from_id, to_id, rel_type) VALUES (?, ?, ?)", id, userID, models.RelMentions); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, t := range append(p.Tags, parse.Mentions(p.Title+" "+p.Content)...) {
|
||||
if !strings.HasPrefix(t, "_") && strings.HasPrefix(t, "@") {
|
||||
if _, err = tx.Exec("INSERT INTO tags (node_id, tag) VALUES (?, ?)", id, "_inbox::"+t[1:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if _, err := tx.Exec("INSERT INTO tags (node_id, tag) VALUES (?, ?)", id, t); err != nil {
|
||||
for _, t := range p.Tags {
|
||||
if _, err := tx.Exec("INSERT INTO tags (node_id, tag) VALUES (?, ?)", id, t); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -188,24 +201,28 @@ func (db *DB) UpdateNode(id string, p UpdateParams) error {
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
var currentTitle, currentContent string
|
||||
err = tx.QueryRow("SELECT title, COALESCE(content, '') FROM nodes WHERE id = ?", id).Scan(¤tTitle, ¤tContent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
upd := func(col, val string) error {
|
||||
_, err := tx.Exec("UPDATE nodes SET "+col+" = ? WHERE id = ?", val, id)
|
||||
return err
|
||||
}
|
||||
newTitle, newContent := currentTitle, currentContent
|
||||
if p.Title != nil {
|
||||
if err := upd("title", *p.Title); err != nil {
|
||||
return err
|
||||
}
|
||||
newTitle = *p.Title
|
||||
}
|
||||
if p.Content != nil {
|
||||
if err := upd("content", *p.Content); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, m := range parse.Mentions(*p.Content) {
|
||||
if _, err := db.ensureUser(tx, m); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
newContent = *p.Content
|
||||
}
|
||||
if p.DueDate != nil {
|
||||
if err := upd("due_date", *p.DueDate); err != nil {
|
||||
@@ -218,6 +235,46 @@ func (db *DB) UpdateNode(id string, p UpdateParams) error {
|
||||
}
|
||||
}
|
||||
|
||||
if p.Title != nil || p.Content != nil {
|
||||
newMentions := parse.Mentions(newTitle + " " + newContent)
|
||||
rows, err := tx.Query("SELECT to_id FROM rels WHERE from_id = ? AND rel_type = ?", id, models.RelMentions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
existingMentionIDs := make(map[string]bool)
|
||||
for rows.Next() {
|
||||
var uid string
|
||||
if err := rows.Scan(&uid); err != nil {
|
||||
rows.Close()
|
||||
return err
|
||||
}
|
||||
existingMentionIDs[uid] = true
|
||||
}
|
||||
rows.Close()
|
||||
|
||||
mentionedUserIDs := make(map[string]bool)
|
||||
for _, m := range newMentions {
|
||||
userID, err := db.resolveUserRef(tx, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mentionedUserIDs[userID] = true
|
||||
if !existingMentionIDs[userID] {
|
||||
if _, err := tx.Exec("INSERT INTO rels (from_id, to_id, rel_type) VALUES (?, ?, ?)", id, userID, models.RelMentions); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for uid := range existingMentionIDs {
|
||||
if !mentionedUserIDs[uid] {
|
||||
if _, err := tx.Exec("DELETE FROM rels WHERE from_id = ? AND to_id = ? AND rel_type = ?", id, uid, models.RelMentions); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, t := range p.RemoveTags {
|
||||
tx.Exec("DELETE FROM tags WHERE node_id = ? AND tag = ?", id, t)
|
||||
}
|
||||
@@ -315,6 +372,11 @@ func (db *DB) ListNodes(f ListFilter) ([]*models.Node, error) {
|
||||
conds = append(conds, "r_assign.to_id = ? AND r_assign.rel_type = ?")
|
||||
args = append(args, f.Assignee, models.RelAssignee)
|
||||
}
|
||||
if f.MentionsUser != "" {
|
||||
joins = append(joins, "JOIN rels r_mentions ON n.id = r_mentions.from_id")
|
||||
conds = append(conds, "r_mentions.to_id = ? AND r_mentions.rel_type = ?")
|
||||
args = append(args, f.MentionsUser, models.RelMentions)
|
||||
}
|
||||
|
||||
if len(joins) > 0 {
|
||||
q += " " + strings.Join(joins, " ") + " "
|
||||
|
||||
Reference in New Issue
Block a user