| """ |
| Visual Query Builder |
| Build SQL queries without writing SQL |
| """ |
|
|
| from typing import Dict, List, Optional |
|
|
| class QueryBuilder: |
| """Build SQL queries programmatically""" |
| |
| def build_select(self, database: str, table: str, columns: List[str] = None, |
| where: Dict = None, order_by: str = None, limit: int = None, |
| offset: int = None, group_by: List[str] = None, |
| having: str = None, joins: List[Dict] = None) -> str: |
| """Build SELECT query""" |
| |
| |
| if columns: |
| cols = ", ".join(columns) |
| else: |
| cols = "*" |
| |
| query = f'SELECT {cols} FROM "{database}"."{table}"' |
| |
| |
| if joins: |
| for join in joins: |
| join_type = join.get('type', 'INNER').upper() |
| join_table = join['table'] |
| on_condition = join['on'] |
| query += f' {join_type} JOIN "{join_table}" ON {on_condition}' |
| |
| |
| if where: |
| conditions = [] |
| for key, value in where.items(): |
| if isinstance(value, dict): |
| |
| op = value.get('op', '=') |
| val = value.get('value') |
| if isinstance(val, str): |
| conditions.append(f'{key} {op} \'{val}\'') |
| else: |
| conditions.append(f'{key} {op} {val}') |
| else: |
| if isinstance(value, str): |
| conditions.append(f'{key} = \'{value}\'') |
| else: |
| conditions.append(f'{key} = {value}') |
| |
| query += ' WHERE ' + ' AND '.join(conditions) |
| |
| |
| if group_by: |
| query += ' GROUP BY ' + ', '.join(group_by) |
| |
| |
| if having: |
| query += f' HAVING {having}' |
| |
| |
| if order_by: |
| query += f' ORDER BY {order_by}' |
| |
| |
| if limit: |
| query += f' LIMIT {limit}' |
| |
| |
| if offset: |
| query += f' OFFSET {offset}' |
| |
| return query |
| |
| def build_insert(self, database: str, table: str, data: Dict) -> str: |
| """Build INSERT query""" |
| columns = list(data.keys()) |
| values = [] |
| |
| for val in data.values(): |
| if val is None: |
| values.append('NULL') |
| elif isinstance(val, str): |
| values.append(f"'{val}'") |
| else: |
| values.append(str(val)) |
| |
| cols_str = ', '.join(columns) |
| vals_str = ', '.join(values) |
| |
| return f'INSERT INTO "{database}"."{table}" ({cols_str}) VALUES ({vals_str})' |
| |
| def build_update(self, database: str, table: str, data: Dict, where: Dict) -> str: |
| """Build UPDATE query""" |
| set_clauses = [] |
| |
| for key, val in data.items(): |
| if val is None: |
| set_clauses.append(f'{key} = NULL') |
| elif isinstance(val, str): |
| set_clauses.append(f'{key} = \'{val}\'') |
| else: |
| set_clauses.append(f'{key} = {val}') |
| |
| query = f'UPDATE "{database}"."{table}" SET ' + ', '.join(set_clauses) |
| |
| if where: |
| conditions = [] |
| for key, val in where.items(): |
| if isinstance(val, str): |
| conditions.append(f'{key} = \'{val}\'') |
| else: |
| conditions.append(f'{key} = {val}') |
| query += ' WHERE ' + ' AND '.join(conditions) |
| |
| return query |
| |
| def build_delete(self, database: str, table: str, where: Dict) -> str: |
| """Build DELETE query""" |
| query = f'DELETE FROM "{database}"."{table}"' |
| |
| if where: |
| conditions = [] |
| for key, val in where.items(): |
| if isinstance(val, str): |
| conditions.append(f'{key} = \'{val}\'') |
| else: |
| conditions.append(f'{key} = {val}') |
| query += ' WHERE ' + ' AND '.join(conditions) |
| |
| return query |
| |
| def build_aggregate(self, database: str, table: str, aggregates: List[Dict], |
| group_by: List[str] = None, where: Dict = None) -> str: |
| """Build aggregate query (COUNT, SUM, AVG, etc.)""" |
| |
| agg_clauses = [] |
| for agg in aggregates: |
| func = agg['function'].upper() |
| column = agg['column'] |
| alias = agg.get('alias', f'{func.lower()}_{column}') |
| agg_clauses.append(f'{func}({column}) AS {alias}') |
| |
| query = f'SELECT {", ".join(agg_clauses)} FROM "{database}"."{table}"' |
| |
| if where: |
| conditions = [] |
| for key, val in where.items(): |
| if isinstance(val, str): |
| conditions.append(f'{key} = \'{val}\'') |
| else: |
| conditions.append(f'{key} = {val}') |
| query += ' WHERE ' + ' AND '.join(conditions) |
| |
| if group_by: |
| query += ' GROUP BY ' + ', '.join(group_by) |
| |
| return query |
|
|
| query_builder = QueryBuilder() |
|
|