Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
34 changes: 34 additions & 0 deletions .cursor/rules/load-github-copilot-instructions.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
description: MANDATORY - Read .github/copilot-instructions.md before ANY coding task in this SQLiteCpp project.
globs:
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The front matter syntax appears to be incorrect. The "globs:" field on line 3 is missing a value. According to Cursor rules file format, this field should either have a list of glob patterns or be omitted entirely if using "alwaysApply: true". Since this rule should apply to all files (as indicated by "alwaysApply: true"), the "globs:" line should either be removed or should have an empty list value like "globs: []".

Suggested change
globs:
globs: []

Copilot uses AI. Check for mistakes.
alwaysApply: true
---

# MANDATORY: Read Custom Instructions Before Coding

**CRITICAL REQUIREMENT**: Before performing ANY coding task (writing code, reviewing code, suggesting changes, answering code questions, or modifying files), you MUST first read the file `.github/copilot-instructions.md` using the Read tool.

This is NON-NEGOTIABLE. Do not skip this step. Do not assume you know the contents. Always read the file fresh.

## Why This Matters

The `copilot-instructions.md` file contains project-specific coding standards that MUST be followed:

- **RAII principles** - Acquire in constructors, release in destructors
- **Exception rules** - NEVER throw in destructors, use `SQLITECPP_ASSERT()` instead
- **C++ version constraints** - C++11 only in core library
- **Naming conventions** - `m` prefix for members, `a` prefix for arguments, etc.
- **Code style** - 4 spaces, Allman braces, 120 char max, `#pragma once`
- **Documentation** - Doxygen with `@brief`, `@param`, `@return`, `@throw`
- **Testing requirements** - Tests required for new functionality
- **Build commands** - CMake and Meson instructions

## Required Action

```
Read the file: .github/copilot-instructions.md
```

Execute this read operation BEFORE responding to any coding request. This ensures you have the current, complete coding guidelines for this SQLiteCpp project.

If you cannot read the file for any reason, inform the user immediately.
231 changes: 231 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
# SQLiteCpp LLM Coding Guide

## Non-Negotiables (MUST Follow)
- RAII only. Acquire in constructors, release in destructors.
- NEVER throw in destructors. Use `SQLITECPP_ASSERT()` instead.
- Errors: use `SQLite::Exception` for throwing APIs; `tryExec()`, `tryExecuteStep()`, `tryReset()` return SQLite codes.
- C++11 only in core library. C++14 only in `VariadicBind.h` and `ExecuteMany.h`.
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The guideline states "C++14 only in VariadicBind.h" but this is misleading. VariadicBind.h contains both C++11 code (the basic variadic bind function, see lines 47-54 in include/SQLiteCpp/VariadicBind.h) and C++14 code (the tuple-based functions, see lines 56-96). Only the tuple-based functionality requires C++14. Consider clarifying this as "C++14 only in ExecuteMany.h; VariadicBind.h has both C++11 (variadic bind) and C++14 (tuple bind) features" or similar.

Suggested change
- C++11 only in core library. C++14 only in `VariadicBind.h` and `ExecuteMany.h`.
- C++11 only in core library. C++14 only in `ExecuteMany.h`; `VariadicBind.h` has both C++11 (variadic bind) and C++14 (tuple bind) features.

Copilot uses AI. Check for mistakes.
- Public API headers must NOT include `sqlite3.h`. Use `SQLite::OPEN_*` flags from `Database.h`.
- Export public API with `SQLITECPP_API` from `SQLiteCppExport.h`.
- Threading: one `Database`/`Statement`/`Column` per thread.
- Public API must have Doxygen: `@brief`, `@param`, `@return`, `@throw`.
- Tests required for new functionality in `tests/`.
- Portability: Windows, Linux, macOS.
- Style: ASCII only, 4 spaces, Allman braces, max 120 chars, LF line endings, final newline, `#pragma once`.
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The guideline states "Allman braces" but the actual codebase consistently uses K&R style braces (opening brace on the same line). For example, see src/Database.cpp:72-75, src/Statement.cpp:58-62, src/Column.cpp:32-36, and src/Transaction.cpp:50-63. All of these show opening braces on the same line as the function declaration or control statement, not on a new line. This guideline should be corrected to reflect the actual convention used throughout the codebase.

Copilot uses AI. Check for mistakes.

## Workflow (Common Tasks)
### Add a Method
1. Declare in `include/SQLiteCpp/<Class>.h` with Doxygen.
2. Implement in `src/<Class>.cpp`.
3. Add tests in `tests/<Class>_test.cpp`.
4. Update `CHANGELOG.md`.

### Add a Class
1. Create `include/SQLiteCpp/NewClass.h` and `src/NewClass.cpp`.
2. Add to `CMakeLists.txt` (`SQLITECPP_SRC` and `SQLITECPP_INC`).
3. Add to `meson.build`.
4. Include in `SQLiteCpp.h` if public API.
5. Create `tests/NewClass_test.cpp`.
6. Add test to `CMakeLists.txt` and `meson.build`.

### Git Workflow (GitHub Issues)
**When to create a new branch:**
- User explicitly mentions working on a task, issue, or feature (e.g., "work on issue #123", "implement feature X")
- User references a GitHub issue number

**Before starting work:**
1. Run `git status` to check current branch.
2. If on `master` or wrong branch, create a task-specific branch from `master`.

**Branch naming:** `<issue>-<type>-<short-description>`
- `123-fix-short-description` for bug fixes
- `123-feature-short-description` for new features

**Commits:**
- Imperative mood, ~50 char first line, body wrapped at 72 chars.
- Reference issue: `Closes #123` or `Fixes #123`.

```bash
git fetch origin
git checkout -b 123-fix-short-description origin/master
```

## Common Pitfalls
- `bind()` is 1-based; `getColumn()` is 0-based.
- Reusing `Statement` requires `reset()` and `clearBindings()`.
- `bindNoCopy()` only if data lifetime exceeds statement execution.
- `execAndGet()` returns a temporary `Column`, copy immediately.
- `exec()` returns changes for DML, 0 for DDL.

## Build and Test
### Quick Build Commands
**Windows (Visual Studio 2022):**
```batch
mkdir build
cd build
cmake -G "Visual Studio 17 2022" -DSQLITECPP_BUILD_TESTS=ON -DSQLITECPP_BUILD_EXAMPLES=ON ..
cmake --build . --config Release
```

**Windows (using build.bat):**
```batch
build.bat
```

**Unix/macOS:**
```bash
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Debug -DSQLITECPP_BUILD_TESTS=ON -DSQLITECPP_BUILD_EXAMPLES=ON ..
cmake --build .
```

**Meson:**
```bash
meson setup builddir -DSQLITECPP_BUILD_TESTS=true -DSQLITECPP_BUILD_EXAMPLES=true
meson compile -C builddir
```

### Essential CMake Options
| Option | Default | Description |
|--------|---------|-------------|
| `SQLITECPP_BUILD_TESTS` | OFF | Build unit tests |
| `SQLITECPP_BUILD_EXAMPLES` | OFF | Build examples |
| `SQLITECPP_INTERNAL_SQLITE` | ON | Use bundled sqlite3/ |
| `BUILD_SHARED_LIBS` | OFF | Build as DLL/shared library |
| `SQLITE_ENABLE_COLUMN_METADATA` | ON | Enable `getColumnOriginName()` |

### Running Tests
```bash
cd build
ctest --output-on-failure
ctest --output-on-failure -V
ctest --output-on-failure -R "Database"
```
```bash
meson test -C builddir
meson test -C builddir -v
```

### Style Checking
```bash
python cpplint.py src/*.cpp include/SQLiteCpp/*.h
```

## Troubleshooting
**MSVC:**
```
c:\path\to\file.cpp(42): error C2065: 'undeclaredVar': undeclared identifier
c:\path\to\file.cpp(50,15): error C2039: 'foo': is not a member of 'SQLite::Database'
```

**GCC/Clang:**
```
src/Database.cpp:42:5: error: use of undeclared identifier 'undeclaredVar'
include/SQLiteCpp/Database.h:100:10: error: no member named 'foo' in 'SQLite::Database'
```

**Linker:**
```
error LNK2019: unresolved external symbol "SQLite::Database::exec"
```

Usually means missing SQLiteCpp library or missing source file in build.

## Reference
### Project Snapshot
- SQLiteCpp is a lean C++11 RAII wrapper around SQLite3 C APIs.
- Minimal dependencies (C++11 STL + SQLite3).
- Cross-platform, thread-safe at SQLite multi-thread level.
- Keep naming close to SQLite.
- Public headers avoid `sqlite3.h`; use `SQLite::OPEN_*` flags from `Database.h`.

### Repository Structure
```
SQLiteCpp/
+-- include/SQLiteCpp/ # Public headers
| +-- SQLiteCpp.h # Umbrella include + version macros
| +-- Database.h # Connection + open flags
| +-- Statement.h # Prepared statements
| +-- Column.h # Result column access
| +-- Transaction.h # RAII transaction
| +-- Savepoint.h # RAII savepoint
| +-- Backup.h # Online backup
| +-- Exception.h # SQLite::Exception
| +-- Assertion.h # SQLITECPP_ASSERT macro
| +-- VariadicBind.h # Bind helper (C++11/14)
| +-- ExecuteMany.h # Batch execute (C++14)
| +-- SQLiteCppExport.h # SQLITECPP_API macro
+-- src/ # Implementations
+-- tests/ # Unit tests (*_test.cpp)
+-- sqlite3/ # Bundled SQLite3 source
+-- examples/ # Example applications
+-- CMakeLists.txt / meson.build / build.bat / build.sh
```

### Naming Rules
| Element | Convention | Example |
|---------|------------|---------|
| Types | PascalCase | `Database`, `Statement`, `TransactionBehavior` |
| Files | Named like contained class | `Database.h`, `Statement.cpp` |
| Functions and variables | camelCase | `executeStep()`, `getColumn()` |
| Member variables | Prefix `m` | `mDatabase`, `mQuery` |
| Function arguments | Prefix `a` | `aDatabase`, `aQuery` |
| Boolean variables | Prefix `b`/`mb` | `bExists`, `mbDone` |
| Pointer variables | Prefix `p`/`mp` | `pValue`, `mpSQLite` |
| Constants | ALL_CAPS | `OPEN_READONLY`, `SQLITE_OK` |

### File Header Template
```cpp
/**
* @file ClassName.h
* @ingroup SQLiteCpp
* @brief Brief description of the file.
*
* Copyright (c) 2012-2025 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#pragma once

#include <SQLiteCpp/SQLiteCppExport.h>
// other includes...
```

### Doxygen Format
```cpp
/**
* @brief Execute a step of the prepared query to fetch one row of results.
*
* @param[in] aIndex Index of the column (0-based)
*
* @return - true (SQLITE_ROW) if there is another row ready
* - false (SQLITE_DONE) if the query has finished executing
*
* @throw SQLite::Exception in case of error
*/
```

### Error Handling
- Use `SQLite::Exception` for errors (inherits `std::runtime_error`).
- Use `check(ret)` after SQLite C API calls.
- In destructors, use `SQLITECPP_ASSERT()` instead of throwing.

### Minimal API Example
```cpp
SQLite::Database db("example.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);

SQLite::Statement query(db, "SELECT * FROM test WHERE id > ? AND name = :name");
query.bind(1, 5);
query.bind(":name", "John");
while (query.executeStep())
{
int id = query.getColumn(0);
std::string value = query.getColumn(1);
}

SQLite::Statement insert(db, "INSERT INTO test VALUES (?, ?)");
insert.bind(1, 42);
insert.bind(2, "value");
int changes = insert.exec();
```