[feat] prepare shared lib

Signed-off-by: Anton Nesterov <anton@demiurg.io>
This commit is contained in:
Anton Nesterov 2024-08-19 17:46:28 +02:00
parent 59b2dde114
commit 87e3fdd18d
No known key found for this signature in database
GPG key ID: 59121E8AE2851FB5
7 changed files with 241 additions and 1 deletions

3
.gitignore vendored
View file

@ -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
View 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
View 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
View 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
View 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=

View 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
}

View file

@ -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)