Skip to content

Commit b6fcb54

Browse files
authored
Add AI coding guidelines for GitHub Copilot and Cursor (#529)
- Add .github/copilot-instructions.md with project-specific coding guidelines for AI assistants (GitHub Copilot, Cursor, etc.) - Add Cursor rule (.cursor/rules/load-github-copilot-instructions.mdc) to ensure the guidelines are loaded before any coding task - Update .editorconfig charset to latin1 for compatibility with existing source files
2 parents 9ec14de + a9d117e commit b6fcb54

File tree

2 files changed

+265
-0
lines changed

2 files changed

+265
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
description: MANDATORY - Read .github/copilot-instructions.md before ANY coding task in this SQLiteCpp project.
3+
globs:
4+
alwaysApply: true
5+
---
6+
7+
# MANDATORY: Read Custom Instructions Before Coding
8+
9+
**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.
10+
11+
This is NON-NEGOTIABLE. Do not skip this step. Do not assume you know the contents. Always read the file fresh.
12+
13+
## Why This Matters
14+
15+
The `copilot-instructions.md` file contains project-specific coding standards that MUST be followed:
16+
17+
- **RAII principles** - Acquire in constructors, release in destructors
18+
- **Exception rules** - NEVER throw in destructors, use `SQLITECPP_ASSERT()` instead
19+
- **C++ version constraints** - C++11 only in core library
20+
- **Naming conventions** - `m` prefix for members, `a` prefix for arguments, etc.
21+
- **Code style** - 4 spaces, Allman braces, 120 char max, `#pragma once`
22+
- **Documentation** - Doxygen with `@brief`, `@param`, `@return`, `@throw`
23+
- **Testing requirements** - Tests required for new functionality
24+
- **Build commands** - CMake and Meson instructions
25+
26+
## Required Action
27+
28+
```
29+
Read the file: .github/copilot-instructions.md
30+
```
31+
32+
Execute this read operation BEFORE responding to any coding request. This ensures you have the current, complete coding guidelines for this SQLiteCpp project.
33+
34+
If you cannot read the file for any reason, inform the user immediately.

.github/copilot-instructions.md

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
# SQLiteCpp LLM Coding Guide
2+
3+
## Non-Negotiables (MUST Follow)
4+
- RAII only. Acquire in constructors, release in destructors.
5+
- NEVER throw in destructors. Use `SQLITECPP_ASSERT()` instead.
6+
- Errors: use `SQLite::Exception` for throwing APIs; `tryExec()`, `tryExecuteStep()`, `tryReset()` return SQLite codes.
7+
- C++11 only in core library. C++14 only in `VariadicBind.h` and `ExecuteMany.h`.
8+
- Public API headers must NOT include `sqlite3.h`. Use `SQLite::OPEN_*` flags from `Database.h`.
9+
- Export public API with `SQLITECPP_API` from `SQLiteCppExport.h`.
10+
- Threading: one `Database`/`Statement`/`Column` per thread.
11+
- Public API must have Doxygen: `@brief`, `@param`, `@return`, `@throw`.
12+
- Tests required for new functionality in `tests/`.
13+
- Portability: Windows, Linux, macOS.
14+
- Style: ASCII only, 4 spaces, Allman braces, max 120 chars, LF line endings, final newline, `#pragma once`.
15+
16+
## Workflow (Common Tasks)
17+
### Add a Method
18+
1. Declare in `include/SQLiteCpp/<Class>.h` with Doxygen.
19+
2. Implement in `src/<Class>.cpp`.
20+
3. Add tests in `tests/<Class>_test.cpp`.
21+
4. Update `CHANGELOG.md`.
22+
23+
### Add a Class
24+
1. Create `include/SQLiteCpp/NewClass.h` and `src/NewClass.cpp`.
25+
2. Add to `CMakeLists.txt` (`SQLITECPP_SRC` and `SQLITECPP_INC`).
26+
3. Add to `meson.build`.
27+
4. Include in `SQLiteCpp.h` if public API.
28+
5. Create `tests/NewClass_test.cpp`.
29+
6. Add test to `CMakeLists.txt` and `meson.build`.
30+
31+
### Git Workflow (GitHub Issues)
32+
**When to create a new branch:**
33+
- User explicitly mentions working on a task, issue, or feature (e.g., "work on issue #123", "implement feature X")
34+
- User references a GitHub issue number
35+
36+
**Before starting work:**
37+
1. Run `git status` to check current branch.
38+
2. If on `master` or wrong branch, create a task-specific branch from `master`.
39+
40+
**Branch naming:** `<issue>-<type>-<short-description>`
41+
- `123-fix-short-description` for bug fixes
42+
- `123-feature-short-description` for new features
43+
44+
**Commits:**
45+
- Imperative mood, ~50 char first line, body wrapped at 72 chars.
46+
- Reference issue: `Closes #123` or `Fixes #123`.
47+
48+
```bash
49+
git fetch origin
50+
git checkout -b 123-fix-short-description origin/master
51+
```
52+
53+
## Common Pitfalls
54+
- `bind()` is 1-based; `getColumn()` is 0-based.
55+
- Reusing `Statement` requires `reset()` and `clearBindings()`.
56+
- `bindNoCopy()` only if data lifetime exceeds statement execution.
57+
- `execAndGet()` returns a temporary `Column`, copy immediately.
58+
- `exec()` returns changes for DML, 0 for DDL.
59+
60+
## Build and Test
61+
### Quick Build Commands
62+
**Windows (Visual Studio 2022):**
63+
```batch
64+
mkdir build
65+
cd build
66+
cmake -G "Visual Studio 17 2022" -DSQLITECPP_BUILD_TESTS=ON -DSQLITECPP_BUILD_EXAMPLES=ON ..
67+
cmake --build . --config Release
68+
```
69+
70+
**Windows (using build.bat):**
71+
```batch
72+
build.bat
73+
```
74+
75+
**Unix/macOS:**
76+
```bash
77+
mkdir build && cd build
78+
cmake -DCMAKE_BUILD_TYPE=Debug -DSQLITECPP_BUILD_TESTS=ON -DSQLITECPP_BUILD_EXAMPLES=ON ..
79+
cmake --build .
80+
```
81+
82+
**Meson:**
83+
```bash
84+
meson setup builddir -DSQLITECPP_BUILD_TESTS=true -DSQLITECPP_BUILD_EXAMPLES=true
85+
meson compile -C builddir
86+
```
87+
88+
### Essential CMake Options
89+
| Option | Default | Description |
90+
|--------|---------|-------------|
91+
| `SQLITECPP_BUILD_TESTS` | OFF | Build unit tests |
92+
| `SQLITECPP_BUILD_EXAMPLES` | OFF | Build examples |
93+
| `SQLITECPP_INTERNAL_SQLITE` | ON | Use bundled sqlite3/ |
94+
| `BUILD_SHARED_LIBS` | OFF | Build as DLL/shared library |
95+
| `SQLITE_ENABLE_COLUMN_METADATA` | ON | Enable `getColumnOriginName()` |
96+
97+
### Running Tests
98+
```bash
99+
cd build
100+
ctest --output-on-failure
101+
ctest --output-on-failure -V
102+
ctest --output-on-failure -R "Database"
103+
```
104+
```bash
105+
meson test -C builddir
106+
meson test -C builddir -v
107+
```
108+
109+
### Style Checking
110+
```bash
111+
python cpplint.py src/*.cpp include/SQLiteCpp/*.h
112+
```
113+
114+
## Troubleshooting
115+
**MSVC:**
116+
```
117+
c:\path\to\file.cpp(42): error C2065: 'undeclaredVar': undeclared identifier
118+
c:\path\to\file.cpp(50,15): error C2039: 'foo': is not a member of 'SQLite::Database'
119+
```
120+
121+
**GCC/Clang:**
122+
```
123+
src/Database.cpp:42:5: error: use of undeclared identifier 'undeclaredVar'
124+
include/SQLiteCpp/Database.h:100:10: error: no member named 'foo' in 'SQLite::Database'
125+
```
126+
127+
**Linker:**
128+
```
129+
error LNK2019: unresolved external symbol "SQLite::Database::exec"
130+
```
131+
132+
Usually means missing SQLiteCpp library or missing source file in build.
133+
134+
## Reference
135+
### Project Snapshot
136+
- SQLiteCpp is a lean C++11 RAII wrapper around SQLite3 C APIs.
137+
- Minimal dependencies (C++11 STL + SQLite3).
138+
- Cross-platform, thread-safe at SQLite multi-thread level.
139+
- Keep naming close to SQLite.
140+
- Public headers avoid `sqlite3.h`; use `SQLite::OPEN_*` flags from `Database.h`.
141+
142+
### Repository Structure
143+
```
144+
SQLiteCpp/
145+
+-- include/SQLiteCpp/ # Public headers
146+
| +-- SQLiteCpp.h # Umbrella include + version macros
147+
| +-- Database.h # Connection + open flags
148+
| +-- Statement.h # Prepared statements
149+
| +-- Column.h # Result column access
150+
| +-- Transaction.h # RAII transaction
151+
| +-- Savepoint.h # RAII savepoint
152+
| +-- Backup.h # Online backup
153+
| +-- Exception.h # SQLite::Exception
154+
| +-- Assertion.h # SQLITECPP_ASSERT macro
155+
| +-- VariadicBind.h # Bind helper (C++11/14)
156+
| +-- ExecuteMany.h # Batch execute (C++14)
157+
| +-- SQLiteCppExport.h # SQLITECPP_API macro
158+
+-- src/ # Implementations
159+
+-- tests/ # Unit tests (*_test.cpp)
160+
+-- sqlite3/ # Bundled SQLite3 source
161+
+-- examples/ # Example applications
162+
+-- CMakeLists.txt / meson.build / build.bat / build.sh
163+
```
164+
165+
### Naming Rules
166+
| Element | Convention | Example |
167+
|---------|------------|---------|
168+
| Types | PascalCase | `Database`, `Statement`, `TransactionBehavior` |
169+
| Files | Named like contained class | `Database.h`, `Statement.cpp` |
170+
| Functions and variables | camelCase | `executeStep()`, `getColumn()` |
171+
| Member variables | Prefix `m` | `mDatabase`, `mQuery` |
172+
| Function arguments | Prefix `a` | `aDatabase`, `aQuery` |
173+
| Boolean variables | Prefix `b`/`mb` | `bExists`, `mbDone` |
174+
| Pointer variables | Prefix `p`/`mp` | `pValue`, `mpSQLite` |
175+
| Constants | ALL_CAPS | `OPEN_READONLY`, `SQLITE_OK` |
176+
177+
### File Header Template
178+
```cpp
179+
/**
180+
* @file ClassName.h
181+
* @ingroup SQLiteCpp
182+
* @brief Brief description of the file.
183+
*
184+
* Copyright (c) 2012-2025 Sebastien Rombauts (sebastien.rombauts@gmail.com)
185+
*
186+
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
187+
* or copy at http://opensource.org/licenses/MIT)
188+
*/
189+
#pragma once
190+
191+
#include <SQLiteCpp/SQLiteCppExport.h>
192+
// other includes...
193+
```
194+
195+
### Doxygen Format
196+
```cpp
197+
/**
198+
* @brief Execute a step of the prepared query to fetch one row of results.
199+
*
200+
* @param[in] aIndex Index of the column (0-based)
201+
*
202+
* @return - true (SQLITE_ROW) if there is another row ready
203+
* - false (SQLITE_DONE) if the query has finished executing
204+
*
205+
* @throw SQLite::Exception in case of error
206+
*/
207+
```
208+
209+
### Error Handling
210+
- Use `SQLite::Exception` for errors (inherits `std::runtime_error`).
211+
- Use `check(ret)` after SQLite C API calls.
212+
- In destructors, use `SQLITECPP_ASSERT()` instead of throwing.
213+
214+
### Minimal API Example
215+
```cpp
216+
SQLite::Database db("example.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
217+
218+
SQLite::Statement query(db, "SELECT * FROM test WHERE id > ? AND name = :name");
219+
query.bind(1, 5);
220+
query.bind(":name", "John");
221+
while (query.executeStep())
222+
{
223+
int id = query.getColumn(0);
224+
std::string value = query.getColumn(1);
225+
}
226+
227+
SQLite::Statement insert(db, "INSERT INTO test VALUES (?, ?)");
228+
insert.bind(1, 42);
229+
insert.bind(2, "value");
230+
int changes = insert.exec();
231+
```

0 commit comments

Comments
 (0)