switch namespaces from tags to relations with auto-creation
This commit is contained in:
79
db/node.go
79
db/node.go
@@ -67,6 +67,50 @@ func (db *DB) resolveUserRef(tx *sql.Tx, ref string) (string, error) {
|
||||
return db.ensureUser(tx, ref)
|
||||
}
|
||||
|
||||
func (db *DB) ensureNamespace(tx *sql.Tx, name 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::namespace'`, name).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, name, now, now); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if _, err := tx.Exec("INSERT INTO tags (node_id, tag) VALUES (?, '_type::namespace')", id); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if _, err := tx.Exec("INSERT INTO rels (from_id, to_id, rel_type) VALUES (?, ?, ?)",
|
||||
id, id, models.RelInNamespace); err != nil {
|
||||
return "", err
|
||||
}
|
||||
userID, err := db.resolveUserRef(tx, GetCurrentUser())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if _, err := tx.Exec("INSERT INTO rels (from_id, to_id, rel_type) VALUES (?, ?, ?)",
|
||||
id, userID, models.RelCreated); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (db *DB) resolveNamespaceRef(tx *sql.Tx, ref string) (string, error) {
|
||||
if exists, _ := db.NodeExists(ref); exists {
|
||||
return ref, nil
|
||||
}
|
||||
return db.ensureNamespace(tx, ref)
|
||||
}
|
||||
|
||||
type CreateParams struct {
|
||||
Title, Content, DueDate string
|
||||
Tags []string
|
||||
@@ -120,6 +164,12 @@ func (db *DB) CreateNode(p CreateParams) (*models.Node, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if rt == models.RelInNamespace {
|
||||
var err error
|
||||
if tgt, err = db.resolveNamespaceRef(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
|
||||
}
|
||||
@@ -187,6 +237,12 @@ func (db *DB) UpdateNode(id string, p UpdateParams) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if rt == models.RelInNamespace {
|
||||
var err error
|
||||
if tgt, err = db.resolveNamespaceRef(tx, tgt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
tx.Exec("INSERT OR IGNORE INTO rels (from_id, to_id, rel_type) VALUES (?, ?, ?)", id, tgt, rt)
|
||||
}
|
||||
}
|
||||
@@ -255,7 +311,9 @@ func (db *DB) ListNodes(f ListFilter) ([]*models.Node, error) {
|
||||
args = append(args, len(f.TagPrefixes))
|
||||
|
||||
if f.Assignee != "" {
|
||||
joins, conds, args = append(joins, "JOIN rels r_assign ON n.id = r_assign.from_id"), append(conds, "r_assign.to_id = ? AND r_assign.rel_type = ?"), append(args, f.Assignee, models.RelAssignee)
|
||||
joins = append(joins, "JOIN rels r_assign ON n.id = r_assign.from_id")
|
||||
conds = append(conds, "r_assign.to_id = ? AND r_assign.rel_type = ?")
|
||||
args = append(args, f.Assignee, models.RelAssignee)
|
||||
}
|
||||
|
||||
if len(joins) > 0 {
|
||||
@@ -309,22 +367,3 @@ func (db *DB) CanClose(id string) (bool, []string, error) {
|
||||
}
|
||||
return len(blocking) == 0, blocking, nil
|
||||
}
|
||||
|
||||
func (db *DB) GetSubtasks(parentID string) ([]*models.Node, error) {
|
||||
rows, err := db.Query("SELECT to_id FROM rels WHERE from_id = ? AND rel_type = ?", parentID, models.RelSubtask)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var nodes []*models.Node
|
||||
for rows.Next() {
|
||||
var id string
|
||||
rows.Scan(&id)
|
||||
if n, err := db.NodeByID(id); err == nil {
|
||||
nodes = append(nodes, n)
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user