Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ ifdef EMSCRIPTEN
$(CXXFLAGS) \
-I$(LIBPG_QUERY_DIR) \
-L$(LIBPG_QUERY_DIR) \
-sEXPORTED_FUNCTIONS="['_malloc','_free','_wasm_parse_query','_wasm_parse_query_protobuf','_wasm_get_protobuf_len','_wasm_deparse_protobuf','_wasm_parse_plpgsql','_wasm_fingerprint','_wasm_normalize_query','_wasm_parse_query_detailed','_wasm_free_detailed_result','_wasm_free_string']" \
-sEXPORTED_FUNCTIONS="['_malloc','_free','_wasm_parse_query','_wasm_parse_query_protobuf','_wasm_get_protobuf_len','_wasm_deparse_protobuf','_wasm_deparse_json','_wasm_parse_plpgsql','_wasm_fingerprint','_wasm_normalize_query','_wasm_parse_query_detailed','_wasm_free_detailed_result','_wasm_free_string']" \
-sEXPORTED_RUNTIME_METHODS="['lengthBytesUTF8','stringToUTF8','UTF8ToString','HEAPU8','HEAPU32']" \
-sEXPORT_NAME="$(WASM_MODULE_NAME)" \
-sENVIRONMENT="web,node" \
Expand Down
32 changes: 32 additions & 0 deletions src/wasm_wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,38 @@ void wasm_free_detailed_result(WasmDetailedResult* result) {
}
}

EMSCRIPTEN_KEEPALIVE
char* wasm_deparse_json(const char* json_input) {
if (!validate_input(json_input)) {
return safe_strdup("Invalid input: JSON cannot be null or empty");
}

PgQueryProtobuf protobuf = pg_query_json_to_protobuf(json_input);

if (!protobuf.data || protobuf.len <= 0) {
return safe_strdup("Failed to convert JSON to protobuf");
}

PgQueryDeparseResult deparse_result = pg_query_deparse_protobuf(protobuf);

free(protobuf.data);

if (deparse_result.error) {
char* error_msg = safe_strdup(deparse_result.error->message);
pg_query_free_deparse_result(deparse_result);
return error_msg;
}

if (!deparse_result.query) {
pg_query_free_deparse_result(deparse_result);
return safe_strdup("Failed to deparse query");
}

char* query_copy = safe_strdup(deparse_result.query);
pg_query_free_deparse_result(deparse_result);
return query_copy;
}

EMSCRIPTEN_KEEPALIVE
void wasm_free_string(char* str) {
free(str);
Expand Down
41 changes: 25 additions & 16 deletions wasm/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ const parseQuery = awaitInit(async (query) => {
throw new Error(resultStr);
}

return JSON.parse(resultStr);
const parsed = JSON.parse(resultStr);
parsed.query = query;
return parsed;
} finally {
wasmModule._free(queryPtr);
if (resultPtr) {
Expand All @@ -58,23 +60,25 @@ const parseQuery = awaitInit(async (query) => {
});

const deparse = awaitInit(async (parseTree) => {
const queryPtr = stringToPtr(JSON.stringify(parseTree));
let resultPtr;
if (!parseTree || !parseTree.stmts || parseTree.stmts.length === 0) {
throw new Error('No protobuf data found in parse tree');
}

const jsonPtr = stringToPtr(JSON.stringify(parseTree));

try {
resultPtr = wasmModule._wasm_deparse_protobuf(queryPtr, 0);
const resultPtr = wasmModule._wasm_deparse_json(jsonPtr);
const resultStr = ptrToString(resultPtr);

wasmModule._wasm_free_string(resultPtr);

if (resultStr.startsWith('syntax error') || resultStr.startsWith('deparse error') || resultStr.includes('ERROR')) {
throw new Error(resultStr);
}

return resultStr;
} finally {
wasmModule._free(queryPtr);
if (resultPtr) {
wasmModule._wasm_free_string(resultPtr);
}
wasmModule._free(jsonPtr);
}
});

Expand Down Expand Up @@ -196,7 +200,9 @@ function parseQuerySync(query) {
throw new Error(resultStr);
}

return JSON.parse(resultStr);
const parsed = JSON.parse(resultStr);
parsed.query = query;
return parsed;
} finally {
wasmModule._free(queryPtr);
if (resultPtr) {
Expand All @@ -209,23 +215,26 @@ function deparseSync(parseTree) {
if (!wasmModule) {
throw new Error('WASM module not initialized. Call loadModule() first.');
}
const queryPtr = stringToPtr(JSON.stringify(parseTree));
let resultPtr;

if (!parseTree || !parseTree.stmts || parseTree.stmts.length === 0) {
throw new Error('No protobuf data found in parse tree');
}

const jsonPtr = stringToPtr(JSON.stringify(parseTree));

try {
resultPtr = wasmModule._wasm_deparse_protobuf(queryPtr, 0);
const resultPtr = wasmModule._wasm_deparse_json(jsonPtr);
const resultStr = ptrToString(resultPtr);

wasmModule._wasm_free_string(resultPtr);

if (resultStr.startsWith('syntax error') || resultStr.startsWith('deparse error') || resultStr.includes('ERROR')) {
throw new Error(resultStr);
}

return resultStr;
} finally {
wasmModule._free(queryPtr);
if (resultPtr) {
wasmModule._wasm_free_string(resultPtr);
}
wasmModule._free(jsonPtr);
}
}

Expand Down
41 changes: 25 additions & 16 deletions wasm/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ export const parseQuery = awaitInit(async (query) => {
throw new Error(resultStr);
}

return JSON.parse(resultStr);
const parsed = JSON.parse(resultStr);
parsed.query = query;
return parsed;
} finally {
wasmModule._free(queryPtr);
if (resultPtr) {
Expand All @@ -58,23 +60,25 @@ export const parseQuery = awaitInit(async (query) => {
});

export const deparse = awaitInit(async (parseTree) => {
const queryPtr = stringToPtr(JSON.stringify(parseTree));
let resultPtr;
if (!parseTree || !parseTree.stmts || parseTree.stmts.length === 0) {
throw new Error('No protobuf data found in parse tree');
}

const jsonPtr = stringToPtr(JSON.stringify(parseTree));

try {
resultPtr = wasmModule._wasm_deparse_protobuf(queryPtr, 0);
const resultPtr = wasmModule._wasm_deparse_json(jsonPtr);
const resultStr = ptrToString(resultPtr);

wasmModule._wasm_free_string(resultPtr);

if (resultStr.startsWith('syntax error') || resultStr.startsWith('deparse error') || resultStr.includes('ERROR')) {
throw new Error(resultStr);
}

return resultStr;
} finally {
wasmModule._free(queryPtr);
if (resultPtr) {
wasmModule._wasm_free_string(resultPtr);
}
wasmModule._free(jsonPtr);
}
});

Expand Down Expand Up @@ -196,7 +200,9 @@ export function parseQuerySync(query) {
throw new Error(resultStr);
}

return JSON.parse(resultStr);
const parsed = JSON.parse(resultStr);
parsed.query = query;
return parsed;
} finally {
wasmModule._free(queryPtr);
if (resultPtr) {
Expand All @@ -209,23 +215,26 @@ export function deparseSync(parseTree) {
if (!wasmModule) {
throw new Error('WASM module not initialized. Call loadModule() first.');
}
const queryPtr = stringToPtr(JSON.stringify(parseTree));
let resultPtr;

if (!parseTree || !parseTree.stmts || parseTree.stmts.length === 0) {
throw new Error('No protobuf data found in parse tree');
}

const jsonPtr = stringToPtr(JSON.stringify(parseTree));

try {
resultPtr = wasmModule._wasm_deparse_protobuf(queryPtr, 0);
const resultPtr = wasmModule._wasm_deparse_json(jsonPtr);
const resultStr = ptrToString(resultPtr);

wasmModule._wasm_free_string(resultPtr);

if (resultStr.startsWith('syntax error') || resultStr.startsWith('deparse error') || resultStr.includes('ERROR')) {
throw new Error(resultStr);
}

return resultStr;
} finally {
wasmModule._free(queryPtr);
if (resultPtr) {
wasmModule._wasm_free_string(resultPtr);
}
wasmModule._free(jsonPtr);
}
}

Expand Down
Loading