Expand description
§bear-query
A completely read-only, minimal-contention library for querying Bear app’s SQLite database.
§Safety Guarantees
This library implements multiple layers of protection to ensure minimal interference with Bear:
- Read-Only File Access: Opens with
SQLITE_OPEN_READ_ONLY - No Internal Locks: Uses
SQLITE_OPEN_NO_MUTEXto minimize lock contention - Query-Only Mode: Enforces
PRAGMA query_only = ONat SQLite level - Short-Lived Connections: Connections are only open during each query
- Busy Timeout: 5000ms timeout handles database contention gracefully
§How It Works
Bear does not use SQLite’s WAL (Write-Ahead Logging) mode by default. To minimize interference, this library uses short-lived connections that are opened only when needed and closed immediately after use.
Each method call:
- Opens a read-only connection with a 5000ms busy timeout
- Executes the query
- Automatically closes the connection
This approach ensures minimal lock contention with Bear’s write operations.
§Normalized Schema
This library automatically normalizes Bear’s Core Data schema through Common Table Expressions (CTEs).
All queries (both typed methods and the generic query() API) have access to these normalized views:
§notes Table
The normalized view of all notes in Bear.
| Column | Type | Description |
|---|---|---|
id | INTEGER | Note’s primary key |
unique_id | TEXT | Bear’s UUID for the note |
title | TEXT | Note title |
content | TEXT | Full note content (Markdown) |
modified | DATETIME | Last modification timestamp (converted from Core Data epoch) |
created | DATETIME | Creation timestamp (converted from Core Data epoch) |
is_pinned | INTEGER | 1 if pinned, 0 otherwise |
is_trashed | INTEGER | 1 if in trash, 0 otherwise |
is_archived | INTEGER | 1 if archived, 0 otherwise |
§tags Table
The normalized view of all tags.
| Column | Type | Description |
|---|---|---|
id | INTEGER | Tag’s primary key |
name | TEXT | Tag name (e.g., “work/projects”) |
modified | DATETIME | Last modification timestamp |
§note_tags Table
Junction table linking notes to their tags (many-to-many relationship).
| Column | Type | Description |
|---|---|---|
note_id | INTEGER | Foreign key to notes.id |
tag_id | INTEGER | Foreign key to tags.id |
§note_links Table
Links between notes (bidirectional wiki-style links).
| Column | Type | Description |
|---|---|---|
from_note_id | INTEGER | Source note ID |
to_note_id | INTEGER | Target note ID |
§Core Data Epoch Conversion
Bear uses Apple’s Core Data timestamp format (seconds since 2001-01-01 00:00:00 UTC). This library automatically converts all timestamps to standard SQLite datetime format.
The conversion is done via a CTE: unixepoch('2001-01-01')
§Schema Discovery
The library discovers variable schema elements at initialization:
- Junction table column names (e.g.,
Z_5NOTES,Z_13TAGS) - These numbers may vary across Bear versions
For full schema details, see the SCHEMA.md documentation file.
§Example
use bear_query::{BearDb, NotesQuery};
// Create a handle (no connection opened yet)
let db = BearDb::new()?;
// Each method opens a connection, queries, and closes
let all_tags = db.tags()?;
let recent_notes = db.notes(NotesQuery::default())?;
for note in recent_notes {
println!("{}", note.title());
}Modules§
Structs§
- BearDb
- Handle to Bear’s database. All operations use short-lived connections internally.
- Bear
Note - Bear
Note Id - BearTag
- Bear
TagId - Bear
Tags - DbId
- Notes
Query - Query options for filtering notes
- Queryable
- A wrapper around a database connection that automatically applies normalizing CTEs to queries. This abstracts away Bear’s Core Data quirks (Z_ prefixes, numbered columns, epoch timestamps).
Enums§
- Bear
Error - Database
Path - Specifies the database location for BearDb.