This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
cqlai-node is a Node.js native bindings package for Apache Cassandra (@axonops/cqlai-node). It provides high-performance Cassandra connectivity by compiling Go source code (using the gocql driver) into a native shared library that is loaded via FFI (Koffi).
Architecture: Hybrid JS + Go
- JavaScript layer (
index.js,session.js,native.js): Promise-based API, session management, FFI bindings - Go layer (
go/): Compiled to C-shared library (lib/libcqlai.so~12MB) with C-exported functions for FFI
# Automatic build (runs postinstall)
npm install
# Manual build via npm script
npm run build
# Manual build (from go/ directory)
cd go && go build -buildmode=c-shared -o ../lib/libcqlai.so ./bindings/
# Build for current platform (auto-detects extension)
node scripts/build.js# Basic JS test (only verifies module loads)
npm test
# Go tests (from go/ directory)
cd go && go test ./internal/...
# Test with live Cassandra instance
node -e "const { CQLSession } = require('.'); CQLSession.testConnection({ host: '127.0.0.1' }).then(r => console.log(r))"# Quick verification after Go changes
cd go && go build -buildmode=c-shared -o ../lib/libcqlai.so ./bindings/ && cd .. && node -e "const {CQLSession} = require('.'); console.log('OK')"
# Enable debug logging for Go code
export CQLAI_DEBUG_LOG_PATH=/tmp/cqlai_debug.log
tail -f /tmp/cqlai_debug.logUses Koffi to load the shared library and define C function signatures. Two calling modes:
- Synchronous (
callNative): For quick operations, runs on main thread - Asynchronous (
callNativeTrueAsync): Uses Koffi's worker threads for non-blocking I/O operations
All native functions return JSON strings for cross-language compatibility. C functions follow this signature pattern:
char* SomeFunction(const char* jsonInput);- Handle-based: Go stores sessions in a map with integer handles; JS stores only the handle
- Static methods (
CQLSession.connect,CQLSession.testConnection): Create new sessions - Instance methods: All operations on an existing session
- Result wrapper: All methods return
{ success: boolean, data?, error?, code? }
Key packages under go/internal/:
db/: Core database operations, query execution, schema caching, UDT handling, type parsingbindings/: C-exported functions (FFI entry points) - one file per feature area (astra.go, ddl.go, metadata.go, etc.)config/: Configuration management, cqlshrc parsingbatch/: CQL statement parsing and splittingsession/: Session lifecycle management
session.execute(cql) ->
native.SplitCQL() [parses statements] ->
For each statement:
- Shell command? → _do_<command>() (CONSISTENCY, PAGING, TRACING, etc.)
- SELECT with paging? → ExecuteQueryPaged() → queryId for pagination
- Regular query? → ExecuteQuery()
Return formatted result
- Iterator-based pagination for large result sets
- Query state stored in Go with unique
queryId hasMoreflag indicates additional pagesfetchNextPage(queryId)retrieves subsequent pages
Extensive metadata support in go/internal/db/:
describe_*.gofiles: Tables, keyspaces, indexes, materialized views, aggregates, functionsschema_cache.go: Caches schema for performanceddl.go: Generates CREATE statementsudt_decoder.go: Custom UDT type handling
| File | Purpose |
|---|---|
index.js |
Package entry, exports CQLSession |
session.js |
Main CQLSession class implementation |
native.js |
FFI setup, library loading, async/sync call wrappers |
scripts/build.js |
Cross-platform build script |
go/bindings/exports.go |
Core C-exported FFI functions |
go/internal/db/ |
Database operations, query execution |
docs/API.md |
Complete API documentation |
docs/BUILDING.md |
Build instructions and troubleshooting |
- Node.js >= 14.0.0
- Go >= 1.21
- CGO enabled (
CGO_ENABLED=1) - GCC for CGO compilation
- Platform: Linux x64/arm64 (primary)
Enable Go debug logging:
export CQLAI_DEBUG_LOG_PATH=/tmp/cqlai_debug.log- "undefined symbol" errors: Rebuild the library (
rm lib/libcqlai.so && npm run build) - "GLIBC_X.XX not found": Build on the oldest target system or use a build container
- Changes not taking effect: Ensure you rebuilt the Go library after changes