-
-
Notifications
You must be signed in to change notification settings - Fork 115
/
persons.go
75 lines (69 loc) · 2.23 KB
/
persons.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package timeliner
import (
"database/sql"
"fmt"
)
// getPerson returns the person mapped to userID on service.
// If the person does not exist, it is created.
func (t *Timeline) getPerson(dataSourceID, userID, name string) (Person, error) {
// first, load the person
var p Person
err := t.db.QueryRow(`SELECT persons.id, persons.name
FROM persons, person_identities
WHERE person_identities.data_source_id=?
AND person_identities.user_id=?
AND persons.id = person_identities.person_id
LIMIT 1`, dataSourceID, userID).Scan(&p.ID, &p.Name)
if err == sql.ErrNoRows {
// person does not exist; create this mapping - TODO: do in a transaction
p = Person{Name: name}
res, err := t.db.Exec(`INSERT INTO persons (name) VALUES (?)`, p.Name)
if err != nil {
return Person{}, fmt.Errorf("adding new person: %v", err)
}
p.ID, err = res.LastInsertId()
if err != nil {
return Person{}, fmt.Errorf("getting person ID: %v", err)
}
_, err = t.db.Exec(`INSERT OR IGNORE INTO person_identities
(person_id, data_source_id, user_id) VALUES (?, ?, ?)`,
p.ID, dataSourceID, userID)
if err != nil {
return Person{}, fmt.Errorf("adding new person identity mapping: %v", err)
}
} else if err != nil {
return Person{}, fmt.Errorf("selecting person identity: %v", err)
}
// now get all the person's identities
rows, err := t.db.Query(`SELECT id, person_id, data_source_id, user_id
FROM person_identities WHERE person_id=?`, p.ID)
if err != nil {
return Person{}, fmt.Errorf("selecting person's known identities: %v", err)
}
defer rows.Close()
for rows.Next() {
var ident PersonIdentity
err := rows.Scan(&ident.ID, &ident.PersonID, &ident.DataSourceID, &ident.UserID)
if err != nil {
return Person{}, fmt.Errorf("loading person's identity: %v", err)
}
p.Identities = append(p.Identities, ident)
}
if err = rows.Err(); err != nil {
return Person{}, fmt.Errorf("scanning identity rows: %v", err)
}
return p, nil
}
// Person represents a person.
type Person struct {
ID int64
Name string
Identities []PersonIdentity
}
// PersonIdentity is a way to map a user ID on a service to a person.
type PersonIdentity struct {
ID int64
PersonID string
DataSourceID string
UserID string
}