/* util.c - various utility functions
 *
 * Copyright (C) 2005-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.
 */

#include "module.h"
#include "connection.h"

int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection)
{
    int rc;

    if (statement == NULL) {
        /* this is a workaround for SQLite 3.5 and later. it now apparently
         * returns NULL for "no-operation" statements */
        rc = SQLITE_OK;
    } else {
        Py_BEGIN_ALLOW_THREADS
        rc = sqlite3_step(statement);
        Py_END_ALLOW_THREADS
    }

    return rc;
}

/**
 * Checks the SQLite error code and sets the appropriate DB-API exception.
 * Returns the error code (0 means no error occurred).
 */
int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st)
{
    int errorcode;

    /* SQLite often doesn't report anything useful, unless you reset the statement first */
    if (st != NULL) {
        (void)sqlite3_reset(st);
    }

    errorcode = sqlite3_errcode(db);

    switch (errorcode)
    {
        case SQLITE_OK:
            PyErr_Clear();
            break;
        case SQLITE_INTERNAL:
        case SQLITE_NOTFOUND:
            PyErr_SetString(pysqlite_InternalError, sqlite3_errmsg(db));
            break;
        case SQLITE_NOMEM:
            (void)PyErr_NoMemory();
            break;
        case SQLITE_ERROR:
        case SQLITE_PERM:
        case SQLITE_ABORT:
        case SQLITE_BUSY:
        case SQLITE_LOCKED:
        case SQLITE_READONLY:
        case SQLITE_INTERRUPT:
        case SQLITE_IOERR:
        case SQLITE_FULL:
        case SQLITE_CANTOPEN:
        case SQLITE_PROTOCOL:
        case SQLITE_EMPTY:
        case SQLITE_SCHEMA:
            PyErr_SetString(pysqlite_OperationalError, sqlite3_errmsg(db));
            break;
        case SQLITE_CORRUPT:
            PyErr_SetString(pysqlite_DatabaseError, sqlite3_errmsg(db));
            break;
        case SQLITE_TOOBIG:
            PyErr_SetString(pysqlite_DataError, sqlite3_errmsg(db));
            break;
        case SQLITE_CONSTRAINT:
        case SQLITE_MISMATCH:
            PyErr_SetString(pysqlite_IntegrityError, sqlite3_errmsg(db));
            break;
        case SQLITE_MISUSE:
            PyErr_SetString(pysqlite_ProgrammingError, sqlite3_errmsg(db));
            break;
        default:
            PyErr_SetString(pysqlite_DatabaseError, sqlite3_errmsg(db));
            break;
    }

    return errorcode;
}

#ifdef WORDS_BIGENDIAN
# define IS_LITTLE_ENDIAN 0
#else
# define IS_LITTLE_ENDIAN 1
#endif

PyObject *
_pysqlite_long_from_int64(sqlite_int64 value)
{
#ifdef HAVE_LONG_LONG
# if SIZEOF_LONG_LONG < 8
    if (value > PY_LLONG_MAX || value < PY_LLONG_MIN) {
        return _PyLong_FromByteArray(&value, sizeof(value),
                                     IS_LITTLE_ENDIAN, 1 /* signed */);
    }
# endif
# if SIZEOF_LONG < SIZEOF_LONG_LONG
    if (value > LONG_MAX || value < LONG_MIN)
        return PyLong_FromLongLong(value);
# endif
#else
# if SIZEOF_LONG < 8
    if (value > LONG_MAX || value < LONG_MIN) {
        return _PyLong_FromByteArray(&value, sizeof(value),
                                     IS_LITTLE_ENDIAN, 1 /* signed */);
    }
# endif
#endif
    return PyLong_FromLong(Py_SAFE_DOWNCAST(value, sqlite_int64, long));
}

sqlite_int64
_pysqlite_long_as_int64(PyObject * py_val)
{
    int overflow;
#ifdef HAVE_LONG_LONG
    PY_LONG_LONG value = PyLong_AsLongLongAndOverflow(py_val, &overflow);
#else
    long value = PyLong_AsLongAndOverflow(py_val, &overflow);
#endif
    if (value == -1 && PyErr_Occurred())
        return -1;
    if (!overflow) {
#ifdef HAVE_LONG_LONG
# if SIZEOF_LONG_LONG > 8
        if (-0x8000000000000000LL <= value && value <= 0x7FFFFFFFFFFFFFFFLL)
# endif
#else
# if SIZEOF_LONG > 8
        if (-0x8000000000000000L <= value && value <= 0x7FFFFFFFFFFFFFFFL)
# endif
#endif
            return value;
    }
    else if (sizeof(value) < sizeof(sqlite_int64)) {
        sqlite_int64 int64val;
        if (_PyLong_AsByteArray((PyLongObject *)py_val,
                                (unsigned char *)&int64val, sizeof(int64val),
                                IS_LITTLE_ENDIAN, 1 /* signed */) >= 0) {
            return int64val;
        }
    }
    PyErr_SetString(PyExc_OverflowError,
                    "Python int too large to convert to SQLite INTEGER");
    return -1;
}
