Initial upload: shell-history-semantic-search v0.1.0
Some checks failed
CI / test (push) Has been cancelled
Some checks failed
CI / test (push) Has been cancelled
This commit is contained in:
91
src/shell_history_search/db/__init__.py
Normal file
91
src/shell_history_search/db/__init__.py
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
import os
|
||||||
|
import sqlite3
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Optional
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
DEFAULT_DB_PATH = Path.home() / ".local" / "share" / "shell_history_search" / "history.db"
|
||||||
|
|
||||||
|
|
||||||
|
def get_db_path() -> Path:
|
||||||
|
return Path(os.environ.get("SHELL_HISTORY_DB", str(DEFAULT_DB_PATH)))
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_db_directory(db_path: Path) -> None:
|
||||||
|
db_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_connection(db_path: Optional[Path] = None) -> sqlite3.Connection:
|
||||||
|
if db_path is None:
|
||||||
|
db_path = get_db_path()
|
||||||
|
|
||||||
|
ensure_db_directory(db_path)
|
||||||
|
|
||||||
|
conn = sqlite3.connect(str(db_path), check_same_thread=False)
|
||||||
|
conn.row_factory = sqlite3.Row
|
||||||
|
|
||||||
|
conn.execute("PRAGMA journal_mode=WAL")
|
||||||
|
conn.execute("PRAGMA foreign_keys=ON")
|
||||||
|
|
||||||
|
return conn
|
||||||
|
|
||||||
|
|
||||||
|
def init_database(db_path: Optional[Path] = None) -> sqlite3.Connection:
|
||||||
|
conn = get_connection(db_path)
|
||||||
|
|
||||||
|
conn.execute("""
|
||||||
|
CREATE TABLE IF NOT EXISTS commands (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
command TEXT NOT NULL,
|
||||||
|
shell_type TEXT NOT NULL,
|
||||||
|
timestamp INTEGER,
|
||||||
|
hostname TEXT,
|
||||||
|
command_hash TEXT UNIQUE NOT NULL,
|
||||||
|
created_at INTEGER DEFAULT (strftime('%s', 'now')),
|
||||||
|
indexed_at INTEGER
|
||||||
|
)
|
||||||
|
""")
|
||||||
|
|
||||||
|
conn.execute("""
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_commands_hash ON commands(command_hash)
|
||||||
|
""")
|
||||||
|
|
||||||
|
conn.execute("""
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_commands_shell ON commands(shell_type)
|
||||||
|
""")
|
||||||
|
|
||||||
|
conn.execute("""
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_commands_timestamp ON commands(timestamp)
|
||||||
|
""")
|
||||||
|
|
||||||
|
conn.execute("""
|
||||||
|
CREATE TABLE IF NOT EXISTS embeddings (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
command_id INTEGER NOT NULL,
|
||||||
|
embedding BLOB NOT NULL,
|
||||||
|
model_name TEXT NOT NULL,
|
||||||
|
created_at INTEGER DEFAULT (strftime('%s', 'now')),
|
||||||
|
FOREIGN KEY (command_id) REFERENCES commands(id) ON DELETE CASCADE,
|
||||||
|
UNIQUE(command_id)
|
||||||
|
)
|
||||||
|
""")
|
||||||
|
|
||||||
|
conn.execute("""
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_embeddings_command ON embeddings(command_id)
|
||||||
|
""")
|
||||||
|
|
||||||
|
conn.execute("""
|
||||||
|
CREATE TABLE IF NOT EXISTS index_state (
|
||||||
|
shell_type TEXT PRIMARY KEY,
|
||||||
|
last_indexed_at INTEGER,
|
||||||
|
last_indexed_hash TEXT
|
||||||
|
)
|
||||||
|
""")
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
logger.info(f"Database initialized at {db_path}")
|
||||||
|
|
||||||
|
return conn
|
||||||
Reference in New Issue
Block a user