Ejemplo n.º 1
0
static PyObject* mod_connect(PyObject* self, PyObject* args, PyObject* kwargs)
{
    UNUSED(self);

    Object pConnectString;
    int fAutoCommit = 0;
    int fAnsi = 0;              // force ansi
    int fReadOnly = 0;
    long timeout = 0;
    Object encoding;

    Object attrs_before; // Optional connect attrs set before connecting

    Py_ssize_t size = args ? PyTuple_Size(args) : 0;

    if (size > 1)
    {
        PyErr_SetString(PyExc_TypeError, "function takes at most 1 non-keyword argument");
        return 0;
    }

    if (size == 1)
    {
        if (!PyString_Check(PyTuple_GET_ITEM(args, 0)) && !PyUnicode_Check(PyTuple_GET_ITEM(args, 0)))
            return PyErr_Format(PyExc_TypeError, "argument 1 must be a string or unicode object");

        pConnectString.Attach(PyUnicode_FromObject(PyTuple_GetItem(args, 0)));
        if (!pConnectString.IsValid())
            return 0;
    }

    if (kwargs && PyDict_Size(kwargs) > 0)
    {
        Object partsdict(PyDict_New());
        if (!partsdict.IsValid())
            return 0;

        Py_ssize_t pos = 0;
        PyObject* key = 0;
        PyObject* value = 0;

        Object okey; // in case we need to allocate a new key

        while (PyDict_Next(kwargs, &pos, &key, &value))
        {
            if (!Text_Check(key))
                return PyErr_Format(PyExc_TypeError, "Dictionary keys passed to connect must be strings");

            // // Note: key and value are *borrowed*.
            //
            // // Check for the two non-connection string keywords we accept.  (If we get many more of these, create something
            // // table driven.  Are we sure there isn't a Python function to parse keywords but leave those it doesn't know?)
            // const char* szKey = PyString_AsString(key);

            if (Text_EqualsI(key, "autocommit"))
            {
                fAutoCommit = PyObject_IsTrue(value);
                continue;
            }
            if (Text_EqualsI(key, "ansi"))
            {
                fAnsi = PyObject_IsTrue(value);
                continue;
            }
            if (Text_EqualsI(key, "timeout"))
            {
                timeout = PyInt_AsLong(value);
                if (PyErr_Occurred())
                    return 0;
                continue;
            }
            if (Text_EqualsI(key, "readonly"))
            {
                fReadOnly = PyObject_IsTrue(value);
                continue;
            }
            if (Text_EqualsI(key, "attrs_before"))
            {
                attrs_before = _CheckAttrsDict(value);
                if (PyErr_Occurred())
                    return 0;
                continue;
            }
            if (Text_EqualsI(key, "encoding"))
            {
#if PY_MAJOR_VERSION < 3
                if (!PyString_Check(value) || !PyUnicode_Check(value))
                    return PyErr_Format(PyExc_TypeError, "encoding must be a string or unicode object");
#else
                if (!PyUnicode_Check(value))
                    return PyErr_Format(PyExc_TypeError, "encoding must be a string");
#endif
                encoding = value;
                continue;
            }

            // Map DB API recommended names to ODBC names (e.g. user --> uid).

            for (size_t i = 0; i < _countof(keywordmaps); i++)
            {
                if (Text_EqualsI(key, keywordmaps[i].oldname))
                {
                    if (keywordmaps[i].newnameObject == 0)
                    {
                        keywordmaps[i].newnameObject = PyString_FromString(keywordmaps[i].newname);
                        if (keywordmaps[i].newnameObject == 0)
                            return 0;
                    }

                    key = keywordmaps[i].newnameObject;
                    break;
                }
            }

            PyObject* str = PyObject_Str(value); // convert if necessary
            if (!str)
                return 0;

            if (PyDict_SetItem(partsdict.Get(), key, str) == -1)
            {
                Py_XDECREF(str);
                return 0;
            }

            Py_XDECREF(str);
        }

        if (PyDict_Size(partsdict.Get()))
            pConnectString.Attach(MakeConnectionString(pConnectString.Get(), partsdict));
    }

    if (!pConnectString.IsValid())
        return PyErr_Format(PyExc_TypeError, "no connection information was passed");

    if (henv == SQL_NULL_HANDLE)
    {
        if (!AllocateEnv())
            return 0;
    }

    return (PyObject*)Connection_New(pConnectString.Get(), fAutoCommit != 0, fAnsi != 0, timeout,
                                     fReadOnly != 0, attrs_before, encoding);
}
Ejemplo n.º 2
0
static PyObject* mod_connect(PyObject* self, PyObject* args, PyObject* kwargs)
{
    UNUSED(self);
    
    Object pConnectString = 0;
    int fAutoCommit = 0;
    int fAnsi = 0;              // force ansi
    int fUnicodeResults = 0;
    long timeout = 0;

    Py_ssize_t size = args ? PyTuple_Size(args) : 0;

    if (size > 1)
    {
        PyErr_SetString(PyExc_TypeError, "function takes at most 1 non-keyword argument");
        return 0;
    }

    if (size == 1)
    {
        if (!PyString_Check(PyTuple_GET_ITEM(args, 0)) && !PyUnicode_Check(PyTuple_GET_ITEM(args, 0)))
            return PyErr_Format(PyExc_TypeError, "argument 1 must be a string or unicode object");

        pConnectString.Attach(PyUnicode_FromObject(PyTuple_GetItem(args, 0)));
        if (!pConnectString.IsValid())
            return 0;
    }

    if (kwargs && PyDict_Size(kwargs) > 0)
    {
        Object partsdict(PyDict_New());
        if (!partsdict.IsValid())
            return 0;

        Object unicodeT;            // used to temporarily hold Unicode objects if we have to convert values to unicode

        Py_ssize_t pos = 0;
        PyObject* key = 0;
        PyObject* value = 0;

        while (PyDict_Next(kwargs, &pos, &key, &value))
        {
            // Note: key and value are *borrowed*.

            // Check for the two non-connection string keywords we accept.  (If we get many more of these, create something
            // table driven.  Are we sure there isn't a Python function to parse keywords but leave those it doesn't know?)
            const char* szKey = PyString_AsString(key);

            if (_strcmpi(szKey, "autocommit") == 0)
            {
                fAutoCommit = PyObject_IsTrue(value);
                continue;
            }
            if (_strcmpi(szKey, "ansi") == 0)
            {
                fAnsi = PyObject_IsTrue(value);
                continue;
            }
            if (_strcmpi(szKey, "unicode_results") == 0)
            {
                fUnicodeResults = PyObject_IsTrue(value);
                continue;
            }
            if (_strcmpi(szKey, "timeout") == 0)
            {
                timeout = PyInt_AsLong(value);
                if (PyErr_Occurred())
                    return 0;
                continue;
            }
        
            // Anything else must be a string that is appended, along with the keyword to the connection string.

            if (!(PyString_Check(value) || PyUnicode_Check(value)))
                return PyErr_Format(PyExc_TypeError, "'%s' is not a string or unicode value'", szKey);

            // Map DB API recommended names to ODBC names (e.g. user --> uid).
            for (size_t i = 0; i < _countof(keywordmaps); i++)
            {
                if (_strcmpi(szKey, keywordmaps[i].oldname) == 0)
                {
                    if (keywordmaps[i].newnameObject == 0)
                    {
                        keywordmaps[i].newnameObject = PyString_FromString(keywordmaps[i].newname);
                        if (keywordmaps[i].newnameObject == 0)
                            return 0;
                    }

                    key = keywordmaps[i].newnameObject;
                    break;
                }
            }

            if (PyString_Check(value))
            {
                unicodeT.Attach(PyUnicode_FromObject(value));
                if (!unicodeT.IsValid())
                    return 0;
                value = unicodeT.Get();
            }

            if (PyDict_SetItem(partsdict.Get(), key, value) == -1)
                return 0;

            unicodeT.Detach();
        }

        if (PyDict_Size(partsdict.Get()))
            pConnectString.Attach(MakeConnectionString(pConnectString.Get(), partsdict));
    }
    
    if (!pConnectString.IsValid())
        return PyErr_Format(PyExc_TypeError, "no connection information was passed");

    if (henv == SQL_NULL_HANDLE)
    {
        if (!AllocateEnv())
            return 0;
    }
     
    return (PyObject*)Connection_New(pConnectString.Get(), fAutoCommit != 0, fAnsi != 0, fUnicodeResults != 0, timeout);
}