detached e7259a0

Delete changes.txt

commit
e7259a0ebdab899ff265137cd1311296c983e052
author
Brice Nema · · 2023-09-15 20:43 UTC
committer
GitHub · · 2023-09-15 20:43 UTC
parent
ecbc08c
signature
unsigned
1 file · +0 -326
D changes.txt +0 -326
@@ -1,326 +0,0 @@
1-diff --git a/:memory b/:memory
2-new file mode 100644
3-index 0000000..9760229
4-Binary files /dev/null and b/:memory differ
5-diff --git a/cmd/main.go b/cmd/main.go
6-index 6a95d32..b8e2cd4 100644
7---- a/cmd/main.go
8-+++ b/cmd/main.go
9-@@ -4,17 +4,30 @@ import (
10- "fmt"
11- "log/slog"
12-
13-+ "github.com/labstack/echo/v4"
14-+
15- "github.com/bnema/gordon/internal/app"
16- "github.com/bnema/gordon/internal/httpserve"
17-- "github.com/labstack/echo/v4"
18- )
19-
20- func main() {
21- a := app.NewApp()
22-+
23-+ // Initialize database
24-+ db, err := app.InitializeDB(a)
25-+ if err != nil {
26-+ slog.Error("Failed to load database", err)
27-+ } else {
28-+ slog.Info("Database loaded")
29-+ }
30-+
31-+ fmt.Println(db)
32-+
33- e := echo.New()
34- e.HideBanner = true
35- e.HidePort = true
36- e = httpserve.RegisterRoutes(e, a)
37- slog.Info("Starting server", "port", a.HttpPort)
38- slog.Error("Server error", e.Start(fmt.Sprintf(":%d", a.HttpPort)))
39-+
40- }
41-diff --git a/go.mod b/go.mod
42-index 35e2d3c..8a3ac59 100644
43---- a/go.mod
44-+++ b/go.mod
45-@@ -24,6 +24,7 @@ require (
46- github.com/gorilla/securecookie v1.1.1 // indirect
47- github.com/gorilla/sessions v1.2.1 // indirect
48- github.com/klauspost/compress v1.16.7 // indirect
49-+ github.com/kr/text v0.1.0 // indirect
50- github.com/labstack/gommon v0.4.0 // indirect
51- github.com/mattn/go-colorable v0.1.13 // indirect
52- github.com/mattn/go-isatty v0.0.19 // indirect
53-@@ -35,6 +36,7 @@ require (
54- github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect
55- github.com/opencontainers/runc v1.1.9 // indirect
56- github.com/pkg/errors v0.9.1 // indirect
57-+ github.com/rogpeppe/go-internal v1.11.0 // indirect
58- github.com/sirupsen/logrus v1.9.3 // indirect
59- github.com/valyala/bytebufferpool v1.0.0 // indirect
60- github.com/valyala/fasttemplate v1.2.2 // indirect
61-@@ -45,5 +47,6 @@ require (
62- golang.org/x/text v0.11.0 // indirect
63- golang.org/x/time v0.3.0 // indirect
64- golang.org/x/tools v0.7.0 // indirect
65-+ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
66- gotest.tools/v3 v3.5.0 // indirect
67- )
68-diff --git a/go.sum b/go.sum
69-index 7b9b857..17b0bcd 100644
70---- a/go.sum
71-+++ b/go.sum
72-@@ -39,6 +39,11 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
73- github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
74- github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
75- github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
76-+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
77-+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
78-+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
79-+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
80-+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
81- github.com/labstack/echo-contrib v0.15.0 h1:9K+oRU265y4Mu9zpRDv3X+DGTqUALY6oRHCSZZKCRVU=
82- github.com/labstack/echo-contrib v0.15.0/go.mod h1:lei+qt5CLB4oa7VHTE0yEfQSEB9XTJI1LUqko9UWvo4=
83- github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4=
84-@@ -72,6 +77,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
85- github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
86- github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
87- github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
88-+github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
89-+github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
90- github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
91- github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
92- github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
93-@@ -153,8 +160,9 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
94- golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
95- golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
96- golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
97--gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
98- gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
99-+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
100-+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
101- gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
102- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
103- gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
104-diff --git a/internal/app/app.go b/internal/app/app.go
105-index c6f49ac..1dd44b8 100644
106---- a/internal/app/app.go
107-+++ b/internal/app/app.go
108-@@ -27,6 +27,7 @@ const (
109- type App struct {
110- TemplateFS fs.FS
111- PublicFS fs.FS
112-+ DB interface{}
113- BuildVersion string
114- BuildDir string
115- DBDir string
116-diff --git a/internal/app/sqlite.go b/internal/app/sqlite.go
117-index 9f1b1ab..ddc6a1e 100644
118---- a/internal/app/sqlite.go
119-+++ b/internal/app/sqlite.go
120-@@ -5,58 +5,78 @@ import (
121- "database/sql"
122- "fmt"
123- "os"
124-+ "path/filepath"
125-
126-- sqlite3 "github.com/mattn/go-sqlite3"
127-+ "github.com/bnema/gordon/internal/database/migrate"
128-+ "github.com/mattn/go-sqlite3"
129- )
130-
131--// Initialize in-memory SQLite database and returns its connection
132--func InitDB() (db *sql.DB, err error) {
133-- db, err = sql.Open("sqlite3", "file::memory?cache=shared")
134-- if err != nil {
135-- return nil, fmt.Errorf("failed to open in-memory database: %v", err)
136-- }
137-- return
138--}
139--
140--// CloseDB closes the database connection and backs up the in-memory database to disk
141--func CloseDB(db *sql.DB, a *App) error {
142-- if err := BackupDB(db, a); err != nil {
143-- return err
144-- }
145-+// InitializeDB initializes the SQLite database. If a database file exists on disk, it loads it into memory.
146-+// Otherwise, it creates a new in-memory database and bootstraps it.
147-+func InitializeDB(a *App) (*sql.DB, error) {
148-+ dbfp := a.GetDBFilePath()
149-
150-- if err := db.Close(); err != nil {
151-- return fmt.Errorf("failed to close database: %v", err)
152-+ // Check if the directory exists, if not create it
153-+ dir := filepath.Dir(a.DBDir)
154-+ fmt.Println("dir", dir)
155-+ if _, err := os.Stat(dir); os.IsNotExist(err) {
156-+ err = os.MkdirAll(dir, 0755)
157-+ if err != nil {
158-+ return nil, fmt.Errorf("failed to create directory: %v", err)
159-+ }
160- }
161-
162-- return nil
163--}
164-+ // If the database file doesn't exist on disk
165-+ if _, err := os.Stat(dbfp); os.IsNotExist(err) {
166-+ memDB, err := initInMemoryDB()
167-+ if err != nil {
168-+ return nil, err
169-+ }
170-
171--// LoadDBIntoMemory loads the database from disk into memory
172--func LoadDBIntoMemory(a *App) (*sql.DB, error) {
173-- dbfp := a.GetDBFilePath()
174-+ // Run the bootstrap
175-+ RunBootstrap(memDB)
176-
177-- if _, err := os.Stat(dbfp); err != nil {
178-- return nil, nil
179-+ // Explicitly backup the in-memory database to disk
180-+ err = BackupDB(memDB, a)
181-+ if err != nil {
182-+ return nil, fmt.Errorf("failed to backup in-memory database to disk: %v", err)
183-+ }
184- }
185-
186-- memDB, err := InitDB()
187-+ memDB, err := initInMemoryDB()
188- if err != nil {
189- return nil, err
190- }
191--
192- diskDB, err := sql.Open("sqlite3", dbfp)
193- if err != nil {
194- return nil, fmt.Errorf("failed to open database file: %v", err)
195- }
196-+ defer diskDB.Close()
197-
198- if err := transferData(diskDB, memDB); err != nil {
199- return nil, err
200- }
201--
202- return memDB, nil
203- }
204-
205--// transferData transfers data from srcDB to dstDB
206-+func initInMemoryDB() (*sql.DB, error) {
207-+ db, err := sql.Open("sqlite3", "file::memory?cache=shared")
208-+ if err != nil {
209-+ return nil, fmt.Errorf("failed to open in-memory database: %v", err)
210-+ }
211-+ return db, nil
212-+}
213-+
214-+func CloseAndBackupDB(db *sql.DB, a *App) error {
215-+ if err := BackupDB(db, a); err != nil {
216-+ return err
217-+ }
218-+ if err := db.Close(); err != nil {
219-+ return fmt.Errorf("failed to close database: %v", err)
220-+ }
221-+ return nil
222-+}
223-+
224- func transferData(srcDB, dstDB *sql.DB) error {
225- srcConn, err := srcDB.Conn(context.Background())
226- if err != nil {
227-@@ -74,35 +94,50 @@ func transferData(srcDB, dstDB *sql.DB) error {
228- return dstConn.Raw(func(dstRawConn interface{}) error {
229- srcSqlite3Conn := srcRawConn.(*sqlite3.SQLiteConn)
230- dstSqlite3Conn := dstRawConn.(*sqlite3.SQLiteConn)
231--
232- _, err := srcSqlite3Conn.Backup("main", dstSqlite3Conn, "main")
233- return err
234- })
235- })
236- }
237-
238--// BackupDB backs up the in-memory database to disk
239- func BackupDB(db *sql.DB, a *App) error {
240- dbfp := a.GetDBFilePath()
241--
242- conn, err := db.Conn(context.Background())
243- if err != nil {
244- return fmt.Errorf("failed to get underlying database connection: %v", err)
245- }
246-+ defer conn.Close()
247-
248- return conn.Raw(func(sqliteConn interface{}) error {
249- sqlite3Conn := sqliteConn.(*sqlite3.SQLiteConn)
250-- backupDB, err := sqlite3Conn.Backup(dbfp, sqlite3Conn, "main")
251-+ diskDB, err := sql.Open("sqlite3", dbfp)
252-+ fmt.Println("diskDB", diskDB)
253-+ if err != nil {
254-+ return fmt.Errorf("failed to open destination database file: %v", err)
255-+ }
256-+ defer diskDB.Close()
257-+
258-+ diskConn, err := diskDB.Conn(context.Background())
259- if err != nil {
260-- return fmt.Errorf("failed to create backup: %v", err)
261-+ return fmt.Errorf("failed to get connection from diskDB: %v", err)
262- }
263-+ defer diskConn.Close()
264-+
265-+ var backupDB *sqlite3.SQLiteBackup
266-+ err = diskConn.Raw(func(diskRawConn interface{}) error {
267-+ backupDB, err = sqlite3Conn.Backup("main", diskRawConn.(*sqlite3.SQLiteConn), "main")
268-+ return err
269-+ })
270- defer backupDB.Close()
271-
272- _, err = backupDB.Step(-1)
273- if err != nil {
274- return fmt.Errorf("failed to backup in-memory database: %v", err)
275- }
276--
277- return nil
278- })
279- }
280-+
281-+func RunBootstrap(db *sql.DB) error {
282-+ return migrate.CreateUserTable(db)
283-+}
284-diff --git a/internal/database/migrate/bootstrapdb.go b/internal/database/migrate/bootstrapdb.go
285-new file mode 100644
286-index 0000000..1f53246
287---- /dev/null
288-+++ b/internal/database/migrate/bootstrapdb.go
289-@@ -0,0 +1,24 @@
290-+package migrate
291-+
292-+import (
293-+ "database/sql"
294-+ "fmt"
295-+)
296-+
297-+// createUserTable creates the 'user' table in the provided SQLite database.
298-+func CreateUserTable(db *sql.DB) error {
299-+ createTableSQL := `
300-+ CREATE TABLE user (
301-+ id INTEGER PRIMARY KEY AUTOINCREMENT,
302-+ username TEXT NOT NULL,
303-+ password TEXT NOT NULL, -- This should be hashed and salted in a real-world scenario.
304-+ oauth_token TEXT
305-+ );`
306-+
307-+ _, err := db.Exec(createTableSQL)
308-+ if err != nil {
309-+ return fmt.Errorf("failed to create user table: %v", err)
310-+ }
311-+
312-+ return nil
313-+}
314-diff --git a/internal/httpserve/handler/adminroutes.go b/internal/httpserve/handler/adminroutes.go
315-index 8701ae3..f4acd64 100644
316---- a/internal/httpserve/handler/adminroutes.go
317-+++ b/internal/httpserve/handler/adminroutes.go
318-@@ -1,8 +1,6 @@
319- package handler
320-
321- import (
322-- "fmt"
323--
324- "github.com/bnema/gordon/internal/app"
325- "github.com/bnema/gordon/internal/gotemplate/render"
326- "github.com/bnema/gordon/internal/httpserve/middleware"
@@ -1,326 +0,0 @@
1-diff --git a/:memory b/:memory
2-new file mode 100644
3-index 0000000..9760229
4-Binary files /dev/null and b/:memory differ
5-diff --git a/cmd/main.go b/cmd/main.go
6-index 6a95d32..b8e2cd4 100644
7---- a/cmd/main.go
8-+++ b/cmd/main.go
9-@@ -4,17 +4,30 @@ import (
10- "fmt"
11- "log/slog"
12-
13-+ "github.com/labstack/echo/v4"
14-+
15- "github.com/bnema/gordon/internal/app"
16- "github.com/bnema/gordon/internal/httpserve"
17-- "github.com/labstack/echo/v4"
18- )
19-
20- func main() {
21- a := app.NewApp()
22-+
23-+ // Initialize database
24-+ db, err := app.InitializeDB(a)
25-+ if err != nil {
26-+ slog.Error("Failed to load database", err)
27-+ } else {
28-+ slog.Info("Database loaded")
29-+ }
30-+
31-+ fmt.Println(db)
32-+
33- e := echo.New()
34- e.HideBanner = true
35- e.HidePort = true
36- e = httpserve.RegisterRoutes(e, a)
37- slog.Info("Starting server", "port", a.HttpPort)
38- slog.Error("Server error", e.Start(fmt.Sprintf(":%d", a.HttpPort)))
39-+
40- }
41-diff --git a/go.mod b/go.mod
42-index 35e2d3c..8a3ac59 100644
43---- a/go.mod
44-+++ b/go.mod
45-@@ -24,6 +24,7 @@ require (
46- github.com/gorilla/securecookie v1.1.1 // indirect
47- github.com/gorilla/sessions v1.2.1 // indirect
48- github.com/klauspost/compress v1.16.7 // indirect
49-+ github.com/kr/text v0.1.0 // indirect
50- github.com/labstack/gommon v0.4.0 // indirect
51- github.com/mattn/go-colorable v0.1.13 // indirect
52- github.com/mattn/go-isatty v0.0.19 // indirect
53-@@ -35,6 +36,7 @@ require (
54- github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect
55- github.com/opencontainers/runc v1.1.9 // indirect
56- github.com/pkg/errors v0.9.1 // indirect
57-+ github.com/rogpeppe/go-internal v1.11.0 // indirect
58- github.com/sirupsen/logrus v1.9.3 // indirect
59- github.com/valyala/bytebufferpool v1.0.0 // indirect
60- github.com/valyala/fasttemplate v1.2.2 // indirect
61-@@ -45,5 +47,6 @@ require (
62- golang.org/x/text v0.11.0 // indirect
63- golang.org/x/time v0.3.0 // indirect
64- golang.org/x/tools v0.7.0 // indirect
65-+ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
66- gotest.tools/v3 v3.5.0 // indirect
67- )
68-diff --git a/go.sum b/go.sum
69-index 7b9b857..17b0bcd 100644
70---- a/go.sum
71-+++ b/go.sum
72-@@ -39,6 +39,11 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
73- github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
74- github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
75- github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
76-+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
77-+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
78-+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
79-+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
80-+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
81- github.com/labstack/echo-contrib v0.15.0 h1:9K+oRU265y4Mu9zpRDv3X+DGTqUALY6oRHCSZZKCRVU=
82- github.com/labstack/echo-contrib v0.15.0/go.mod h1:lei+qt5CLB4oa7VHTE0yEfQSEB9XTJI1LUqko9UWvo4=
83- github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4=
84-@@ -72,6 +77,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
85- github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
86- github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
87- github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
88-+github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
89-+github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
90- github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
91- github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
92- github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
93-@@ -153,8 +160,9 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
94- golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
95- golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
96- golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
97--gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
98- gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
99-+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
100-+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
101- gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
102- gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
103- gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
104-diff --git a/internal/app/app.go b/internal/app/app.go
105-index c6f49ac..1dd44b8 100644
106---- a/internal/app/app.go
107-+++ b/internal/app/app.go
108-@@ -27,6 +27,7 @@ const (
109- type App struct {
110- TemplateFS fs.FS
111- PublicFS fs.FS
112-+ DB interface{}
113- BuildVersion string
114- BuildDir string
115- DBDir string
116-diff --git a/internal/app/sqlite.go b/internal/app/sqlite.go
117-index 9f1b1ab..ddc6a1e 100644
118---- a/internal/app/sqlite.go
119-+++ b/internal/app/sqlite.go
120-@@ -5,58 +5,78 @@ import (
121- "database/sql"
122- "fmt"
123- "os"
124-+ "path/filepath"
125-
126-- sqlite3 "github.com/mattn/go-sqlite3"
127-+ "github.com/bnema/gordon/internal/database/migrate"
128-+ "github.com/mattn/go-sqlite3"
129- )
130-
131--// Initialize in-memory SQLite database and returns its connection
132--func InitDB() (db *sql.DB, err error) {
133-- db, err = sql.Open("sqlite3", "file::memory?cache=shared")
134-- if err != nil {
135-- return nil, fmt.Errorf("failed to open in-memory database: %v", err)
136-- }
137-- return
138--}
139--
140--// CloseDB closes the database connection and backs up the in-memory database to disk
141--func CloseDB(db *sql.DB, a *App) error {
142-- if err := BackupDB(db, a); err != nil {
143-- return err
144-- }
145-+// InitializeDB initializes the SQLite database. If a database file exists on disk, it loads it into memory.
146-+// Otherwise, it creates a new in-memory database and bootstraps it.
147-+func InitializeDB(a *App) (*sql.DB, error) {
148-+ dbfp := a.GetDBFilePath()
149-
150-- if err := db.Close(); err != nil {
151-- return fmt.Errorf("failed to close database: %v", err)
152-+ // Check if the directory exists, if not create it
153-+ dir := filepath.Dir(a.DBDir)
154-+ fmt.Println("dir", dir)
155-+ if _, err := os.Stat(dir); os.IsNotExist(err) {
156-+ err = os.MkdirAll(dir, 0755)
157-+ if err != nil {
158-+ return nil, fmt.Errorf("failed to create directory: %v", err)
159-+ }
160- }
161-
162-- return nil
163--}
164-+ // If the database file doesn't exist on disk
165-+ if _, err := os.Stat(dbfp); os.IsNotExist(err) {
166-+ memDB, err := initInMemoryDB()
167-+ if err != nil {
168-+ return nil, err
169-+ }
170-
171--// LoadDBIntoMemory loads the database from disk into memory
172--func LoadDBIntoMemory(a *App) (*sql.DB, error) {
173-- dbfp := a.GetDBFilePath()
174-+ // Run the bootstrap
175-+ RunBootstrap(memDB)
176-
177-- if _, err := os.Stat(dbfp); err != nil {
178-- return nil, nil
179-+ // Explicitly backup the in-memory database to disk
180-+ err = BackupDB(memDB, a)
181-+ if err != nil {
182-+ return nil, fmt.Errorf("failed to backup in-memory database to disk: %v", err)
183-+ }
184- }
185-
186-- memDB, err := InitDB()
187-+ memDB, err := initInMemoryDB()
188- if err != nil {
189- return nil, err
190- }
191--
192- diskDB, err := sql.Open("sqlite3", dbfp)
193- if err != nil {
194- return nil, fmt.Errorf("failed to open database file: %v", err)
195- }
196-+ defer diskDB.Close()
197-
198- if err := transferData(diskDB, memDB); err != nil {
199- return nil, err
200- }
201--
202- return memDB, nil
203- }
204-
205--// transferData transfers data from srcDB to dstDB
206-+func initInMemoryDB() (*sql.DB, error) {
207-+ db, err := sql.Open("sqlite3", "file::memory?cache=shared")
208-+ if err != nil {
209-+ return nil, fmt.Errorf("failed to open in-memory database: %v", err)
210-+ }
211-+ return db, nil
212-+}
213-+
214-+func CloseAndBackupDB(db *sql.DB, a *App) error {
215-+ if err := BackupDB(db, a); err != nil {
216-+ return err
217-+ }
218-+ if err := db.Close(); err != nil {
219-+ return fmt.Errorf("failed to close database: %v", err)
220-+ }
221-+ return nil
222-+}
223-+
224- func transferData(srcDB, dstDB *sql.DB) error {
225- srcConn, err := srcDB.Conn(context.Background())
226- if err != nil {
227-@@ -74,35 +94,50 @@ func transferData(srcDB, dstDB *sql.DB) error {
228- return dstConn.Raw(func(dstRawConn interface{}) error {
229- srcSqlite3Conn := srcRawConn.(*sqlite3.SQLiteConn)
230- dstSqlite3Conn := dstRawConn.(*sqlite3.SQLiteConn)
231--
232- _, err := srcSqlite3Conn.Backup("main", dstSqlite3Conn, "main")
233- return err
234- })
235- })
236- }
237-
238--// BackupDB backs up the in-memory database to disk
239- func BackupDB(db *sql.DB, a *App) error {
240- dbfp := a.GetDBFilePath()
241--
242- conn, err := db.Conn(context.Background())
243- if err != nil {
244- return fmt.Errorf("failed to get underlying database connection: %v", err)
245- }
246-+ defer conn.Close()
247-
248- return conn.Raw(func(sqliteConn interface{}) error {
249- sqlite3Conn := sqliteConn.(*sqlite3.SQLiteConn)
250-- backupDB, err := sqlite3Conn.Backup(dbfp, sqlite3Conn, "main")
251-+ diskDB, err := sql.Open("sqlite3", dbfp)
252-+ fmt.Println("diskDB", diskDB)
253-+ if err != nil {
254-+ return fmt.Errorf("failed to open destination database file: %v", err)
255-+ }
256-+ defer diskDB.Close()
257-+
258-+ diskConn, err := diskDB.Conn(context.Background())
259- if err != nil {
260-- return fmt.Errorf("failed to create backup: %v", err)
261-+ return fmt.Errorf("failed to get connection from diskDB: %v", err)
262- }
263-+ defer diskConn.Close()
264-+
265-+ var backupDB *sqlite3.SQLiteBackup
266-+ err = diskConn.Raw(func(diskRawConn interface{}) error {
267-+ backupDB, err = sqlite3Conn.Backup("main", diskRawConn.(*sqlite3.SQLiteConn), "main")
268-+ return err
269-+ })
270- defer backupDB.Close()
271-
272- _, err = backupDB.Step(-1)
273- if err != nil {
274- return fmt.Errorf("failed to backup in-memory database: %v", err)
275- }
276--
277- return nil
278- })
279- }
280-+
281-+func RunBootstrap(db *sql.DB) error {
282-+ return migrate.CreateUserTable(db)
283-+}
284-diff --git a/internal/database/migrate/bootstrapdb.go b/internal/database/migrate/bootstrapdb.go
285-new file mode 100644
286-index 0000000..1f53246
287---- /dev/null
288-+++ b/internal/database/migrate/bootstrapdb.go
289-@@ -0,0 +1,24 @@
290-+package migrate
291-+
292-+import (
293-+ "database/sql"
294-+ "fmt"
295-+)
296-+
297-+// createUserTable creates the 'user' table in the provided SQLite database.
298-+func CreateUserTable(db *sql.DB) error {
299-+ createTableSQL := `
300-+ CREATE TABLE user (
301-+ id INTEGER PRIMARY KEY AUTOINCREMENT,
302-+ username TEXT NOT NULL,
303-+ password TEXT NOT NULL, -- This should be hashed and salted in a real-world scenario.
304-+ oauth_token TEXT
305-+ );`
306-+
307-+ _, err := db.Exec(createTableSQL)
308-+ if err != nil {
309-+ return fmt.Errorf("failed to create user table: %v", err)
310-+ }
311-+
312-+ return nil
313-+}
314-diff --git a/internal/httpserve/handler/adminroutes.go b/internal/httpserve/handler/adminroutes.go
315-index 8701ae3..f4acd64 100644
316---- a/internal/httpserve/handler/adminroutes.go
317-+++ b/internal/httpserve/handler/adminroutes.go
318-@@ -1,8 +1,6 @@
319- package handler
320-
321- import (
322-- "fmt"
323--
324- "github.com/bnema/gordon/internal/app"
325- "github.com/bnema/gordon/internal/gotemplate/render"
326- "github.com/bnema/gordon/internal/httpserve/middleware"

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close