Skip to content

Switch from LZZ to .cpp/.hpp #1377

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 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
1 change: 1 addition & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
BasedOnStyle: LLVM
24 changes: 24 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"permissions": {
"allow": [
"WebFetch(domain:www.lazycplusplus.com)",
"Bash(grep:*)",
"Bash(ls:*)",
"Bash(find:*)",
"Bash(lzz:*)",
"Bash(cp:*)",
"Bash(npm run:*)",
"Bash(chmod:*)",
"Bash(python3:*)",
"Bash(npm test:*)",
"Bash(timeout:*)",
"Bash(awk:*)",
"Bash(git fetch:*)",
"Bash(git merge-base:*)",
"Bash(git stash:*)",
"Bash(rg:*)",
"Bash(clang-format:*)"
]
},
"enableAllProjectMcpServers": false
}
4 changes: 0 additions & 4 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
*.lzz linguist-language=C++
*.cpp -diff
*.hpp -diff
*.c -diff
*.h -diff
78 changes: 78 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

**better-sqlite3** is a Node.js native addon providing synchronous SQLite database access. It's architected as a hybrid C++/JavaScript library where C++ handles direct SQLite operations and JavaScript provides the high-level API.

## Build & Development Commands

### Essential Commands
- **Build**: `npm run build-release` (production build)
- **Debug Build**: `npm run build-debug`
- **Test**: `npm test` (mocha with 5s timeout)
- **Single Test**: `npx mocha test/[test-file].js`
- **Benchmark**: `npm run benchmark`
- **Download SQLite**: `npm run download`

## Architecture

### Code Organization
```
lib/ # JavaScript API layer
├── index.js # Main export (Database constructor)
├── database.js # Database class with native binding
└── methods/ # Method implementations

src/ # C++ source
├── better_sqlite3.cpp # Main implementation file
├── better_sqlite3.hpp # Main header file
├── objects/ # Core classes (Database, Statement, etc.)
└── util/ # Utilities and type conversion
```

### C++ Architecture
- Standard C++ source files (.cpp/.hpp)
- Modular header structure in `src/objects/` and `src/util/`
- Single compilation unit architecture maintained
- Uses standard C++ #include directives

## Native Addon Structure

### Data Flow
```
JavaScript API → C++ Native Methods → SQLite C API → Results → Type Conversion → JavaScript
```

### Key Classes
- `Database`: Main database connection and operations
- `Statement`: Prepared SQL statements
- `StatementIterator`: Row iteration
- `Backup`: Database backup functionality

### Type Conversion
The C++ layer handles conversion between SQLite types and V8/JavaScript types, including support for 64-bit integers, Buffers, and BigInts.

## Testing

Tests are organized by functionality in `test/`:
- `00.setup.js`: Global test setup
- `10-19.*`: Database-level operations
- `20-29.*`: Statement operations
- `30-39.*`: Advanced features (transactions, custom functions)
- `40-50.*`: Special cases (BigInts, worker threads, unsafe mode)

## Development Workflow

1. **For C++ changes**: Edit `.cpp/.hpp` files → `npm run build-release` → `npm test`
2. **For JavaScript changes**: Edit files in `lib/` → `npm test`
3. **Performance testing**: Use `npm run benchmark` after changes

## Important Notes

- This is a **synchronous** SQLite library (no async/await)
- Single-threaded SQLite access for performance
- Uses Node.js N-API for forward compatibility
- Embeds SQLite source in `deps/` directory
- Supports Node.js 20.x, 22.x, 23.x, 24.x
17 changes: 16 additions & 1 deletion binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,22 @@
{
'target_name': 'better_sqlite3',
'dependencies': ['deps/sqlite3.gyp:sqlite3'],
'sources': ['src/better_sqlite3.cpp'],
'sources': [
'src/better_sqlite3.cpp',
'src/objects/database.cpp',
'src/objects/statement.cpp',
'src/objects/statement-iterator.cpp',
'src/objects/backup.cpp',
'src/util/macros.cpp',
'src/util/constants.cpp',
'src/util/bind-map.cpp',
'src/util/binder.cpp',
'src/util/data-converter.cpp',
'src/util/custom-function.cpp',
'src/util/custom-aggregate.cpp',
'src/util/custom-table.cpp',
'src/util/data.cpp'
],
'cflags_cc': ['-std=c++20'],
'xcode_settings': {
'OTHER_CPLUSPLUSFLAGS': ['-std=c++20', '-stdlib=libc++'],
Expand Down
4 changes: 3 additions & 1 deletion docs/contribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,14 @@ If you've never written a native addon for Node.js before, you should start by r

#### C++

The C++ code in `better-sqlite3` is written using a tool called [`lzz`](https://github.com/WiseLibs/lzz), which alleviates the programmer from needing to write header files. If you plan on changing any C++ code, you'll need to edit `*.lzz` files and then re-compile them into `*.cpp` and `*.hpp` by running `npm run lzz` (while the `lzz` executable is in your PATH). You can learn how to download and install `lzz` [here](https://github.com/WiseLibs/lzz).
The C++ code in `better-sqlite3` uses standard C++ source files (`.cpp`) and header files (`.hpp`). The codebase is organized into modular components under `src/objects/` (core classes like Database, Statement) and `src/util/` (utilities and type conversion). When making C++ changes, edit the appropriate `.cpp` and `.hpp` files directly, then build with `npm run build-release`.

#### Style guide

There is currently no linter or style guide associated with `better-sqlite3` (this may change in the future). For now, just try to match the style of existing code as much as possible. Code owners will reject your PR or rewrite your changes if they feel that you've used a coding style that doesn't match the existing code. Although the rules aren't layed out formally, you are expected to adhere to them by using your eyeballs.

For C++ code formatting, you can use `npm run fmt` to run `clang-format` on all C++ source files, which will automatically format your code according to the project's formatting standards.

#### Testing

All tests are written in JavaScript, and they test `better-sqlite3`'s public API. All new features must be accompanied by a robust set of tests that scrutinize the new feature under all manner of circumstances and edge cases. It's not enough to simply test the "common case". If you write code that detects errors and throws exceptions, those error cases should be tested too, to ensure that all errors are being properly detected. If a new feature interacts with existing features, those interactions must be tested as well.
Expand Down
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,10 @@
"install": "prebuild-install || node-gyp rebuild --release",
"build-release": "node-gyp rebuild --release",
"build-debug": "node-gyp rebuild --debug",
"rebuild-release": "npm run lzz && npm run build-release",
"rebuild-debug": "npm run lzz && npm run build-debug",
"test": "mocha --exit --slow=75 --timeout=5000",
"benchmark": "node benchmark",
"download": "bash ./deps/download.sh",
"lzz": "lzz -hx hpp -sx cpp -k BETTER_SQLITE3 -d -hl -sl -e ./src/better_sqlite3.lzz"
"fmt": "find src -name '*.cpp' -o -name '*.hpp' | grep -v withlines | xargs clang-format -i"
},
"license": "MIT",
"keywords": [
Expand Down
Loading