[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
|
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
# Logs
|
# Logs
|
||||||
|
|
||||||
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
|
package facade
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -64,6 +65,8 @@ Use `GetHandler` to get a handler for a custom server.
|
||||||
*/
|
*/
|
||||||
func (s *SQLiteServer) Serve() {
|
func (s *SQLiteServer) Serve() {
|
||||||
s.Init()
|
s.Init()
|
||||||
|
log.Println("Starting server on port " + s.Port)
|
||||||
|
log.Println("Using directory: " + s.Cwd)
|
||||||
err := http.ListenAndServe(":"+s.Port, s.GetHandler())
|
err := http.ListenAndServe(":"+s.Port, s.GetHandler())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
Loading…
Reference in a new issue