/* connection.c - the connection type
 *
 * Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
 *
 * This file is part of pysqlite.
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 *    misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 */

#ifndef Py_BUILD_CORE_BUILTIN
#  define Py_BUILD_CORE_MODULE 1
#endif

#include "module.h"

#include "connection.h"
#include "statement.h"
#include "cursor.h"
#include "blob.h"
#include "prepare_protocol.h"
#include "util.h"

#include "pycore_modsupport.h"    // _PyArg_NoKeywords()
#include "pycore_pyerrors.h"      // _PyErr_ChainExceptions1()
#include "pycore_pylifecycle.h"   // _Py_IsInterpreterFinalizing()
#include "pycore_unicodeobject.h" // _PyUnicode_AsUTF8NoNUL

#include <stdbool.h>

#if SQLITE_VERSION_NUMBER >= 3025000
#define HAVE_WINDOW_FUNCTIONS
#endif

static const char *
get_isolation_level(const char *level)
{
    assert(level != NULL);
    static const char *const allowed_levels[] = {
        "",
        "DEFERRED",
        "IMMEDIATE",
        "EXCLUSIVE",
        NULL
    };
    for (int i = 0; allowed_levels[i] != NULL; i++) {
        const char *candidate = allowed_levels[i];
        if (sqlite3_stricmp(level, candidate) == 0) {
            return candidate;
        }
    }
    PyErr_SetString(PyExc_ValueError,
                    "isolation_level string must be '', 'DEFERRED', "
                    "'IMMEDIATE', or 'EXCLUSIVE'");
    return NULL;
}

static int
isolation_level_converter(PyObject *str_or_none, const char **result)
{
    if (Py_IsNone(str_or_none)) {
        *result = NULL;
    }
    else if (PyUnicode_Check(str_or_none)) {
        const char *str = _PyUnicode_AsUTF8NoNUL(str_or_none);
        if (str == NULL) {
            return 0;
        }
        const char *level = get_isolation_level(str);
        if (level == NULL) {
            return 0;
        }
        *result = level;
    }
    else {
        PyErr_SetString(PyExc_TypeError,
                        "isolation_level must be str or None");
        return 0;
    }
    return 1;
}

static int
autocommit_converter(PyObject *val, enum autocommit_mode *result)
{
    if (Py_IsTrue(val)) {
        *result = AUTOCOMMIT_ENABLED;
        return 1;
    }
    if (Py_IsFalse(val)) {
        *result = AUTOCOMMIT_DISABLED;
        return 1;
    }
    if (PyLong_Check(val)) {
        int overflow;
        long value = PyLong_AsLongAndOverflow(val, &overflow);
        if (value == -1 && PyErr_Occurred()) {
            return 0;
        }
        if (!overflow && value == LEGACY_TRANSACTION_CONTROL) {
            *result = AUTOCOMMIT_LEGACY;
            return 1;
        }
    }

    PyErr_SetString(PyExc_ValueError,
        "autocommit must be True, False, or "
        "sqlite3.LEGACY_TRANSACTION_CONTROL");
    return 0;
}

static int
sqlite3_int64_converter(PyObject *obj, sqlite3_int64 *result)
{
    if (!PyLong_Check(obj)) {
        PyErr_SetString(PyExc_TypeError, "expected 'int'");
        return 0;
    }
    *result = _pysqlite_long_as_int64(obj);
    if (PyErr_Occurred()) {
        return 0;
    }
    return 1;
}

#define clinic_state() (pysqlite_get_state_by_type(Py_TYPE(self)))
#include "clinic/connection.c.h"
#undef clinic_state

#define _pysqlite_Connection_CAST(op)   ((pysqlite_Connection *)(op))

/*[clinic input]
module _sqlite3
class _sqlite3.Connection "pysqlite_Connection *" "clinic_state()->ConnectionType"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=67369db2faf80891]*/

static void incref_callback_context(callback_context *ctx);
static void decref_callback_context(callback_context *ctx);
static void set_callback_context(callback_context **ctx_pp,
                                 callback_context *ctx);
static int connection_close(pysqlite_Connection *self);
PyObject *_pysqlite_query_execute(pysqlite_Cursor *, int, PyObject *, PyObject *);

static PyObject *
new_statement_cache(pysqlite_Connection *self, pysqlite_state *state,
                    int maxsize)
{
    PyObject *args[] = { NULL, PyLong_FromLong(maxsize), };
    if (args[1] == NULL) {
        return NULL;
    }
    PyObject *lru_cache = state->lru_cache;
    size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
    PyObject *inner = PyObject_Vectorcall(lru_cache, args + 1, nargsf, NULL);
    Py_DECREF(args[1]);
    if (inner == NULL) {
        return NULL;
    }

    args[1] = (PyObject *)self;  // Borrowed ref.
    nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
    PyObject *res = PyObject_Vectorcall(inner, args + 1, nargsf, NULL);
    Py_DECREF(inner);
    return res;
}

static inline int
connection_exec_stmt(pysqlite_Connection *self, const char *sql)
{
    int rc;
    Py_BEGIN_ALLOW_THREADS
    int len = (int)strlen(sql) + 1;
    sqlite3_stmt *stmt;
    rc = sqlite3_prepare_v2(self->db, sql, len, &stmt, NULL);
    if (rc == SQLITE_OK) {
        (void)sqlite3_step(stmt);
        rc = sqlite3_finalize(stmt);
    }
    Py_END_ALLOW_THREADS

    if (rc != SQLITE_OK) {
        set_error_from_db(self->state, self->db);
        return -1;
    }
    return 0;
}

/*[python input]
class IsolationLevel_converter(CConverter):
    type = "const char *"
    converter = "isolation_level_converter"

class Autocommit_converter(CConverter):
    type = "enum autocommit_mode"
    converter = "autocommit_converter"

class sqlite3_int64_converter(CConverter):
    type = "sqlite3_int64"
    converter = "sqlite3_int64_converter"

[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=dff8760fb1eba6a1]*/

/*[clinic input]
_sqlite3.Connection.__init__ as pysqlite_connection_init

    database: object
    *
    timeout: double = 5.0
    detect_types: int = 0
    isolation_level: IsolationLevel = ""
    check_same_thread: bool = True
    factory: object(c_default='(PyObject*)clinic_state()->ConnectionType') = ConnectionType
    cached_statements as cache_size: int = 128
    uri: bool = False
    autocommit: Autocommit(c_default='LEGACY_TRANSACTION_CONTROL') = sqlite3.LEGACY_TRANSACTION_CONTROL
[clinic start generated code]*/

static int
pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database,
                              double timeout, int detect_types,
                              const char *isolation_level,
                              int check_same_thread, PyObject *factory,
                              int cache_size, int uri,
                              enum autocommit_mode autocommit)
/*[clinic end generated code: output=cba057313ea7712f input=5ca4883d8747a49b]*/
{
    if (PySys_Audit("sqlite3.connect", "O", database) < 0) {
        return -1;
    }

    PyObject *bytes;
    if (!PyUnicode_FSConverter(database, &bytes)) {
        return -1;
    }

    if (self->initialized) {
        self->initialized = 0;

        PyTypeObject *tp = Py_TYPE(self);
        tp->tp_clear((PyObject *)self);
        if (connection_close(self) < 0) {
            return -1;
        }
    }

    // Create and configure SQLite database object.
    sqlite3 *db;
    int rc;
    Py_BEGIN_ALLOW_THREADS
    rc = sqlite3_open_v2(PyBytes_AS_STRING(bytes), &db,
                         SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
                         (uri ? SQLITE_OPEN_URI : 0), NULL);
    if (rc == SQLITE_OK) {
        (void)sqlite3_busy_timeout(db, (int)(timeout*1000));
    }
    Py_END_ALLOW_THREADS

    Py_DECREF(bytes);
    if (db == NULL && rc == SQLITE_NOMEM) {
        PyErr_NoMemory();
        return -1;
    }

    pysqlite_state *state = pysqlite_get_state_by_type(Py_TYPE(self));
    if (rc != SQLITE_OK) {
        set_error_from_db(state, db);
        goto error;
    }

    // Create LRU statement cache; returns a new reference.
    PyObject *statement_cache = new_statement_cache(self, state, cache_size);
    if (statement_cache == NULL) {
        goto error;
    }

    /* Create lists of weak references to blobs */
    PyObject *blobs = PyList_New(0);
    if (blobs == NULL) {
        Py_DECREF(statement_cache);
        goto error;
    }

    // Init connection state members.
    self->db = db;
    self->state = state;
    self->detect_types = detect_types;
    self->isolation_level = isolation_level;
    self->autocommit = autocommit;
    self->check_same_thread = check_same_thread;
    self->thread_ident = PyThread_get_thread_ident();
    self->statement_cache = statement_cache;
    self->blobs = blobs;
    pysqlite_set_ref((PyObject *)self, &self->row_factory, Py_NewRef(Py_None));
    pysqlite_set_ref((PyObject *)self, &self->text_factory,
                     Py_NewRef(&PyUnicode_Type));
    self->trace_ctx = NULL;
    self->progress_ctx = NULL;
    self->authorizer_ctx = NULL;

    // Borrowed refs
    self->Warning               = state->Warning;
    self->Error                 = state->Error;
    self->InterfaceError        = state->InterfaceError;
    self->DatabaseError         = state->DatabaseError;
    self->DataError             = state->DataError;
    self->OperationalError      = state->OperationalError;
    self->IntegrityError        = state->IntegrityError;
    self->InternalError         = state->InternalError;
    self->ProgrammingError      = state->ProgrammingError;
    self->NotSupportedError     = state->NotSupportedError;

    if (PySys_Audit("sqlite3.connect/handle", "O", self) < 0) {
        return -1;  // Don't goto error; at this point, dealloc will clean up.
    }

    self->initialized = 1;

    if (autocommit == AUTOCOMMIT_DISABLED) {
        if (connection_exec_stmt(self, "BEGIN") < 0) {
            return -1;
        }
    }
    return 0;

error:
    // There are no statements or other SQLite objects attached to the
    // database, so sqlite3_close() should always return SQLITE_OK.
    rc = sqlite3_close(db);
    assert(rc == SQLITE_OK);
    return -1;
}

/*[clinic input]
# Create a new destination 'connect' for the docstring and methoddef only.
# This makes it possible to keep the signatures for Connection.__init__ and
# sqlite3.connect() synchronised.
output push
destination connect new file '{dirname}/clinic/_sqlite3.connect.c.h'

# Only output the docstring and the PyMethodDef entry.
output everything suppress
output docstring_definition connect
output methoddef_define connect

# Define the sqlite3.connect function by cloning Connection.__init__.
_sqlite3.connect as pysqlite_connect = _sqlite3.Connection.__init__

Open a connection to the SQLite database file 'database'.

You can use ":memory:" to open a database connection to a database that
resides in RAM instead of on disk.
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=92260edff95d1720]*/

/*[clinic input]
# Restore normal Argument Clinic operation for the rest of this file.
output pop
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b899ba9273edcce7]*/

#define VISIT_CALLBACK_CONTEXT(ctx) \
do {                                \
    if (ctx) {                      \
        Py_VISIT(ctx->callable);    \
        Py_VISIT(ctx->module);      \
    }                               \
} while (0)

static int
connection_traverse(PyObject *op, visitproc visit, void *arg)
{
    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
    Py_VISIT(Py_TYPE(self));
    Py_VISIT(self->statement_cache);
    Py_VISIT(self->blobs);
    Py_VISIT(self->row_factory);
    Py_VISIT(self->text_factory);
    VISIT_CALLBACK_CONTEXT(self->trace_ctx);
    VISIT_CALLBACK_CONTEXT(self->progress_ctx);
    VISIT_CALLBACK_CONTEXT(self->authorizer_ctx);
#undef VISIT_CALLBACK_CONTEXT
    return 0;
}

static inline void
clear_callback_context(callback_context *ctx)
{
    if (ctx != NULL) {
        Py_CLEAR(ctx->callable);
        Py_CLEAR(ctx->module);
    }
}

static int
connection_clear(PyObject *op)
{
    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
    Py_CLEAR(self->statement_cache);
    Py_CLEAR(self->blobs);
    pysqlite_set_ref(op, &self->row_factory, NULL);
    pysqlite_set_ref(op, &self->text_factory, NULL);
    clear_callback_context(self->trace_ctx);
    clear_callback_context(self->progress_ctx);
    clear_callback_context(self->authorizer_ctx);
    return 0;
}

static void
free_callback_contexts(pysqlite_Connection *self)
{
    set_callback_context(&self->trace_ctx, NULL);
    set_callback_context(&self->progress_ctx, NULL);
    set_callback_context(&self->authorizer_ctx, NULL);
}

static void
remove_callbacks(sqlite3 *db)
{
    /* None of these APIs can fail, as long as they are given a valid
     * database pointer. */
    assert(db != NULL);
    int rc = sqlite3_trace_v2(db, SQLITE_TRACE_STMT, 0, 0);
    assert(rc == SQLITE_OK), (void)rc;

    sqlite3_progress_handler(db, 0, 0, (void *)0);

    rc = sqlite3_set_authorizer(db, NULL, NULL);
    assert(rc == SQLITE_OK), (void)rc;
}

static int
connection_close(pysqlite_Connection *self)
{
    if (self->db == NULL) {
        return 0;
    }

    int rc = 0;
    if (self->autocommit == AUTOCOMMIT_DISABLED &&
        !sqlite3_get_autocommit(self->db))
    {
        if (connection_exec_stmt(self, "ROLLBACK") < 0) {
            rc = -1;
        }
    }

    sqlite3 *db = self->db;
    self->db = NULL;

    Py_BEGIN_ALLOW_THREADS
    /* The v2 close call always returns SQLITE_OK if given a valid database
     * pointer (which we do), so we can safely ignore the return value */
    (void)sqlite3_close_v2(db);
    Py_END_ALLOW_THREADS

    free_callback_contexts(self);
    return rc;
}

static void
connection_finalize(PyObject *self)
{
    pysqlite_Connection *con = (pysqlite_Connection *)self;
    PyObject *exc = PyErr_GetRaisedException();

    /* If close is implicitly called as a result of interpreter
     * tear-down, we must not call back into Python. */
    PyInterpreterState *interp = PyInterpreterState_Get();
    int teardown = _Py_IsInterpreterFinalizing(interp);
    if (teardown && con->db) {
        remove_callbacks(con->db);
    }

    /* Clean up if user has not called .close() explicitly. */
    if (con->db) {
        if (PyErr_ResourceWarning(self, 1, "unclosed database in %R", self)) {
            /* Spurious errors can appear at shutdown */
            if (PyErr_ExceptionMatches(PyExc_Warning)) {
                PyErr_FormatUnraisable("Exception ignored while finalizing "
                                       "database connection %R", self);
            }
        }
    }
    if (connection_close(con) < 0) {
        if (teardown) {
            PyErr_Clear();
        }
        else {
            PyErr_FormatUnraisable("Exception ignored while closing database %R",
                                   self);
        }
    }

    PyErr_SetRaisedException(exc);
}

static void
connection_dealloc(PyObject *self)
{
    if (PyObject_CallFinalizerFromDealloc(self) < 0) {
        return;
    }
    PyTypeObject *tp = Py_TYPE(self);
    PyObject_GC_UnTrack(self);
    (void)tp->tp_clear(self);
    tp->tp_free(self);
    Py_DECREF(tp);
}

/*[clinic input]
_sqlite3.Connection.cursor as pysqlite_connection_cursor

    factory: object = NULL

Return a cursor for the connection.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory)
/*[clinic end generated code: output=562432a9e6af2aa1 input=4127345aa091b650]*/
{
    PyObject* cursor;

    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }

    if (factory == NULL) {
        factory = (PyObject *)self->state->CursorType;
    }

    cursor = PyObject_CallOneArg(factory, (PyObject *)self);
    if (cursor == NULL)
        return NULL;
    if (!PyObject_TypeCheck(cursor, self->state->CursorType)) {
        PyErr_Format(PyExc_TypeError,
                     "factory must return a cursor, not %.100s",
                     Py_TYPE(cursor)->tp_name);
        Py_DECREF(cursor);
        return NULL;
    }

    PyObject *row_factory = pysqlite_get_ref((PyObject *)self,
                                             &self->row_factory, Py_None);
    if (row_factory != Py_None) {
        pysqlite_Cursor *cur = (pysqlite_Cursor *)cursor;
        pysqlite_set_ref(cursor, &cur->row_factory, row_factory);
    }
    else {
        Py_DECREF(row_factory);
    }

    return cursor;
}

static PyObject *
connection_get_row_factory(PyObject *op, void *closure)
{
    pysqlite_Connection *self = (pysqlite_Connection *)op;
    return pysqlite_get_ref(op, &self->row_factory, Py_None);
}

static int
connection_set_row_factory(PyObject *op, PyObject *value, void *closure)
{
    pysqlite_Connection *self = (pysqlite_Connection *)op;
    if (value == NULL) {
        PyErr_SetString(PyExc_AttributeError,
                        "cannot delete row_factory attribute");
        return -1;
    }
    pysqlite_set_ref(op, &self->row_factory, Py_NewRef(value));
    return 0;
}

static PyObject *
connection_get_text_factory(PyObject *op, void *closure)
{
    pysqlite_Connection *self = (pysqlite_Connection *)op;
    return pysqlite_get_ref(op, &self->text_factory,
                            (PyObject *)&PyUnicode_Type);
}

static int
connection_set_text_factory(PyObject *op, PyObject *value, void *closure)
{
    pysqlite_Connection *self = (pysqlite_Connection *)op;
    if (value == NULL) {
        PyErr_SetString(PyExc_AttributeError,
                        "cannot delete text_factory attribute");
        return -1;
    }
    pysqlite_set_ref(op, &self->text_factory, Py_NewRef(value));
    return 0;
}


/*[clinic input]
_sqlite3.Connection.blobopen as blobopen

    table: str
        Table name.
    column as col: str
        Column name.
    rowid as row: sqlite3_int64
        Row id.
    /
    *
    readonly: bool = False
        Open the BLOB without write permissions.
    name: str = "main"
        Database name.

Open and return a BLOB object.
[clinic start generated code]*/

static PyObject *
blobopen_impl(pysqlite_Connection *self, const char *table, const char *col,
              sqlite3_int64 row, int readonly, const char *name)
/*[clinic end generated code: output=6a02d43efb885d1c input=cc3d4b47dac08401]*/
{
    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }

    int rc;
    sqlite3_blob *blob;

    Py_BEGIN_ALLOW_THREADS
    rc = sqlite3_blob_open(self->db, name, table, col, row, !readonly, &blob);
    Py_END_ALLOW_THREADS

    if (rc == SQLITE_MISUSE) {
        set_error_from_code(self->state, rc);
        return NULL;
    }
    else if (rc != SQLITE_OK) {
        set_error_from_db(self->state, self->db);
        return NULL;
    }

    pysqlite_Blob *obj = PyObject_GC_New(pysqlite_Blob, self->state->BlobType);
    if (obj == NULL) {
        goto error;
    }

    obj->connection = (pysqlite_Connection *)Py_NewRef(self);
    obj->blob = blob;
    obj->offset = 0;
    obj->in_weakreflist = NULL;

    PyObject_GC_Track(obj);

    // Add our blob to connection blobs list
    PyObject *weakref = PyWeakref_NewRef((PyObject *)obj, NULL);
    if (weakref == NULL) {
        goto error;
    }
    rc = PyList_Append(self->blobs, weakref);
    Py_DECREF(weakref);
    if (rc < 0) {
        goto error;
    }

    return (PyObject *)obj;

error:
    Py_XDECREF(obj);
    return NULL;
}

/*[clinic input]
_sqlite3.Connection.close as pysqlite_connection_close

Close the database connection.

Any pending transaction is not committed implicitly.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_close_impl(pysqlite_Connection *self)
/*[clinic end generated code: output=a546a0da212c9b97 input=b3ed5b74f6fefc06]*/
{
    if (!pysqlite_check_thread(self)) {
        return NULL;
    }

    if (!self->initialized) {
        PyTypeObject *tp = Py_TYPE(self);
        pysqlite_state *state = pysqlite_get_state_by_type(tp);
        PyErr_SetString(state->ProgrammingError,
                        "Base Connection.__init__ not called.");
        return NULL;
    }

    pysqlite_close_all_blobs(self);
    Py_CLEAR(self->statement_cache);
    if (connection_close(self) < 0) {
        return NULL;
    }

    Py_RETURN_NONE;
}

/*
 * Checks if a connection object is usable (i. e. not closed).
 *
 * 0 => error; 1 => ok
 */
int pysqlite_check_connection(pysqlite_Connection* con)
{
    if (!con->initialized) {
        pysqlite_state *state = pysqlite_get_state_by_type(Py_TYPE(con));
        PyErr_SetString(state->ProgrammingError,
                        "Base Connection.__init__ not called.");
        return 0;
    }

    if (!con->db) {
        PyErr_SetString(con->state->ProgrammingError,
                        "Cannot operate on a closed database.");
        return 0;
    } else {
        return 1;
    }
}

/*[clinic input]
_sqlite3.Connection.commit as pysqlite_connection_commit

Commit any pending transaction to the database.

If there is no open transaction, this method is a no-op.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_commit_impl(pysqlite_Connection *self)
/*[clinic end generated code: output=3da45579e89407f2 input=c8793c97c3446065]*/
{
    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }

    if (self->autocommit == AUTOCOMMIT_LEGACY) {
        if (!sqlite3_get_autocommit(self->db)) {
            if (connection_exec_stmt(self, "COMMIT") < 0) {
                return NULL;
            }
        }
    }
    else if (self->autocommit == AUTOCOMMIT_DISABLED) {
        if (connection_exec_stmt(self, "COMMIT") < 0) {
            return NULL;
        }
        if (connection_exec_stmt(self, "BEGIN") < 0) {
            return NULL;
        }
    }
    Py_RETURN_NONE;
}

/*[clinic input]
_sqlite3.Connection.rollback as pysqlite_connection_rollback

Roll back to the start of any pending transaction.

If there is no open transaction, this method is a no-op.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_rollback_impl(pysqlite_Connection *self)
/*[clinic end generated code: output=b66fa0d43e7ef305 input=7f60a2f1076f16b3]*/
{
    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }

    if (self->autocommit == AUTOCOMMIT_LEGACY) {
        if (!sqlite3_get_autocommit(self->db)) {
            if (connection_exec_stmt(self, "ROLLBACK") < 0) {
                return NULL;
            }
        }
    }
    else if (self->autocommit == AUTOCOMMIT_DISABLED) {
        if (connection_exec_stmt(self, "ROLLBACK") < 0) {
            return NULL;
        }
        if (connection_exec_stmt(self, "BEGIN") < 0) {
            return NULL;
        }
    }
    Py_RETURN_NONE;
}

static int
_pysqlite_set_result(sqlite3_context* context, PyObject* py_val)
{
    if (py_val == Py_None) {
        sqlite3_result_null(context);
    } else if (PyLong_Check(py_val)) {
        sqlite_int64 value = _pysqlite_long_as_int64(py_val);
        if (value == -1 && PyErr_Occurred())
            return -1;
        sqlite3_result_int64(context, value);
    } else if (PyFloat_Check(py_val)) {
        double value = PyFloat_AsDouble(py_val);
        if (value == -1 && PyErr_Occurred()) {
            return -1;
        }
        sqlite3_result_double(context, value);
    } else if (PyUnicode_Check(py_val)) {
        Py_ssize_t sz;
        const char *str = PyUnicode_AsUTF8AndSize(py_val, &sz);
        if (str == NULL) {
            return -1;
        }
        if (sz > INT_MAX) {
            PyErr_SetString(PyExc_OverflowError,
                            "string is longer than INT_MAX bytes");
            return -1;
        }
        sqlite3_result_text(context, str, (int)sz, SQLITE_TRANSIENT);
    } else if (PyObject_CheckBuffer(py_val)) {
        Py_buffer view;
        if (PyObject_GetBuffer(py_val, &view, PyBUF_SIMPLE) != 0) {
            return -1;
        }
        if (view.len > INT_MAX) {
            PyErr_SetString(PyExc_OverflowError,
                            "BLOB longer than INT_MAX bytes");
            PyBuffer_Release(&view);
            return -1;
        }
        sqlite3_result_blob(context, view.buf, (int)view.len, SQLITE_TRANSIENT);
        PyBuffer_Release(&view);
    } else {
        callback_context *ctx = (callback_context *)sqlite3_user_data(context);
        PyErr_Format(ctx->state->ProgrammingError,
                     "User-defined functions cannot return '%s' values to "
                     "SQLite",
                     Py_TYPE(py_val)->tp_name);
        return -1;
    }
    return 0;
}

static PyObject *
_pysqlite_build_py_params(sqlite3_context *context, int argc,
                          sqlite3_value **argv)
{
    PyObject* args;
    int i;
    sqlite3_value* cur_value;
    PyObject* cur_py_value;

    args = PyTuple_New(argc);
    if (!args) {
        return NULL;
    }

    for (i = 0; i < argc; i++) {
        cur_value = argv[i];
        switch (sqlite3_value_type(argv[i])) {
            case SQLITE_INTEGER:
                cur_py_value = PyLong_FromLongLong(sqlite3_value_int64(cur_value));
                break;
            case SQLITE_FLOAT:
                cur_py_value = PyFloat_FromDouble(sqlite3_value_double(cur_value));
                break;
            case SQLITE_TEXT: {
                sqlite3 *db = sqlite3_context_db_handle(context);
                const char *text = (const char *)sqlite3_value_text(cur_value);

                if (text == NULL && sqlite3_errcode(db) == SQLITE_NOMEM) {
                    PyErr_NoMemory();
                    goto error;
                }

                Py_ssize_t size = sqlite3_value_bytes(cur_value);
                cur_py_value = PyUnicode_FromStringAndSize(text, size);
                break;
            }
            case SQLITE_BLOB: {
                sqlite3 *db = sqlite3_context_db_handle(context);
                const void *blob = sqlite3_value_blob(cur_value);

                if (blob == NULL && sqlite3_errcode(db) == SQLITE_NOMEM) {
                    PyErr_NoMemory();
                    goto error;
                }

                Py_ssize_t size = sqlite3_value_bytes(cur_value);
                cur_py_value = PyBytes_FromStringAndSize(blob, size);
                break;
            }
            case SQLITE_NULL:
            default:
                cur_py_value = Py_NewRef(Py_None);
        }

        if (!cur_py_value) {
            goto error;
        }

        PyTuple_SET_ITEM(args, i, cur_py_value);
    }

    return args;

error:
    Py_DECREF(args);
    return NULL;
}

static void
print_or_clear_traceback(callback_context *ctx)
{
    assert(ctx != NULL);
    assert(ctx->state != NULL);
    if (ctx->state->enable_callback_tracebacks) {
        PyErr_FormatUnraisable("Exception ignored on sqlite3 callback %R",
                               ctx->callable);
    }
    else {
        PyErr_Clear();
    }
}

// Checks the Python exception and sets the appropriate SQLite error code.
static void
set_sqlite_error(sqlite3_context *context, const char *msg)
{
    assert(PyErr_Occurred());
    if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
        sqlite3_result_error_nomem(context);
    }
    else if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
        sqlite3_result_error_toobig(context);
    }
    else {
        sqlite3_result_error(context, msg, -1);
    }
    callback_context *ctx = (callback_context *)sqlite3_user_data(context);
    print_or_clear_traceback(ctx);
}

static void
func_callback(sqlite3_context *context, int argc, sqlite3_value **argv)
{
    PyGILState_STATE threadstate = PyGILState_Ensure();

    PyObject* args;
    PyObject* py_retval = NULL;
    int ok;

    args = _pysqlite_build_py_params(context, argc, argv);
    if (args) {
        callback_context *ctx = (callback_context *)sqlite3_user_data(context);
        incref_callback_context(ctx);
        py_retval = PyObject_CallObject(ctx->callable, args);
        decref_callback_context(ctx);
        Py_DECREF(args);
    }

    ok = 0;
    if (py_retval) {
        ok = _pysqlite_set_result(context, py_retval) == 0;
        Py_DECREF(py_retval);
    }
    if (!ok) {
        set_sqlite_error(context, "user-defined function raised exception");
    }

    PyGILState_Release(threadstate);
}

static void
step_callback(sqlite3_context *context, int argc, sqlite3_value **params)
{
    PyGILState_STATE threadstate = PyGILState_Ensure();

    PyObject* args;
    PyObject* function_result = NULL;
    PyObject** aggregate_instance;
    PyObject* stepmethod = NULL;

    callback_context *ctx = (callback_context *)sqlite3_user_data(context);
    incref_callback_context(ctx);

    aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, sizeof(PyObject*));
    if (aggregate_instance == NULL) {
        (void)PyErr_NoMemory();
        set_sqlite_error(context, "unable to allocate SQLite aggregate context");
        goto error;
    }
    if (*aggregate_instance == NULL) {
        *aggregate_instance = PyObject_CallNoArgs(ctx->callable);
        if (!*aggregate_instance) {
            set_sqlite_error(context,
                    "user-defined aggregate's '__init__' method raised error");
            goto error;
        }
    }

    stepmethod = PyObject_GetAttr(*aggregate_instance, ctx->state->str_step);
    if (!stepmethod) {
        set_sqlite_error(context,
                "user-defined aggregate's 'step' method not defined");
        goto error;
    }

    args = _pysqlite_build_py_params(context, argc, params);
    if (!args) {
        goto error;
    }

    function_result = PyObject_CallObject(stepmethod, args);
    Py_DECREF(args);

    if (!function_result) {
        set_sqlite_error(context,
                "user-defined aggregate's 'step' method raised error");
    }

error:
    decref_callback_context(ctx);
    Py_XDECREF(stepmethod);
    Py_XDECREF(function_result);

    PyGILState_Release(threadstate);
}

static void
final_callback(sqlite3_context *context)
{
    PyGILState_STATE threadstate = PyGILState_Ensure();

    PyObject* function_result;
    PyObject** aggregate_instance;
    int ok;

    aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, 0);
    if (aggregate_instance == NULL) {
        /* No rows matched the query; the step handler was never called. */
        goto error;
    }
    else if (!*aggregate_instance) {
        /* this branch is executed if there was an exception in the aggregate's
         * __init__ */

        goto error;
    }

    // Keep the exception (if any) of the last call to step, value, or inverse
    PyObject *exc = PyErr_GetRaisedException();

    callback_context *ctx = (callback_context *)sqlite3_user_data(context);
    incref_callback_context(ctx);
    function_result = PyObject_CallMethodNoArgs(*aggregate_instance,
                                                ctx->state->str_finalize);
    decref_callback_context(ctx);
    Py_DECREF(*aggregate_instance);

    ok = 0;
    if (function_result) {
        ok = _pysqlite_set_result(context, function_result) == 0;
        Py_DECREF(function_result);
    }
    if (!ok) {
        int attr_err = PyErr_ExceptionMatches(PyExc_AttributeError);
        _PyErr_ChainExceptions1(exc);

        /* Note: contrary to the step, value, and inverse callbacks, SQLite
         * does _not_, as of SQLite 3.38.0, propagate errors to sqlite3_step()
         * from the finalize callback. This implies that execute*() will not
         * raise OperationalError, as it normally would. */
        set_sqlite_error(context, attr_err
                ? "user-defined aggregate's 'finalize' method not defined"
                : "user-defined aggregate's 'finalize' method raised error");
    }
    else {
        PyErr_SetRaisedException(exc);
    }

error:
    PyGILState_Release(threadstate);
}

/* Allocate a UDF/callback context structure. In order to ensure that the state
 * pointer always outlives the callback context, we make sure it owns a
 * reference to the module itself. create_callback_context() is always called
 * from connection methods, so we use the defining class to fetch the module
 * pointer.
 */
static callback_context *
create_callback_context(PyTypeObject *cls, PyObject *callable)
{
    callback_context *ctx = PyMem_Malloc(sizeof(callback_context));
    if (ctx == NULL) {
        PyErr_NoMemory();
        return NULL;
    }

    PyObject *module = PyType_GetModule(cls);
    ctx->refcount = 1;
    ctx->callable = Py_NewRef(callable);
    ctx->module = Py_NewRef(module);
    ctx->state = pysqlite_get_state(module);
    return ctx;
}

static void
free_callback_context(callback_context *ctx)
{
    assert(ctx != NULL);
    assert(ctx->refcount == 0);
    Py_XDECREF(ctx->callable);
    Py_XDECREF(ctx->module);
    PyMem_Free(ctx);
}

static inline void
incref_callback_context(callback_context *ctx)
{
    assert(PyGILState_Check());
    assert(ctx != NULL);
    assert(ctx->refcount > 0);
    ctx->refcount++;
}

static inline void
decref_callback_context(callback_context *ctx)
{
    assert(PyGILState_Check());
    assert(ctx != NULL);
    assert(ctx->refcount > 0);
    ctx->refcount--;
    if (ctx->refcount == 0) {
        free_callback_context(ctx);
    }
}

static void
set_callback_context(callback_context **ctx_pp, callback_context *ctx)
{
    assert(ctx_pp != NULL);
    callback_context *tmp = *ctx_pp;
    *ctx_pp = ctx;
    if (tmp != NULL) {
        decref_callback_context(tmp);
    }
}

static void
destructor_callback(void *ctx)
{
    if (ctx != NULL) {
        // This function may be called without the GIL held, so we need to
        // ensure that we destroy 'ctx' with the GIL held.
        PyGILState_STATE gstate = PyGILState_Ensure();
        decref_callback_context((callback_context *)ctx);
        PyGILState_Release(gstate);
    }
}

static int
check_num_params(pysqlite_Connection *self, const int n, const char *name)
{
    int limit = sqlite3_limit(self->db, SQLITE_LIMIT_FUNCTION_ARG, -1);
    assert(limit >= 0);
    if (n < -1 || n > limit) {
        PyErr_Format(self->ProgrammingError,
                     "'%s' must be between -1 and %d, not %d",
                     name, limit, n);
        return -1;
    }
    return 0;
}

/*[clinic input]
_sqlite3.Connection.create_function as pysqlite_connection_create_function

    cls: defining_class
    name: str
    narg: int
    func: object
    /
    *
    deterministic: bool = False

Creates a new function.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_create_function_impl(pysqlite_Connection *self,
                                         PyTypeObject *cls, const char *name,
                                         int narg, PyObject *func,
                                         int deterministic)
/*[clinic end generated code: output=8a811529287ad240 input=a896096ed5390ae1]*/
{
    int rc;
    int flags = SQLITE_UTF8;

    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }
    if (check_num_params(self, narg, "narg") < 0) {
        return NULL;
    }

    if (deterministic) {
        flags |= SQLITE_DETERMINISTIC;
    }
    callback_context *ctx = create_callback_context(cls, func);
    if (ctx == NULL) {
        return NULL;
    }
    rc = sqlite3_create_function_v2(self->db, name, narg, flags, ctx,
                                    func_callback,
                                    NULL,
                                    NULL,
                                    &destructor_callback);  // will free 'ctx'

    if (rc != SQLITE_OK) {
        /* Workaround for SQLite bug: no error code or string is available here */
        PyErr_SetString(self->OperationalError, "Error creating function");
        return NULL;
    }
    Py_RETURN_NONE;
}

#ifdef HAVE_WINDOW_FUNCTIONS
/*
 * Regarding the 'inverse' aggregate callback:
 * This method is only required by window aggregate functions, not
 * ordinary aggregate function implementations.  It is invoked to remove
 * a row from the current window.  The function arguments, if any,
 * correspond to the row being removed.
 */
static void
inverse_callback(sqlite3_context *context, int argc, sqlite3_value **params)
{
    PyGILState_STATE gilstate = PyGILState_Ensure();

    callback_context *ctx = (callback_context *)sqlite3_user_data(context);
    incref_callback_context(ctx);

    int size = sizeof(PyObject *);
    PyObject **cls = (PyObject **)sqlite3_aggregate_context(context, size);
    assert(cls != NULL);
    assert(*cls != NULL);

    PyObject *method = PyObject_GetAttr(*cls, ctx->state->str_inverse);
    if (method == NULL) {
        set_sqlite_error(context,
                "user-defined aggregate's 'inverse' method not defined");
        goto exit;
    }

    PyObject *args = _pysqlite_build_py_params(context, argc, params);
    if (args == NULL) {
        set_sqlite_error(context,
                "unable to build arguments for user-defined aggregate's "
                "'inverse' method");
        goto exit;
    }

    PyObject *res = PyObject_CallObject(method, args);
    Py_DECREF(args);
    if (res == NULL) {
        set_sqlite_error(context,
                "user-defined aggregate's 'inverse' method raised error");
        goto exit;
    }
    Py_DECREF(res);

exit:
    decref_callback_context(ctx);
    Py_XDECREF(method);
    PyGILState_Release(gilstate);
}

/*
 * Regarding the 'value' aggregate callback:
 * This method is only required by window aggregate functions, not
 * ordinary aggregate function implementations.  It is invoked to return
 * the current value of the aggregate.
 */
static void
value_callback(sqlite3_context *context)
{
    PyGILState_STATE gilstate = PyGILState_Ensure();

    callback_context *ctx = (callback_context *)sqlite3_user_data(context);
    incref_callback_context(ctx);

    int size = sizeof(PyObject *);
    PyObject **cls = (PyObject **)sqlite3_aggregate_context(context, size);
    assert(cls != NULL);
    assert(*cls != NULL);

    PyObject *res = PyObject_CallMethodNoArgs(*cls, ctx->state->str_value);
    decref_callback_context(ctx);

    if (res == NULL) {
        int attr_err = PyErr_ExceptionMatches(PyExc_AttributeError);
        set_sqlite_error(context, attr_err
                ? "user-defined aggregate's 'value' method not defined"
                : "user-defined aggregate's 'value' method raised error");
    }
    else {
        int rc = _pysqlite_set_result(context, res);
        Py_DECREF(res);
        if (rc < 0) {
            set_sqlite_error(context,
                    "unable to set result from user-defined aggregate's "
                    "'value' method");
        }
    }

    PyGILState_Release(gilstate);
}

/*[clinic input]
_sqlite3.Connection.create_window_function as create_window_function

    cls: defining_class
    name: str
        The name of the SQL aggregate window function to be created or
        redefined.
    num_params: int
        The number of arguments the step and inverse methods takes.
    aggregate_class: object
        A class with step(), finalize(), value(), and inverse() methods.
        Set to None to clear the window function.
    /

Creates or redefines an aggregate window function. Non-standard.
[clinic start generated code]*/

static PyObject *
create_window_function_impl(pysqlite_Connection *self, PyTypeObject *cls,
                            const char *name, int num_params,
                            PyObject *aggregate_class)
/*[clinic end generated code: output=5332cd9464522235 input=46d57a54225b5228]*/
{
    if (sqlite3_libversion_number() < 3025000) {
        PyErr_SetString(self->NotSupportedError,
                        "create_window_function() requires "
                        "SQLite 3.25.0 or higher");
        return NULL;
    }
    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }
    if (check_num_params(self, num_params, "num_params") < 0) {
        return NULL;
    }

    int flags = SQLITE_UTF8;
    int rc;
    if (Py_IsNone(aggregate_class)) {
        rc = sqlite3_create_window_function(self->db, name, num_params, flags,
                                            0, 0, 0, 0, 0, 0);
    }
    else {
        callback_context *ctx = create_callback_context(cls, aggregate_class);
        if (ctx == NULL) {
            return NULL;
        }
        rc = sqlite3_create_window_function(self->db, name, num_params, flags,
                                            ctx,
                                            &step_callback,
                                            &final_callback,
                                            &value_callback,
                                            &inverse_callback,
                                            &destructor_callback);
    }

    if (rc != SQLITE_OK) {
        /* Errors are not set on the database connection; use result code
         * instead. */
        set_error_from_code(self->state, rc);
        return NULL;
    }
    Py_RETURN_NONE;
}
#endif

/*[clinic input]
_sqlite3.Connection.create_aggregate as pysqlite_connection_create_aggregate

    cls: defining_class
    name: str
    n_arg: int
    aggregate_class: object
    /

Creates a new aggregate.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_create_aggregate_impl(pysqlite_Connection *self,
                                          PyTypeObject *cls,
                                          const char *name, int n_arg,
                                          PyObject *aggregate_class)
/*[clinic end generated code: output=1b02d0f0aec7ff96 input=aa2773f6a42f7e17]*/
{
    int rc;

    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }
    if (check_num_params(self, n_arg, "n_arg") < 0) {
        return NULL;
    }

    callback_context *ctx = create_callback_context(cls, aggregate_class);
    if (ctx == NULL) {
        return NULL;
    }
    rc = sqlite3_create_function_v2(self->db, name, n_arg, SQLITE_UTF8, ctx,
                                    0,
                                    &step_callback,
                                    &final_callback,
                                    &destructor_callback); // will free 'ctx'
    if (rc != SQLITE_OK) {
        /* Workaround for SQLite bug: no error code or string is available here */
        PyErr_SetString(self->OperationalError, "Error creating aggregate");
        return NULL;
    }
    Py_RETURN_NONE;
}

static int
authorizer_callback(void *ctx_vp, int action, const char *arg1,
                    const char *arg2 , const char *dbname,
                    const char *access_attempt_source)
{
    PyGILState_STATE gilstate = PyGILState_Ensure();

    PyObject *ret;
    int rc = SQLITE_DENY;

    callback_context *ctx = (callback_context *)ctx_vp;
    incref_callback_context(ctx);
    PyObject *callable = ctx->callable;
    ret = PyObject_CallFunction(callable, "issss", action, arg1, arg2, dbname,
                                access_attempt_source);

    if (ret == NULL) {
        print_or_clear_traceback(ctx);
        rc = SQLITE_DENY;
    }
    else {
        if (PyLong_Check(ret)) {
            rc = PyLong_AsInt(ret);
            if (rc == -1 && PyErr_Occurred()) {
                print_or_clear_traceback(ctx);
                rc = SQLITE_DENY;
            }
        }
        else {
            rc = SQLITE_DENY;
        }
        Py_DECREF(ret);
    }

    decref_callback_context(ctx);
    PyGILState_Release(gilstate);
    return rc;
}

static int
progress_callback(void *ctx_vp)
{
    PyGILState_STATE gilstate = PyGILState_Ensure();

    int rc;
    PyObject *ret;

    callback_context *ctx = (callback_context *)ctx_vp;
    incref_callback_context(ctx);

    ret = PyObject_CallNoArgs(ctx->callable);
    if (!ret) {
        /* abort query if error occurred */
        rc = -1;
    }
    else {
        rc = PyObject_IsTrue(ret);
        Py_DECREF(ret);
    }
    if (rc < 0) {
        print_or_clear_traceback(ctx);
    }

    decref_callback_context(ctx);
    PyGILState_Release(gilstate);
    return rc;
}

/*
 * From https://sqlite.org/c3ref/trace_v2.html:
 * The integer return value from the callback is currently ignored, though this
 * may change in future releases. Callback implementations should return zero
 * to ensure future compatibility.
 */
static int
trace_callback(unsigned int type, void *ctx_vp, void *stmt, void *sql)
{
    if (type != SQLITE_TRACE_STMT) {
        return 0;
    }

    PyGILState_STATE gilstate = PyGILState_Ensure();

    callback_context *ctx = (callback_context *)ctx_vp;
    incref_callback_context(ctx);
    pysqlite_state *state = ctx->state;
    assert(state != NULL);

    PyObject *py_statement = NULL;
    const char *expanded_sql = sqlite3_expanded_sql((sqlite3_stmt *)stmt);
    if (expanded_sql == NULL) {
        sqlite3 *db = sqlite3_db_handle((sqlite3_stmt *)stmt);
        if (sqlite3_errcode(db) == SQLITE_NOMEM) {
            (void)PyErr_NoMemory();
            goto exit;
        }

        PyErr_SetString(state->DataError,
                "Expanded SQL string exceeds the maximum string length");
        print_or_clear_traceback(ctx);

        // Fall back to unexpanded sql
        py_statement = PyUnicode_FromString((const char *)sql);
    }
    else {
        py_statement = PyUnicode_FromString(expanded_sql);
        sqlite3_free((void *)expanded_sql);
    }
    if (py_statement) {
        PyObject *ret = PyObject_CallOneArg(ctx->callable, py_statement);
        Py_DECREF(py_statement);
        Py_XDECREF(ret);
    }
    if (PyErr_Occurred()) {
        print_or_clear_traceback(ctx);
    }

exit:
    decref_callback_context(ctx);
    PyGILState_Release(gilstate);
    return 0;
}

/*[clinic input]
_sqlite3.Connection.set_authorizer as pysqlite_connection_set_authorizer

    cls: defining_class
    authorizer_callback as callable: object
    /

Set authorizer callback.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_set_authorizer_impl(pysqlite_Connection *self,
                                        PyTypeObject *cls,
                                        PyObject *callable)
/*[clinic end generated code: output=75fa60114fc971c3 input=e76469ab0bb1bbcd]*/
{
    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }

    int rc;
    if (callable == Py_None) {
        rc = sqlite3_set_authorizer(self->db, NULL, NULL);
        set_callback_context(&self->authorizer_ctx, NULL);
    }
    else {
        callback_context *ctx = create_callback_context(cls, callable);
        if (ctx == NULL) {
            return NULL;
        }
        rc = sqlite3_set_authorizer(self->db, authorizer_callback, ctx);
        set_callback_context(&self->authorizer_ctx, ctx);
    }
    if (rc != SQLITE_OK) {
        PyErr_SetString(self->OperationalError,
                        "Error setting authorizer callback");
        set_callback_context(&self->authorizer_ctx, NULL);
        return NULL;
    }
    Py_RETURN_NONE;
}

/*[clinic input]
_sqlite3.Connection.set_progress_handler as pysqlite_connection_set_progress_handler

    cls: defining_class
    progress_handler as callable: object
        A callable that takes no arguments.
        If the callable returns non-zero, the current query is
        terminated, and an exception is raised.
    /
    n: int
        The number of SQLite virtual machine instructions that are
        executed between invocations of 'progress_handler'.

Set progress handler callback.

If 'progress_handler' is None or 'n' is 0, the progress handler is
disabled.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_set_progress_handler_impl(pysqlite_Connection *self,
                                              PyTypeObject *cls,
                                              PyObject *callable, int n)
/*[clinic end generated code: output=0739957fd8034a50 input=fd0d5abb004f370f]*/
{
    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }

    if (callable == Py_None) {
        /* None clears the progress handler previously set */
        sqlite3_progress_handler(self->db, 0, 0, (void*)0);
        set_callback_context(&self->progress_ctx, NULL);
    }
    else {
        callback_context *ctx = create_callback_context(cls, callable);
        if (ctx == NULL) {
            return NULL;
        }
        sqlite3_progress_handler(self->db, n, progress_callback, ctx);
        set_callback_context(&self->progress_ctx, ctx);
    }
    Py_RETURN_NONE;
}

/*[clinic input]
@permit_long_summary
_sqlite3.Connection.set_trace_callback as pysqlite_connection_set_trace_callback

    cls: defining_class
    trace_callback as callable: object
    /

Set a trace callback called for each SQL statement (passed as unicode).
[clinic start generated code]*/

static PyObject *
pysqlite_connection_set_trace_callback_impl(pysqlite_Connection *self,
                                            PyTypeObject *cls,
                                            PyObject *callable)
/*[clinic end generated code: output=d91048c03bfcee05 input=edfd7d890200a9cb]*/
{
    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }

    if (callable == Py_None) {
        /*
         * None clears the trace callback previously set
         *
         * Ref.
         * - https://sqlite.org/c3ref/c_trace.html
         * - https://sqlite.org/c3ref/trace_v2.html
         */
        sqlite3_trace_v2(self->db, SQLITE_TRACE_STMT, 0, 0);
        set_callback_context(&self->trace_ctx, NULL);
    }
    else {
        callback_context *ctx = create_callback_context(cls, callable);
        if (ctx == NULL) {
            return NULL;
        }
        sqlite3_trace_v2(self->db, SQLITE_TRACE_STMT, trace_callback, ctx);
        set_callback_context(&self->trace_ctx, ctx);
    }

    Py_RETURN_NONE;
}

#ifdef PY_SQLITE_ENABLE_LOAD_EXTENSION
/*[clinic input]
_sqlite3.Connection.enable_load_extension as pysqlite_connection_enable_load_extension

    enable as onoff: bool
    /

Enable dynamic loading of SQLite extension modules.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_enable_load_extension_impl(pysqlite_Connection *self,
                                               int onoff)
/*[clinic end generated code: output=9cac37190d388baf input=2a1e87931486380f]*/
{
    int rc;

    if (PySys_Audit("sqlite3.enable_load_extension",
                    "OO", self, onoff ? Py_True : Py_False) < 0) {
        return NULL;
    }

    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }

    rc = sqlite3_enable_load_extension(self->db, onoff);

    if (rc != SQLITE_OK) {
        PyErr_SetString(self->OperationalError,
                        "Error enabling load extension");
        return NULL;
    } else {
        Py_RETURN_NONE;
    }
}

/*[clinic input]
_sqlite3.Connection.load_extension as pysqlite_connection_load_extension

    name as extension_name: str
    /
    *
    entrypoint: str(accept={str, NoneType}) = None

Load SQLite extension module.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_load_extension_impl(pysqlite_Connection *self,
                                        const char *extension_name,
                                        const char *entrypoint)
/*[clinic end generated code: output=7e61a7add9de0286 input=c36b14ea702e04f5]*/
{
    int rc;
    char* errmsg;

    if (PySys_Audit("sqlite3.load_extension", "Os", self, extension_name) < 0) {
        return NULL;
    }

    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }

    rc = sqlite3_load_extension(self->db, extension_name, entrypoint, &errmsg);
    if (rc != 0) {
        PyErr_SetString(self->OperationalError, errmsg);
        return NULL;
    } else {
        Py_RETURN_NONE;
    }
}
#endif

int pysqlite_check_thread(pysqlite_Connection* self)
{
    if (self->check_same_thread) {
        if (PyThread_get_thread_ident() != self->thread_ident) {
            PyErr_Format(self->ProgrammingError,
                        "SQLite objects created in a thread can only be used in that same thread. "
                        "The object was created in thread id %lu and this is thread id %lu.",
                        self->thread_ident, PyThread_get_thread_ident());
            return 0;
        }

    }
    return 1;
}

static PyObject *
pysqlite_connection_get_isolation_level(PyObject *op, void *Py_UNUSED(closure))
{
    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
    if (!pysqlite_check_connection(self)) {
        return NULL;
    }
    if (self->isolation_level != NULL) {
        return PyUnicode_FromString(self->isolation_level);
    }
    Py_RETURN_NONE;
}

static PyObject *
pysqlite_connection_get_total_changes(PyObject *op, void *Py_UNUSED(closure))
{
    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
    if (!pysqlite_check_connection(self)) {
        return NULL;
    }
    return PyLong_FromLong(sqlite3_total_changes(self->db));
}

static PyObject *
pysqlite_connection_get_in_transaction(PyObject *op, void *Py_UNUSED(closure))
{
    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
    if (!pysqlite_check_connection(self)) {
        return NULL;
    }
    if (!sqlite3_get_autocommit(self->db)) {
        Py_RETURN_TRUE;
    }
    Py_RETURN_FALSE;
}

static int
pysqlite_connection_set_isolation_level(PyObject *op,
                                        PyObject *isolation_level,
                                        void *Py_UNUSED(ignored))
{
    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
    if (isolation_level == NULL) {
        PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
        return -1;
    }
    if (Py_IsNone(isolation_level)) {
        self->isolation_level = NULL;

        // Execute a COMMIT to re-enable autocommit mode
        PyObject *res = pysqlite_connection_commit_impl(self);
        if (res == NULL) {
            return -1;
        }
        Py_DECREF(res);
        return 0;
    }
    if (!isolation_level_converter(isolation_level, &self->isolation_level)) {
        return -1;
    }
    return 0;
}

static PyObject *
pysqlite_connection_call(PyObject *op, PyObject *args, PyObject *kwargs)
{
    PyObject* sql;
    pysqlite_Statement* statement;
    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);

    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }

    if (!_PyArg_NoKeywords(MODULE_NAME ".Connection", kwargs))
        return NULL;

    if (!PyArg_ParseTuple(args, "U", &sql))
        return NULL;

    statement = pysqlite_statement_create(self, sql);
    if (statement == NULL) {
        return NULL;
    }

    return (PyObject*)statement;
}

/*[clinic input]
_sqlite3.Connection.execute as pysqlite_connection_execute

    sql: unicode
    parameters: object(c_default = 'NULL') = ()
    /

Executes an SQL statement.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_execute_impl(pysqlite_Connection *self, PyObject *sql,
                                 PyObject *parameters)
/*[clinic end generated code: output=5be05ae01ee17ee4 input=847390a17de45cc7]*/
{
    PyObject* result = 0;

    PyObject *cursor = pysqlite_connection_cursor_impl(self, NULL);
    if (!cursor) {
        goto error;
    }

    result = _pysqlite_query_execute((pysqlite_Cursor *)cursor, 0, sql, parameters);
    if (!result) {
        Py_CLEAR(cursor);
    }

error:
    Py_XDECREF(result);

    return cursor;
}

/*[clinic input]
_sqlite3.Connection.executemany as pysqlite_connection_executemany

    sql: unicode
    parameters: object
    /

Repeatedly executes an SQL statement.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_executemany_impl(pysqlite_Connection *self,
                                     PyObject *sql, PyObject *parameters)
/*[clinic end generated code: output=776cd2fd20bfe71f input=495be76551d525db]*/
{
    PyObject* result = 0;

    PyObject *cursor = pysqlite_connection_cursor_impl(self, NULL);
    if (!cursor) {
        goto error;
    }

    result = _pysqlite_query_execute((pysqlite_Cursor *)cursor, 1, sql, parameters);
    if (!result) {
        Py_CLEAR(cursor);
    }

error:
    Py_XDECREF(result);

    return cursor;
}

/*[clinic input]
_sqlite3.Connection.executescript as pysqlite_connection_executescript

    sql_script as script_obj: object
    /

Executes multiple SQL statements at once.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_executescript_impl(pysqlite_Connection *self,
                                       PyObject *script_obj)
/*[clinic end generated code: output=e921c49e2291782c input=f6e5f1ccfa313db4]*/
{
    PyObject* result = 0;

    PyObject *cursor = pysqlite_connection_cursor_impl(self, NULL);
    if (!cursor) {
        goto error;
    }

    PyObject *meth = self->state->str_executescript;  // borrowed ref.
    result = PyObject_CallMethodObjArgs(cursor, meth, script_obj, NULL);
    if (!result) {
        Py_CLEAR(cursor);
    }

error:
    Py_XDECREF(result);

    return cursor;
}

/* ------------------------- COLLATION CODE ------------------------ */

static int
collation_callback(void *context, int text1_length, const void *text1_data,
                   int text2_length, const void *text2_data)
{
    PyGILState_STATE gilstate = PyGILState_Ensure();

    PyObject* string1 = 0;
    PyObject* string2 = 0;
    PyObject* retval = NULL;
    long longval;
    int result = 0;
    callback_context *ctx = (callback_context *)context;
    incref_callback_context(ctx);

    /* This callback may be executed multiple times per sqlite3_step(). Bail if
     * the previous call failed */
    if (PyErr_Occurred()) {
        goto finally;
    }

    string1 = PyUnicode_FromStringAndSize((const char*)text1_data, text1_length);
    if (string1 == NULL) {
        goto finally;
    }
    string2 = PyUnicode_FromStringAndSize((const char*)text2_data, text2_length);
    if (string2 == NULL) {
        goto finally;
    }

    PyObject *args[] = { NULL, string1, string2 };  // Borrowed refs.
    size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
    retval = PyObject_Vectorcall(ctx->callable, args + 1, nargsf, NULL);
    if (retval == NULL) {
        /* execution failed */
        goto finally;
    }

    longval = PyLong_AsLongAndOverflow(retval, &result);
    if (longval == -1 && PyErr_Occurred()) {
        PyErr_Clear();
        result = 0;
    }
    else if (!result) {
        if (longval > 0)
            result = 1;
        else if (longval < 0)
            result = -1;
    }

finally:
    decref_callback_context(ctx);
    Py_XDECREF(string1);
    Py_XDECREF(string2);
    Py_XDECREF(retval);
    PyGILState_Release(gilstate);
    return result;
}

/*[clinic input]
_sqlite3.Connection.interrupt as pysqlite_connection_interrupt

Abort any pending database operation.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_interrupt_impl(pysqlite_Connection *self)
/*[clinic end generated code: output=f193204bc9e70b47 input=75ad03ade7012859]*/
{
    PyObject* retval = NULL;

    if (!pysqlite_check_connection(self)) {
        goto finally;
    }

    sqlite3_interrupt(self->db);

    retval = Py_NewRef(Py_None);

finally:
    return retval;
}

/* Function author: Paul Kippes <kippesp@gmail.com>
 * Class method of Connection to call the Python function _iterdump
 * of the sqlite3 module.
 */
/*[clinic input]
_sqlite3.Connection.iterdump as pysqlite_connection_iterdump

    *
    filter: object = None
        An optional LIKE pattern for database objects to dump

Returns iterator to the dump of the database in an SQL text format.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_iterdump_impl(pysqlite_Connection *self,
                                  PyObject *filter)
/*[clinic end generated code: output=fd81069c4bdeb6b0 input=4ae6d9a898f108df]*/
{
    if (!pysqlite_check_connection(self)) {
        return NULL;
    }

    PyObject *iterdump = PyImport_ImportModuleAttrString(MODULE_NAME ".dump", "_iterdump");
    if (!iterdump) {
        if (!PyErr_Occurred()) {
            PyErr_SetString(self->OperationalError,
                            "Failed to obtain _iterdump() reference");
        }
        return NULL;
    }
    PyObject *args[3] = {NULL, (PyObject *)self, filter};
    PyObject *kwnames = Py_BuildValue("(s)", "filter");
    if (!kwnames) {
        Py_DECREF(iterdump);
        return NULL;
    }
    Py_ssize_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
    PyObject *retval = PyObject_Vectorcall(iterdump, args + 1, nargsf, kwnames);
    Py_DECREF(iterdump);
    Py_DECREF(kwnames);
    return retval;
}

/*[clinic input]
_sqlite3.Connection.backup as pysqlite_connection_backup

    target: object(type='pysqlite_Connection *', subclass_of='clinic_state()->ConnectionType')
    *
    pages: int = -1
    progress: object = None
    name: str = "main"
    sleep: double = 0.250

Makes a backup of the database.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_backup_impl(pysqlite_Connection *self,
                                pysqlite_Connection *target, int pages,
                                PyObject *progress, const char *name,
                                double sleep)
/*[clinic end generated code: output=306a3e6a38c36334 input=c6519d0f59d0fd7f]*/
{
    int rc;
    int sleep_ms = (int)(sleep * 1000.0);
    sqlite3 *bck_conn;
    sqlite3_backup *bck_handle;

    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }

    if (!pysqlite_check_connection(target)) {
        return NULL;
    }

    if (target == self) {
        PyErr_SetString(PyExc_ValueError, "target cannot be the same connection instance");
        return NULL;
    }

    if (progress != Py_None && !PyCallable_Check(progress)) {
        PyErr_SetString(PyExc_TypeError, "progress argument must be a callable");
        return NULL;
    }

    if (pages == 0) {
        pages = -1;
    }

    bck_conn = target->db;

    Py_BEGIN_ALLOW_THREADS
    bck_handle = sqlite3_backup_init(bck_conn, "main", self->db, name);
    Py_END_ALLOW_THREADS

    if (bck_handle == NULL) {
        set_error_from_db(self->state, bck_conn);
        return NULL;
    }

    do {
        Py_BEGIN_ALLOW_THREADS
        rc = sqlite3_backup_step(bck_handle, pages);
        Py_END_ALLOW_THREADS

        if (progress != Py_None) {
            int remaining = sqlite3_backup_remaining(bck_handle);
            int pagecount = sqlite3_backup_pagecount(bck_handle);
            PyObject *res = PyObject_CallFunction(progress, "iii", rc,
                                                  remaining, pagecount);
            if (res == NULL) {
                /* Callback failed: abort backup and bail. */
                Py_BEGIN_ALLOW_THREADS
                sqlite3_backup_finish(bck_handle);
                Py_END_ALLOW_THREADS
                return NULL;
            }
            Py_DECREF(res);
        }

        /* Sleep for a while if there are still further pages to copy and
           the engine could not make any progress */
        if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED) {
            Py_BEGIN_ALLOW_THREADS
            sqlite3_sleep(sleep_ms);
            Py_END_ALLOW_THREADS
        }
    } while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED);

    Py_BEGIN_ALLOW_THREADS
    rc = sqlite3_backup_finish(bck_handle);
    Py_END_ALLOW_THREADS

    if (rc != SQLITE_OK) {
        set_error_from_db(self->state, bck_conn);
        return NULL;
    }

    Py_RETURN_NONE;
}

/*[clinic input]
_sqlite3.Connection.create_collation as pysqlite_connection_create_collation

    cls: defining_class
    name: str
    callback as callable: object
    /

Creates a collation function.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_create_collation_impl(pysqlite_Connection *self,
                                          PyTypeObject *cls,
                                          const char *name,
                                          PyObject *callable)
/*[clinic end generated code: output=32d339e97869c378 input=f67ecd2e31e61ad3]*/
{
    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }

    callback_context *ctx = NULL;
    int rc;
    int flags = SQLITE_UTF8;
    if (callable == Py_None) {
        rc = sqlite3_create_collation_v2(self->db, name, flags,
                                         NULL, NULL, NULL);
    }
    else {
        if (!PyCallable_Check(callable)) {
            PyErr_SetString(PyExc_TypeError, "parameter must be callable");
            return NULL;
        }
        ctx = create_callback_context(cls, callable);
        if (ctx == NULL) {
            return NULL;
        }
        rc = sqlite3_create_collation_v2(self->db, name, flags, ctx,
                                         &collation_callback,
                                         &destructor_callback);
    }

    if (rc != SQLITE_OK) {
        /* Unlike other sqlite3_* functions, the destructor callback is _not_
         * called if sqlite3_create_collation_v2() fails, so we have to free
         * the context before returning.
         */
        if (callable != Py_None) {
            decref_callback_context(ctx);
        }
        set_error_from_db(self->state, self->db);
        return NULL;
    }

    Py_RETURN_NONE;
}

#ifdef PY_SQLITE_HAVE_SERIALIZE
/*[clinic input]
_sqlite3.Connection.serialize as serialize

    *
    name: str = "main"
        Which database to serialize.

Serialize a database into a byte string.

For an ordinary on-disk database file, the serialization is just
a copy of the disk file.  For an in-memory database or a "temp"
database, the serialization is the same sequence of bytes which
would be written to disk if that database were backed up to disk.
[clinic start generated code]*/

static PyObject *
serialize_impl(pysqlite_Connection *self, const char *name)
/*[clinic end generated code: output=97342b0e55239dd3 input=7e48654e8e082fa8]*/
{
    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }

    /* If SQLite has a contiguous memory representation of the database, we can
     * avoid memory allocations, so we try with the no-copy flag first.
     */
    sqlite3_int64 size;
    unsigned int flags = SQLITE_SERIALIZE_NOCOPY;
    const char *data;

    Py_BEGIN_ALLOW_THREADS
    data = (const char *)sqlite3_serialize(self->db, name, &size, flags);
    if (data == NULL) {
        flags &= ~SQLITE_SERIALIZE_NOCOPY;
        data = (const char *)sqlite3_serialize(self->db, name, &size, flags);
    }
    Py_END_ALLOW_THREADS

    if (data == NULL) {
        PyErr_Format(self->OperationalError, "unable to serialize '%s'",
                     name);
        return NULL;
    }
    PyObject *res = PyBytes_FromStringAndSize(data, (Py_ssize_t)size);
    if (!(flags & SQLITE_SERIALIZE_NOCOPY)) {
        sqlite3_free((void *)data);
    }
    return res;
}

/*[clinic input]
_sqlite3.Connection.deserialize as deserialize

    data: Py_buffer(accept={buffer, str})
        The serialized database content.
    /
    *
    name: str = "main"
        Which database to reopen with the deserialization.

Load a serialized database.

The deserialize interface causes the database connection to
disconnect from the target database, and then reopen it as
an in-memory database based on the given serialized data.

The deserialize interface will fail with SQLITE_BUSY if the database
is currently in a read transaction or is involved in a backup
operation.
[clinic start generated code]*/

static PyObject *
deserialize_impl(pysqlite_Connection *self, Py_buffer *data,
                 const char *name)
/*[clinic end generated code: output=e394c798b98bad89 input=5d20e028d98c0686]*/
{
    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }

    /* Transfer ownership of the buffer to SQLite:
     * - Move buffer from Py to SQLite
     * - Tell SQLite to free buffer memory
     * - Tell SQLite that it is permitted to grow the resulting database
     *
     * Make sure we don't overflow sqlite3_deserialize(); it accepts a signed
     * 64-bit int as its data size argument.
     *
     * We can safely use sqlite3_malloc64 here, since it was introduced before
     * the serialize APIs.
     */
    if (data->len > 9223372036854775807) {  // (1 << 63) - 1
        PyErr_SetString(PyExc_OverflowError, "'data' is too large");
        return NULL;
    }

    sqlite3_int64 size = (sqlite3_int64)data->len;
    unsigned char *buf = sqlite3_malloc64(size);
    if (buf == NULL) {
        return PyErr_NoMemory();
    }

    const unsigned int flags = SQLITE_DESERIALIZE_FREEONCLOSE |
                               SQLITE_DESERIALIZE_RESIZEABLE;
    int rc;
    Py_BEGIN_ALLOW_THREADS
    (void)memcpy(buf, data->buf, data->len);
    rc = sqlite3_deserialize(self->db, name, buf, size, size, flags);
    Py_END_ALLOW_THREADS

    if (rc != SQLITE_OK) {
        set_error_from_db(self->state, self->db);
        return NULL;
    }
    Py_RETURN_NONE;
}
#endif  // PY_SQLITE_HAVE_SERIALIZE


/*[clinic input]
_sqlite3.Connection.__enter__ as pysqlite_connection_enter

Called when the connection is used as a context manager.

Returns itself as a convenience to the caller.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_enter_impl(pysqlite_Connection *self)
/*[clinic end generated code: output=457b09726d3e9dcd input=127d7a4f17e86d8f]*/
{
    if (!pysqlite_check_connection(self)) {
        return NULL;
    }
    return Py_NewRef((PyObject *)self);
}

/*[clinic input]
_sqlite3.Connection.__exit__ as pysqlite_connection_exit

    type as exc_type: object
    value as exc_value: object
    traceback as exc_tb: object
    /

Called when the connection is used as a context manager.

If there was any exception, a rollback takes place; otherwise we
commit.
[clinic start generated code]*/

static PyObject *
pysqlite_connection_exit_impl(pysqlite_Connection *self, PyObject *exc_type,
                              PyObject *exc_value, PyObject *exc_tb)
/*[clinic end generated code: output=0705200e9321202a input=8fdb0392ee6f3466]*/
{
    int commit = 0;
    PyObject* result;

    if (exc_type == Py_None && exc_value == Py_None && exc_tb == Py_None) {
        commit = 1;
        result = pysqlite_connection_commit_impl(self);
    }
    else {
        result = pysqlite_connection_rollback_impl(self);
    }

    if (result == NULL) {
        if (commit) {
            /* Commit failed; try to rollback in order to unlock the database.
             * If rollback also fails, chain the exceptions. */
            PyObject *exc = PyErr_GetRaisedException();
            result = pysqlite_connection_rollback_impl(self);
            if (result == NULL) {
                _PyErr_ChainExceptions1(exc);
            }
            else {
                Py_DECREF(result);
                PyErr_SetRaisedException(exc);
            }
        }
        return NULL;
    }
    Py_DECREF(result);

    Py_RETURN_FALSE;
}

/*[clinic input]
_sqlite3.Connection.setlimit as setlimit

    category: int
        The limit category to be set.
    limit: int
        The new limit. If the new limit is a negative number, the limit
        is unchanged.
    /

Set connection run-time limits.

Attempts to increase a limit above its hard upper bound are silently
truncated to the hard upper bound. Regardless of whether or not the
limit was changed, the prior value of the limit is returned.
[clinic start generated code]*/

static PyObject *
setlimit_impl(pysqlite_Connection *self, int category, int limit)
/*[clinic end generated code: output=0d208213f8d68ccd input=5c2e430091206677]*/
{
    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }

    int old_limit = sqlite3_limit(self->db, category, limit);
    if (old_limit < 0) {
        PyErr_SetString(self->ProgrammingError, "'category' is out of bounds");
        return NULL;
    }
    return PyLong_FromLong(old_limit);
}

/*[clinic input]
_sqlite3.Connection.getlimit as getlimit

    category: int
        The limit category to be queried.
    /

Get connection run-time limits.
[clinic start generated code]*/

static PyObject *
getlimit_impl(pysqlite_Connection *self, int category)
/*[clinic end generated code: output=7c3f5d11f24cecb1 input=61e0849fb4fb058f]*/
{
    return setlimit_impl(self, category, -1);
}

static inline bool
is_int_config(const int op)
{
    switch (op) {
        case SQLITE_DBCONFIG_ENABLE_FKEY:
        case SQLITE_DBCONFIG_ENABLE_TRIGGER:
        case SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER:
        case SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION:
#if SQLITE_VERSION_NUMBER >= 3016000
        case SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE:
#endif
#if SQLITE_VERSION_NUMBER >= 3020000
        case SQLITE_DBCONFIG_ENABLE_QPSG:
#endif
#if SQLITE_VERSION_NUMBER >= 3022000
        case SQLITE_DBCONFIG_TRIGGER_EQP:
#endif
#if SQLITE_VERSION_NUMBER >= 3024000
        case SQLITE_DBCONFIG_RESET_DATABASE:
#endif
#if SQLITE_VERSION_NUMBER >= 3026000
        case SQLITE_DBCONFIG_DEFENSIVE:
#endif
#if SQLITE_VERSION_NUMBER >= 3028000
        case SQLITE_DBCONFIG_WRITABLE_SCHEMA:
#endif
#if SQLITE_VERSION_NUMBER >= 3029000
        case SQLITE_DBCONFIG_DQS_DDL:
        case SQLITE_DBCONFIG_DQS_DML:
        case SQLITE_DBCONFIG_LEGACY_ALTER_TABLE:
#endif
#if SQLITE_VERSION_NUMBER >= 3030000
        case SQLITE_DBCONFIG_ENABLE_VIEW:
#endif
#if SQLITE_VERSION_NUMBER >= 3031000
        case SQLITE_DBCONFIG_LEGACY_FILE_FORMAT:
        case SQLITE_DBCONFIG_TRUSTED_SCHEMA:
#endif
            return true;
        default:
            return false;
    }
}

/*[clinic input]
_sqlite3.Connection.setconfig as setconfig

    op: int
        The configuration verb; one of the sqlite3.SQLITE_DBCONFIG codes.
    enable: bool = True
    /

Set a boolean connection configuration option.
[clinic start generated code]*/

static PyObject *
setconfig_impl(pysqlite_Connection *self, int op, int enable)
/*[clinic end generated code: output=c60b13e618aff873 input=a10f1539c2d7da6b]*/
{
    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }
    if (!is_int_config(op)) {
        return PyErr_Format(PyExc_ValueError, "unknown config 'op': %d", op);
    }

    int actual;
    int rc = sqlite3_db_config(self->db, op, enable, &actual);
    if (rc != SQLITE_OK) {
        set_error_from_db(self->state, self->db);
        return NULL;
    }
    if (enable != actual) {
        PyErr_SetString(self->state->OperationalError, "Unable to set config");
        return NULL;
    }
    Py_RETURN_NONE;
}

/*[clinic input]
_sqlite3.Connection.getconfig as getconfig -> bool

    op: int
        The configuration verb; one of the sqlite3.SQLITE_DBCONFIG codes.
    /

Query a boolean connection configuration option.
[clinic start generated code]*/

static int
getconfig_impl(pysqlite_Connection *self, int op)
/*[clinic end generated code: output=25ac05044c7b78a3 input=b0526d7e432e3f2f]*/
{
    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return -1;
    }
    if (!is_int_config(op)) {
        PyErr_Format(PyExc_ValueError, "unknown config 'op': %d", op);
        return -1;
    }

    int current;
    int rc = sqlite3_db_config(self->db, op, -1, &current);
    if (rc != SQLITE_OK) {
        set_error_from_db(self->state, self->db);
        return -1;
    }
    return current;
}

static PyObject *
get_autocommit(PyObject *op, void *Py_UNUSED(closure))
{
    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return NULL;
    }
    if (self->autocommit == AUTOCOMMIT_ENABLED) {
        Py_RETURN_TRUE;
    }
    if (self->autocommit == AUTOCOMMIT_DISABLED) {
        Py_RETURN_FALSE;
    }
    return PyLong_FromLong(LEGACY_TRANSACTION_CONTROL);
}

static int
set_autocommit(PyObject *op, PyObject *val, void *Py_UNUSED(closure))
{
    pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
    if (val == NULL) {
        PyErr_SetString(PyExc_AttributeError,
                        "cannot delete autocommit attribute");
        return -1;
    }
    if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
        return -1;
    }
    if (!autocommit_converter(val, &self->autocommit)) {
        return -1;
    }
    if (self->autocommit == AUTOCOMMIT_ENABLED) {
        if (!sqlite3_get_autocommit(self->db)) {
            if (connection_exec_stmt(self, "COMMIT") < 0) {
                return -1;
            }
        }
    }
    else if (self->autocommit == AUTOCOMMIT_DISABLED) {
        if (sqlite3_get_autocommit(self->db)) {
            if (connection_exec_stmt(self, "BEGIN") < 0) {
                return -1;
            }
        }
    }
    return 0;
}

static PyObject *
get_sig(PyObject *Py_UNUSED(self), void *Py_UNUSED(closure))
{
    return PyUnicode_FromString("(sql, /)");
}


static const char connection_doc[] =
PyDoc_STR("SQLite database connection object.");

static PyGetSetDef connection_getset[] = {
    {"isolation_level", pysqlite_connection_get_isolation_level,
     pysqlite_connection_set_isolation_level},
    {"total_changes",  pysqlite_connection_get_total_changes, NULL},
    {"in_transaction", pysqlite_connection_get_in_transaction, NULL},
    {"autocommit",  get_autocommit, set_autocommit},
    {"__text_signature__", get_sig, NULL},
    {"row_factory", connection_get_row_factory,
                    connection_set_row_factory},
    {"text_factory", connection_get_text_factory,
                     connection_set_text_factory},
    {NULL}
};

static PyMethodDef connection_methods[] = {
    PYSQLITE_CONNECTION_BACKUP_METHODDEF
    PYSQLITE_CONNECTION_CLOSE_METHODDEF
    PYSQLITE_CONNECTION_COMMIT_METHODDEF
    PYSQLITE_CONNECTION_CREATE_AGGREGATE_METHODDEF
    PYSQLITE_CONNECTION_CREATE_COLLATION_METHODDEF
    PYSQLITE_CONNECTION_CREATE_FUNCTION_METHODDEF
    PYSQLITE_CONNECTION_CURSOR_METHODDEF
    PYSQLITE_CONNECTION_ENABLE_LOAD_EXTENSION_METHODDEF
    PYSQLITE_CONNECTION_ENTER_METHODDEF
    PYSQLITE_CONNECTION_EXECUTEMANY_METHODDEF
    PYSQLITE_CONNECTION_EXECUTESCRIPT_METHODDEF
    PYSQLITE_CONNECTION_EXECUTE_METHODDEF
    PYSQLITE_CONNECTION_EXIT_METHODDEF
    PYSQLITE_CONNECTION_INTERRUPT_METHODDEF
    PYSQLITE_CONNECTION_ITERDUMP_METHODDEF
    PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
    PYSQLITE_CONNECTION_ROLLBACK_METHODDEF
    PYSQLITE_CONNECTION_SET_AUTHORIZER_METHODDEF
    PYSQLITE_CONNECTION_SET_PROGRESS_HANDLER_METHODDEF
    PYSQLITE_CONNECTION_SET_TRACE_CALLBACK_METHODDEF
    SETLIMIT_METHODDEF
    GETLIMIT_METHODDEF
    SERIALIZE_METHODDEF
    DESERIALIZE_METHODDEF
    CREATE_WINDOW_FUNCTION_METHODDEF
    BLOBOPEN_METHODDEF
    SETCONFIG_METHODDEF
    GETCONFIG_METHODDEF
    {NULL, NULL}
};

static struct PyMemberDef connection_members[] =
{
    {"Warning", _Py_T_OBJECT, offsetof(pysqlite_Connection, Warning), Py_READONLY},
    {"Error", _Py_T_OBJECT, offsetof(pysqlite_Connection, Error), Py_READONLY},
    {"InterfaceError", _Py_T_OBJECT, offsetof(pysqlite_Connection, InterfaceError), Py_READONLY},
    {"DatabaseError", _Py_T_OBJECT, offsetof(pysqlite_Connection, DatabaseError), Py_READONLY},
    {"DataError", _Py_T_OBJECT, offsetof(pysqlite_Connection, DataError), Py_READONLY},
    {"OperationalError", _Py_T_OBJECT, offsetof(pysqlite_Connection, OperationalError), Py_READONLY},
    {"IntegrityError", _Py_T_OBJECT, offsetof(pysqlite_Connection, IntegrityError), Py_READONLY},
    {"InternalError", _Py_T_OBJECT, offsetof(pysqlite_Connection, InternalError), Py_READONLY},
    {"ProgrammingError", _Py_T_OBJECT, offsetof(pysqlite_Connection, ProgrammingError), Py_READONLY},
    {"NotSupportedError", _Py_T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), Py_READONLY},
    {NULL}
};

static PyType_Slot connection_slots[] = {
    {Py_tp_finalize, connection_finalize},
    {Py_tp_dealloc, connection_dealloc},
    {Py_tp_doc, (void *)connection_doc},
    {Py_tp_methods, connection_methods},
    {Py_tp_members, connection_members},
    {Py_tp_getset, connection_getset},
    {Py_tp_init, pysqlite_connection_init},
    {Py_tp_call, pysqlite_connection_call},
    {Py_tp_traverse, connection_traverse},
    {Py_tp_clear, connection_clear},
    {0, NULL},
};

static PyType_Spec connection_spec = {
    .name = MODULE_NAME ".Connection",
    .basicsize = sizeof(pysqlite_Connection),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
              Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE),
    .slots = connection_slots,
};

int
pysqlite_connection_setup_types(PyObject *module)
{
    PyObject *type = PyType_FromModuleAndSpec(module, &connection_spec, NULL);
    if (type == NULL) {
        return -1;
    }
    pysqlite_state *state = pysqlite_get_state(module);
    state->ConnectionType = (PyTypeObject *)type;
    return 0;
}
