forked from
tangled.org/core
Monorepo for Tangled
2.5 kB
90 lines
1package db
2
3import (
4 "database/sql"
5 "log"
6 "time"
7
8 "tangled.org/core/appview/models"
9)
10
11// GetOnboarding returns the onboarding record for a did, or (nil, nil) if none exists.
12func GetOnboarding(e Execer, did string) (*models.Onboarding, error) {
13 query := `select did, step, status, created, updated from onboarding where did = ?`
14 row := e.QueryRow(query, did)
15
16 var o models.Onboarding
17 var status string
18 var created, updated string
19 err := row.Scan(&o.Did, &o.Step, &status, &created, &updated)
20 if err == sql.ErrNoRows {
21 return nil, nil
22 }
23 if err != nil {
24 return nil, err
25 }
26
27 o.Status = models.OnboardingStatus(status)
28 if t, err := time.Parse(time.RFC3339, created); err == nil {
29 o.Created = t
30 }
31 if t, err := time.Parse(time.RFC3339, updated); err == nil {
32 o.Updated = t
33 }
34
35 return &o, nil
36}
37
38func UpsertOnboarding(e Execer, o *models.Onboarding) error {
39 query := `
40 insert into onboarding (did, step, status, updated)
41 values (?, ?, ?, strftime('%Y-%m-%dT%H:%M:%SZ', 'now'))
42 on conflict(did) do update set
43 step = excluded.step,
44 status = excluded.status,
45 updated = excluded.updated
46 `
47 _, err := e.Exec(query, o.Did, o.Step, string(o.Status))
48 return err
49}
50
51// AdvanceOnboardingStep moves the stored step forward to the given step. It is
52// monotonic: it never decreases the step, so navigating back to an earlier page
53// and re-submitting does not regress recorded progress.
54func AdvanceOnboardingStep(e Execer, did string, step int) error {
55 _, err := e.Exec(
56 `update onboarding set step = ?, updated = strftime('%Y-%m-%dT%H:%M:%SZ', 'now') where did = ? and step < ?`,
57 step, did, step,
58 )
59 return err
60}
61
62func CompleteOnboarding(e Execer, did string) error {
63 _, err := e.Exec(
64 `update onboarding set status = ?, step = ?, updated = strftime('%Y-%m-%dT%H:%M:%SZ', 'now') where did = ?`,
65 string(models.OnboardingCompleted), models.OnboardingStepDone, did,
66 )
67 return err
68}
69
70func SkipOnboarding(e Execer, did string) error {
71 _, err := e.Exec(
72 `update onboarding set status = ?, updated = strftime('%Y-%m-%dT%H:%M:%SZ', 'now') where did = ?`,
73 string(models.OnboardingSkipped), did,
74 )
75 return err
76}
77
78// IsOnboarding reports whether a did has an in-progress onboarding record.
79func IsOnboarding(e Execer, did string) (bool, error) {
80 var exists bool
81 err := e.QueryRow(
82 `select exists(select 1 from onboarding where did = ? and status = 'in_progress')`,
83 did,
84 ).Scan(&exists)
85 if err != nil {
86 log.Println("failed to check onboarding status", err)
87 return false, err
88 }
89 return exists, nil
90}