new-codigoparallevar/scripts/search-server/server.go
2025-02-23 23:33:38 +01:00

184 lines
4.4 KiB
Go

package main
import (
"github.com/gin-gonic/gin"
"database/sql"
"log"
"os"
"fmt"
"strconv"
_ "github.com/mattn/go-sqlite3"
)
func main() {
database_path, ok := os.LookupEnv("DB_PATH")
if !ok {
log.Fatal("Environment variable $DB_PATH must point to sqlite3 database with text indices.")
os.Exit(1)
}
port := 3000
port_str, ok := os.LookupEnv("PORT")
if ok {
port_num, err := strconv.Atoi(port_str)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
if (port_num < 1) || (port_num > 65535) {
log.Fatal("Environment variale $PORT must be a number between 1 and 65535.")
os.Exit(1)
}
port = port_num
}
snippet_size := 128
snippet_size_str, ok := os.LookupEnv("SNIPPET_SIZE")
if ok {
snippet_size_num, err := strconv.Atoi(snippet_size_str)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
if (snippet_size_num < 64) {
log.Fatal("Environment variale $SNIPPET_SIZE must be >= 64.")
os.Exit(1)
}
snippet_size = snippet_size_num
}
db, err := sql.Open("sqlite3", database_path)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
r := gin.Default()
api := r.Group("/api")
api.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
api.OPTIONS("/search", func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept-Encoding, Authorization, accept, origin, Cache-Control, X-Requested-With")
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
c.AbortWithStatus(204)
})
api.GET("/search", func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept-Encoding, Authorization, accept, origin, Cache-Control, X-Requested-With")
c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
query := c.Query("q")
body_type := c.Query("body")
if ((body_type != "all") && (body_type != "none") && (body_type != "snippet")) {
body_type = "none"
}
var stm *sql.Stmt
var err error
if (body_type == "snippet") {
stm, err = db.Prepare("SELECT note_id, highlight(note_search, 1, '<span class=\"match\">', '</span>'), top_level_title, is_done, is_todo, snippet(note_search, 2, '<span class=\"match\">', '</span>', '<span class=\"search-result-break\"></span>', ?) FROM note_search(?)")
} else if (body_type == "all") {
stm, err = db.Prepare("SELECT note_id, highlight(note_search, 1, '<span class=\"match\">', '</span>'), top_level_title, is_done, is_todo, highlight(note_search, 2, '<span class=\"match\">', '</span>') FROM note_search(?)")
} else if (body_type == "none") {
stm, err = db.Prepare("SELECT note_id, highlight(note_search, 1, '<span class=\"match\">', '</span>'), top_level_title, is_done, is_todo FROM note_search(?)")
}
if err != nil {
log.Fatal(err)
c.JSON(500, gin.H{
"success": false,
"message": "Error preparing note-search query",
})
return
}
results := make([]map[string]string, 0)
var rows *sql.Rows
if (body_type == "snippet") {
rows, err = stm.Query(snippet_size, query)
} else {
rows, err = stm.Query(query)
}
if err != nil {
log.Fatal(err)
c.JSON(500, gin.H{
"success": false,
"message": "Error querying note DB",
})
return
}
for rows.Next() {
var note_id string
var note_title string
var note_top_level_title string
var note_is_done string
var note_is_todo string
item := make(map[string]string)
if (body_type != "none") {
var note_highlight string
err = rows.Scan(
&note_id,
&note_title,
&note_top_level_title,
&note_is_done,
&note_is_todo,
&note_highlight,
)
if (body_type != "none") {
item["highlight"] = note_highlight
}
} else {
err = rows.Scan(
&note_id,
&note_title,
&note_top_level_title,
&note_is_done,
&note_is_todo,
)
}
if err != nil {
log.Fatal(err)
c.JSON(500, gin.H{
"success": false,
"message": "Error reading note DB results",
})
return
}
item["id"] = note_id
item["title"] = note_title
item["top_level_title"] = note_top_level_title
item["is_done"] = note_is_done
item["is_todo"] = note_is_todo
results = append(results, item)
}
c.JSON(200, gin.H{
"results": gin.H{
"notes": results,
},
})
})
r.Run(fmt.Sprintf(":%v", port))
}