Esempio n. 1
0
class SQLiteBuilder(SQLBuilder):
    dialect = 'SQLite'
    def SELECT_FOR_UPDATE(builder, nowait, *sections):
        assert not builder.indent and not nowait
        return builder.SELECT(*sections)
    def INSERT(builder, table_name, columns, values, returning=None):
        if not values: return 'INSERT INTO %s DEFAULT VALUES' % builder.quote_name(table_name)
        return SQLBuilder.INSERT(builder, table_name, columns, values, returning)
    def TODAY(builder):
        return "date('now', 'localtime')"
    def NOW(builder):
        return "datetime('now', 'localtime')"
    def YEAR(builder, expr):
        return 'cast(substr(', builder(expr), ', 1, 4) as integer)'
    def MONTH(builder, expr):
        return 'cast(substr(', builder(expr), ', 6, 2) as integer)'
    def DAY(builder, expr):
        return 'cast(substr(', builder(expr), ', 9, 2) as integer)'
    def HOUR(builder, expr):
        return 'cast(substr(', builder(expr), ', 12, 2) as integer)'
    def MINUTE(builder, expr):
        return 'cast(substr(', builder(expr), ', 15, 2) as integer)'
    def SECOND(builder, expr):
        return 'cast(substr(', builder(expr), ', 18, 2) as integer)'
    def datetime_add(builder, funcname, expr, td):
        assert isinstance(td, timedelta)
        modifiers = []
        seconds = td.seconds + td.days * 24 * 3600
        sign = '+' if seconds > 0 else '-'
        seconds = abs(seconds)
        if seconds >= (24 * 3600):
            days = seconds // (24 * 3600)
            modifiers.append(", '%s%d days'" % (sign, days))
            seconds -= days * 24 * 3600
        if seconds >= 3600:
            hours = seconds // 3600
            modifiers.append(", '%s%d hours'" % (sign, hours))
            seconds -= hours * 3600
        if seconds >= 60:
            minutes = seconds // 60
            modifiers.append(", '%s%d minutes'" % (sign, minutes))
            seconds -= minutes * 60
        if seconds:
            modifiers.append(", '%s%d seconds'" % (sign, seconds))
        if not modifiers: return builder(expr)
        return funcname, '(', builder(expr), modifiers, ')'
    def DATE_ADD(builder, expr, delta):
        if isinstance(delta, timedelta):
            return builder.datetime_add('date', expr, delta)
        return 'datetime(julianday(', builder(expr), ') + ', builder(delta), ')'
    def DATE_SUB(builder, expr, delta):
        if isinstance(delta, timedelta):
            return builder.datetime_add('date', expr, -delta)
        return 'datetime(julianday(', builder(expr), ') - ', builder(delta), ')'
    def DATETIME_ADD(builder, expr, delta):
        if isinstance(delta, timedelta):
            return builder.datetime_add('datetime', expr, delta)
        return 'datetime(julianday(', builder(expr), ') + ', builder(delta), ')'
    def DATETIME_SUB(builder, expr, delta):
        if isinstance(delta, timedelta):
            return builder.datetime_add('datetime', expr, -delta)
        return 'datetime(julianday(', builder(expr), ') - ', builder(delta), ')'
    def MIN(builder, *args):
        if len(args) == 0: assert False  # pragma: no cover
        elif len(args) == 1: fname = 'MIN'
        else: fname = 'min'
        return fname, '(',  join(', ', imap(builder, args)), ')'
    def MAX(builder, *args):
        if len(args) == 0: assert False  # pragma: no cover
        elif len(args) == 1: fname = 'MAX'
        else: fname = 'max'
        return fname, '(',  join(', ', imap(builder, args)), ')'
    def RANDOM(builder):
        return 'rand()'  # return '(random() / 9223372036854775807.0 + 1.0) / 2.0'
    PY_UPPER = make_unary_func('py_upper')
    PY_LOWER = make_unary_func('py_lower')
Esempio n. 2
0
class SQLiteBuilder(SQLBuilder):
    dialect = 'SQLite'

    def __init__(builder, provider, ast):
        builder.json1_available = provider.json1_available
        SQLBuilder.__init__(builder, provider, ast)

    def SELECT_FOR_UPDATE(builder, nowait, *sections):
        assert not builder.indent and not nowait
        return builder.SELECT(*sections)

    def INSERT(builder, table_name, columns, values, returning=None):
        if not values:
            return 'INSERT INTO %s DEFAULT VALUES' % builder.quote_name(
                table_name)
        return SQLBuilder.INSERT(builder, table_name, columns, values,
                                 returning)

    def TODAY(builder):
        return "date('now', 'localtime')"

    def NOW(builder):
        return "datetime('now', 'localtime')"

    def YEAR(builder, expr):
        return 'cast(substr(', builder(expr), ', 1, 4) as integer)'

    def MONTH(builder, expr):
        return 'cast(substr(', builder(expr), ', 6, 2) as integer)'

    def DAY(builder, expr):
        return 'cast(substr(', builder(expr), ', 9, 2) as integer)'

    def HOUR(builder, expr):
        return 'cast(substr(', builder(expr), ', 12, 2) as integer)'

    def MINUTE(builder, expr):
        return 'cast(substr(', builder(expr), ', 15, 2) as integer)'

    def SECOND(builder, expr):
        return 'cast(substr(', builder(expr), ', 18, 2) as integer)'

    def datetime_add(builder, funcname, expr, td):
        assert isinstance(td, timedelta)
        modifiers = []
        seconds = td.seconds + td.days * 24 * 3600
        sign = '+' if seconds > 0 else '-'
        seconds = abs(seconds)
        if seconds >= (24 * 3600):
            days = seconds // (24 * 3600)
            modifiers.append(", '%s%d days'" % (sign, days))
            seconds -= days * 24 * 3600
        if seconds >= 3600:
            hours = seconds // 3600
            modifiers.append(", '%s%d hours'" % (sign, hours))
            seconds -= hours * 3600
        if seconds >= 60:
            minutes = seconds // 60
            modifiers.append(", '%s%d minutes'" % (sign, minutes))
            seconds -= minutes * 60
        if seconds:
            modifiers.append(", '%s%d seconds'" % (sign, seconds))
        if not modifiers: return builder(expr)
        return funcname, '(', builder(expr), modifiers, ')'

    def DATE_ADD(builder, expr, delta):
        if isinstance(delta, timedelta):
            return builder.datetime_add('date', expr, delta)
        return 'datetime(julianday(', builder(expr), ') + ', builder(
            delta), ')'

    def DATE_SUB(builder, expr, delta):
        if isinstance(delta, timedelta):
            return builder.datetime_add('date', expr, -delta)
        return 'datetime(julianday(', builder(expr), ') - ', builder(
            delta), ')'

    def DATETIME_ADD(builder, expr, delta):
        if isinstance(delta, timedelta):
            return builder.datetime_add('datetime', expr, delta)
        return 'datetime(julianday(', builder(expr), ') + ', builder(
            delta), ')'

    def DATETIME_SUB(builder, expr, delta):
        if isinstance(delta, timedelta):
            return builder.datetime_add('datetime', expr, -delta)
        return 'datetime(julianday(', builder(expr), ') - ', builder(
            delta), ')'

    def MIN(builder, *args):
        if len(args) == 0: assert False  # pragma: no cover
        elif len(args) == 1: fname = 'MIN'
        else: fname = 'min'
        return fname, '(', join(', ', imap(builder, args)), ')'

    def MAX(builder, *args):
        if len(args) == 0: assert False  # pragma: no cover
        elif len(args) == 1: fname = 'MAX'
        else: fname = 'max'
        return fname, '(', join(', ', imap(builder, args)), ')'

    def RANDOM(builder):
        return 'rand()'  # return '(random() / 9223372036854775807.0 + 1.0) / 2.0'

    PY_UPPER = make_unary_func('py_upper')
    PY_LOWER = make_unary_func('py_lower')

    def FLOAT_EQ(builder, a, b):
        a, b = builder(a), builder(b)
        return 'abs(', a, ' - ', b, ') / coalesce(nullif(max(abs(', a, '), abs(', b, ')), 0), 1) <= 1e-14'

    def FLOAT_NE(builder, a, b):
        a, b = builder(a), builder(b)
        return 'abs(', a, ' - ', b, ') / coalesce(nullif(max(abs(', a, '), abs(', b, ')), 0), 1) > 1e-14'

    def JSON_QUERY(builder, expr, path):
        fname = 'json_extract' if builder.json1_available else 'py_json_extract'
        path_sql, has_params, has_wildcards = builder.build_json_path(path)
        return 'py_json_unwrap(', fname, '(', builder(
            expr), ', null, ', path_sql, '))'

    # json_value_type_mapping = {unicode: 'text', bool: 'boolean', int: 'integer', float: 'real', Json: None}
    def JSON_VALUE(builder, expr, path, type):
        func_name = 'json_extract' if builder.json1_available else 'py_json_extract'
        path_sql, has_params, has_wildcards = builder.build_json_path(path)
        return func_name, '(', builder(expr), ', ', path_sql, ')'

    def JSON_NONZERO(builder, expr):
        return builder(
            expr), ''' NOT IN ('null', 'false', '0', '""', '[]', '{}')'''

    def JSON_ARRAY_LENGTH(builder, value):
        func_name = 'json_array_length' if builder.json1_available else 'py_json_array_length'
        return func_name, '(', builder(value), ')'

    def JSON_CONTAINS(builder, expr, path, key):
        path_sql, has_params, has_wildcards = builder.build_json_path(path)
        return 'py_json_contains(', builder(
            expr), ', ', path_sql, ',  ', builder(key), ')'
Esempio n. 3
0
class SQLiteBuilder(SQLBuilder):
    dialect = 'SQLite'
    least_func_name = 'min'
    greatest_func_name = 'max'
    value_class = SQLiteValue

    def __init__(builder, provider, ast):
        builder.json1_available = provider.json1_available
        SQLBuilder.__init__(builder, provider, ast)

    def SELECT_FOR_UPDATE(builder, nowait, skip_locked, *sections):
        assert not builder.indent
        return builder.SELECT(*sections)

    def INSERT(builder, table_name, columns, values, returning=None):
        if not values:
            return 'INSERT INTO %s DEFAULT VALUES' % builder.quote_name(
                table_name)
        return SQLBuilder.INSERT(builder, table_name, columns, values,
                                 returning)

    def STRING_SLICE(builder, expr, start, stop):
        if start is None:
            start = ['VALUE', None]
        if stop is None:
            stop = ['VALUE', None]
        return "py_string_slice(", builder(expr), ', ', builder(
            start), ', ', builder(stop), ")"

    def IN(builder, expr1, x):
        if not x:
            return '0 = 1'
        if len(x) >= 1 and x[0] == 'SELECT':
            return builder(expr1), ' IN ', builder(x)
        op = ' IN (VALUES ' if expr1[0] == 'ROW' else ' IN ('
        expr_list = [builder(expr) for expr in x]
        return builder(expr1), op, join(', ', expr_list), ')'

    def NOT_IN(builder, expr1, x):
        if not x:
            return '1 = 1'
        if len(x) >= 1 and x[0] == 'SELECT':
            return builder(expr1), ' NOT IN ', builder(x)
        op = ' NOT IN (VALUES ' if expr1[0] == 'ROW' else ' NOT IN ('
        expr_list = [builder(expr) for expr in x]
        return builder(expr1), op, join(', ', expr_list), ')'

    def TODAY(builder):
        return "date('now', 'localtime')"

    def NOW(builder):
        return "datetime('now', 'localtime')"

    def YEAR(builder, expr):
        return 'cast(substr(', builder(expr), ', 1, 4) as integer)'

    def MONTH(builder, expr):
        return 'cast(substr(', builder(expr), ', 6, 2) as integer)'

    def DAY(builder, expr):
        return 'cast(substr(', builder(expr), ', 9, 2) as integer)'

    def HOUR(builder, expr):
        return 'cast(substr(', builder(expr), ', 12, 2) as integer)'

    def MINUTE(builder, expr):
        return 'cast(substr(', builder(expr), ', 15, 2) as integer)'

    def SECOND(builder, expr):
        return 'cast(substr(', builder(expr), ', 18, 2) as integer)'

    def datetime_add(builder, funcname, expr, td):
        assert isinstance(td, timedelta)
        modifiers = []
        seconds = td.seconds + td.days * 24 * 3600
        sign = '+' if seconds > 0 else '-'
        seconds = abs(seconds)
        if seconds >= (24 * 3600):
            days = seconds // (24 * 3600)
            modifiers.append(", '%s%d days'" % (sign, days))
            seconds -= days * 24 * 3600
        if seconds >= 3600:
            hours = seconds // 3600
            modifiers.append(", '%s%d hours'" % (sign, hours))
            seconds -= hours * 3600
        if seconds >= 60:
            minutes = seconds // 60
            modifiers.append(", '%s%d minutes'" % (sign, minutes))
            seconds -= minutes * 60
        if seconds:
            modifiers.append(", '%s%d seconds'" % (sign, seconds))
        if not modifiers: return builder(expr)
        return funcname, '(', builder(expr), modifiers, ')'

    def DATE_ADD(builder, expr, delta):
        if delta[0] == 'VALUE' and isinstance(delta[1], timedelta):
            return builder.datetime_add('date', expr, delta[1])
        return 'datetime(julianday(', builder(expr), ') + ', builder(
            delta), ')'

    def DATE_SUB(builder, expr, delta):
        if delta[0] == 'VALUE' and isinstance(delta[1], timedelta):
            return builder.datetime_add('date', expr, -delta[1])
        return 'datetime(julianday(', builder(expr), ') - ', builder(
            delta), ')'

    def DATE_DIFF(builder, expr1, expr2):
        return 'julianday(', builder(expr1), ') - julianday(', builder(
            expr2), ')'

    def DATETIME_ADD(builder, expr, delta):
        if delta[0] == 'VALUE' and isinstance(delta[1], timedelta):
            return builder.datetime_add('datetime', expr, delta[1])
        return 'datetime(julianday(', builder(expr), ') + ', builder(
            delta), ')'

    def DATETIME_SUB(builder, expr, delta):
        if delta[0] == 'VALUE' and isinstance(delta[1], timedelta):
            return builder.datetime_add('datetime', expr, -delta[1])
        return 'datetime(julianday(', builder(expr), ') - ', builder(
            delta), ')'

    def DATETIME_DIFF(builder, expr1, expr2):
        return 'julianday(', builder(expr1), ') - julianday(', builder(
            expr2), ')'

    def RANDOM(builder):
        return 'rand()'  # return '(random() / 9223372036854775807.0 + 1.0) / 2.0'

    PY_UPPER = make_unary_func('py_upper')
    PY_LOWER = make_unary_func('py_lower')

    def FLOAT_EQ(builder, a, b):
        a, b = builder(a), builder(b)
        return 'abs(', a, ' - ', b, ') / coalesce(nullif(max(abs(', a, '), abs(', b, ')), 0), 1) <= 1e-14'

    def FLOAT_NE(builder, a, b):
        a, b = builder(a), builder(b)
        return 'abs(', a, ' - ', b, ') / coalesce(nullif(max(abs(', a, '), abs(', b, ')), 0), 1) > 1e-14'

    def JSON_QUERY(builder, expr, path):
        fname = 'json_extract' if builder.json1_available else 'py_json_extract'
        path_sql, has_params, has_wildcards = builder.build_json_path(path)
        return 'py_json_unwrap(', fname, '(', builder(
            expr), ', null, ', path_sql, '))'

    json_value_type_mapping = {
        unicode: 'text',
        bool: 'integer',
        int: 'integer',
        float: 'real'
    }

    def JSON_VALUE(builder, expr, path, type):
        func_name = 'json_extract' if builder.json1_available else 'py_json_extract'
        path_sql, has_params, has_wildcards = builder.build_json_path(path)
        type_name = builder.json_value_type_mapping.get(type)
        result = func_name, '(', builder(expr), ', ', path_sql, ')'
        if type_name is not None:
            result = 'CAST(', result, ' as ', type_name, ')'
        return result

    def JSON_NONZERO(builder, expr):
        return builder(
            expr), ''' NOT IN ('null', 'false', '0', '""', '[]', '{}')'''

    def JSON_ARRAY_LENGTH(builder, value):
        func_name = 'json_array_length' if builder.json1_available else 'py_json_array_length'
        return func_name, '(', builder(value), ')'

    def JSON_CONTAINS(builder, expr, path, key):
        path_sql, has_params, has_wildcards = builder.build_json_path(path)
        return 'py_json_contains(', builder(
            expr), ', ', path_sql, ',  ', builder(key), ')'

    def ARRAY_INDEX(builder, col, index):
        return 'py_array_index(', builder(col), ', ', builder(index), ')'

    def ARRAY_CONTAINS(builder, key, not_in, col):
        return ('NOT ' if not_in else ''
                ), 'py_array_contains(', builder(col), ', ', builder(key), ')'

    def ARRAY_SUBSET(builder, array1, not_in, array2):
        return ('NOT ' if not_in else ''), 'py_array_subset(', builder(
            array2), ', ', builder(array1), ')'

    def ARRAY_LENGTH(builder, array):
        return 'py_array_length(', builder(array), ')'

    def ARRAY_SLICE(builder, array, start, stop):
        return 'py_array_slice(', builder(array), ', ', \
               builder(start) if start else 'null', ',',\
               builder(stop) if stop else 'null', ')'

    def MAKE_ARRAY(builder, *items):
        return 'py_make_array(', join(', ',
                                      (builder(item) for item in items)), ')'