Author: Kevin Schoon [me@kevinschoon.com]
Hash: d231e031d2b6c40389d5256e91dd97ee171d3105
Timestamp: Tue, 31 May 2022 19:14:53 +0000 (2 years ago)

+120 -110 +/-3 browse
continued refactoring
1diff --git a/pkg/hierarchy/database.go b/pkg/hierarchy/database.go
2index 1f649dd..aa94544 100644
3--- a/pkg/hierarchy/database.go
4+++ b/pkg/hierarchy/database.go
5 @@ -3,8 +3,12 @@ package hierarchy
6 import (
7 "database/sql"
8 _ "embed"
9+ "encoding/json"
10+ "io/ioutil"
11+ "os"
12
13 _ "github.com/mattn/go-sqlite3"
14+ "kevinschoon.com/hierarchy/pkg/config"
15 )
16
17 //go:embed migrate/init.sql
18 @@ -39,3 +43,103 @@ func With(path string, fn func(*sql.Tx) error) error {
19 return tx.Commit()
20 }
21
22+ type dbNote struct {
23+ ID int64
24+ Name string
25+ Content string
26+ Parent int64
27+ }
28+
29+ func Edit(cfg config.Config, notePath string) error {
30+ np := ReadPath(notePath)
31+ return With(cfg.Database, func(tx *sql.Tx) error {
32+ raw, err := ioutil.ReadAll(os.Stdin)
33+ if err != nil {
34+ return err
35+ }
36+ var parent *int64
37+ if np.Parent() != "" {
38+ parent = new(int64)
39+ row := tx.QueryRow(`
40+ SELECT id FROM notes
41+ WHERE name = ?
42+ `, np.Parent())
43+ err = row.Scan(&parent)
44+ if err != nil {
45+ return err
46+ }
47+ }
48+ _, err = tx.Exec(`
49+ INSERT INTO notes (name, parent, content)
50+ VALUES (?, ?, ?)
51+ `, np.Name(), parent, string(raw))
52+ return err
53+ })
54+ }
55+
56+ // TODO: garbage
57+ func linkNotes2(dbNotes []*dbNote, notes []*Note) []*Note {
58+ remaining := []*dbNote{}
59+ for _, note := range dbNotes {
60+ if note.Parent == 0 {
61+ notes = append(notes, &Note{
62+ ID: note.ID,
63+ Name: note.Name,
64+ Content: note.Content,
65+ Parent: nil,
66+ })
67+ continue
68+ } else {
69+ remaining = append(remaining, note)
70+ }
71+ }
72+ nextRemaining := []*dbNote{}
73+ loop:
74+ for _, note := range remaining {
75+ for _, other := range notes {
76+ if note.Parent == other.ID {
77+ n := &Note{
78+ ID: note.ID,
79+ Name: note.Name,
80+ Content: note.Content,
81+ Parent: other,
82+ }
83+ other.Children = append(other.Children, n)
84+ continue loop
85+ }
86+ }
87+ nextRemaining = append(nextRemaining, note)
88+ }
89+ if len(remaining) > 0 {
90+ notes = linkNotes2(nextRemaining, notes)
91+ }
92+ return notes
93+ }
94+
95+ func LoadNotes(cfg config.Config) (notes []*Note, err error) {
96+ return notes, With(cfg.Database, func(tx *sql.Tx) error {
97+ var dbNotes []*dbNote
98+ rows, err := tx.Query(`
99+ SELECT
100+ id, name, parent, content
101+ FROM notes
102+ `)
103+ if err != nil {
104+ return err
105+ }
106+ for rows.Next() {
107+ parentId := new(int64)
108+ note := &dbNote{}
109+ err = rows.Scan(&note.ID, &note.Name, &parentId, &note.Content)
110+ if err != nil {
111+ return err
112+ }
113+ if parentId != nil {
114+ note.Parent = *parentId
115+ }
116+ dbNotes = append(dbNotes, note)
117+ }
118+ notes = linkNotes2(dbNotes, nil)
119+ return nil
120+ })
121+ }
122 diff --git a/pkg/hierarchy/editor.go b/pkg/hierarchy/editor.go
123index bc67a3c..87bc58e 100644
124--- a/pkg/hierarchy/editor.go
125+++ b/pkg/hierarchy/editor.go
126 @@ -1 +1,17 @@
127 package hierarchy
128+
129+ import (
130+ "os"
131+
132+ "kevinschoon.com/hierarchy/pkg/config"
133+ )
134+
135+ func OpenWithEditor(cfg config.Config, note *Note) error {
136+ editor := cfg.Editor
137+ if editor == "" {
138+ editor = os.Getenv("EDITOR")
139+ }
140+ if editor == "" {
141+ editor = "vim"
142+ }
143+ }
144 diff --git a/pkg/hierarchy/hierarchy.go b/pkg/hierarchy/hierarchy.go
145index 5786eca..bc67a3c 100644
146--- a/pkg/hierarchy/hierarchy.go
147+++ b/pkg/hierarchy/hierarchy.go
148 @@ -1,111 +1 @@
149 package hierarchy
150-
151- import (
152- "database/sql"
153- "encoding/json"
154- "io/ioutil"
155- "os"
156-
157- "kevinschoon.com/hierarchy/pkg/config"
158- )
159-
160- type dbNote struct {
161- ID int64
162- Name string
163- Content string
164- Parent int64
165- }
166-
167- func Edit(cfg config.Config, notePath string) error {
168- np := ReadPath(notePath)
169- return With(cfg.Database, func(tx *sql.Tx) error {
170- raw, err := ioutil.ReadAll(os.Stdin)
171- if err != nil {
172- return err
173- }
174- var parent *int64
175- if np.Parent() != "" {
176- parent = new(int64)
177- row := tx.QueryRow(`
178- SELECT id FROM notes
179- WHERE name = ?
180- `, np.Parent())
181- err = row.Scan(&parent)
182- if err != nil {
183- return err
184- }
185- }
186- _, err = tx.Exec(`
187- INSERT INTO notes (name, parent, content)
188- VALUES (?, ?, ?)
189- `, np.Name(), parent, string(raw))
190- return err
191- })
192- }
193-
194- // TODO: garbage
195- func linkNotes2(dbNotes []*dbNote, notes []*Note) []*Note {
196- remaining := []*dbNote{}
197- for _, note := range dbNotes {
198- if note.Parent == 0 {
199- notes = append(notes, &Note{
200- ID: note.ID,
201- Name: note.Name,
202- Content: note.Content,
203- Parent: nil,
204- })
205- continue
206- } else {
207- remaining = append(remaining, note)
208- }
209- }
210- nextRemaining := []*dbNote{}
211- loop:
212- for _, note := range remaining {
213- for _, other := range notes {
214- if note.Parent == other.ID {
215- n := &Note{
216- ID: note.ID,
217- Name: note.Name,
218- Content: note.Content,
219- Parent: other,
220- }
221- other.Children = append(other.Children, n)
222- continue loop
223- }
224- }
225- nextRemaining = append(nextRemaining, note)
226- }
227- if len(remaining) > 0 {
228- notes = linkNotes2(nextRemaining, notes)
229- }
230- return notes
231- }
232-
233- func LoadNotes(cfg config.Config) error {
234- return With(cfg.Database, func(tx *sql.Tx) error {
235- var notes []*dbNote
236- rows, err := tx.Query(`
237- SELECT
238- id, name, parent, content
239- FROM notes
240- `)
241- if err != nil {
242- return err
243- }
244- for rows.Next() {
245- parentId := new(int64)
246- note := &dbNote{}
247- err = rows.Scan(&note.ID, &note.Name, &parentId, &note.Content)
248- if err != nil {
249- return err
250- }
251- if parentId != nil {
252- note.Parent = *parentId
253- }
254- notes = append(notes, note)
255- }
256- linked := linkNotes2(notes, nil)
257- return json.NewEncoder(os.Stdout).Encode(linked)
258- })
259- }