summaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
authorunwox <me@unwox.com>2024-09-14 15:54:27 +0600
committerunwox <me@unwox.com>2024-09-14 23:59:38 +0600
commitcc8d3cf4a7cd296d8c409fef5db9df138c3b238d (patch)
tree4eae9d64ce9927e8b505fad359511bab22eccd80 /main.go
parent986522e417406956e83362e08adbd6a18ec904a5 (diff)
add luna.db.* module
Diffstat (limited to 'main.go')
-rw-r--r--main.go213
1 files changed, 211 insertions, 2 deletions
diff --git a/main.go b/main.go
index bde394e..eaa3ec6 100644
--- a/main.go
+++ b/main.go
@@ -2,6 +2,7 @@ package main
import (
"bufio"
+ "database/sql"
"errors"
"flag"
"fmt"
@@ -10,8 +11,11 @@ import (
"net/http"
"os"
"runtime"
+ "runtime/cgo"
"strings"
"time"
+
+ _ "github.com/mattn/go-sqlite3"
)
func main() {
@@ -28,7 +32,7 @@ func main() {
httpClient := &http.Client{}
// queue for http messages for workers to handle
- msgs := make(chan interface{}, 4096)
+ msgs := make(chan any, 4096)
mux := http.NewServeMux()
wrks := []*Worker{}
// track routes for mux to avoid registering the same route twice
@@ -128,9 +132,214 @@ func main() {
return 3
}
+ // define luna.db module
+ dbModule := make(map[string]any)
+ dbModule["open"] = func (l *Lua) int {
+ var file string
+ err := l.Scan(&file)
+ if err != nil {
+ // FIXME: handle.
+ return 0
+ }
+ r, err := sql.Open("sqlite3", file)
+ if err != nil {
+ // FIXME: handle.
+ return 0
+ }
+ h := cgo.NewHandle(r)
+ l.PushNumber(int(h))
+ return 1
+ }
+ dbModule["begin"] = func (l *Lua) int {
+ var handle cgo.Handle
+ err := l.Scan(&handle)
+ if err != nil {
+ // FIXME: handle.
+ return 0
+ }
+ db := handle.Value().(*sql.DB)
+ tx, err := db.Begin()
+ if err != nil {
+ // FIXME: handle.
+ return 0
+ }
+ txh := cgo.NewHandle(tx)
+ l.PushNumber(int(txh))
+ return 1
+ }
+ dbModule["commit"] = func (l *Lua) int {
+ var handle cgo.Handle
+ err := l.Scan(&handle)
+ if err != nil {
+ // FIXME: handle.
+ return 0
+ }
+ tx := handle.Value().(*sql.Tx)
+ err = tx.Commit()
+ if err != nil {
+ // FIXME: handle.
+ return 0
+ }
+ handle.Delete()
+ return 0
+ }
+ dbModule["rollback"] = func (l *Lua) int {
+ var handle cgo.Handle
+ err := l.Scan(&handle)
+ if err != nil {
+ // FIXME: handle.
+ return 0
+ }
+ tx := handle.Value().(*sql.Tx)
+ err = tx.Rollback()
+ if err != nil {
+ // FIXME: handle.
+ return 0
+ }
+ handle.Delete()
+ return 0
+ }
+ dbModule["exec-tx"] = func (l *Lua) int {
+ var handle cgo.Handle
+ var query string
+ var params []any
+ err := l.Scan(&handle, &query, &params)
+ if err != nil {
+ fmt.Println(err)
+ // FIXME: handle.
+ return 0
+ }
+ tx := handle.Value().(*sql.Tx)
+ _, err = tx.Exec(query, params...)
+ if err != nil {
+ fmt.Println(err)
+ // FIXME: handle.
+ return 0
+ }
+ return 0
+ }
+ dbModule["exec"] = func (l *Lua) int {
+ var handle cgo.Handle
+ var query string
+ var params []any
+ err := l.Scan(&handle, &query, &params)
+ if err != nil {
+ fmt.Println(err)
+ // FIXME: handle.
+ return 0
+ }
+ db := handle.Value().(*sql.DB)
+ _, err = db.Exec(query, params...)
+ if err != nil {
+ fmt.Println(err)
+ // FIXME: handle.
+ return 0
+ }
+ return 0
+ }
+ dbModule["query"] = func (l *Lua) int {
+ var handle cgo.Handle
+ var query string
+ var params []any
+ err := l.Scan(&handle, &query, &params)
+ if err != nil {
+ fmt.Println(err)
+ // FIXME: handle.
+ return 0
+ }
+ db := handle.Value().(*sql.DB)
+ rows, err := db.Query(query, params...)
+ if err != nil {
+ // FIXME: handle.
+ return 0
+ }
+ var res [][]any
+ cols, _ := rows.Columns()
+ for rows.Next() {
+ scans := make([]any, len(cols))
+ for i, _ := range scans {
+ scans[i] = &scans[i]
+ }
+ var row []any
+ rows.Scan(scans...)
+ for _, v := range scans {
+ row = append(row, v)
+ }
+ res = append(res, row)
+ }
+ var ares []any
+ for _, v := range res {
+ ares = append(ares, v)
+ }
+ err = l.PushArray(ares)
+ if err != nil {
+ fmt.Println(err)
+ // FIXME: handle
+ return 0
+ }
+ return 1
+ }
+ dbModule["query*"] = func (l *Lua) int {
+ var handle cgo.Handle
+ var query string
+ var params []any
+ err := l.Scan(&handle, &query, &params)
+ if err != nil {
+ // FIXME: handle.
+ return 0
+ }
+ db := handle.Value().(*sql.DB)
+ rows, err := db.Query(query, params...)
+ if err != nil {
+ // FIXME: handle.
+ return 0
+ }
+ var res []map[string]any
+ cols, _ := rows.Columns()
+ for rows.Next() {
+ scans := make([]any, len(cols))
+ for i, _ := range scans {
+ scans[i] = &scans[i]
+ }
+ row := make(map[string]any)
+ rows.Scan(scans...)
+ for i, v := range scans {
+ row[cols[i]] = v
+ }
+ res = append(res, row)
+ }
+ var ares []any
+ for _, v := range res {
+ ares = append(ares, v)
+ }
+ err = l.PushArray(ares)
+ if err != nil {
+ // FIXME: handle
+ return 0
+ }
+ return 1
+ }
+ dbModule["close"] = func (l *Lua) int {
+ var handle cgo.Handle
+ err := l.Scan(&handle)
+ if err != nil {
+ // FIXME: handle.
+ return 0
+ }
+ db := handle.Value().(*sql.DB)
+ err = db.Close()
+ if err != nil {
+ // FIXME: handle.
+ return 0
+ }
+ handle.Delete()
+ return 0
+ }
+
module := make(map[string]any)
module["router"] = routeModule
module["http"] = httpModule
+ module["db"] = dbModule
// start workers
for i := 0; i < *wrksNum; i++ {
@@ -177,7 +386,7 @@ func printUsage() {
func mustExist(file string) {
if _, err := os.Stat(file); errors.Is(err, os.ErrNotExist) {
- fmt.Printf(`file "%s" does not exist\n`, file)
+ fmt.Printf("file \"%s\" does not exist\n", file)
os.Exit(1)
}
}