Conversation
📝 WalkthroughWalkthroughAdds an embedded SQLite static library and extension header, new DB initialization module (schema and PRAGMAs) integrated into the executable, switches ImGui backend to SDL GPU, and updates Changes
Sequence Diagram(s)sequenceDiagram
participant App as Telescode (app)
participant Lib as sqlite3 (embedded)
participant FS as Filesystem
App->>FS: request open/create DB file (dbPath)
FS-->>App: file handle / open result
App->>Lib: sqlite3_open(dbPath, &db)
Lib-->>App: sqlite3 handle / status
App->>Lib: execute PRAGMA statements (WAL, foreign_keys=ON, synchronous)
Lib-->>App: pragma results
App->>Lib: execute schema SQL (CREATE TABLE / INDEX ...)
Lib-->>App: success or error (errmsg)
alt success
App->>App: return SQLITE_OK and db handle
else error
App->>Lib: sqlite3_close(db) (if opened)
App-->>App: print error, return error code
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/db.h (1)
3-8: Use forward declaration to reduce transitive dependency onsqlite3.hin public header.The function signature in
db.honly usessqlite3as an opaque pointer type, so a forward declaration suffices here. Moving#include <sqlite3.h>tosrc/db.cpp(where it's actually needed for the function implementation) removes an unnecessary header dependency:Change
-#include <sqlite3.h> +struct sqlite3;Add
#include <sqlite3.h>insrc/db.cppif not already present (it is at line 1, included viadb.h).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/db.h` around lines 3 - 8, The public header currently includes <sqlite3.h> unnecessarily; replace that include with a forward declaration (e.g., declare struct sqlite3;) so db.h only exposes the opaque sqlite3* type for the initDb(const char* dbPath, sqlite3** db) declaration, and move or add `#include` <sqlite3.h> into the implementation file (src/db.cpp) where initDb is defined so the concrete sqlite3 definitions are available for the function implementation.src/db.cpp (1)
65-81: Consider removing dead code or adding defensive checks if this function is intended for future use.
initDb()is currently dead code—it's declared in the public API header but never called bymain.cpp(which is largely stubbed out) or anywhere else in the codebase. If the function is intended for future use, the suggested defensive checks (null pointer validation and handle reset) are reasonable safeguards for a public API. However, without active usage, the concerns cannot be validated as preventing real crashes. Either remove the unused function or, if it's meant for future expansion, apply the proposed checks as preventive measures.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/db.cpp` around lines 65 - 81, The initDb function is currently unused; either remove it from the public API (delete declaration from header and the implementation) or harden it for future use: in initDb(const char* dbPath, sqlite3** db) validate db and dbPath are non-null at entry, set *db = nullptr on error paths, check return codes before calling sqlite3_errmsg or sqlite3_close, free errMsg when set, and consider marking the implementation static or removing it from the public header to avoid exposing dead API; locate symbols initDb, sqlite3_open, sqlite3_close, sqlite3_errmsg, sqlite3_exec, sqlite3_free and kInitSQL to apply these changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/db.cpp`:
- Around line 65-81: The initDb function is currently unused; either remove it
from the public API (delete declaration from header and the implementation) or
harden it for future use: in initDb(const char* dbPath, sqlite3** db) validate
db and dbPath are non-null at entry, set *db = nullptr on error paths, check
return codes before calling sqlite3_errmsg or sqlite3_close, free errMsg when
set, and consider marking the implementation static or removing it from the
public header to avoid exposing dead API; locate symbols initDb, sqlite3_open,
sqlite3_close, sqlite3_errmsg, sqlite3_exec, sqlite3_free and kInitSQL to apply
these changes.
In `@src/db.h`:
- Around line 3-8: The public header currently includes <sqlite3.h>
unnecessarily; replace that include with a forward declaration (e.g., declare
struct sqlite3;) so db.h only exposes the opaque sqlite3* type for the
initDb(const char* dbPath, sqlite3** db) declaration, and move or add `#include`
<sqlite3.h> into the implementation file (src/db.cpp) where initDb is defined so
the concrete sqlite3 definitions are available for the function implementation.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 1d92eca7-4f06-485b-a771-2bee860ba18b
📒 Files selected for processing (8)
.gitignoreCMakeLists.txtsrc/db.cppsrc/db.hthird_party/sqlite/shell.cthird_party/sqlite/sqlite3.cthird_party/sqlite/sqlite3.hthird_party/sqlite/sqlite3ext.h
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/db.cpp`:
- Around line 36-45: The function table's parent_id/parent_type lacks
referential integrity; replace them with explicit nullable foreign keys file_id
and class_id (referencing the file and class PKs), drop parent_id/parent_type,
add a CHECK constraint enforcing exactly one of file_id or class_id IS NOT NULL
(and the other IS NULL), and add ON DELETE CASCADE/RESTRICT as appropriate so
deleting a file or class cannot leave orphaned function rows; update any code
that reads/writes function.parent_id or function.parent_type to use
function.file_id / function.class_id instead.
- Line 3: Update the project's .clang-tidy to set HeaderFilterRegex so
clang-tidy can analyze transitive headers like the sqlite3.h included in
src/db.cpp; open .clang-tidy and set HeaderFilterRegex to a pattern matching
your project headers (for example 'src/.*' or '.*') so static analysis resolves
includes exported by linked targets and clang-tidy will analyze project headers
referenced by files such as the sqlite3.h include in src/db.cpp.
- Around line 82-84: The log call in initDb (where rc != SQLITE_OK) uses fprintf
with "%s" on errMsg which may be null; change the branch to guard errMsg before
passing it to fprintf by computing a const char* msg = errMsg ? errMsg :
"unknown sqlite error" (or similar fallback) and use msg in the fprintf, and
only call sqlite3_free(errMsg) if errMsg is non-null; update the block around
rc, errMsg in src/db.cpp (initDb/error handling) to use the guarded message and
conditional free.
In `@src/db.h`:
- Around line 3-8: The header forward-declares `struct sqlite3` but the `initDb`
prototype uses `sqlite3**`; update the parameter to use the forward-declared tag
by changing the function declaration for `initDb` to accept `struct sqlite3**
db` (i.e., replace `sqlite3** db` with `struct sqlite3** db`) so the declaration
matches the forward declaration and avoids mismatch between the tag and typedef;
leave the function name `initDb` and other comments unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 29dd5638-b668-4443-b930-63b03dad374b
📒 Files selected for processing (2)
src/db.cppsrc/db.h
| @@ -0,0 +1,91 @@ | |||
| #include "db.h" | |||
|
|
|||
| #include <sqlite3.h> | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Inspect CMake wiring for sqlite source/include propagation.
fd -i 'CMakeLists.txt' -x sh -c '
echo "### {}"
rg -n "sqlite3|third_party/sqlite|target_include_directories|include_directories|target_link_libraries" "{}"
'Repository: c5ln/Telescode
Length of output: 758
🏁 Script executed:
# Check if sqlite3.h exists in third_party/sqlite
find . -name "sqlite3.h" -type f
# List contents of third_party/sqlite to understand structure
ls -la third_party/sqlite/ 2>/dev/null | head -20
# Check if src/db.cpp exists and what it includes
if [ -f src/db.cpp ]; then
echo "=== src/db.cpp first 10 lines ==="
head -10 src/db.cpp
fiRepository: c5ln/Telescode
Length of output: 680
🏁 Script executed:
# Check for compile_commands.json or other compilation database files
find . -name "compile_commands.json" -o -name ".clangd" -o -name ".clang-tidy" | head -10
# Check if there's a build directory with any compilation database
ls -la build/ 2>/dev/null | grep -E "compile_commands|CMakeCache"
# Verify the CMake target setup more thoroughly
rg -n "add_library(Telescode|add_executable(Telescode)" -A 20Repository: c5ln/Telescode
Length of output: 198
🏁 Script executed:
# Fix the regex to search for Telescode target definition
rg -n "add_library\(Telescode\)|add_executable\(Telescode\)" -A 15 CMakeLists.txt
# Check .clang-tidy configuration
echo "=== .clang-tidy content ===" && cat .clang-tidy
# Check for generate_database or compilation settings
rg -n "set\(CMAKE_EXPORT_COMPILE_COMMANDS" CMakeLists.txtRepository: c5ln/Telescode
Length of output: 862
🏁 Script executed:
# Simpler search for Telescode target
rg -n "Telescode" CMakeLists.txt | head -20
# Check the exact target definition lines around where sqlite3 is linked
sed -n '100,115p' CMakeLists.txtRepository: c5ln/Telescode
Length of output: 575
Configure HeaderFilterRegex in .clang-tidy to enable static analysis of project headers.
The sqlite3.h include resolves correctly in the CMake build (sqlite3 target exports third_party/sqlite as a PUBLIC include directory, and Telescode links to it). However, clang-tidy's empty HeaderFilterRegex prevents it from analyzing transitive includes from linked libraries. Set HeaderFilterRegex to a pattern matching project headers (e.g., 'src/.*' or '.*') so static analysis tools properly resolve includes:
HeaderFilterRegex: 'src/.*'🧰 Tools
🪛 Clang (14.0.6)
[error] 3-3: 'sqlite3.h' file not found
(clang-diagnostic-error)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/db.cpp` at line 3, Update the project's .clang-tidy to set
HeaderFilterRegex so clang-tidy can analyze transitive headers like the
sqlite3.h included in src/db.cpp; open .clang-tidy and set HeaderFilterRegex to
a pattern matching your project headers (for example 'src/.*' or '.*') so static
analysis resolves includes exported by linked targets and clang-tidy will
analyze project headers referenced by files such as the sqlite3.h include in
src/db.cpp.
| if (rc != SQLITE_OK) { | ||
| std::fprintf(stderr, "initDb: schema init failed: %s\n", errMsg); | ||
| sqlite3_free(errMsg); |
There was a problem hiding this comment.
Guard errMsg before logging with %s.
At Line 83, passing a null errMsg to %s is undefined behavior on some runtimes. Use a fallback message.
Proposed fix
- if (rc != SQLITE_OK) {
- std::fprintf(stderr, "initDb: schema init failed: %s\n", errMsg);
- sqlite3_free(errMsg);
+ if (rc != SQLITE_OK) {
+ std::fprintf(stderr, "initDb: schema init failed: %s\n",
+ errMsg ? errMsg : sqlite3_errmsg(*db));
+ if (errMsg) sqlite3_free(errMsg);
sqlite3_close(*db);
*db = nullptr;
return rc;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (rc != SQLITE_OK) { | |
| std::fprintf(stderr, "initDb: schema init failed: %s\n", errMsg); | |
| sqlite3_free(errMsg); | |
| if (rc != SQLITE_OK) { | |
| std::fprintf(stderr, "initDb: schema init failed: %s\n", | |
| errMsg ? errMsg : sqlite3_errmsg(*db)); | |
| if (errMsg) sqlite3_free(errMsg); | |
| sqlite3_close(*db); | |
| *db = nullptr; | |
| return rc; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/db.cpp` around lines 82 - 84, The log call in initDb (where rc !=
SQLITE_OK) uses fprintf with "%s" on errMsg which may be null; change the branch
to guard errMsg before passing it to fprintf by computing a const char* msg =
errMsg ? errMsg : "unknown sqlite error" (or similar fallback) and use msg in
the fprintf, and only call sqlite3_free(errMsg) if errMsg is non-null; update
the block around rc, errMsg in src/db.cpp (initDb/error handling) to use the
guarded message and conditional free.
| struct sqlite3; | ||
|
|
||
| // Opens (or creates) telescode.db at the given path. | ||
| // Applies WAL pragmas and creates all tables if they do not exist. | ||
| // Returns SQLITE_OK on success; caller must call sqlite3_close() when done. | ||
| int initDb(const char* dbPath, sqlite3** db); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify whether db.h is included by any C/C++ units and where this declaration is consumed.
rg -n --iglob '*.{c,cc,cpp,cxx,h,hpp}' '#include\s*["<]db\.h[">]'Repository: c5ln/Telescode
Length of output: 86
🏁 Script executed:
# Search for sqlite3 typedef or type definitions in the codebase
rg -n "typedef.*sqlite3|struct sqlite3" --type c --type cpp --type hRepository: c5ln/Telescode
Length of output: 17292
🏁 Script executed:
# Check db.cpp to see how initDb is used and what the context is
head -50 src/db.cppRepository: c5ln/Telescode
Length of output: 1882
🏁 Script executed:
# Search for sqlite3_open and other sqlite3 function calls to understand sqlite3 usage
rg -n "sqlite3_" src/db.cpp | head -20Repository: c5ln/Telescode
Length of output: 340
🏁 Script executed:
# Search for all files that include db.h
rg -n '#include.*db\.h' --type c --type cpp --type hRepository: c5ln/Telescode
Length of output: 86
🏁 Script executed:
# Check if there are any compilation issues mentioned or if the code builds successfully
# Look for any build configuration or CMakeLists
find . -maxdepth 2 -name "CMakeLists.txt" -o -name "Makefile" -o -name "*.mk" -o -name "build.sh" | head -5Repository: c5ln/Telescode
Length of output: 74
🏁 Script executed:
# Check CMakeLists.txt to understand build setup
cat CMakeLists.txtRepository: c5ln/Telescode
Length of output: 3646
🏁 Script executed:
# Check if db.h is only included by db.cpp or if it's part of the public interface
grep -r "initDb" --include="*.h" --include="*.cpp" | head -20Repository: c5ln/Telescode
Length of output: 327
Add struct keyword to the function parameter type for consistency.
At line 8, the header forward-declares struct sqlite3 but uses sqlite3** (the typedef name) without the struct tag. This inconsistency should be fixed for clarity and to match the forward declaration style.
Proposed fix
struct sqlite3;
-int initDb(const char* dbPath, sqlite3** db);
+int initDb(const char* dbPath, struct sqlite3** db);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| struct sqlite3; | |
| // Opens (or creates) telescode.db at the given path. | |
| // Applies WAL pragmas and creates all tables if they do not exist. | |
| // Returns SQLITE_OK on success; caller must call sqlite3_close() when done. | |
| int initDb(const char* dbPath, sqlite3** db); | |
| struct sqlite3; | |
| // Opens (or creates) telescode.db at the given path. | |
| // Applies WAL pragmas and creates all tables if they do not exist. | |
| // Returns SQLITE_OK on success; caller must call sqlite3_close() when done. | |
| int initDb(const char* dbPath, struct sqlite3** db); |
🧰 Tools
🪛 Clang (14.0.6)
[error] 8-8: must use 'struct' tag to refer to type 'sqlite3'
(clang-diagnostic-error)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/db.h` around lines 3 - 8, The header forward-declares `struct sqlite3`
but the `initDb` prototype uses `sqlite3**`; update the parameter to use the
forward-declared tag by changing the function declaration for `initDb` to accept
`struct sqlite3** db` (i.e., replace `sqlite3** db` with `struct sqlite3** db`)
so the declaration matches the forward declaration and avoids mismatch between
the tag and typedef; leave the function name `initDb` and other comments
unchanged.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/db.cpp`:
- Line 69: The null-pointer check `if (!dbPath || !db) return SQLITE_MISUSE;`
must also reject empty strings so an empty path doesn't open a temp DB; update
the validation to treat an empty C-string as misuse by adding a check for
dbPath[0] == '\0' (or equivalent strlen(dbPath) == 0) alongside the existing
dbPath and db checks before proceeding with sqlite3_open, keeping the same
return value SQLITE_MISUSE and referencing the same dbPath and db variables.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
|
|
||
| int initDb(const char* dbPath, sqlite3** db) | ||
| { | ||
| if (!dbPath || !db) return SQLITE_MISUSE; |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
In SQLite C API, what does sqlite3_open("") (empty filename) do, and does it create a temporary database?
💡 Result:
sqlite3_open("") opens a private, temporary on-disk database. It creates a temporary file to hold the database, which is automatically deleted when the database connection is closed. This differs from sqlite3_open(":memory:") which creates a pure in-memory database.
Citations:
- 1: https://sqlite.org/c3ref/open.html
- 2: https://tool.oschina.net/uploads/apidocs/sqlite/c3ref/open.html
- 3: https://sqlite.org/inmemorydb.html
🏁 Script executed:
head -100 src/db.cpp | tail -50Repository: c5ln/Telescode
Length of output: 1877
🏁 Script executed:
rg "initDb" --type cpp -B 2 -A 2Repository: c5ln/Telescode
Length of output: 1069
🏁 Script executed:
rg "initDb\(" --type cpp --type h | grep -v "fprintf\|std::"Repository: c5ln/Telescode
Length of output: 168
🏁 Script executed:
rg "initDb" --type cpp --type h --glob "*.cpp" --glob "*.h" | grep -v "^src/db\."Repository: c5ln/Telescode
Length of output: 40
🏁 Script executed:
rg "initDb" --type cpp --type h -lRepository: c5ln/Telescode
Length of output: 77
🏁 Script executed:
rg "initDb" -A 0 -B 0Repository: c5ln/Telescode
Length of output: 327
🏁 Script executed:
git ls-files --cached --others --exclude-standard | head -20Repository: c5ln/Telescode
Length of output: 384
🏁 Script executed:
rg "initDb" src/main.cpp -B 3 -A 3Repository: c5ln/Telescode
Length of output: 40
🏁 Script executed:
grep -r "initDb" src/ --include="*.cpp" --include="*.h"Repository: c5ln/Telescode
Length of output: 327
🏁 Script executed:
cat -n src/main.cppRepository: c5ln/Telescode
Length of output: 431
🏁 Script executed:
find . -name "*.cpp" -o -name "*.h" | xargs grep -l "sqlite3\|db\." | head -10Repository: c5ln/Telescode
Length of output: 146
🏁 Script executed:
cat -n src/db.hRepository: c5ln/Telescode
Length of output: 389
Add validation to reject empty dbPath strings.
The current check !dbPath catches null pointers but not empty strings. According to SQLite documentation, sqlite3_open("") opens a private temporary on-disk database instead of a file-based one, which contradicts the documented intent to open "telescode.db at the given path."
Proposed fix
- if (!dbPath || !db) return SQLITE_MISUSE;
+ if (!dbPath || dbPath[0] == '\0' || !db) return SQLITE_MISUSE;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/db.cpp` at line 69, The null-pointer check `if (!dbPath || !db) return
SQLITE_MISUSE;` must also reject empty strings so an empty path doesn't open a
temp DB; update the validation to treat an empty C-string as misuse by adding a
check for dbPath[0] == '\0' (or equivalent strlen(dbPath) == 0) alongside the
existing dbPath and db checks before proceeding with sqlite3_open, keeping the
same return value SQLITE_MISUSE and referencing the same dbPath and db
variables.
Summary
closes #3
third_party/sqlite/. No network dependency at build timesrc/db.h/src/db.cppwithinitDb()that opens/createstelescode.dband runs full schema initBUILD_SHARED_LIBS OFFin CMake to force tree-sitter to build as a static library*.db,*.db-shm,*.db-walto.gitignoreSchema (
src/db.cpp)Pragmas:
journal_mode=WAL,foreign_keys=ON,synchronous=NORMALfilefile_idclassclass_id, FK →fileCASCADE, UNIQUE(file_id,class_name)base_classclass_id,ordinal), FK →classCASCADEfunctionfunction_id, CHECKparent_type IN ('file','class')paramfunction_id,ordinal), FK →functionCASCADElinksource_id,target_id,link_type), CHECKlink_type IN ('CALLS','INHERITS','IMPORTS','DECORATES')Indexes:
idx_class_file,idx_function_parent,idx_function_file(partial),idx_link_source,idx_link_target,idx_link_typeTest plan
cmake -S . -B build && cmake --build build --config Debugsucceeds with no linker errors./build/Debug/Telescode.exeprintsinitDb: OKtelescode.dbis created and readable as a valid SQLite database