[feat] prepare shared lib
Signed-off-by: Anton Nesterov <anton@demiurg.io>
This commit is contained in:
parent
59b2dde114
commit
87e3fdd18d
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,5 +1,6 @@
|
|||
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
||||
|
||||
*.so
|
||||
*.dylib
|
||||
# Logs
|
||||
|
||||
logs
|
||||
|
|
31
cgo/dal.go
Normal file
31
cgo/dal.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package main
|
||||
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
import (
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"l12.xyz/dal/facade"
|
||||
)
|
||||
|
||||
//export InitSQLite
|
||||
func InitSQLite(pragmas *C.char) {
|
||||
str := C.GoString(pragmas)
|
||||
pragmasArray := strings.Split(str, ";")
|
||||
facade.InitSQLite(pragmasArray)
|
||||
}
|
||||
|
||||
//export HandleQuery
|
||||
func HandleQuery(input *C.char) *C.char {
|
||||
var in, out []byte
|
||||
inPtr := unsafe.Pointer(input)
|
||||
defer C.free(inPtr)
|
||||
|
||||
in = C.GoBytes(inPtr, C.int(len(C.GoString(input))))
|
||||
facade.HandleQuery(&in, &out)
|
||||
output := C.CString(string(out))
|
||||
return output
|
||||
}
|
||||
|
||||
func main() {}
|
86
cgo/dal.h
Normal file
86
cgo/dal.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/* Code generated by cmd/cgo; DO NOT EDIT. */
|
||||
|
||||
/* package command-line-arguments */
|
||||
|
||||
|
||||
#line 1 "cgo-builtin-export-prolog"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef GO_CGO_EXPORT_PROLOGUE_H
|
||||
#define GO_CGO_EXPORT_PROLOGUE_H
|
||||
|
||||
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Start of preamble from import "C" comments. */
|
||||
|
||||
|
||||
#line 3 "dal.go"
|
||||
#include <stdlib.h>
|
||||
|
||||
#line 1 "cgo-generated-wrapper"
|
||||
|
||||
|
||||
/* End of preamble from import "C" comments. */
|
||||
|
||||
|
||||
/* Start of boilerplate cgo prologue. */
|
||||
#line 1 "cgo-gcc-export-header-prolog"
|
||||
|
||||
#ifndef GO_CGO_PROLOGUE_H
|
||||
#define GO_CGO_PROLOGUE_H
|
||||
|
||||
typedef signed char GoInt8;
|
||||
typedef unsigned char GoUint8;
|
||||
typedef short GoInt16;
|
||||
typedef unsigned short GoUint16;
|
||||
typedef int GoInt32;
|
||||
typedef unsigned int GoUint32;
|
||||
typedef long long GoInt64;
|
||||
typedef unsigned long long GoUint64;
|
||||
typedef GoInt64 GoInt;
|
||||
typedef GoUint64 GoUint;
|
||||
typedef size_t GoUintptr;
|
||||
typedef float GoFloat32;
|
||||
typedef double GoFloat64;
|
||||
#ifdef _MSC_VER
|
||||
#include <complex.h>
|
||||
typedef _Fcomplex GoComplex64;
|
||||
typedef _Dcomplex GoComplex128;
|
||||
#else
|
||||
typedef float _Complex GoComplex64;
|
||||
typedef double _Complex GoComplex128;
|
||||
#endif
|
||||
|
||||
/*
|
||||
static assertion to make sure the file is being used on architecture
|
||||
at least with matching size of GoInt.
|
||||
*/
|
||||
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
|
||||
|
||||
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef _GoString_ GoString;
|
||||
#endif
|
||||
typedef void *GoMap;
|
||||
typedef void *GoChan;
|
||||
typedef struct { void *t; void *v; } GoInterface;
|
||||
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
|
||||
|
||||
#endif
|
||||
|
||||
/* End of boilerplate cgo prologue. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void InitSQLite(char* pragmas);
|
||||
extern char* HandleQuery(char* input);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
33
cgo/go.mod
Normal file
33
cgo/go.mod
Normal file
|
@ -0,0 +1,33 @@
|
|||
module srv
|
||||
|
||||
go 1.22.6
|
||||
|
||||
replace l12.xyz/dal/filters v0.0.0 => ../pkg/filters
|
||||
|
||||
replace l12.xyz/dal/builder v0.0.0 => ../pkg/builder
|
||||
|
||||
replace l12.xyz/dal/handler v0.0.0 => ../pkg/handler
|
||||
|
||||
require l12.xyz/dal/adapter v0.0.0 // indirect
|
||||
|
||||
replace l12.xyz/dal/adapter v0.0.0 => ../pkg/adapter
|
||||
|
||||
replace l12.xyz/dal/utils v0.0.0 => ../pkg/utils
|
||||
|
||||
replace l12.xyz/dal/proto v0.0.0 => ../pkg/proto
|
||||
|
||||
require l12.xyz/dal/facade v0.0.0
|
||||
|
||||
require l12.xyz/dal/handler v0.0.0 // indirect
|
||||
|
||||
replace l12.xyz/dal/facade v0.0.0 => ../pkg/facade
|
||||
|
||||
require (
|
||||
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/tinylib/msgp v1.2.0 // indirect
|
||||
l12.xyz/dal/builder v0.0.0 // indirect
|
||||
l12.xyz/dal/filters v0.0.0 // indirect
|
||||
l12.xyz/dal/proto v0.0.0 // indirect
|
||||
l12.xyz/dal/utils v0.0.0 // indirect
|
||||
)
|
8
cgo/go.sum
Normal file
8
cgo/go.sum
Normal file
|
@ -0,0 +1,8 @@
|
|||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 h1:jYi87L8j62qkXzaYHAQAhEapgukhenIMZRBKTNRLHJ4=
|
||||
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/tinylib/msgp v1.2.0 h1:0uKB/662twsVBpYUPbokj4sTSKhWFKB7LopO2kWK8lY=
|
||||
github.com/tinylib/msgp v1.2.0/go.mod h1:2vIGs3lcUo8izAATNobrCHevYZC/LMsJtw4JPiYPHro=
|
78
pkg/facade/SQLIteShared.go
Normal file
78
pkg/facade/SQLIteShared.go
Normal file
|
@ -0,0 +1,78 @@
|
|||
package facade
|
||||
|
||||
import (
|
||||
"log"
|
||||
"reflect"
|
||||
|
||||
"l12.xyz/dal/adapter"
|
||||
"l12.xyz/dal/proto"
|
||||
)
|
||||
|
||||
var db adapter.DBAdapter
|
||||
|
||||
func InitSQLite(pragmas []string) {
|
||||
if db.Type == "" {
|
||||
adapter.RegisterDialect("sqlite3", adapter.CommonDialect{})
|
||||
db = adapter.DBAdapter{
|
||||
Type: "sqlite3",
|
||||
}
|
||||
db.AfterOpen("PRAGMA journal_mode=WAL")
|
||||
}
|
||||
for _, pragma := range pragmas {
|
||||
if pragma == "" {
|
||||
continue
|
||||
}
|
||||
db.AfterOpen(pragma)
|
||||
}
|
||||
}
|
||||
|
||||
func HandleQuery(input *[]byte, output *[]byte) int {
|
||||
InitSQLite([]string{})
|
||||
req := proto.Request{}
|
||||
_, err := req.UnmarshalMsg(*input)
|
||||
if err != nil {
|
||||
log.Printf("failed to unmarshal request: %v", err)
|
||||
return 1
|
||||
}
|
||||
query, err := req.Parse(adapter.GetDialect(db.Type))
|
||||
if err != nil {
|
||||
log.Printf("failed to parse request: %v", err)
|
||||
return 1
|
||||
}
|
||||
if query.Exec {
|
||||
result, err := db.Exec(query)
|
||||
if err != nil {
|
||||
log.Printf("failed to exec query: %v", err)
|
||||
return 1
|
||||
}
|
||||
ra, _ := result.RowsAffected()
|
||||
la, _ := result.LastInsertId()
|
||||
res := proto.Response{
|
||||
Id: 0,
|
||||
RowsAffected: ra,
|
||||
LastInsertId: la,
|
||||
}
|
||||
*output, _ = res.MarshalMsg(nil)
|
||||
return 0
|
||||
}
|
||||
rows, err := db.Query(query)
|
||||
if err != nil {
|
||||
log.Printf("failed to query: %v", err)
|
||||
return 1
|
||||
}
|
||||
columns, _ := rows.Columns()
|
||||
types, _ := rows.ColumnTypes()
|
||||
cols, _ := proto.MarshalRow(columns)
|
||||
*output = append(*output, cols...)
|
||||
for rows.Next() {
|
||||
data := make([]interface{}, len(columns))
|
||||
for i := range data {
|
||||
typ := reflect.New(types[i].ScanType()).Interface()
|
||||
data[i] = &typ
|
||||
}
|
||||
rows.Scan(data...)
|
||||
cols, _ := proto.MarshalRow(data)
|
||||
*output = append(*output, cols...)
|
||||
}
|
||||
return 0
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package facade
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -64,6 +65,8 @@ Use `GetHandler` to get a handler for a custom server.
|
|||
*/
|
||||
func (s *SQLiteServer) Serve() {
|
||||
s.Init()
|
||||
log.Println("Starting server on port " + s.Port)
|
||||
log.Println("Using directory: " + s.Cwd)
|
||||
err := http.ListenAndServe(":"+s.Port, s.GetHandler())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
|
Loading…
Reference in a new issue