Skip to content

Commit

Permalink
Merge pull request #13 from billywhizz/main
Browse files Browse the repository at this point in the history
duckdb bindings
  • Loading branch information
billywhizz authored Dec 1, 2023
2 parents cc111d6 + 959237f commit 85d7f17
Show file tree
Hide file tree
Showing 10 changed files with 184 additions and 15 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ CCARGS=-std=c++17 -c -fno-omit-frame-pointer -fno-rtti -fno-exceptions
CARGS=-c -fno-omit-frame-pointer
WARN=-Werror -Wpedantic -Wall -Wextra -Wno-unused-parameter
OPT=-O3
VERSION=0.0.5-pre
VERSION=0.0.6-pre
V8_VERSION=1.0.0
RUNTIME=lo
LO_HOME=$(shell pwd)
Expand Down
5 changes: 5 additions & 0 deletions builtins.S
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ __binary_lib_curl_api_js_start:
.incbin "lib/curl/api.js"
.global __binary_lib_curl_api_js_end
__binary_lib_curl_api_js_end:
.global __binary_lib_duckdb_api_js_start
__binary_lib_duckdb_api_js_start:
.incbin "lib/duckdb/api.js"
.global __binary_lib_duckdb_api_js_end
__binary_lib_duckdb_api_js_end:
.global __binary_lib_encode_api_js_start
__binary_lib_encode_api_js_start:
.incbin "lib/encode/api.js"
Expand Down
5 changes: 5 additions & 0 deletions builtins_linux.S
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ _binary_lib_curl_api_js_start:
.incbin "lib/curl/api.js"
.global _binary_lib_curl_api_js_end
_binary_lib_curl_api_js_end:
.global _binary_lib_duckdb_api_js_start
_binary_lib_duckdb_api_js_start:
.incbin "lib/duckdb/api.js"
.global _binary_lib_duckdb_api_js_end
_binary_lib_duckdb_api_js_end:
.global _binary_lib_encode_api_js_start
_binary_lib_encode_api_js_start:
.incbin "lib/encode/api.js"
Expand Down
16 changes: 6 additions & 10 deletions lib/bench.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { mem } from 'lib/proc.js'

const { AY, AD, AG, AM } = lo.colors

function pad (v, size, precision = 0) {
Expand All @@ -16,11 +18,9 @@ class Bench {
#end = 0
#name = 'bench'
#display = true
#mem = undefined

constructor (display = true, mem) {
constructor (display = true) {
this.#display = display
this.#mem = mem
}

start (name = 'bench', pad = 32) {
Expand All @@ -33,13 +33,9 @@ class Bench {
const elapsed = this.#end - this.#start
const rate = Math.floor(count / (elapsed / 1e9))
const nanos = 1000000000 / rate
if (this.#mem) {
const rss = this.#mem()
if (this.#display) console.log(`${this.#name} ${AG}rate${AD} ${pad(rate, 10)} ${formatNanos(nanos)} ${AM}rss${AD} ${rss}`)
return { name: this.#name.trim(), count, elapsed, rate, nanos, rss }
}
if (this.#display) console.log(`${this.#name} ${AG}rate${AD} ${pad(rate, 10)} ${formatNanos(nanos)}`)
return { name: this.#name.trim(), count, elapsed, rate, nanos }
const rss = mem()
if (this.#display) console.log(`${this.#name} ${AG}rate${AD} ${pad(rate, 10)} ${formatNanos(nanos)} ${AM}rss${AD} ${rss}`)
return { name: this.#name.trim(), count, elapsed, rate, nanos, rss }
}
}

Expand Down
3 changes: 2 additions & 1 deletion lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ const encoder = new TextEncoder()
const status = new Int32Array(2)

// todo: clean up api so we can pass a config in and run builds through api
const VERSION = getenv('VERSION') || '"0.0.5pre"'
const VERSION = getenv('VERSION') || '"0.0.6pre"'
const RUNTIME = getenv('RUNTIME') || '"lo"'
const TARGET = getenv('TARGET') || 'lo'
const C = getenv('C') || 'gcc'
Expand Down Expand Up @@ -278,6 +278,7 @@ const runtimes = {
'lo.h',
'lib/core/api.js',
'lib/curl/api.js',
'lib/duckdb/api.js',
'lib/encode/api.js',
'lib/epoll/api.js',
'lib/inflate/api.js',
Expand Down
37 changes: 36 additions & 1 deletion lib/duckdb/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,39 @@ const api = {
pointers: ['duckdb_prepared_statement', 'duckdb_result*'],
result: 'i32',
name: 'duckdb_execute_prepared'
},
duckdb_column_name: {
// todo: these should be u64
parameters: ['pointer', 'u32'],
pointers: ['duckdb_result*'],
result: 'pointer',
rpointer: 'const char*',
name: 'duckdb_column_name'
},
result_error: {
parameters: ['pointer'],
pointers: ['duckdb_result*'],
result: 'pointer',
rpointer: 'const char*',
name: 'duckdb_result_error'
},
value_is_null: {
parameters: ['pointer', 'u32', 'u32'],
pointers: ['duckdb_result*'],
result: 'u32',
name: 'duckdb_value_is_null'
},
disconnect: {
parameters: ['pointer'],
pointers: ['duckdb_connection*'],
result: 'void',
name: 'duckdb_disconnect'
},
library_version: {
parameters: [],
result: 'pointer',
rpointer: 'const char*',
name: 'duckdb_library_version'
}
}

Expand All @@ -99,7 +132,9 @@ const obj = [
'deps/duckdb/duckdb.o', 'duckdb.a'
]

const constants = {}
const constants = {
DuckDBSuccess: 'i32', DuckDBError: 'i32'
}
const include_paths = ['./deps/duckdb/src/include']
const includes = [
'duckdb.h'
Expand Down
125 changes: 124 additions & 1 deletion lib/duckdb/duckdb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,57 @@ v8::CTypeInfo rcexecute_prepared = v8::CTypeInfo(v8::CTypeInfo::Type::kInt32);
v8::CFunctionInfo infoexecute_prepared = v8::CFunctionInfo(rcexecute_prepared, 3, cargsexecute_prepared);
v8::CFunction pFexecute_prepared = v8::CFunction((const void*)&execute_preparedFast, &infoexecute_prepared);

void duckdb_column_nameFast(void* p, void* p0, uint32_t p1, struct FastApiTypedArray* const p_ret);
v8::CTypeInfo cargsduckdb_column_name[4] = {
v8::CTypeInfo(v8::CTypeInfo::Type::kV8Value),
v8::CTypeInfo(v8::CTypeInfo::Type::kUint64),
v8::CTypeInfo(v8::CTypeInfo::Type::kUint32),
v8::CTypeInfo(v8::CTypeInfo::Type::kUint32, v8::CTypeInfo::SequenceType::kIsTypedArray, v8::CTypeInfo::Flags::kNone)
};
v8::CTypeInfo rcduckdb_column_name = v8::CTypeInfo(v8::CTypeInfo::Type::kVoid);
v8::CFunctionInfo infoduckdb_column_name = v8::CFunctionInfo(rcduckdb_column_name, 4, cargsduckdb_column_name);
v8::CFunction pFduckdb_column_name = v8::CFunction((const void*)&duckdb_column_nameFast, &infoduckdb_column_name);

void result_errorFast(void* p, void* p0, struct FastApiTypedArray* const p_ret);
v8::CTypeInfo cargsresult_error[3] = {
v8::CTypeInfo(v8::CTypeInfo::Type::kV8Value),
v8::CTypeInfo(v8::CTypeInfo::Type::kUint64),
v8::CTypeInfo(v8::CTypeInfo::Type::kUint32, v8::CTypeInfo::SequenceType::kIsTypedArray, v8::CTypeInfo::Flags::kNone)
};
v8::CTypeInfo rcresult_error = v8::CTypeInfo(v8::CTypeInfo::Type::kVoid);
v8::CFunctionInfo inforesult_error = v8::CFunctionInfo(rcresult_error, 3, cargsresult_error);
v8::CFunction pFresult_error = v8::CFunction((const void*)&result_errorFast, &inforesult_error);

uint32_t value_is_nullFast(void* p, void* p0, uint32_t p1, uint32_t p2);
v8::CTypeInfo cargsvalue_is_null[4] = {
v8::CTypeInfo(v8::CTypeInfo::Type::kV8Value),
v8::CTypeInfo(v8::CTypeInfo::Type::kUint64),
v8::CTypeInfo(v8::CTypeInfo::Type::kUint32),
v8::CTypeInfo(v8::CTypeInfo::Type::kUint32),
};
v8::CTypeInfo rcvalue_is_null = v8::CTypeInfo(v8::CTypeInfo::Type::kUint32);
v8::CFunctionInfo infovalue_is_null = v8::CFunctionInfo(rcvalue_is_null, 4, cargsvalue_is_null);
v8::CFunction pFvalue_is_null = v8::CFunction((const void*)&value_is_nullFast, &infovalue_is_null);

void disconnectFast(void* p, void* p0);
v8::CTypeInfo cargsdisconnect[2] = {
v8::CTypeInfo(v8::CTypeInfo::Type::kV8Value),
v8::CTypeInfo(v8::CTypeInfo::Type::kUint64),
};
v8::CTypeInfo rcdisconnect = v8::CTypeInfo(v8::CTypeInfo::Type::kVoid);
v8::CFunctionInfo infodisconnect = v8::CFunctionInfo(rcdisconnect, 2, cargsdisconnect);
v8::CFunction pFdisconnect = v8::CFunction((const void*)&disconnectFast, &infodisconnect);

void library_versionFast(void* p, struct FastApiTypedArray* const p_ret);
v8::CTypeInfo cargslibrary_version[2] = {
v8::CTypeInfo(v8::CTypeInfo::Type::kV8Value),

v8::CTypeInfo(v8::CTypeInfo::Type::kUint32, v8::CTypeInfo::SequenceType::kIsTypedArray, v8::CTypeInfo::Flags::kNone)
};
v8::CTypeInfo rclibrary_version = v8::CTypeInfo(v8::CTypeInfo::Type::kVoid);
v8::CFunctionInfo infolibrary_version = v8::CFunctionInfo(rclibrary_version, 2, cargslibrary_version);
v8::CFunction pFlibrary_version = v8::CFunction((const void*)&library_versionFast, &infolibrary_version);



void create_configSlow(const FunctionCallbackInfo<Value> &args) {
Expand Down Expand Up @@ -397,6 +448,71 @@ int32_t execute_preparedFast(void* p, void* p0, void* p1) {
duckdb_result* v1 = reinterpret_cast<duckdb_result*>(p1);
return duckdb_execute_prepared(v0, v1);
}
void duckdb_column_nameSlow(const FunctionCallbackInfo<Value> &args) {
duckdb_result* v0 = reinterpret_cast<duckdb_result*>((uint64_t)Local<Integer>::Cast(args[0])->Value());
uint32_t v1 = Local<Integer>::Cast(args[1])->Value();
const char* rc = duckdb_column_name(v0, v1);
Local<ArrayBuffer> ab = args[2].As<Uint32Array>()->Buffer();
((const char**)ab->Data())[0] = rc;
}

void duckdb_column_nameFast(void* p, void* p0, uint32_t p1, struct FastApiTypedArray* const p_ret) {
duckdb_result* v0 = reinterpret_cast<duckdb_result*>(p0);
uint32_t v1 = p1;
const char* r = duckdb_column_name(v0, v1);
((const char**)p_ret->data)[0] = r;

}
void result_errorSlow(const FunctionCallbackInfo<Value> &args) {
duckdb_result* v0 = reinterpret_cast<duckdb_result*>((uint64_t)Local<Integer>::Cast(args[0])->Value());
const char* rc = duckdb_result_error(v0);
Local<ArrayBuffer> ab = args[1].As<Uint32Array>()->Buffer();
((const char**)ab->Data())[0] = rc;
}

void result_errorFast(void* p, void* p0, struct FastApiTypedArray* const p_ret) {
duckdb_result* v0 = reinterpret_cast<duckdb_result*>(p0);
const char* r = duckdb_result_error(v0);
((const char**)p_ret->data)[0] = r;

}
void value_is_nullSlow(const FunctionCallbackInfo<Value> &args) {
Isolate *isolate = args.GetIsolate();
duckdb_result* v0 = reinterpret_cast<duckdb_result*>((uint64_t)Local<Integer>::Cast(args[0])->Value());
uint32_t v1 = Local<Integer>::Cast(args[1])->Value();
uint32_t v2 = Local<Integer>::Cast(args[2])->Value();
uint32_t rc = duckdb_value_is_null(v0, v1, v2);
args.GetReturnValue().Set(Number::New(isolate, rc));
}

uint32_t value_is_nullFast(void* p, void* p0, uint32_t p1, uint32_t p2) {
duckdb_result* v0 = reinterpret_cast<duckdb_result*>(p0);
uint32_t v1 = p1;
uint32_t v2 = p2;
return duckdb_value_is_null(v0, v1, v2);
}
void disconnectSlow(const FunctionCallbackInfo<Value> &args) {
duckdb_connection* v0 = reinterpret_cast<duckdb_connection*>((uint64_t)Local<Integer>::Cast(args[0])->Value());
duckdb_disconnect(v0);
}

void disconnectFast(void* p, void* p0) {
duckdb_connection* v0 = reinterpret_cast<duckdb_connection*>(p0);
duckdb_disconnect(v0);
}
void library_versionSlow(const FunctionCallbackInfo<Value> &args) {

const char* rc = duckdb_library_version();
Local<ArrayBuffer> ab = args[0].As<Uint32Array>()->Buffer();
((const char**)ab->Data())[0] = rc;
}

void library_versionFast(void* p, struct FastApiTypedArray* const p_ret) {

const char* r = duckdb_library_version();
((const char**)p_ret->data)[0] = r;

}

void Init(Isolate* isolate, Local<ObjectTemplate> target) {
Local<ObjectTemplate> module = ObjectTemplate::New(isolate);
Expand All @@ -414,7 +530,14 @@ void Init(Isolate* isolate, Local<ObjectTemplate> target) {
SET_FAST_METHOD(isolate, module, "destroy_result", &pFdestroy_result, destroy_resultSlow);
SET_FAST_METHOD(isolate, module, "destroy_prepare", &pFdestroy_prepare, destroy_prepareSlow);
SET_FAST_METHOD(isolate, module, "execute_prepared", &pFexecute_prepared, execute_preparedSlow);

SET_FAST_METHOD(isolate, module, "duckdb_column_name", &pFduckdb_column_name, duckdb_column_nameSlow);
SET_FAST_METHOD(isolate, module, "result_error", &pFresult_error, result_errorSlow);
SET_FAST_METHOD(isolate, module, "value_is_null", &pFvalue_is_null, value_is_nullSlow);
SET_FAST_METHOD(isolate, module, "disconnect", &pFdisconnect, disconnectSlow);
SET_FAST_METHOD(isolate, module, "library_version", &pFlibrary_version, library_versionSlow);

SET_VALUE(isolate, module, "DuckDBSuccess", Integer::New(isolate, DuckDBSuccess));
SET_VALUE(isolate, module, "DuckDBError", Integer::New(isolate, DuckDBError));

SET_VALUE(isolate, module, "struct_duckdb_config_size", Integer::New(isolate, sizeof(duckdb_config)));
SET_VALUE(isolate, module, "struct_duckdb_result_size", Integer::New(isolate, sizeof(duckdb_result)));
Expand Down
3 changes: 3 additions & 0 deletions main.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ extern char _binary_lib_core_api_js_start[];
extern char _binary_lib_core_api_js_end[];
extern char _binary_lib_curl_api_js_start[];
extern char _binary_lib_curl_api_js_end[];
extern char _binary_lib_duckdb_api_js_start[];
extern char _binary_lib_duckdb_api_js_end[];
extern char _binary_lib_encode_api_js_start[];
extern char _binary_lib_encode_api_js_end[];
extern char _binary_lib_epoll_api_js_start[];
Expand Down Expand Up @@ -94,6 +96,7 @@ void register_builtins() {
lo::builtins_add("lo.h", _binary_lo_h_start, _binary_lo_h_end - _binary_lo_h_start);
lo::builtins_add("lib/core/api.js", _binary_lib_core_api_js_start, _binary_lib_core_api_js_end - _binary_lib_core_api_js_start);
lo::builtins_add("lib/curl/api.js", _binary_lib_curl_api_js_start, _binary_lib_curl_api_js_end - _binary_lib_curl_api_js_start);
lo::builtins_add("lib/duckdb/api.js", _binary_lib_duckdb_api_js_start, _binary_lib_duckdb_api_js_end - _binary_lib_duckdb_api_js_start);
lo::builtins_add("lib/encode/api.js", _binary_lib_encode_api_js_start, _binary_lib_encode_api_js_end - _binary_lib_encode_api_js_start);
lo::builtins_add("lib/epoll/api.js", _binary_lib_epoll_api_js_start, _binary_lib_epoll_api_js_end - _binary_lib_epoll_api_js_start);
lo::builtins_add("lib/inflate/api.js", _binary_lib_inflate_api_js_start, _binary_lib_inflate_api_js_end - _binary_lib_inflate_api_js_start);
Expand Down
2 changes: 1 addition & 1 deletion main.js
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ lo.core = core
// todo: should we just overwrite the existing ones and not put these on "lo"?
lo.getenv = wrap_getenv()
lo.getcwd = wrap_getcwd()
const LO_HOME = lo.getenv('LO_HOME')
const LO_HOME = lo.getenv('LO_HOME') || './'
const LO_CACHE = parseInt(lo.getenv('LO_CACHE') || '0', 10)
core.dlopen = wrap(handle, core.dlopen, 2)
core.dlsym = wrap(handle, core.dlsym, 2)
Expand Down
1 change: 1 addition & 0 deletions main_win.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ void register_builtins() {
lo::builtins_add("lo.h", _binary_lo_h_start, _binary_lo_h_len);
lo::builtins_add("lib/core/api.js", _binary_lib_core_api_js_start, _binary_lib_core_api_js_len);
lo::builtins_add("lib/curl/api.js", _binary_lib_curl_api_js_start, _binary_lib_curl_api_js_len);
lo::builtins_add("lib/duckdb/api.js", _binary_lib_duckdb_api_js_start, _binary_lib_duckdb_api_js_len);
lo::builtins_add("lib/encode/api.js", _binary_lib_encode_api_js_start, _binary_lib_encode_api_js_len);
lo::builtins_add("lib/epoll/api.js", _binary_lib_epoll_api_js_start, _binary_lib_epoll_api_js_len);
lo::builtins_add("lib/inflate/api.js", _binary_lib_inflate_api_js_start, _binary_lib_inflate_api_js_len);
Expand Down

0 comments on commit 85d7f17

Please sign in to comment.