import sqlite3

class PhaseDBCursor:
    def __init__(self, connection):
        """
        Initialize PhaseDBCursor with a PhaseDBConnection object.
        """
        self.conn = connection.conn  # underlying sqlite3 connection
        self.cursor = self.conn.cursor()

    # ---------- Raw SQL ----------
    def execute(self, sql, params=()):
        return self.cursor.execute(sql, params)

    def executemany(self, sql, seq_of_params):
        return self.cursor.executemany(sql, seq_of_params)

    def fetchall(self):
        return self.cursor.fetchall()

    def fetchone(self):
        return self.cursor.fetchone()

    def close(self):
        self.cursor.close()

    # ---------- PhaseDB Helper Methods ----------
    def insert(self, table_name, row):
        """
        Insert a row into a table.
        row = dict of column_name: value
        """
        keys = ", ".join(row.keys())
        question_marks = ", ".join(["?"]*len(row))
        values = tuple(row.values())
        sql = f"INSERT INTO {table_name} ({keys}) VALUES ({question_marks})"
        self.execute(sql, values)
        self.conn.commit()
        return self.cursor.lastrowid

    def select(self, table_name, where=None):
        sql = f"SELECT * FROM {table_name}"
        params = ()
        if where:
            sql += f" WHERE {where[0]}"
            params = where[1]
        self.execute(sql, params)
        return self.fetchall()

    def update(self, table_name, updates, where=None):
        set_clause = ", ".join([f"{k} = ?" for k in updates.keys()])
        params = tuple(updates.values())
        sql = f"UPDATE {table_name} SET {set_clause}"
        if where:
            sql += f" WHERE {where[0]}"
            params += tuple(where[1])
        self.execute(sql, params)
        self.conn.commit()

    def delete(self, table_name, where=None):
        sql = f"DELETE FROM {table_name}"
        params = ()
        if where:
            sql += f" WHERE {where[0]}"
            params = where[1]
        self.execute(sql, params)
        self.conn.commit()