File size: 2,919 Bytes
01a0455
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import os
import logging
import pyodbc
import sqlite3
from typing import Optional, List, Tuple


def connect_to_memory_database() -> Optional[pyodbc.Connection]:
    """Connect to Azure SQL Database using HF secret environment variables."""
    try:
        server = os.getenv("AZURE_SQL_SERVER")
        database = os.getenv("AZURE_SQL_DATABASE")
        username = os.getenv("AZURE_SQL_USERNAME")
        password = os.getenv("AZURE_SQL_PASSWORD")
        driver = "{ODBC Driver 17 for SQL Server}"

        if not all([server, database, username, password]):
            logging.warning("Azure SQL credentials missing. Falling back to SQLite.")
            return None

        conn_str = (
            f"DRIVER={driver};SERVER={server};DATABASE={database};"
            f"UID={username};PWD={password}"
        )
        conn = pyodbc.connect(conn_str)
        logging.info("Connected to Azure SQL Database.")
        return conn
    except pyodbc.Error as e:
        logging.error(f"Azure SQL connection error: {e}")
        return None


def log_memory(conn, query: str, response: str) -> None:
    try:
        cursor = conn.cursor()
        cursor.execute(
            "CREATE TABLE IF NOT EXISTS codette_memory (query TEXT, response TEXT)"
        )
        cursor.execute(
            "INSERT INTO codette_memory (query, response) VALUES (?, ?)", (query, response)
        )
        conn.commit()
        logging.info("Memory logged successfully.")
    except Exception as e:
        logging.error(f"Failed to log memory: {e}")


def get_recent_entries(conn, limit: int = 5) -> List[Tuple[str, str]]:
    try:
        cursor = conn.cursor()
        cursor.execute(
            "SELECT TOP (?) query, response FROM codette_memory ORDER BY 1 DESC", (limit,)
        )
        return cursor.fetchall()
    except Exception as e:
        logging.warning(f"Failed to fetch memory: {e}")
        return []


def ping_database(conn) -> bool:
    try:
        cursor = conn.cursor()
        cursor.execute("SELECT 1")
        return True
    except Exception as e:
        logging.warning(f"Ping failed: {e}")
        return False


# SQLite fallback (in-memory or file-backed)
def get_sqlite_memory(fallback_path: Optional[str] = ":memory:") -> sqlite3.Connection:
    conn = sqlite3.connect(fallback_path)
    conn.execute("CREATE TABLE IF NOT EXISTS codette_memory (query TEXT, response TEXT)")
    return conn


# Context manager for auto-closing
class MemoryConnection:
    def __init__(self):
        self.conn = connect_to_memory_database()
        if self.conn is None:
            self.conn = get_sqlite_memory()

    def __enter__(self):
        return self.conn

    def __exit__(self, exc_type, exc_value, traceback):
        try:
            self.conn.close()
            logging.info("Memory DB connection closed.")
        except Exception as e:
            logging.warning(f"Failed to close DB: {e}")