diff options
Diffstat (limited to 'main.go')
| -rw-r--r-- | main.go | 213 |
1 files changed, 211 insertions, 2 deletions
@@ -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, ¶ms) + 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, ¶ms) + 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, ¶ms) + 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, ¶ms) + 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) } } |
