Skip to content

Commit a5faf04

Browse files
author
Dylan Storey
committed
Fix Windows DLL runtime dependencies with static linking
- Add -static flag to Windows (MINGW/MSYS) extension builds - Statically links C runtime and libsystre to eliminate MSYS2 DLL dependencies - Bump version to 0.1.1rc1 for testing Fixes #4
1 parent 5251d4a commit a5faf04

File tree

7 files changed

+147
-4
lines changed

7 files changed

+147
-4
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,9 @@ $(EXTENSION_LIB): $(EXTENSION_OBJ) $(PARSER_OBJS_PIC) $(TRANSFORM_OBJS_PIC) $(EX
267267
ifeq ($(UNAME_S),Darwin)
268268
$(CC) -g -fPIC -dynamiclib $(EXTENSION_OBJ) $(PARSER_OBJS_PIC) $(TRANSFORM_OBJS_PIC) $(EXECUTOR_OBJS_PIC) -o $@ -undefined dynamic_lookup
269269
else ifneq (,$(findstring MINGW,$(UNAME_S)))
270-
$(CC) -shared $(EXTENSION_OBJ) $(PARSER_OBJS_PIC) $(TRANSFORM_OBJS_PIC) $(EXECUTOR_OBJS_PIC) -o $@ -lsqlite3 -lsystre
270+
$(CC) -shared -static $(EXTENSION_OBJ) $(PARSER_OBJS_PIC) $(TRANSFORM_OBJS_PIC) $(EXECUTOR_OBJS_PIC) -o $@ -lsqlite3 -lsystre -ltre
271271
else ifneq (,$(findstring MSYS,$(UNAME_S)))
272-
$(CC) -shared $(EXTENSION_OBJ) $(PARSER_OBJS_PIC) $(TRANSFORM_OBJS_PIC) $(EXECUTOR_OBJS_PIC) -o $@ -lsqlite3 -lsystre
272+
$(CC) -shared -static $(EXTENSION_OBJ) $(PARSER_OBJS_PIC) $(TRANSFORM_OBJS_PIC) $(EXECUTOR_OBJS_PIC) -o $@ -lsqlite3 -lsystre -ltre
273273
else
274274
$(CC) -shared -fPIC $(EXTENSION_OBJ) $(PARSER_OBJS_PIC) $(TRANSFORM_OBJS_PIC) $(EXECUTOR_OBJS_PIC) -o $@
275275
endif

bindings/python/src/graphqlite/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from .utils import escape_string, sanitize_rel_type, CYPHER_RESERVED
88
from ._platform import get_loadable_path
99

10-
__version__ = "0.1.0"
10+
__version__ = "0.1.1rc1"
1111
__all__ = [
1212
"Connection", "connect", "wrap", "load", "loadable_path",
1313
"Graph", "graph", "escape_string", "sanitize_rel_type", "CYPHER_RESERVED"

bindings/rust/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "graphqlite"
3-
version = "0.1.0"
3+
version = "0.1.1-rc1"
44
edition = "2021"
55
description = "SQLite extension for graph queries using Cypher"
66
license = "MIT"

test_param_id

33.6 KB
Binary file not shown.

test_param_match

33.1 KB
Binary file not shown.

tests/test_param_id.c

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/**
2+
* Test parameterized queries returning correct node IDs
3+
*/
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <string.h>
7+
#include <sqlite3.h>
8+
9+
int main() {
10+
sqlite3 *db;
11+
char *err_msg = NULL;
12+
int rc;
13+
14+
// Open in-memory database
15+
rc = sqlite3_open(":memory:", &db);
16+
if (rc != SQLITE_OK) {
17+
fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
18+
return 1;
19+
}
20+
21+
// Load graphqlite extension
22+
sqlite3_enable_load_extension(db, 1);
23+
rc = sqlite3_load_extension(db, "./build/graphqlite", NULL, &err_msg);
24+
if (rc != SQLITE_OK) {
25+
fprintf(stderr, "Cannot load extension: %s\n", err_msg);
26+
sqlite3_free(err_msg);
27+
return 1;
28+
}
29+
30+
printf("Test: Parameterized queries should return unique node IDs\n\n");
31+
32+
// Create three nodes with different names using parameters
33+
const char *names[] = {"Alice", "Bob", "Charlie"};
34+
int node_ids[3] = {0, 0, 0};
35+
36+
for (int i = 0; i < 3; i++) {
37+
// Create node with parameterized query
38+
char query[512];
39+
snprintf(query, sizeof(query),
40+
"SELECT cypher('CREATE (a:Person {name: $name})', '{\"name\": \"%s\"}')",
41+
names[i]);
42+
43+
rc = sqlite3_exec(db, query, NULL, NULL, &err_msg);
44+
if (rc != SQLITE_OK) {
45+
fprintf(stderr, "Create failed: %s\n", err_msg);
46+
sqlite3_free(err_msg);
47+
return 1;
48+
}
49+
printf("Created node with name: %s\n", names[i]);
50+
}
51+
52+
printf("\nQuerying nodes back:\n");
53+
54+
// Query each node back
55+
for (int i = 0; i < 3; i++) {
56+
char query[512];
57+
snprintf(query, sizeof(query),
58+
"SELECT cypher('MATCH (a:Person {name: $name}) RETURN id(a) AS node_id, a.name AS name', '{\"name\": \"%s\"}')",
59+
names[i]);
60+
61+
sqlite3_stmt *stmt;
62+
rc = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
63+
if (rc != SQLITE_OK) {
64+
fprintf(stderr, "Prepare failed: %s\n", sqlite3_errmsg(db));
65+
return 1;
66+
}
67+
68+
while (sqlite3_step(stmt) == SQLITE_ROW) {
69+
const char *result = (const char *)sqlite3_column_text(stmt, 0);
70+
printf(" Query for '%s': %s\n", names[i], result);
71+
}
72+
sqlite3_finalize(stmt);
73+
}
74+
75+
printf("\nQuerying all nodes without parameters:\n");
76+
77+
// Query all nodes
78+
sqlite3_stmt *stmt;
79+
rc = sqlite3_prepare_v2(db,
80+
"SELECT cypher('MATCH (a:Person) RETURN id(a) AS node_id, a.name AS name')",
81+
-1, &stmt, NULL);
82+
if (rc == SQLITE_OK) {
83+
while (sqlite3_step(stmt) == SQLITE_ROW) {
84+
const char *result = (const char *)sqlite3_column_text(stmt, 0);
85+
printf(" %s\n", result);
86+
}
87+
sqlite3_finalize(stmt);
88+
}
89+
90+
sqlite3_close(db);
91+
printf("\nTest complete.\n");
92+
return 0;
93+
}

tests/test_param_match.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* Test: Parameters in MATCH WHERE clause
3+
*/
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <string.h>
7+
#include <sqlite3.h>
8+
9+
static int callback(void *data, int argc, char **argv, char **colnames) {
10+
for (int i = 0; i < argc; i++) {
11+
printf(" %s = %s\n", colnames[i], argv[i] ? argv[i] : "NULL");
12+
}
13+
return 0;
14+
}
15+
16+
int main() {
17+
sqlite3 *db;
18+
char *err_msg = NULL;
19+
int rc;
20+
21+
rc = sqlite3_open(":memory:", &db);
22+
sqlite3_enable_load_extension(db, 1);
23+
rc = sqlite3_load_extension(db, "./build/graphqlite", NULL, &err_msg);
24+
if (rc != SQLITE_OK) {
25+
fprintf(stderr, "Load failed: %s\n", err_msg);
26+
return 1;
27+
}
28+
29+
printf("=== Test 1: CREATE with literal values ===\n");
30+
sqlite3_exec(db, "SELECT cypher('CREATE (a:Person {name: \"Alice\"})')", callback, NULL, &err_msg);
31+
sqlite3_exec(db, "SELECT cypher('CREATE (a:Person {name: \"Bob\"})')", callback, NULL, &err_msg);
32+
33+
printf("\n=== Query all nodes ===\n");
34+
sqlite3_exec(db, "SELECT cypher('MATCH (a:Person) RETURN a.name AS name')", callback, NULL, &err_msg);
35+
36+
printf("\n=== Test 2: MATCH with literal filter ===\n");
37+
sqlite3_exec(db, "SELECT cypher('MATCH (a:Person {name: \"Alice\"}) RETURN a.name AS name')", callback, NULL, &err_msg);
38+
39+
printf("\n=== Test 3: MATCH with parameter filter ===\n");
40+
sqlite3_exec(db, "SELECT cypher('MATCH (a:Person {name: $name}) RETURN a.name AS name', '{\"name\": \"Alice\"}')", callback, NULL, &err_msg);
41+
42+
printf("\n=== Test 4: CREATE with parameter ===\n");
43+
sqlite3_exec(db, "SELECT cypher('CREATE (a:Person {name: $name})', '{\"name\": \"Charlie\"}')", callback, NULL, &err_msg);
44+
45+
printf("\n=== Query all after param CREATE ===\n");
46+
sqlite3_exec(db, "SELECT cypher('MATCH (a:Person) RETURN a.name AS name')", callback, NULL, &err_msg);
47+
48+
sqlite3_close(db);
49+
return 0;
50+
}

0 commit comments

Comments
 (0)