Example #1
0
PyObject* SetResultError(PGresult* r)
{
    // Creates an exception from `result`.
    //
    // This function takes ownership of `result` and will clear it, even if an exception cannot be created.
    //
    // Always returns zero so it can be called using "return SetResultError(result);"

    // TODO: Make a new exception class that always has SQLSTATE

    ResultHolder result(r); // make sure `r` gets cleared no matter what

    const char* szMessage  = PQresultErrorMessage(result);
    const char* szSQLSTATE = PQresultErrorField(result, PG_DIAG_SQLSTATE);
    if (!szMessage || !szSQLSTATE)
        return PyErr_NoMemory();

    Object msg(PyUnicode_FromFormat("[%s] %s", szSQLSTATE, szMessage));
    if (!msg)
        return 0;

    PyObject* error = PyObject_CallFunction(Error, (char*)"O", msg.Get());
    if (!error)
        return 0;

    for (size_t i = 0; i < _countof(errorFields); i++)
    {
        const char* szValue = PQresultErrorField(result, errorFields[i].fieldcode);

        Object value;

        if (szValue == 0)
        {
            value.AttachAndIncrement(Py_None);
        }
        else
        {
            value.Attach(PyUnicode_FromString(szValue));
            if (!value)
                return 0;
        }

        if (PyObject_SetAttrString(error, errorFields[i].szAttr, value) == -1)
            return 0;
    }
    
    PyErr_SetObject(Error, error);

    return 0;
}
Example #2
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);
}
Example #3
0
initpyodbc(void)
#endif
{
    ErrorInit();

    if (PyType_Ready(&ConnectionType) < 0 || PyType_Ready(&CursorType) < 0 || PyType_Ready(&RowType) < 0 || PyType_Ready(&CnxnInfoType) < 0)
        return MODRETURN(0);

    Object module;

#if PY_MAJOR_VERSION >= 3
    module.Attach(PyModule_Create(&moduledef));
#else
    module.Attach(Py_InitModule4("pyodbc", pyodbc_methods, module_doc, NULL, PYTHON_API_VERSION));
#endif

    pModule = module.Get();

    if (!module || !import_types() || !CreateExceptions())
        return MODRETURN(0);

    init_locale_info();

    const char* szVersion = TOSTRING(PYODBC_VERSION);
    PyModule_AddStringConstant(module, "version", (char*)szVersion);

    PyModule_AddIntConstant(module, "threadsafety", 1);
    PyModule_AddStringConstant(module, "apilevel", "2.0");
    PyModule_AddStringConstant(module, "paramstyle", "qmark");
    PyModule_AddObject(module, "pooling", Py_True);
    Py_INCREF(Py_True);
    PyModule_AddObject(module, "lowercase", Py_False);
    Py_INCREF(Py_False);
    PyModule_AddObject(module, "native_uuid", Py_False);
    Py_INCREF(Py_False);

    PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType);
    Py_INCREF((PyObject*)&ConnectionType);
    PyModule_AddObject(module, "Cursor", (PyObject*)&CursorType);
    Py_INCREF((PyObject*)&CursorType);
    PyModule_AddObject(module, "Row", (PyObject*)&RowType);
    Py_INCREF((PyObject*)&RowType);

    // Add the SQL_XXX defines from ODBC.
    for (unsigned int i = 0; i < _countof(aConstants); i++)
        PyModule_AddIntConstant(module, (char*)aConstants[i].szName, aConstants[i].value);

    PyModule_AddObject(module, "Date", (PyObject*)PyDateTimeAPI->DateType);
    Py_INCREF((PyObject*)PyDateTimeAPI->DateType);
    PyModule_AddObject(module, "Time", (PyObject*)PyDateTimeAPI->TimeType);
    Py_INCREF((PyObject*)PyDateTimeAPI->TimeType);
    PyModule_AddObject(module, "Timestamp", (PyObject*)PyDateTimeAPI->DateTimeType);
    Py_INCREF((PyObject*)PyDateTimeAPI->DateTimeType);
    PyModule_AddObject(module, "DATETIME", (PyObject*)PyDateTimeAPI->DateTimeType);
    Py_INCREF((PyObject*)PyDateTimeAPI->DateTimeType);
    PyModule_AddObject(module, "STRING", (PyObject*)&PyString_Type);
    Py_INCREF((PyObject*)&PyString_Type);
    PyModule_AddObject(module, "NUMBER", (PyObject*)&PyFloat_Type);
    Py_INCREF((PyObject*)&PyFloat_Type);
    PyModule_AddObject(module, "ROWID", (PyObject*)&PyInt_Type);
    Py_INCREF((PyObject*)&PyInt_Type);

    PyObject* binary_type;
#if PY_VERSION_HEX >= 0x02060000
    binary_type = (PyObject*)&PyByteArray_Type;
#else
    binary_type = (PyObject*)&PyBuffer_Type;
#endif
    PyModule_AddObject(module, "BINARY", binary_type);
    Py_INCREF(binary_type);
    PyModule_AddObject(module, "Binary", binary_type);
    Py_INCREF(binary_type);

    I(null_binary != 0);        // must be initialized first
    PyModule_AddObject(module, "BinaryNull", null_binary);

    PyModule_AddIntConstant(module, "UNICODE_SIZE", sizeof(Py_UNICODE));
    PyModule_AddIntConstant(module, "SQLWCHAR_SIZE", sizeof(SQLWCHAR));

    if (!PyErr_Occurred())
    {
        module.Detach();
    }
    else
    {
        ErrorCleanup();
    }

    return MODRETURN(pModule);
}
Example #4
0
void Object::AddMOB(const MOBType *type) {
  Object *mob = new Object(this);

  mob->Attach(get_mob_mind());
  mob->Activate();
  mob->SetPos(POS_STAND);
  mob->SetAttribute(0, type->b + rand() % type->bm);
  mob->SetAttribute(1, type->q + rand() % type->qm);
  mob->SetAttribute(2, type->s + rand() % type->sm);
  mob->SetAttribute(3, type->c + rand() % type->cm);
  mob->SetAttribute(4, type->i + rand() % type->im);
  mob->SetAttribute(5, type->w + rand() % type->wm);

  typeof(type->skills.begin()) sk_it;
  for(sk_it = type->skills.begin(); sk_it != type->skills.end(); ++sk_it) {
    if(sk_it->second.first < 0) {
      mob->SetSkill(sk_it->first, sk_it->second.second);
      }
    else {
      mob->SetSkill(sk_it->first,
	mob->Attribute(get_linked(sk_it->first))
	* sk_it->second.first / 100
	- rand() % sk_it->second.second
	);
      }
    //fprintf(stderr, "DBG: %d %d %d\n", get_linked(sk_it->first), sk_it->second.first, sk_it->second.second);
    }

  mob->SetShortDesc(type->name.c_str());
  mob->SetDesc(type->desc.c_str());
  mob->SetLongDesc(type->long_desc.c_str());
  if(type->genders.length() > 0) {
    mob->SetGender(type->genders[rand() % type->genders.length()]);
    }
  mob->SetDesc(gender_proc(type->desc.c_str(), mob->Gender()).c_str());
  mob->SetLongDesc(gender_proc(type->long_desc.c_str(), mob->Gender()).c_str());

  if(type->g > 0 || type->gm > 1) give_gold(mob, type->g + rand() % type->gm);

  if(type->armed) {
    Object *obj = new Object(mob);
    obj->SetSkill("WeaponType", type->armed->type);
    obj->SetSkill("WeaponReach", type->armed->reach);
    obj->SetSkill("WeaponForce",
	type->armed->force + rand() % type->armed->forcem);
    obj->SetSkill("WeaponSeverity",
	type->armed->sev + rand() % type->armed->sevm);
    obj->SetShortDesc(type->armed->name.c_str());
    obj->SetDesc(type->armed->desc.c_str());
    obj->SetLongDesc(type->armed->long_desc.c_str());
    obj->SetWeight(type->armed->weight);
    obj->SetVolume(type->armed->volume);
    obj->SetValue(type->armed->value);
    obj->SetPos(POS_LIE);
    mob->AddAct(ACT_WIELD, obj);
    if(two_handed(type->armed->type)) mob->AddAct(ACT_HOLD, obj);
    }

  typeof(type->armor.begin()) ar_it;
  for(ar_it = type->armor.begin(); ar_it != type->armor.end(); ++ar_it) {
    if(wear_attribs.size() <= 0) {
      init_wear_attribs();
      }
    Object *obj = new Object(mob);
    obj->SetAttribute(0, (*ar_it)->bulk + rand() %(*ar_it)->bulkm);
    obj->SetSkill("ArmorB", (*ar_it)->bulk + rand() %(*ar_it)->bulkm);
    obj->SetSkill("ArmorI", (*ar_it)->impact + rand() %(*ar_it)->impactm);
    obj->SetSkill("ArmorT", (*ar_it)->thread + rand() %(*ar_it)->threadm);
    obj->SetSkill("ArmorP", (*ar_it)->planar + rand() %(*ar_it)->planarm);
    obj->SetShortDesc((*ar_it)->name.c_str());
    obj->SetDesc((*ar_it)->desc.c_str());
    obj->SetLongDesc((*ar_it)->long_desc.c_str());
    obj->SetWeight((*ar_it)->weight);
    obj->SetVolume((*ar_it)->volume);
    obj->SetValue((*ar_it)->value);
    obj->SetPos(POS_LIE);

    typeof((*ar_it)->loc.begin()) l_it;
    for(l_it = (*ar_it)->loc.begin(); l_it != (*ar_it)->loc.end(); ++l_it) {
      obj->SetSkill(wear_attribs[*l_it], 1);
      mob->AddAct(*l_it, obj);
      }
    }
  }
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);
}