/** * SQL Query Constants * * All SQL queries used in the application. * Repositories reference these by name (e.g., MARKET_CALLS_QUERIES.SELECT_ALL). * QueryBuilder looks them up and binds parameters. * * All queries use parameterized statements (?) for security. * User input NEVER goes into the SQL string. */ // ── Holdings Table Queries ─────────────────────────────────────────────────── export const HOLDINGS_QUERIES = { // Check if any holdings exist EXISTS: 'SELECT COUNT(*) AS n FROM holdings', // Get all holdings, sorted by ticker SELECT_ALL: 'SELECT ticker, shares, cost_basis, type, source FROM holdings ORDER BY ticker ASC', // Insert or update a holding (UPSERT) UPSERT: ` INSERT INTO holdings (ticker, shares, cost_basis, type, source) VALUES (?, ?, ?, ?, ?) ON CONFLICT(ticker) DO UPDATE SET shares = excluded.shares, cost_basis = excluded.cost_basis, type = excluded.type, source = excluded.source `, // Delete a holding by ticker DELETE_BY_TICKER: 'DELETE FROM holdings WHERE ticker = ?', }; // ── Market Calls Table Queries ─────────────────────────────────────────────── export const MARKET_CALLS_QUERIES = { // Get all market calls, newest first SELECT_ALL: ` SELECT id, title, quarter, date, thesis, tickers, snapshot, created_at FROM market_calls ORDER BY created_at DESC `, // Get a single market call by ID SELECT_BY_ID: ` SELECT id, title, quarter, date, thesis, tickers, snapshot, created_at FROM market_calls WHERE id = ? `, // Insert a new market call INSERT: ` INSERT INTO market_calls (id, title, quarter, date, thesis, tickers, snapshot, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) `, // Delete a market call by ID DELETE_BY_ID: 'DELETE FROM market_calls WHERE id = ?', }; // ── Migration Queries (for DatabaseInitializer) ────────────────────────────── export const MIGRATION_QUERIES = { // Insert holdings during migration HOLDINGS_INSERT_OR_IGNORE: ` INSERT OR IGNORE INTO holdings (ticker, shares, cost_basis, type, source) VALUES (?, ?, ?, ?, ?) `, // Insert market calls during migration MARKET_CALLS_INSERT_OR_IGNORE: ` INSERT OR IGNORE INTO market_calls (id, title, quarter, date, thesis, tickers, snapshot, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) `, }; // ── Schema Definition (DDL) ────────────────────────────────────────────────── export const DDL = ` CREATE TABLE IF NOT EXISTS holdings ( ticker TEXT PRIMARY KEY, shares REAL NOT NULL, cost_basis REAL NOT NULL DEFAULT 0, type TEXT NOT NULL DEFAULT 'stock', source TEXT NOT NULL DEFAULT 'Manual' ); CREATE TABLE IF NOT EXISTS market_calls ( id TEXT PRIMARY KEY, title TEXT NOT NULL, quarter TEXT NOT NULL, date TEXT NOT NULL, thesis TEXT NOT NULL, tickers TEXT NOT NULL, -- JSON array snapshot TEXT NOT NULL, -- JSON object created_at TEXT NOT NULL ); `;