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

Commit 587cdb4

Browse files
committed
api: add function to retrieve list of views in the database
This is called using the path "/v1/views" on the API server. This command also moves the API end point for retrieving table names to "/v1/tables".
1 parent 44f4c64 commit 587cdb4

File tree

2 files changed

+125
-55
lines changed

2 files changed

+125
-55
lines changed

api/handlers.go

Lines changed: 123 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,30 @@ import (
1010
com "github.com/sqlitebrowser/dbhub.io/common"
1111
)
1212

13-
// getTablesHandler returns the list of tables present in a SQLite database
14-
// This can be run from the command line using curl, like this:
15-
// $ curl -F apikey="YOUR_API_KEY_HERE" -F dbowner="justinclift" -F dbname="Join Testing.sqlite" https://api.dbhub.io/v1/get_tables
16-
// * "apikey" is one of your API keys. These can be generated from your Settings page once logged in
17-
// * "dbowner" is the owner of the database being queried
18-
// * "dbname" is the name of the database being queried
19-
func getTablesHandler(w http.ResponseWriter, r *http.Request) {
20-
loggedInUser, err := checkAuth(w, r)
13+
// collectInfo is an internal function which checks the authentication of incoming requests, extracts
14+
// the database owner, name, & commitID, then fetches the Minio bucket and ID for the database file.
15+
// This function exists purely because this code is commonly to most of the handlers
16+
func collectInfo(w http.ResponseWriter, r *http.Request) (bucket, id string, err error, httpStatus int) {
17+
var loggedInUser string
18+
loggedInUser, err = checkAuth(w, r)
2119
if err != nil {
22-
jsonErr(w, err.Error(), http.StatusUnauthorized)
20+
httpStatus = http.StatusUnauthorized
2321
return
2422
}
2523

2624
// Extract the database owner name, database name, and (optional) commit ID for the database from the request
27-
dbOwner, dbName, commitID, err := com.GetFormODC(r)
25+
var dbOwner, dbName, commitID string
26+
dbOwner, dbName, commitID, err = com.GetFormODC(r)
2827
if err != nil {
29-
jsonErr(w, err.Error(), http.StatusInternalServerError)
28+
httpStatus = http.StatusInternalServerError
3029
return
3130
}
3231
dbFolder := "/"
3332

3433
// Check if the user has access to the requested database
35-
var bucket, id string
3634
bucket, id, _, err = com.MinioLocation(dbOwner, dbFolder, dbName, commitID, loggedInUser)
3735
if err != nil {
38-
jsonErr(w, err.Error(), http.StatusInternalServerError)
36+
httpStatus = http.StatusInternalServerError
3937
return
4038
}
4139

@@ -44,49 +42,10 @@ func getTablesHandler(w http.ResponseWriter, r *http.Request) {
4442
// The requested database wasn't found, or the user doesn't have permission to access it
4543
err = fmt.Errorf("Requested database not found")
4644
log.Printf("Requested database not found. Owner: '%s%s%s'", dbOwner, dbFolder, dbName)
47-
jsonErr(w, err.Error(), http.StatusNotFound)
48-
return
49-
}
50-
51-
// Retrieve database file from Minio, using locally cached version if it's already there
52-
newDB, err := com.RetrieveDatabaseFile(bucket, id)
53-
if err != nil {
54-
jsonErr(w, err.Error(), http.StatusNotFound)
55-
return
56-
}
57-
58-
// Open the SQLite database in read only mode
59-
var sdb *sqlite.Conn
60-
sdb, err = sqlite.Open(newDB, sqlite.OpenReadOnly)
61-
if err != nil {
62-
log.Printf("Couldn't open database in getTablesHandler(): %s", err)
63-
jsonErr(w, err.Error(), http.StatusInternalServerError)
64-
return
65-
}
66-
if err = sdb.EnableExtendedResultCodes(true); err != nil {
67-
log.Printf("Couldn't enable extended result codes in getTablesHandler(): %v\n", err.Error())
68-
jsonErr(w, err.Error(), http.StatusInternalServerError)
69-
return
70-
}
71-
72-
// Retrieve the list of tables
73-
var returnData struct {
74-
Tables []string `json:"tables"`
75-
}
76-
returnData.Tables, err = com.Tables(sdb, dbName)
77-
if err != nil {
78-
jsonErr(w, err.Error(), http.StatusInternalServerError)
45+
httpStatus = http.StatusNotFound
7946
return
8047
}
81-
82-
// Return the results
83-
jsonData, err := json.Marshal(returnData.Tables)
84-
if err != nil {
85-
log.Printf("Error when JSON marshalling returned data in getTablesHandler(): %v\n", err)
86-
jsonErr(w, err.Error(), http.StatusInternalServerError)
87-
return
88-
}
89-
fmt.Fprintf(w, string(jsonData))
48+
return
9049
}
9150

9251
// queryHandler executes a SQL query on a SQLite database, returning the results to the caller
@@ -180,3 +139,113 @@ func rootHandler(w http.ResponseWriter, r *http.Request) {
180139
log.Printf("Error: %s", err)
181140
}
182141
}
142+
143+
// tablesHandler returns the list of tables present in a SQLite database
144+
// This can be run from the command line using curl, like this:
145+
// $ curl -F apikey="YOUR_API_KEY_HERE" -F dbowner="justinclift" -F dbname="Join Testing.sqlite" https://api.dbhub.io/v1/tables
146+
// * "apikey" is one of your API keys. These can be generated from your Settings page once logged in
147+
// * "dbowner" is the owner of the database being queried
148+
// * "dbname" is the name of the database being queried
149+
func tablesHandler(w http.ResponseWriter, r *http.Request) {
150+
// Do auth check, database existence check, and grab it's Minio bucket and ID
151+
bucket, id, err, httpStatus := collectInfo(w, r)
152+
if err != nil {
153+
jsonErr(w, err.Error(), httpStatus)
154+
return
155+
}
156+
157+
// Retrieve database file from Minio, using locally cached version if it's already there
158+
newDB, err := com.RetrieveDatabaseFile(bucket, id)
159+
if err != nil {
160+
jsonErr(w, err.Error(), http.StatusNotFound)
161+
return
162+
}
163+
164+
// Open the SQLite database in read only mode
165+
var sdb *sqlite.Conn
166+
sdb, err = sqlite.Open(newDB, sqlite.OpenReadOnly)
167+
if err != nil {
168+
log.Printf("Couldn't open database in tablesHandler(): %s", err)
169+
jsonErr(w, err.Error(), http.StatusInternalServerError)
170+
return
171+
}
172+
if err = sdb.EnableExtendedResultCodes(true); err != nil {
173+
log.Printf("Couldn't enable extended result codes in tablesHandler(): %v\n", err.Error())
174+
jsonErr(w, err.Error(), http.StatusInternalServerError)
175+
return
176+
}
177+
178+
// Retrieve the list of tables
179+
var returnData struct {
180+
Tables []string `json:"tables"`
181+
}
182+
returnData.Tables, err = com.Tables(sdb)
183+
if err != nil {
184+
jsonErr(w, err.Error(), http.StatusInternalServerError)
185+
return
186+
}
187+
188+
// Return the results
189+
jsonData, err := json.Marshal(returnData.Tables)
190+
if err != nil {
191+
log.Printf("Error when JSON marshalling returned data in tablesHandler(): %v\n", err)
192+
jsonErr(w, err.Error(), http.StatusInternalServerError)
193+
return
194+
}
195+
fmt.Fprintf(w, string(jsonData))
196+
}
197+
198+
// viewsHandler returns the list of views present in a SQLite database
199+
// This can be run from the command line using curl, like this:
200+
// $ curl -F apikey="YOUR_API_KEY_HERE" -F dbowner="justinclift" -F dbname="Join Testing.sqlite" https://api.dbhub.io/v1/views
201+
// * "apikey" is one of your API keys. These can be generated from your Settings page once logged in
202+
// * "dbowner" is the owner of the database being queried
203+
// * "dbname" is the name of the database being queried
204+
func viewsHandler(w http.ResponseWriter, r *http.Request) {
205+
// Do auth check, database existence check, and grab it's Minio bucket and ID
206+
bucket, id, err, httpStatus := collectInfo(w, r)
207+
if err != nil {
208+
jsonErr(w, err.Error(), httpStatus)
209+
return
210+
}
211+
212+
// Retrieve database file from Minio, using locally cached version if it's already there
213+
newDB, err := com.RetrieveDatabaseFile(bucket, id)
214+
if err != nil {
215+
jsonErr(w, err.Error(), http.StatusNotFound)
216+
return
217+
}
218+
219+
// Open the SQLite database in read only mode
220+
var sdb *sqlite.Conn
221+
sdb, err = sqlite.Open(newDB, sqlite.OpenReadOnly)
222+
if err != nil {
223+
log.Printf("Couldn't open database in viewsHandler(): %s", err)
224+
jsonErr(w, err.Error(), http.StatusInternalServerError)
225+
return
226+
}
227+
if err = sdb.EnableExtendedResultCodes(true); err != nil {
228+
log.Printf("Couldn't enable extended result codes in viewsHandler(): %v\n", err.Error())
229+
jsonErr(w, err.Error(), http.StatusInternalServerError)
230+
return
231+
}
232+
233+
// Retrieve the list of views
234+
var returnData struct {
235+
Views []string `json:"views"`
236+
}
237+
returnData.Views, err = com.Views(sdb)
238+
if err != nil {
239+
jsonErr(w, err.Error(), http.StatusInternalServerError)
240+
return
241+
}
242+
243+
// Return the results
244+
jsonData, err := json.Marshal(returnData.Views)
245+
if err != nil {
246+
log.Printf("Error when JSON marshalling returned data in viewsHandler(): %v\n", err)
247+
jsonErr(w, err.Error(), http.StatusInternalServerError)
248+
return
249+
}
250+
fmt.Fprintf(w, string(jsonData))
251+
}

api/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ func main() {
7878
// Our pages
7979
http.Handle("/", gz.GzipHandler(handleWrapper(rootHandler)))
8080
http.Handle("/v1/query", gz.GzipHandler(handleWrapper(queryHandler)))
81-
http.Handle("/v1/get_tables", gz.GzipHandler(handleWrapper(getTablesHandler)))
81+
http.Handle("/v1/tables", gz.GzipHandler(handleWrapper(tablesHandler)))
82+
http.Handle("/v1/views", gz.GzipHandler(handleWrapper(viewsHandler)))
8283

8384
// Generate the formatted server string
8485
server = fmt.Sprintf("https://%s", com.Conf.Api.ServerName)

0 commit comments

Comments
 (0)