[feat] test nodejs bindings
Signed-off-by: Anton Nesterov <anton@demiurg.io>
This commit is contained in:
parent
87e3fdd18d
commit
07a61af8e5
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,6 +1,8 @@
|
||||||
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
||||||
*.so
|
*.so
|
||||||
|
*.a
|
||||||
*.dylib
|
*.dylib
|
||||||
|
build/
|
||||||
# Logs
|
# Logs
|
||||||
|
|
||||||
logs
|
logs
|
||||||
|
|
16
binding.gyp
Normal file
16
binding.gyp
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
'targets': [
|
||||||
|
{
|
||||||
|
'target_name': 'dal',
|
||||||
|
'sources': [
|
||||||
|
'cgo/dal.h',
|
||||||
|
'cgo/dal.cc'
|
||||||
|
],
|
||||||
|
'libraries': [ '../cgo/dal.a' ],
|
||||||
|
'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
|
||||||
|
"include_dirs": [
|
||||||
|
"<!@(node -p \"require('node-addon-api').include\")"
|
||||||
|
],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
26
cgo/dal.cc
Normal file
26
cgo/dal.cc
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include <napi.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "dal.h"
|
||||||
|
|
||||||
|
static void _InitSQLite(const Napi::CallbackInfo& args) {
|
||||||
|
Napi::Buffer<uint8_t> buf = args[0].As<Napi::Buffer<uint8_t>>();
|
||||||
|
char * charstr = reinterpret_cast<char *>(buf.Data());
|
||||||
|
InitSQLite(charstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Napi::Value Handle(const Napi::CallbackInfo& args) {
|
||||||
|
Napi::Buffer<uint8_t> buf = args[0].As<Napi::Buffer<uint8_t>>();
|
||||||
|
char * charstr = reinterpret_cast<char *>(buf.Data());
|
||||||
|
GoSlice result = HandleQuery(charstr);
|
||||||
|
return Napi::Buffer<char>::Copy(args.Env(), reinterpret_cast<char *>(result.data), result.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
||||||
|
exports["InitSQLite"] = Napi::Function::New(env, _InitSQLite);
|
||||||
|
exports["Handle"] = Napi::Function::New(env, Handle);
|
||||||
|
return exports;
|
||||||
|
}
|
||||||
|
|
||||||
|
NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)
|
||||||
|
|
12
cgo/dal.go
12
cgo/dal.go
|
@ -4,8 +4,8 @@ package main
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
"l12.xyz/dal/facade"
|
"l12.xyz/dal/facade"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,15 +17,11 @@ func InitSQLite(pragmas *C.char) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//export HandleQuery
|
//export HandleQuery
|
||||||
func HandleQuery(input *C.char) *C.char {
|
func HandleQuery(input *C.char) []byte {
|
||||||
var in, out []byte
|
var in, out []byte
|
||||||
inPtr := unsafe.Pointer(input)
|
in = []byte(C.GoString(input))
|
||||||
defer C.free(inPtr)
|
|
||||||
|
|
||||||
in = C.GoBytes(inPtr, C.int(len(C.GoString(input))))
|
|
||||||
facade.HandleQuery(&in, &out)
|
facade.HandleQuery(&in, &out)
|
||||||
output := C.CString(string(out))
|
return out
|
||||||
return output
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {}
|
func main() {}
|
||||||
|
|
|
@ -79,7 +79,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void InitSQLite(char* pragmas);
|
extern void InitSQLite(char* pragmas);
|
||||||
extern char* HandleQuery(char* input);
|
extern GoSlice HandleQuery(char* input);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,10 @@ replace l12.xyz/dal/utils v0.0.0 => ../pkg/utils
|
||||||
|
|
||||||
replace l12.xyz/dal/proto v0.0.0 => ../pkg/proto
|
replace l12.xyz/dal/proto v0.0.0 => ../pkg/proto
|
||||||
|
|
||||||
require l12.xyz/dal/facade v0.0.0
|
require (
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.22
|
||||||
|
l12.xyz/dal/facade v0.0.0
|
||||||
|
)
|
||||||
|
|
||||||
require l12.xyz/dal/handler v0.0.0 // indirect
|
require l12.xyz/dal/handler v0.0.0 // indirect
|
||||||
|
|
||||||
|
|
3
dal/SQLite.ts
Normal file
3
dal/SQLite.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { createRequire } from 'node:module';
|
||||||
|
const require = createRequire(import.meta.url);
|
||||||
|
export default require('../build/Release/dal.node');
|
6
dal/__test__/sqlite.node.cjs
Normal file
6
dal/__test__/sqlite.node.cjs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
const dal = require('../../build/Release/dal.node');
|
||||||
|
dal.InitSQLite(Buffer.from([]));
|
||||||
|
const buf = fs.readFileSync('./pkg/__test__/proto_test.msgpack');
|
||||||
|
data = dal.Handle(buf);
|
||||||
|
console.log(data);
|
|
@ -4,6 +4,8 @@
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "latest",
|
"@types/bun": "latest",
|
||||||
|
"node-addon-api": "^8.1.0",
|
||||||
|
"node-gyp": "^10.2.0",
|
||||||
"prettier": "^3.3.3"
|
"prettier": "^3.3.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
@ -16,6 +18,8 @@
|
||||||
"test:client": "bun test:*",
|
"test:client": "bun test:*",
|
||||||
"test:dal": "bun test dal/__test__",
|
"test:dal": "bun test dal/__test__",
|
||||||
"test:serve": "cd dal/__test__/srv && go run main.go",
|
"test:serve": "cd dal/__test__/srv && go run main.go",
|
||||||
"fmt": "prettier --write ."
|
"fmt": "prettier --write .",
|
||||||
|
"cgo:prepare":"cd cgo && go build -buildmode=c-archive -o dal.a ./dal.go",
|
||||||
|
"cgo:build": "node-gyp configure build"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package tests
|
package tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -15,6 +16,7 @@ func TestProtoMessagePack(t *testing.T) {
|
||||||
t.Fatalf("failed to read file: %v", err)
|
t.Fatalf("failed to read file: %v", err)
|
||||||
}
|
}
|
||||||
req := proto.Request{}
|
req := proto.Request{}
|
||||||
|
fmt.Println(message)
|
||||||
req.UnmarshalMsg(message)
|
req.UnmarshalMsg(message)
|
||||||
query, err := req.Parse(adapter.CommonDialect{})
|
query, err := req.Parse(adapter.CommonDialect{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
いdbッdatabase.sqliteィcommands窒ヲmethod「In、args側dataえmethod、Find、args曹。a。b▲$gt
|
<EFBFBD>id ▃b留atabase.sqlite牢ommands<64>妃ethod@n兀rgs𪈠data<74>method了ind兀rgs<67>{}<>$gt
|
|
@ -2,6 +2,7 @@
|
||||||
import { encode } from "https://deno.land/x/msgpack@v1.2/mod.ts";
|
import { encode } from "https://deno.land/x/msgpack@v1.2/mod.ts";
|
||||||
|
|
||||||
const Query = {
|
const Query = {
|
||||||
|
id: 9,
|
||||||
db: "database.sqlite",
|
db: "database.sqlite",
|
||||||
commands: [
|
commands: [
|
||||||
{ method: "In", args: ["data"] },
|
{ method: "In", args: ["data"] },
|
||||||
|
|
|
@ -31,6 +31,7 @@ func HandleQuery(input *[]byte, output *[]byte) int {
|
||||||
req := proto.Request{}
|
req := proto.Request{}
|
||||||
_, err := req.UnmarshalMsg(*input)
|
_, err := req.UnmarshalMsg(*input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(*input)
|
||||||
log.Printf("failed to unmarshal request: %v", err)
|
log.Printf("failed to unmarshal request: %v", err)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@ require (
|
||||||
github.com/tinylib/msgp v1.2.0 // indirect
|
github.com/tinylib/msgp v1.2.0 // indirect
|
||||||
l12.xyz/dal/builder v0.0.0 // indirect
|
l12.xyz/dal/builder v0.0.0 // indirect
|
||||||
l12.xyz/dal/filters 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
|
l12.xyz/dal/utils v0.0.0 // indirect
|
||||||
|
l12.xyz/dal/proto v0.0.0
|
||||||
)
|
)
|
||||||
|
|
||||||
replace l12.xyz/dal/proto v0.0.0 => ../proto
|
replace l12.xyz/dal/proto v0.0.0 => ../proto
|
||||||
|
|
Loading…
Reference in a new issue