import pandas as pd


class QDBConnector:
    def selectObj(self, columns, condition): pass
    def deleteObj(self, idx): pass
    def insertObj(self, new_data): pass
    def updateObj(self, new_data, index=None): pass

class QPDConnector(QDBConnector):
    def __init__(self, table):
        self.table = table
    
    def selectObj(self, columns, condition):
        if isinstance(condition, list): condition = " & ".join(condition)
        return self.table.query(condition)[self.table.columns if columns=="*" else columns].copy()
    
    def deleteObj(self, idx):
        self.table.drop(idx, inplace=True)
    
    def insertObj(self, new_data):
        new_data = pd.DataFrame([new_data])
        self.table = pd.concat([self.table, new_data], ignore_index=True)
    
    def updateObj(self, new_data, index=None):
        if isinstance(new_data, dict): new_data = pd.DataFrame(dict, index=index)
        self.table.update(new_data)
        
    def columns(self):
        return self.table.columns

class QHiveConnector(QDBConnector):
    def __init__(self, table, connector, to_pandas=True):
        self._table = table
        self._connector=connector
        self._columns = self._get_columns(self._connector(f"select * from  {self._table} limit 1"))
        
    def _get_columns(self, row):
        if type(row).__name__ == 'Table': row=row.to_pandas()
        return row.columns
    
    def selectObj(self, columns="*", condition=None):
        print(f"select {columns} from {self._table} {'where '+condition if condition else ''}")
        return self._connector(f"select {columns} from {self._table} {'where '+condition if condition else ''}")
    
    def deleteObj(self, condition):
        print(f"delete from {self._table} where {condition}")
        self._connector(f"delete from {self._table} where {condition}")
    
    def insertObj(self, new_data):
        print(f"insert into {self._table} ({','.join(new_data.keys())}) VALUES ({','.join([qstr(x) for x in new_data.values()])})")
        self._connector(f"insert into table {self._table} ({','.join(new_data.keys())}) VALUES ({','.join([qstr(x) for x in new_data.values()])})")

    def executeQuery(self, query):
        return self._connector(query)
    
    @property
    def columns(self):
        return self._columns
    
    @property
    def table(self):
        return self._table