auto-create users on mention and resolve user refs in relationships
This commit is contained in:
56
db/node.go
56
db/node.go
@@ -35,6 +35,38 @@ func (db *DB) generateUniqueID() string {
|
||||
}
|
||||
}
|
||||
|
||||
func (db *DB) ensureUser(tx *sql.Tx, username string) (string, error) {
|
||||
var existingID string
|
||||
err := tx.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(&existingID)
|
||||
if err == nil {
|
||||
return existingID, nil
|
||||
}
|
||||
if err != sql.ErrNoRows {
|
||||
return "", err
|
||||
}
|
||||
|
||||
id := db.generateUniqueID()
|
||||
now := time.Now().UTC().Format(time.RFC3339)
|
||||
if _, err := tx.Exec("INSERT INTO nodes (id, title, created_at, updated_at) VALUES (?, ?, ?, ?)",
|
||||
id, username, now, now); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if _, err := tx.Exec("INSERT INTO tags (node_id, tag) VALUES (?, '_type::user')", id); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (db *DB) resolveUserRef(tx *sql.Tx, ref string) (string, error) {
|
||||
if exists, _ := db.NodeExists(ref); exists {
|
||||
return ref, nil
|
||||
}
|
||||
return db.ensureUser(tx, ref)
|
||||
}
|
||||
|
||||
type CreateParams struct {
|
||||
Title, Content, DueDate string
|
||||
Tags []string
|
||||
@@ -64,6 +96,13 @@ func (db *DB) CreateNode(p CreateParams) (*models.Node, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, m := range parse.Mentions(p.Title + " " + p.Content) {
|
||||
if _, err := db.ensureUser(tx, m); 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 {
|
||||
@@ -75,6 +114,12 @@ func (db *DB) CreateNode(p CreateParams) (*models.Node, error) {
|
||||
}
|
||||
for rt, tgts := range p.Rels {
|
||||
for _, tgt := range tgts {
|
||||
if rt == models.RelAssignee || rt == models.RelCreated {
|
||||
var err error
|
||||
if tgt, err = db.resolveUserRef(tx, tgt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if _, err := tx.Exec("INSERT INTO rels (from_id, to_id, rel_type) VALUES (?, ?, ?)", id, tgt, rt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -106,6 +151,11 @@ func (db *DB) UpdateNode(id string, p UpdateParams) error {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
if p.DueDate != nil {
|
||||
if err := upd("due_date", *p.DueDate); err != nil {
|
||||
@@ -131,6 +181,12 @@ func (db *DB) UpdateNode(id string, p UpdateParams) error {
|
||||
}
|
||||
for rt, tgts := range p.AddRels {
|
||||
for _, tgt := range tgts {
|
||||
if rt == models.RelAssignee || rt == models.RelCreated {
|
||||
var err error
|
||||
if tgt, err = db.resolveUserRef(tx, tgt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
tx.Exec("INSERT OR IGNORE INTO rels (from_id, to_id, rel_type) VALUES (?, ?, ?)", id, tgt, rt)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user