Skip to content

Commit a7790ac

Browse files
author
Dylan Storey
committed
chore: bump version to 0.2.0 and update documentation
1 parent ea4e642 commit a7790ac

File tree

11 files changed

+821
-21
lines changed

11 files changed

+821
-21
lines changed

bindings/python/src/graphqlite/__init__.py

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

11-
__version__ = "0.2.0rc2"
11+
__version__ = "0.2.0"
1212
__all__ = [
1313
"Connection", "connect", "wrap", "load", "loadable_path",
1414
"Graph", "graph", "GraphManager", "graphs",

bindings/rust/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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.2.0-rc.2"
3+
version = "0.2.0"
44
edition = "2021"
55
description = "SQLite extension for graph queries using Cypher"
66
license = "MIT"

docs/src/how-to/cli.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ This creates `build/gqlite`.
1515
## Usage
1616

1717
```bash
18-
# Interactive mode with default database
18+
# Interactive mode with default database (graphqlite.db)
1919
./build/gqlite
2020

2121
# Specify a database file

docs/src/how-to/installation.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pip install graphqlite
77
```
88

99
This installs pre-built binaries for:
10-
- Linux (x86_64)
10+
- Linux (x86_64, aarch64)
1111
- macOS (arm64, x86_64)
1212
- Windows (x86_64)
1313

@@ -17,7 +17,7 @@ Add to your `Cargo.toml`:
1717

1818
```toml
1919
[dependencies]
20-
graphqlite = "0.1"
20+
graphqlite = "0.2"
2121
```
2222

2323
## From Source

docs/src/reference/algorithms.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ Detects communities by propagating labels through the network.
6969
```cypher
7070
RETURN labelPropagation()
7171
RETURN labelPropagation(10) -- max iterations
72+
RETURN communities() -- alias
7273
```
7374

7475
**Returns**: `[{"node_id": int, "user_id": string, "community": int}, ...]`

docs/src/reference/cypher-clauses.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,29 @@ MATCH (a)-[:KNOWS]->(b) RETURN a, b
1212
MATCH (n:Person {name: 'Alice'}) RETURN n
1313
```
1414

15+
### Shortest Path Patterns
16+
17+
Find shortest paths between nodes:
18+
19+
```cypher
20+
// Find a single shortest path
21+
MATCH p = shortestPath((a:Person {name: 'Alice'})-[*]-(b:Person {name: 'Bob'}))
22+
RETURN p, length(p)
23+
24+
// Find all shortest paths (all paths with minimum length)
25+
MATCH p = allShortestPaths((a:Person)-[*]-(b:Person))
26+
WHERE a.name = 'Alice' AND b.name = 'Bob'
27+
RETURN p
28+
29+
// With relationship type filter
30+
MATCH p = shortestPath((a)-[:KNOWS*]->(b))
31+
RETURN nodes(p), relationships(p)
32+
33+
// With length constraints
34+
MATCH p = shortestPath((a)-[*..10]->(b))
35+
RETURN p
36+
```
37+
1538
### OPTIONAL MATCH
1639

1740
Like MATCH, but returns NULL for non-matches (left join semantics):
@@ -137,6 +160,67 @@ MATCH p = (start)-[*]->(end)
137160
FOREACH (n IN nodes(p) | SET n.visited = true)
138161
```
139162

163+
### LOAD CSV
164+
165+
Import data from CSV files:
166+
167+
```cypher
168+
// With headers (access columns by name)
169+
LOAD CSV WITH HEADERS FROM 'file:///people.csv' AS row
170+
CREATE (n:Person {name: row.name, age: toInteger(row.age)})
171+
172+
// Without headers (access columns by index)
173+
LOAD CSV FROM 'file:///data.csv' AS row
174+
CREATE (n:Item {id: row[0], value: row[1]})
175+
176+
// Custom field terminator
177+
LOAD CSV WITH HEADERS FROM 'file:///data.tsv' AS row FIELDTERMINATOR '\t'
178+
CREATE (n:Record {field1: row.col1})
179+
```
180+
181+
**Note**: File paths are relative to the current working directory. Use `file:///` prefix for local files.
182+
183+
## Multi-Graph Queries
184+
185+
### FROM Clause
186+
187+
Query specific graphs when using GraphManager (multi-graph support):
188+
189+
```cypher
190+
// Query a specific graph
191+
MATCH (n:Person) FROM social
192+
RETURN n.name
193+
194+
// Combined with other clauses
195+
MATCH (p:Person) FROM social
196+
WHERE p.age > 21
197+
RETURN p.name, graph(p) AS source_graph
198+
```
199+
200+
The `graph()` function returns which graph a node came from.
201+
202+
## Combining Results
203+
204+
### UNION
205+
206+
Combine results from multiple queries, removing duplicates:
207+
208+
```cypher
209+
MATCH (n:Person) WHERE n.city = 'NYC' RETURN n.name
210+
UNION
211+
MATCH (n:Person) WHERE n.age > 50 RETURN n.name
212+
```
213+
214+
### UNION ALL
215+
216+
Combine results keeping all rows (including duplicates):
217+
218+
```cypher
219+
MATCH (a:Person)-[:KNOWS]->(b) RETURN b.name AS connection
220+
UNION ALL
221+
MATCH (a:Person)-[:WORKS_WITH]->(b) RETURN b.name AS connection
222+
```
223+
140224
## Return Clause
141225

142226
### RETURN

docs/src/reference/cypher-functions.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
| `right(s, n)` | Last n characters | `right('hello', 2)``'lo'` |
1616
| `split(s, delim)` | Split into list | `split('a,b,c', ',')``['a','b','c']` |
1717
| `reverse(s)` | Reverse string | `reverse('hello')``'olleh'` |
18+
| `length(s)` | String length | `length('hello')``5` |
19+
| `size(s)` | String length (alias) | `size('hello')``5` |
1820
| `toString(x)` | Convert to string | `toString(123)``'123'` |
1921

2022
## String Predicates
@@ -39,6 +41,7 @@
3941
| `log10(n)` | Base-10 logarithm | `log10(100)``2` |
4042
| `exp(n)` | e^n | `exp(1)``2.718...` |
4143
| `rand()` | Random 0-1 | `rand()``0.42...` |
44+
| `random()` | Random 0-1 (alias) | `random()``0.42...` |
4245
| `pi()` | π constant | `pi()``3.14159...` |
4346
| `e()` | e constant | `e()``2.71828...` |
4447

@@ -93,6 +96,7 @@
9396
|----------|-------------|---------|
9497
| `nodes(path)` | Get all nodes in path | `nodes(p)` |
9598
| `relationships(path)` | Get all relationships | `relationships(p)` |
99+
| `rels(path)` | Get all relationships (alias) | `rels(p)` |
96100
| `length(path)` | Path length (edges) | `length(p)` |
97101

98102
## Type Conversion
@@ -113,6 +117,7 @@
113117
| `time()` | Current time | `time()` |
114118
| `timestamp()` | Unix timestamp (ms) | `timestamp()` |
115119
| `localdatetime()` | Local datetime | `localdatetime()` |
120+
| `randomUUID()` | Generate random UUID | `randomUUID()``'550e8400-e29b-...'` |
116121

117122
## Predicate Functions
118123

@@ -130,3 +135,78 @@
130135
| Function | Description | Example |
131136
|----------|-------------|---------|
132137
| `reduce(acc = init, x IN list \| expr)` | Fold/reduce | `reduce(s = 0, x IN [1,2,3] \| s + x)``6` |
138+
139+
## CASE Expressions
140+
141+
### Searched CASE
142+
143+
Evaluates conditions in order and returns the first matching result:
144+
145+
```cypher
146+
RETURN CASE
147+
WHEN n.age < 18 THEN 'minor'
148+
WHEN n.age < 65 THEN 'adult'
149+
ELSE 'senior'
150+
END AS category
151+
```
152+
153+
### Simple CASE
154+
155+
Compares an expression against values:
156+
157+
```cypher
158+
RETURN CASE n.status
159+
WHEN 'A' THEN 'Active'
160+
WHEN 'I' THEN 'Inactive'
161+
WHEN 'P' THEN 'Pending'
162+
ELSE 'Unknown'
163+
END AS status_name
164+
```
165+
166+
## Comprehensions
167+
168+
### List Comprehension
169+
170+
Create lists by transforming or filtering:
171+
172+
```cypher
173+
// Transform each element
174+
RETURN [x IN range(1, 5) | x * 2]
175+
// → [2, 4, 6, 8, 10]
176+
177+
// Filter elements
178+
RETURN [x IN range(1, 10) WHERE x % 2 = 0]
179+
// → [2, 4, 6, 8, 10]
180+
181+
// Filter and transform
182+
RETURN [x IN range(1, 10) WHERE x % 2 = 0 | x * x]
183+
// → [4, 16, 36, 64, 100]
184+
```
185+
186+
### Pattern Comprehension
187+
188+
Extract data from pattern matches within an expression:
189+
190+
```cypher
191+
// Collect names of friends
192+
MATCH (p:Person)
193+
RETURN p.name, [(p)-[:KNOWS]->(friend) | friend.name] AS friends
194+
195+
// With filtering
196+
RETURN [(p)-[:KNOWS]->(f:Person) WHERE f.age > 21 | f.name] AS adult_friends
197+
```
198+
199+
### Map Projection
200+
201+
Create maps by selecting properties from nodes:
202+
203+
```cypher
204+
// Select specific properties
205+
MATCH (n:Person)
206+
RETURN n {.name, .age}
207+
// → {name: "Alice", age: 30}
208+
209+
// Include computed values
210+
MATCH (n:Person)
211+
RETURN n {.name, status: 'active', upperName: toUpper(n.name)}
212+
```

docs/src/reference/cypher.md

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,24 @@ Cypher is a declarative graph query language originally developed by Neo4j. Grap
1313
| Node patterns | ✅ Full |
1414
| Relationship patterns | ✅ Full |
1515
| Variable-length paths | ✅ Full |
16+
| shortestPath/allShortestPaths | ✅ Full |
1617
| Parameterized queries | ✅ Full |
1718
| MATCH/OPTIONAL MATCH | ✅ Full |
1819
| CREATE/MERGE | ✅ Full |
1920
| SET/REMOVE/DELETE | ✅ Full |
2021
| WITH/UNWIND/FOREACH | ✅ Full |
22+
| LOAD CSV | ✅ Full |
23+
| UNION/UNION ALL | ✅ Full |
2124
| RETURN with modifiers | ✅ Full |
2225
| Aggregation functions | ✅ Full |
23-
| List comprehensions | ⚠️ Partial |
26+
| CASE expressions | ✅ Full |
27+
| List comprehensions | ✅ Full |
28+
| Pattern comprehensions | ✅ Full |
29+
| Map projections | ✅ Full |
30+
| Multi-graph (FROM clause) | ✅ Full |
31+
| Graph algorithms | ✅ 15+ built-in |
2432
| CALL procedures | ❌ Not supported |
33+
| CREATE INDEX/CONSTRAINT | ❌ Use SQLite |
2534

2635
## Pattern Syntax
2736

@@ -70,7 +79,7 @@ See [Operators Reference](./cypher-operators.md) for comparison and logical oper
7079
GraphQLite implements standard Cypher with some differences from full implementations:
7180

7281
1. **No CALL procedures** - Use built-in graph algorithm functions instead (e.g., `RETURN pageRank()`)
73-
2. **List comprehensions** - Basic support for `[x IN list | expr]` and `[x IN list WHERE pred | expr]`
74-
3. **No CREATE CONSTRAINT** - Use SQLite's constraint mechanisms
75-
4. **EXPLAIN supported** - Returns the generated SQL for debugging
76-
5. **UNION supported** - Combine results from multiple queries with `UNION` or `UNION ALL`
82+
2. **No CREATE INDEX/CONSTRAINT** - Use SQLite's indexing and constraint mechanisms directly
83+
3. **EXPLAIN supported** - Returns the generated SQL for debugging instead of a query plan
84+
4. **Multi-graph support** - Use the `FROM` clause to query specific graphs with GraphManager
85+
5. **Substring indexing** - Uses 0-based indexing (Cypher standard), automatically converted for SQLite

0 commit comments

Comments
 (0)