from .parts import Column


def CAST(type1, type2):
    return Column('CAST(%s)' % _actual_n('%s AS %s' % (type1, type2)))

def CONCAT(*args):
    arg = ['"%s"' % _actual_n(a) for a in args]
    arg = ', '.join(arg)
    return Column('CONCAT(%s)' % arg)

def IF(cond, val_t, val_f):
    cond, val_t, val_f = (_actual_n(x) for x in [cond, val_t, val_f])
    return Column('IF(%s, %s, %s)' % (cond, val_t, val_f))

def _fn_factory(name):
    return lambda col: Column('{0}({1})'.format(name, _actual_n(col)))
    #return eval("lambda col: Column('{0}(%s)' % _actual_n(col))".format(name))

def _actual_n(col):
    if isinstance(col, str):
        return col
    elif isinstance(col, Column):
        return col.real_name
    else:
        return str(col)

COUNT = _fn_factory('COUNT')
SUM = _fn_factory('SUM')
INTEGER = _fn_factory('INTEGER')
from .parts import Column


def CAST(type1, type2):
    return Column('CAST(%s)' % _actual_n('%s AS %s' % (type1, type2)))

def CONCAT(*args):
    arg = ['"%s"' % _actual_n(a) for a in args]
    arg = ', '.join(arg)
    return Column('CONCAT(%s)' % arg)

def _fn_factory(name):
    def _fn(*col):
        return Column('{0}({1})'.format(name, ','.join(_actual_n(x) for x in col)))
    return _fn

def _actual_n(col):
    if isinstance(col, str):
        return col
    elif isinstance(col, Column):
        return col.real_name
    else:
        return str(col)

COUNT = _fn_factory('COUNT')
SUM = _fn_factory('SUM')
INTEGER = _fn_factory('INTEGER')
SQRT = _fn_factory('SQRT')
IF = _fn_factory('IF')
POW = _fn_factory('POW')

Add clever func factory and math funcs