Skip to content
This repository was archived by the owner on Mar 4, 2025. It is now read-only.

Commit efa86a0

Browse files
committed
api: move non-handler functions out of handler.go, sort functions alphanumerically
1 parent b236ad0 commit efa86a0

File tree

2 files changed

+146
-146
lines changed

2 files changed

+146
-146
lines changed

api/handlers.go

Lines changed: 83 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -7,70 +7,113 @@ import (
77
"net/http"
88
"net/url"
99

10-
sqlite "github.com/gwenn/gosqlite"
1110
com "github.com/sqlitebrowser/dbhub.io/common"
1211
)
1312

14-
// collectInfo is an internal function which:
15-
// 1. Authenticates incoming requests
16-
// 2. Extracts the database owner, name, & commitID from the request
17-
// 3. Fetches the database from Minio (with appropriate permission checks)
18-
// 4. Opens the database, returning the connection handle
19-
// This function exists purely because this code is commonly to most of the handlers
20-
func collectInfo(w http.ResponseWriter, r *http.Request) (sdb *sqlite.Conn, err error, httpStatus int) {
21-
var loggedInUser string
22-
loggedInUser, err = checkAuth(w, r)
13+
// diffHandler generates a diff between two databases or two versions of a database
14+
// This can be run from the command line using curl, like this:
15+
// $ curl -F apikey="YOUR_API_KEY_HERE" -F dbowner_a="justinclift" -F dbname_a="Join Testing.sqlite" -F commit_a="ea12..." -F commit_b="5a7c..." https://api.dbhub.io/v1/diff
16+
// * "apikey" is one of your API keys. These can be generated from your Settings page once logged in
17+
// * "dbowner_a" is the owner of the first database being diffed
18+
// * "dbname_a" is the name of the first database being diffed
19+
// * "dbowner_b" is the owner of the second database being diffed (optional, if not provided same as first owner)
20+
// * "dbname_b" is the name of the second database being diffed (optional, if not provided same as first name)
21+
// * "commit_a" is the first commit for diffing
22+
// * "commit_b" is the second commit for diffing
23+
func diffHandler(w http.ResponseWriter, r *http.Request) {
24+
loggedInUser, err := checkAuth(w, r)
2325
if err != nil {
24-
httpStatus = http.StatusUnauthorized
26+
jsonErr(w, err.Error(), http.StatusUnauthorized)
2527
return
2628
}
2729

28-
// Extract the database owner name, database name, and (optional) commit ID for the database from the request
29-
var dbOwner, dbName, commitID string
30-
dbOwner, dbName, commitID, err = com.GetFormODC(r)
31-
if err != nil {
32-
httpStatus = http.StatusInternalServerError
30+
// Retrieve owner, name, and commit ids
31+
oa := r.PostFormValue("dbowner_a")
32+
na := r.PostFormValue("dbname_a")
33+
ca := r.PostFormValue("commit_a")
34+
ob := r.PostFormValue("dbowner_a")
35+
nb := r.PostFormValue("dbname_b")
36+
cb := r.PostFormValue("commit_b")
37+
38+
// If no primary database owner and name are given or if no commit ids are given, return
39+
if oa == "" || na == "" || ca == "" || cb == "" {
40+
jsonErr(w, err.Error(), http.StatusBadRequest)
3341
return
3442
}
35-
dbFolder := "/"
3643

37-
// Check if the user has access to the requested database
38-
var bucket, id string
39-
bucket, id, _, err = com.MinioLocation(dbOwner, dbFolder, dbName, commitID, loggedInUser)
44+
// If no secondary database owner and name are provided, use the ones of the first database
45+
if ob == "" || nb == "" {
46+
ob = oa
47+
nb = na
48+
}
49+
50+
// Unescape, then validate the owner and database names and commit ids
51+
dbOwnerA, err := url.QueryUnescape(oa)
4052
if err != nil {
41-
httpStatus = http.StatusInternalServerError
53+
jsonErr(w, err.Error(), http.StatusBadRequest)
4254
return
4355
}
44-
45-
// Sanity check
46-
if id == "" {
47-
// The requested database wasn't found, or the user doesn't have permission to access it
48-
err = fmt.Errorf("Requested database not found")
49-
log.Printf("Requested database not found. Owner: '%s%s%s'", dbOwner, dbFolder, dbName)
50-
httpStatus = http.StatusNotFound
56+
dbOwnerB, err := url.QueryUnescape(ob)
57+
if err != nil {
58+
jsonErr(w, err.Error(), http.StatusBadRequest)
5159
return
5260
}
53-
54-
// Retrieve database file from Minio, using locally cached version if it's already there
55-
newDB, err := com.RetrieveDatabaseFile(bucket, id)
61+
dbNameA, err := url.QueryUnescape(na)
62+
if err != nil {
63+
jsonErr(w, err.Error(), http.StatusBadRequest)
64+
return
65+
}
66+
dbNameB, err := url.QueryUnescape(nb)
5667
if err != nil {
57-
httpStatus = http.StatusNotFound
68+
jsonErr(w, err.Error(), http.StatusBadRequest)
69+
return
70+
}
71+
err = com.ValidateUser(dbOwnerA)
72+
if err != nil {
73+
jsonErr(w, err.Error(), http.StatusBadRequest)
74+
return
75+
}
76+
err = com.ValidateUser(dbOwnerB)
77+
if err != nil {
78+
jsonErr(w, err.Error(), http.StatusBadRequest)
79+
return
80+
}
81+
err = com.ValidateDB(dbNameA)
82+
if err != nil {
83+
jsonErr(w, err.Error(), http.StatusBadRequest)
84+
return
85+
}
86+
err = com.ValidateDB(dbNameB)
87+
if err != nil {
88+
jsonErr(w, err.Error(), http.StatusBadRequest)
89+
return
90+
}
91+
err = com.ValidateCommitID(ca)
92+
if err != nil {
93+
jsonErr(w, err.Error(), http.StatusBadRequest)
94+
return
95+
}
96+
err = com.ValidateCommitID(cb)
97+
if err != nil {
98+
jsonErr(w, err.Error(), http.StatusBadRequest)
5899
return
59100
}
60101

61-
// Open the SQLite database in read only mode
62-
sdb, err = sqlite.Open(newDB, sqlite.OpenReadOnly)
102+
// Perform diff
103+
diffs, err := com.Diff(dbOwnerA, "/", dbNameA, ca, dbOwnerB, "/", dbNameB, cb, loggedInUser)
63104
if err != nil {
64-
log.Printf("Couldn't open database in viewsHandler(): %s", err)
65-
httpStatus = http.StatusInternalServerError
105+
jsonErr(w, err.Error(), http.StatusInternalServerError)
66106
return
67107
}
68-
if err = sdb.EnableExtendedResultCodes(true); err != nil {
69-
log.Printf("Couldn't enable extended result codes in viewsHandler(): %v\n", err.Error())
70-
httpStatus = http.StatusInternalServerError
108+
109+
// Return the results
110+
jsonData, err := json.Marshal(diffs)
111+
if err != nil {
112+
log.Printf("Error when JSON marshalling returned data in diffHandler(): %v\n", err)
113+
jsonErr(w, err.Error(), http.StatusInternalServerError)
71114
return
72115
}
73-
return
116+
fmt.Fprintf(w, string(jsonData))
74117
}
75118

76119
// indexesHandler returns the list of indexes present in a SQLite database
@@ -256,109 +299,3 @@ func viewsHandler(w http.ResponseWriter, r *http.Request) {
256299
}
257300
fmt.Fprintf(w, string(jsonData))
258301
}
259-
260-
// diffHandler generates a diff between two databases or two versions of a database
261-
// This can be run from the command line using curl, like this:
262-
// $ curl -F apikey="YOUR_API_KEY_HERE" -F dbowner_a="justinclift" -F dbname_a="Join Testing.sqlite" -F commit_a="ea12..." -F commit_b="5a7c..." https://api.dbhub.io/v1/diff
263-
// * "apikey" is one of your API keys. These can be generated from your Settings page once logged in
264-
// * "dbowner_a" is the owner of the first database being diffed
265-
// * "dbname_a" is the name of the first database being diffed
266-
// * "dbowner_b" is the owner of the second database being diffed (optional, if not provided same as first owner)
267-
// * "dbname_b" is the name of the second database being diffed (optional, if not provided same as first name)
268-
// * "commit_a" is the first commit for diffing
269-
// * "commit_b" is the second commit for diffing
270-
func diffHandler(w http.ResponseWriter, r *http.Request) {
271-
loggedInUser, err := checkAuth(w, r)
272-
if err != nil {
273-
jsonErr(w, err.Error(), http.StatusUnauthorized)
274-
return
275-
}
276-
277-
// Retrieve owner, name, and commit ids
278-
oa := r.PostFormValue("dbowner_a")
279-
na := r.PostFormValue("dbname_a")
280-
ca := r.PostFormValue("commit_a")
281-
ob := r.PostFormValue("dbowner_a")
282-
nb := r.PostFormValue("dbname_b")
283-
cb := r.PostFormValue("commit_b")
284-
285-
// If no primary database owner and name are given or if no commit ids are given, return
286-
if oa == "" || na == "" || ca == "" || cb == "" {
287-
jsonErr(w, err.Error(), http.StatusBadRequest)
288-
return
289-
}
290-
291-
// If no secondary database owner and name are provided, use the ones of the first database
292-
if ob == "" || nb == "" {
293-
ob = oa
294-
nb = na
295-
}
296-
297-
// Unescape, then validate the owner and database names and commit ids
298-
dbOwnerA, err := url.QueryUnescape(oa)
299-
if err != nil {
300-
jsonErr(w, err.Error(), http.StatusBadRequest)
301-
return
302-
}
303-
dbOwnerB, err := url.QueryUnescape(ob)
304-
if err != nil {
305-
jsonErr(w, err.Error(), http.StatusBadRequest)
306-
return
307-
}
308-
dbNameA, err := url.QueryUnescape(na)
309-
if err != nil {
310-
jsonErr(w, err.Error(), http.StatusBadRequest)
311-
return
312-
}
313-
dbNameB, err := url.QueryUnescape(nb)
314-
if err != nil {
315-
jsonErr(w, err.Error(), http.StatusBadRequest)
316-
return
317-
}
318-
err = com.ValidateUser(dbOwnerA)
319-
if err != nil {
320-
jsonErr(w, err.Error(), http.StatusBadRequest)
321-
return
322-
}
323-
err = com.ValidateUser(dbOwnerB)
324-
if err != nil {
325-
jsonErr(w, err.Error(), http.StatusBadRequest)
326-
return
327-
}
328-
err = com.ValidateDB(dbNameA)
329-
if err != nil {
330-
jsonErr(w, err.Error(), http.StatusBadRequest)
331-
return
332-
}
333-
err = com.ValidateDB(dbNameB)
334-
if err != nil {
335-
jsonErr(w, err.Error(), http.StatusBadRequest)
336-
return
337-
}
338-
err = com.ValidateCommitID(ca)
339-
if err != nil {
340-
jsonErr(w, err.Error(), http.StatusBadRequest)
341-
return
342-
}
343-
err = com.ValidateCommitID(cb)
344-
if err != nil {
345-
jsonErr(w, err.Error(), http.StatusBadRequest)
346-
return
347-
}
348-
349-
// Perform diff
350-
diffs, err := com.Diff(dbOwnerA, "/", dbNameA, ca, dbOwnerB, "/", dbNameB, cb, loggedInUser)
351-
if err != nil {
352-
jsonErr(w, err.Error(), http.StatusInternalServerError)
353-
return
354-
}
355-
356-
// Return the results
357-
jsonData, err := json.Marshal(diffs)
358-
if err != nil {
359-
log.Printf("Error when JSON marshalling returned data in diffHandler(): %v\n", err)
360-
jsonErr(w, err.Error(), http.StatusInternalServerError)
361-
return
362-
}
363-
fmt.Fprintf(w, string(jsonData))
364-
}

api/main.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"time"
1313

1414
gz "github.com/NYTimes/gziphandler"
15+
sqlite "github.com/gwenn/gosqlite"
1516
com "github.com/sqlitebrowser/dbhub.io/common"
1617
)
1718

@@ -125,6 +126,68 @@ func checkAuth(w http.ResponseWriter, r *http.Request) (loggedInUser string, err
125126
return
126127
}
127128

129+
// collectInfo is an internal function which:
130+
// 1. Authenticates incoming requests
131+
// 2. Extracts the database owner, name, & commitID from the request
132+
// 3. Fetches the database from Minio (with appropriate permission checks)
133+
// 4. Opens the database, returning the connection handle
134+
// This function exists purely because this code is commonly to most of the handlers
135+
func collectInfo(w http.ResponseWriter, r *http.Request) (sdb *sqlite.Conn, err error, httpStatus int) {
136+
var loggedInUser string
137+
loggedInUser, err = checkAuth(w, r)
138+
if err != nil {
139+
httpStatus = http.StatusUnauthorized
140+
return
141+
}
142+
143+
// Extract the database owner name, database name, and (optional) commit ID for the database from the request
144+
var dbOwner, dbName, commitID string
145+
dbOwner, dbName, commitID, err = com.GetFormODC(r)
146+
if err != nil {
147+
httpStatus = http.StatusInternalServerError
148+
return
149+
}
150+
dbFolder := "/"
151+
152+
// Check if the user has access to the requested database
153+
var bucket, id string
154+
bucket, id, _, err = com.MinioLocation(dbOwner, dbFolder, dbName, commitID, loggedInUser)
155+
if err != nil {
156+
httpStatus = http.StatusInternalServerError
157+
return
158+
}
159+
160+
// Sanity check
161+
if id == "" {
162+
// The requested database wasn't found, or the user doesn't have permission to access it
163+
err = fmt.Errorf("Requested database not found")
164+
log.Printf("Requested database not found. Owner: '%s%s%s'", dbOwner, dbFolder, dbName)
165+
httpStatus = http.StatusNotFound
166+
return
167+
}
168+
169+
// Retrieve database file from Minio, using locally cached version if it's already there
170+
newDB, err := com.RetrieveDatabaseFile(bucket, id)
171+
if err != nil {
172+
httpStatus = http.StatusNotFound
173+
return
174+
}
175+
176+
// Open the SQLite database in read only mode
177+
sdb, err = sqlite.Open(newDB, sqlite.OpenReadOnly)
178+
if err != nil {
179+
log.Printf("Couldn't open database in viewsHandler(): %s", err)
180+
httpStatus = http.StatusInternalServerError
181+
return
182+
}
183+
if err = sdb.EnableExtendedResultCodes(true); err != nil {
184+
log.Printf("Couldn't enable extended result codes in viewsHandler(): %v\n", err.Error())
185+
httpStatus = http.StatusInternalServerError
186+
return
187+
}
188+
return
189+
}
190+
128191
// handleWrapper does nothing useful except interface between types
129192
// TODO: Get rid of this, as it shouldn't be needed
130193
func handleWrapper(fn http.HandlerFunc) http.HandlerFunc {

0 commit comments

Comments
 (0)