Skip to content

Commit b4cf441

Browse files
authored
Merge pull request #106 from launchql/feat/wasm17-scan
Feat/wasm17 scan
2 parents 4cea9f4 + 5569a5b commit b4cf441

File tree

11 files changed

+1578
-6
lines changed

11 files changed

+1578
-6
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ wasm/libpg-query.js
77
*.wasm
88
.cache
99
esm/
10-
cjs/
10+
cjs/
11+
.claude

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ ifdef EMSCRIPTEN
5454
-v \
5555
$(CXXFLAGS) \
5656
-I$(LIBPG_QUERY_DIR) \
57+
-I$(LIBPG_QUERY_DIR)/vendor \
5758
-L$(LIBPG_QUERY_DIR) \
58-
-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']" \
59+
-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_scan','_wasm_parse_query_detailed','_wasm_free_detailed_result','_wasm_free_string']" \
5960
-sEXPORTED_RUNTIME_METHODS="['lengthBytesUTF8','stringToUTF8','UTF8ToString','HEAPU8','HEAPU32']" \
6061
-sEXPORT_NAME="$(WASM_MODULE_NAME)" \
6162
-sENVIRONMENT="web,node" \

README.md

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,29 @@ const normalized = normalizeSync('SELECT * FROM users WHERE active = true');
157157
// Returns: string - normalized SQL query
158158
```
159159

160+
### `scan(sql: string): Promise<ScanResult>`
161+
162+
Scans (tokenizes) a SQL query and returns detailed information about each token. Returns a Promise for a ScanResult containing all tokens with their positions, types, and classifications.
163+
164+
```typescript
165+
import { scan } from 'libpg-query';
166+
167+
const result = await scan('SELECT * FROM users WHERE id = $1');
168+
// Returns: ScanResult - detailed tokenization information
169+
console.log(result.tokens[0]); // { start: 0, end: 6, text: "SELECT", tokenType: 651, tokenName: "UNKNOWN", keywordKind: 4, keywordName: "RESERVED_KEYWORD" }
170+
```
171+
172+
### `scanSync(sql: string): ScanResult`
173+
174+
Synchronous version that scans (tokenizes) a SQL query directly.
175+
176+
```typescript
177+
import { scanSync } from 'libpg-query';
178+
179+
const result = scanSync('SELECT * FROM users WHERE id = $1');
180+
// Returns: ScanResult - detailed tokenization information
181+
```
182+
160183
### Initialization
161184

162185
The library provides both async and sync methods. Async methods handle initialization automatically, while sync methods require explicit initialization.
@@ -166,37 +189,40 @@ The library provides both async and sync methods. Async methods handle initializ
166189
Async methods handle initialization automatically and are always safe to use:
167190

168191
```typescript
169-
import { parse, deparse } from 'libpg-query';
192+
import { parse, deparse, scan } from 'libpg-query';
170193

171194
// These handle initialization automatically
172195
const result = await parse('SELECT * FROM users');
173196
const sql = await deparse(result);
197+
const tokens = await scan('SELECT * FROM users');
174198
```
175199

176200
#### Sync Methods
177201

178202
Sync methods require explicit initialization using `loadModule()`:
179203

180204
```typescript
181-
import { loadModule, parseSync } from 'libpg-query';
205+
import { loadModule, parseSync, scanSync } from 'libpg-query';
182206

183207
// Initialize first
184208
await loadModule();
185209

186210
// Now safe to use sync methods
187211
const result = parseSync('SELECT * FROM users');
212+
const tokens = scanSync('SELECT * FROM users');
188213
```
189214

190215
### `loadModule(): Promise<void>`
191216

192217
Explicitly initializes the WASM module. Required before using any sync methods.
193218

194219
```typescript
195-
import { loadModule, parseSync } from 'libpg-query';
220+
import { loadModule, parseSync, scanSync } from 'libpg-query';
196221

197222
// Initialize before using sync methods
198223
await loadModule();
199224
const result = parseSync('SELECT * FROM users');
225+
const tokens = scanSync('SELECT * FROM users');
200226
```
201227

202228
Note: We recommend using async methods as they handle initialization automatically. Use sync methods only when necessary, and always call `loadModule()` first.
@@ -215,6 +241,21 @@ interface Statement {
215241
stmt_location: number;
216242
query: string;
217243
}
244+
245+
interface ScanResult {
246+
version: number;
247+
tokens: ScanToken[];
248+
}
249+
250+
interface ScanToken {
251+
start: number; // Starting position in the SQL string
252+
end: number; // Ending position in the SQL string
253+
text: string; // The actual token text
254+
tokenType: number; // Numeric token type identifier
255+
tokenName: string; // Human-readable token type name
256+
keywordKind: number; // Numeric keyword classification
257+
keywordName: string; // Human-readable keyword classification
258+
}
218259
```
219260

220261
**Note:** The return value is an array, as multiple queries may be provided in a single string (semicolon-delimited, as PostgreSQL expects).

0 commit comments

Comments
 (0)