예제 #1
0
CS_RETCODE SybConnection::init_()
{
    CS_RETCODE retcode;
    CS_INT netio_type = CS_SYNC_IO;

    // Get a context handle to use.
    if ((retcode = cs_ctx_alloc(EX_CTLIB_VERSION, &sContext_)) != CS_SUCCEED) {
        SysLogger::error("init_: cs_ctx_alloc() failed");
        return retcode;
    }

    // Initialize Open Client.
    if ((retcode = ct_init(sContext_, EX_CTLIB_VERSION)) != CS_SUCCEED) {
        SysLogger::error("init_: ct_init() failed");
        cs_ctx_drop(sContext_);
        sContext_ = NULL;
        return retcode;
    }

    // Install client message handlers.
    if ((retcode = ct_callback(sContext_, NULL, CS_SET, CS_CLIENTMSG_CB,
                               (CS_VOID *)clientmsg_cb)) != CS_SUCCEED) {
        SysLogger::error("init_: ct_callback(CS_CLIENTMSG_CB) failed");
        ct_exit(sContext_, CS_FORCE_EXIT);
        cs_ctx_drop(sContext_);
        sContext_ = NULL;
        return retcode;
    }

    // Install server message handlers.
    if ((retcode = ct_callback(sContext_, NULL, CS_SET, CS_SERVERMSG_CB,
                               (CS_VOID *)servermsg_cb)) != CS_SUCCEED) {
        SysLogger::error("init_: ct_callback(CS_SERVERMSG_CB) failed");
        ct_exit(sContext_, CS_FORCE_EXIT);
        cs_ctx_drop(sContext_);
        sContext_ = NULL;
        return retcode;
    }

    // Set the input/output type to synchronous.
    if ((retcode = ct_config(sContext_, CS_SET, CS_NETIO, &netio_type,
                             CS_UNUSED, NULL)) != CS_SUCCEED) {
        SysLogger::error("init_: ct_config() failed");
        ct_exit(sContext_, CS_FORCE_EXIT);
        cs_ctx_drop(sContext_);
        sContext_ = NULL;
        return retcode;
    }

    return CS_SUCCEED;
}
예제 #2
0
파일: tds.c 프로젝트: kohenchia/ctds
PyMODINIT_FUNC init_tds(void)
{
#  define FAIL_MODULE_INIT do { Py_XDECREF(module); return; } while (0)
#else /* if PY_MAJOR_VERSION < 3 */
PyMODINIT_FUNC PyInit__tds(void)
{
#  define FAIL_MODULE_INIT do { Py_XDECREF(module); return NULL; } while (0)
#endif /* else if PY_MAJOR_VERSION < 3 */

    /* Create module object. */
#if PY_MAJOR_VERSION < 3
    PyObject* module = Py_InitModule3("_tds", s_tds_methods, s_tds_doc);
    Py_XINCREF(module); /* Py_InitModule3 returns a borrowed reference */
#else /* if PY_MAJOR_VERSION < 3 */
    static struct PyModuleDef moduledef =
    {
        PyModuleDef_HEAD_INIT,
        "_tds",        /* m_name */
        s_tds_doc,     /* m_doc */
        -1,            /* m_size */
        s_tds_methods, /* m_methods */
        NULL,          /* m_slots */
        NULL,          /* m_traverse */
        NULL,          /* m_clear */
        tds_free       /* m_free */
    };
    PyObject* module = PyModule_Create(&moduledef);
#endif /* else if PY_MAJOR_VERSION < 3 */

    if (!module) FAIL_MODULE_INIT;

    /***** Define module-level constants. *****/

    /**
       https://www.python.org/dev/peps/pep-0249/#threadsafety
    */
    if (0 != PyModule_AddIntConstant(module, "threadsafety", 1)) FAIL_MODULE_INIT;

    /**
       https://www.python.org/dev/peps/pep-0249/#apilevel
    */
    if (0 != PyModule_AddStringConstant(module, "apilevel", "2.0")) FAIL_MODULE_INIT;

    /**
       https://www.python.org/dev/peps/pep-0249/#pyformat
    */
    if (0 != PyModule_AddStringConstant(module, "paramstyle", "numeric")) FAIL_MODULE_INIT;

    if (0 != PyModule_AddIntMacro(module, TDSCHAR)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSVARCHAR)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSTEXT)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSBIT)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSBITN)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSINTN)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSTINYINT)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSSMALLINT)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSINT)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSBIGINT)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSFLOAT)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSFLOATN)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSREAL)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSDATETIME)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSSMALLDATETIME)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSDATETIMEN)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSDATE)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSTIME)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSDATETIME2)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSIMAGE)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSSMALLMONEY)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSMONEY)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSMONEYN)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSNUMERIC)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSDECIMAL)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSBINARY)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSVARBINARY)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSGUID)) FAIL_MODULE_INIT;
    if (0 != PyModule_AddIntMacro(module, TDSVOID)) FAIL_MODULE_INIT;

    /***** Define exception types. *****/

    #define ADD_EXCEPTION_TO_MODULE(name) \
        Py_INCREF(PyExc_tds_##name); /* add ref for module to steal (global variable owns existing ref) */ \
        PyModule_AddObject(module, #name, PyExc_tds_##name);

#if PY_MAJOR_VERSION >= 3
#  define PyExc_StandardError PyExc_Exception
#endif

    /**
       https://www.python.org/dev/peps/pep-0249/#warning
    */
    static const char s_tds_Warning_doc[] =
        "Warning\n"
        "\n"
        ":pep:`0249#warning`\n"
        "\n"
        "Exception raised for important warnings like data truncations while\n"
        "inserting, etc.\n";
    if (!(PyExc_tds_Warning = PyErr_NewExceptionWithDoc_("_tds.Warning", s_tds_Warning_doc, PyExc_StandardError, NULL))) FAIL_MODULE_INIT;
    ADD_EXCEPTION_TO_MODULE(Warning);

    /**
       https://www.python.org/dev/peps/pep-0249/#error
    */
    static const char s_tds_Error_doc[] =
        "Error\n"
        "\n"
        ":pep:`0249#error`\n"
        "\n"
        "Exception that is the base class of all other error exceptions. You\n"
        "can use this to catch all errors with one single except statement.\n";
    if (!(PyExc_tds_Error = PyErr_NewExceptionWithDoc_("_tds.Error", s_tds_Error_doc, PyExc_StandardError, NULL))) FAIL_MODULE_INIT;
    ADD_EXCEPTION_TO_MODULE(Error);

    /**
       https://www.python.org/dev/peps/pep-0249/#interfaceerror
    */
    static const char s_tds_InterfaceError_doc[] =
        "InterfaceError\n"
        "\n"
        ":pep:`0249#interfaceerror`\n"
        "\n"
        "Exception raised for errors that are related to the database interface\n"
        "rather than the database itself.\n";
    if (!(PyExc_tds_InterfaceError = PyErr_NewExceptionWithDoc_("_tds.InterfaceError", s_tds_InterfaceError_doc, PyExc_tds_Error, NULL))) FAIL_MODULE_INIT;
    ADD_EXCEPTION_TO_MODULE(InterfaceError);

    /**
       https://www.python.org/dev/peps/pep-0249/#databaseerror
    */
    static const char s_tds_DatabaseError_doc[] =
        "DatabaseError\n"
        "\n"
        ":pep:`0249#databaseerror`\n"
        "\n"
        "Exception raised for errors that are related to the database.\n";
    if (!(PyExc_tds_DatabaseError = PyErr_NewExceptionWithDoc_("_tds.DatabaseError", s_tds_DatabaseError_doc, PyExc_tds_Error, NULL))) FAIL_MODULE_INIT;
    ADD_EXCEPTION_TO_MODULE(DatabaseError);

    /**
       https://www.python.org/dev/peps/pep-0249/#dataerror
    */
    static const char s_tds_DataError_doc[] =
        "DataError\n"
        "\n"
        ":pep:`0249#dataerror`\n"
        "\n"
        "Exception raised for errors that are due to problems with the\n"
        "processed data like division by zero, numeric value out of range,\n"
        "etc.\n";
    if (!(PyExc_tds_DataError = PyErr_NewExceptionWithDoc_("_tds.DataError", s_tds_DataError_doc, PyExc_tds_DatabaseError, NULL))) FAIL_MODULE_INIT;
    ADD_EXCEPTION_TO_MODULE(DataError);

    /**
       https://www.python.org/dev/peps/pep-0249/#operationalerror
    */
    static const char s_tds_OperationalError_doc[] =
        "OperationalError\n"
        "\n"
        ":pep:`0249#operationalerror`\n"
        "\n"
        "Exception raised for errors that are related to the database's\n"
        "operation and not necessarily under the control of the programmer,\n"
        "e.g. an unexpected disconnect occurs, the data source name is not\n"
        "found, a transaction could not be processed, a memory allocation\n"
        "error occurred during processing, etc.\n";
    if (!(PyExc_tds_OperationalError = PyErr_NewExceptionWithDoc_("_tds.OperationalError", s_tds_OperationalError_doc, PyExc_tds_DatabaseError, NULL))) FAIL_MODULE_INIT;
    ADD_EXCEPTION_TO_MODULE(OperationalError);

    /**
       https://www.python.org/dev/peps/pep-0249/#integrityerror
    */
    static const char s_tds_IntegrityError_doc[] =
        "IntegrityError\n"
        "\n"
        ":pep:`0249#integrityerror`\n"
        "\n"
        "Exception raised when the relational integrity of the database is\n"
        "affected, e.g. a foreign key check fails.\n";
    if (!(PyExc_tds_IntegrityError = PyErr_NewExceptionWithDoc_("_tds.IntegrityError", s_tds_IntegrityError_doc, PyExc_tds_DatabaseError, NULL))) FAIL_MODULE_INIT;
    ADD_EXCEPTION_TO_MODULE(IntegrityError);

    /**
       https://www.python.org/dev/peps/pep-0249/#internalerror
    */
    static const char s_tds_InternalError_doc[] =
        "InternalError\n"
        "\n"
        ":pep:`0249#internalerror`\n"
        "\n"
        "Exception raised when the database encounters an internal error,\n"
        "e.g. the cursor is not valid anymore, the transaction is out of\n"
        "sync, etc.\n";
    if (!(PyExc_tds_InternalError = PyErr_NewExceptionWithDoc_("_tds.InternalError", s_tds_InternalError_doc, PyExc_tds_DatabaseError, NULL))) FAIL_MODULE_INIT;
    ADD_EXCEPTION_TO_MODULE(InternalError);

    /**
       https://www.python.org/dev/peps/pep-0249/#programmingerror
    */
    static const char s_tds_ProgrammingError_doc[] =
        "ProgrammingError\n"
        "\n"
        ":pep:`0249#programmingerror`\n"
        "\n"
        "Exception raised for programming errors, e.g. table not found or\n"
        "already exists, syntax error in the SQL statement, wrong number of\n"
        "parameters specified, etc.\n";
    if (!(PyExc_tds_ProgrammingError = PyErr_NewExceptionWithDoc_("_tds.ProgrammingError", s_tds_ProgrammingError_doc, PyExc_tds_DatabaseError, NULL))) FAIL_MODULE_INIT;
    ADD_EXCEPTION_TO_MODULE(ProgrammingError);

    /**
       https://www.python.org/dev/peps/pep-0249/#notsupportederror
    */
    static const char s_tds_NotSupportedError_doc[] =
        "NotSupportedError\n"
        "\n"
        ":pep:`0249#notsupportederror`\n"
        "\n"
        "Exception raised in case a method or database API was used which is\n"
        "not supported by the database, e.g. requesting a .rollback() on a\n"
        "connection that does not support transaction or has transactions\n"
        "turned off.\n";
    if (!(PyExc_tds_NotSupportedError = PyErr_NewExceptionWithDoc_("_tds.NotSupportedError", s_tds_NotSupportedError_doc, PyExc_tds_DatabaseError, NULL))) FAIL_MODULE_INIT;
    ADD_EXCEPTION_TO_MODULE(NotSupportedError);

    /***** Define custom types. *****/

    if (0 != PyModule_AddObject(module, "Connection", (PyObject*)ConnectionType_init())) FAIL_MODULE_INIT;
    if (0 != PyModule_AddObject(module, "Cursor", (PyObject*)CursorType_init())) FAIL_MODULE_INIT;
    if (0 != PyModule_AddObject(module, "Parameter", (PyObject*)ParameterType_init())) FAIL_MODULE_INIT;

    if (0 != SqlTypes_init()) FAIL_MODULE_INIT;

    /* Add SQL type wrappers (in alphabetical order). */
#define SQL_TYPE_INIT(_type) \
        if (0 != PyModule_AddObject(module, "Sql" #_type, (PyObject*)Sql ## _type ## Type_init())) FAIL_MODULE_INIT

    /* Note: types added here must be added to __init__.py */
    SQL_TYPE_INIT(BigInt);
    SQL_TYPE_INIT(Binary);
    SQL_TYPE_INIT(Char);
    SQL_TYPE_INIT(Date);
    SQL_TYPE_INIT(Decimal);
    SQL_TYPE_INIT(Int);
    SQL_TYPE_INIT(SmallInt);
    SQL_TYPE_INIT(TinyInt);
    SQL_TYPE_INIT(VarBinary);
    SQL_TYPE_INIT(VarChar);

    /***** Import datetime module *****/
    if (!PyDateTimeType_init()) FAIL_MODULE_INIT;

    /***** Import decimal type. *****/
    if (!PyDecimalType_init()) FAIL_MODULE_INIT;

    /***** Import uuid type. *****/
    if (!PyUuidType_init()) FAIL_MODULE_INIT;

    /***** Library version *****/
    if (!(version_info = PyTuple_New(3))) FAIL_MODULE_INIT;
    PyTuple_SET_ITEM(version_info, 0, PyLong_FromLong(CTDS_MAJOR_VERSION));
    PyTuple_SET_ITEM(version_info, 1, PyLong_FromLong(CTDS_MINOR_VERSION));
    PyTuple_SET_ITEM(version_info, 2, PyLong_FromLong(CTDS_PATCH_VERSION));

    if (0 != PyModule_AddObject(module, "version_info", version_info)) FAIL_MODULE_INIT;
    Py_INCREF(version_info);

    /***** Initialize DB-lib. *****/

    /*
        FreeTDS version.

        Use the CT-library API since older versions of FreeTDS don't return
        a proper version string from dbversion()
    */
    char freetds_version[100];
    int written;
    (void)ct_config(NULL, CS_GET, CS_VERSION, freetds_version, sizeof(freetds_version), &written);
    if (0 != PyModule_AddStringConstant(module, "freetds_version", freetds_version)) FAIL_MODULE_INIT;

    if (FAIL == dbinit()) FAIL_MODULE_INIT;
    dberrhandle(Connection_dberrhandler);
    dbmsghandle(Connection_dbmsghandler);

#if PY_MAJOR_VERSION >= 3
    return module;
#endif /* if PY_MAJOR_VERSION >= 3 */
}