Simultaneous request

"Sebastien MICHEL" <[email protected]>
Newsgroups gmane.comp.python.sybase
Message-ID <[email protected]>

Hi,

        i've installed python-sybase 0.35 according to INSTALL file. Everything is ok, I got sybasect.so compiled.

        When I make some connections to database, everythin is right. But i'm using this module which is called as an external Method by Zope and if more than 2 connections occured on the same time, it crahsed. Any idea ?


Blow the external method :

import sys
from string import replace, strip
from sybasect import *
from sybase_errors import *

MAX_COLSIZE = 255

def init_db():
    # allocate a context
    status, ctx = cs_ctx_alloc(CS_VERSION_100)
    if status != CS_SUCCEED:
        raise Error('cs_ctx_alloc failed')
    if ctx.cs_diag(CS_INIT) != CS_SUCCEED:
        raise CSError(ctx, 'cs_diag failed')
    # initialize the library
    if ctx.ct_init(CS_VERSION_100) != CS_SUCCEED:
        raise CSError(ctx, 'ct_init failed')
    return ctx

def connect_db(ctx, server, user_name, password):
    # Allocate a connection pointer
    status, con = ctx.ct_con_alloc()
    if status != CS_SUCCEED:
        raise CSError(ctx, 'ct_con_alloc failed')
    if con.ct_diag(CS_INIT) != CS_SUCCEED:
        raise CTError(con, 'ct_diag failed')
    # Set the username and password properties
    if con.ct_con_props(CS_SET, CS_USERNAME, user_name) != CS_SUCCEED:
        raise CTError(con, 'ct_con_props CS_USERNAME failed')
    if con.ct_con_props(CS_SET, CS_PASSWORD, password) != CS_SUCCEED:
        raise CTError(con, 'ct_con_props CS_PASSWORD failed')
    # connect to the server
    if con.ct_connect(server) != CS_SUCCEED:
        raise CTError(con, 'ct_connect failed')
    return con


def bind_columns(cmd):
        status, num_cols = cmd.ct_res_info(CS_NUMDATA)
        if status != CS_SUCCEED:
                #raise CTError(cmd.con, 'ct_res_info failed')
                return bufs

        bufs = [None] * num_cols
        for i in range(num_cols):
                fmt = CS_DATAFMT()
                fmt.datatype = CS_CHAR_TYPE
                fmt.maxlength = MAX_COLSIZE
                fmt.count = 1
                fmt.format = CS_FMT_NULLTERM
                # Bind returned data to host variables
                status, buf = cmd.ct_bind(i + 1, fmt)
                if status != CS_SUCCEED:
                        return bufs
                bufs[i] = buf
        return bufs


def fetch(cmd, bufs, results):
        status, num_cols = cmd.ct_res_info(CS_NUMDATA)
        if status == CS_SUCCEED:
                # Fetch the bound data into host variables
                while 1:
                        status, rows_read = cmd.ct_fetch()
                        row = []
                        if status not in (CS_SUCCEED, CS_ROW_FAIL):
                                break
                        if status == CS_ROW_FAIL:
                                continue
                        for i in range(num_cols):
                                if bufs[i][0] == None:
                                        row.append('')
                                else:
                                        row.append(strip(replace(bufs[i][0],'\000','')))
                        results.append(row)
                if status != CS_END_DATA:
                        #raise CTError(cmd.conn, 'ct_fetch failed')
                        pass
        else:
                #raise CTError(cmd.conn, 'ct_res_info failed')
                pass

def handle_returns(cmd, retcode, outputs, rows):
        # Process all returned result types
        sql_status = CS_SUCCEED
        while 1:
                status, result = cmd.ct_results()
                if status != CS_SUCCEED:
                        break
                if result == CS_ROW_RESULT:
                        bufs = bind_columns(cmd)
                        fetch(cmd, bufs, rows)
                elif result == CS_CMD_SUCCEED:
                        pass
                elif result == CS_CMD_DONE:
                        pass
                elif result == CS_CMD_FAIL:
                        #raise CTError(cmd.conn, 'ct_results: CS_CMD_FAIL')
                        sql_status = CS_FAIL
                elif result == CS_PARAM_RESULT:
                        bufs = bind_columns(cmd)
                        fetch(cmd, bufs, outputs)
                elif result == CS_STATUS_RESULT:
                        bufs = bind_columns(cmd)
                        fetch(cmd, bufs, retcode)
                elif result == CS_COMPUTE_RESULT:
                        pass
                else:
                        break
        if status != CS_END_RESULTS:
                #raise CTError(cmd.conn, 'ct_results failed')
                return CS_FAIL
        else:
                if sql_status != CS_SUCCEED:
                        return CS_FAIL
                else:
                        return CS_SUCCEED


def cleanup_db(ctx,status):
        if status != CS_SUCCEED:
                exit_type = CS_FORCE_EXIT
        else:
                exit_type = CS_UNUSED
                # close and cleanup connection to the server
                if ctx.ct_exit(exit_type) != CS_SUCCEED:
                        raise CSError(ctx, 'ct_exit failed')
                # drop the context
                if ctx.cs_ctx_drop() != CS_SUCCEED:
                        raise CSError(ctx, 'cs_ctx_drop failed')


class SybaseSQL:
        """Execute a stored procedure on a Sybase server"""

        def __init__(self, server, user, password, sql_statement):
                self.__allow_access_to_unprotected_subobjects__ = 1
                self.retcode = []
                self.outputs = []
                self.rows = []


                # Allocate a context and initialize client-library
                ctx = init_db()

                # Allocate a command structure
                con = connect_db(ctx, server, user, password)

                # Allocate a command structure
                status, cmd = con.ct_cmd_alloc()
                if status != CS_SUCCEED:
                        raise CTError(con, 'ct_cmd_alloc failed')

                # Send the command to the server
                status = cmd.ct_command(CS_LANG_CMD, sql_statement)
                if status != CS_SUCCEED:
                        sql_error = CTError(cmd.con, 'ct_command failed')
                        cmd.ct_cmd_drop()
                        con.ct_close()
                        cleanup_db(ctx, status)
                        raise sql_error

                # Execute SQL statement on the server
                status = cmd.ct_send()
                if status != CS_SUCCEED:
                        sql_error = CTError(cmd.con, 'ct_send failed')
                        cmd.ct_cmd_drop()
                        con.ct_close()
                        cleanup_db(ctx, status)
                        raise sql_error

                # Process results from the server
                status = handle_returns(cmd, self.retcode, self.outputs, self.rows)
                if status != CS_SUCCEED:
                        cmd.ct_cmd_drop()
                        con.ct_close()
                        cleanup_db(ctx, status)
                        raise CTError(con,'handle_returns failed')

                # Drop the command structure
                status = cmd.ct_cmd_drop()
                if status != CS_SUCCEED:
                        sql_error =  CTError(con, 'ct_cmd_drop failed')
                        con.ct_close()
                        cleanup_db(ctx, status)
                        raise sql_error

                # Close the connection to the server
                status = con.ct_close()
                if status != CS_SUCCEED:
                        sql_error =  CTError(con, 'ct_close failed')
                        cleanup_db(ctx, status)
                        raise sql_error

                # Drop the context and do general cleanup
                cleanup_db(ctx, status)



        def ReturnCode(self):
                """Return the code of the procedure"""
                return self.retcode

        def Outputs(self):
                """Return the output parameters"""
                return self.outputs

        def Rows(self):
                """Return the rows"""
                return self.rows


def execSybaseSQL(server, user, password, sql_statement):
        """Init a Sybase RPC object"""
        return SybaseSQL(server, user, password, sql_statement)


if __name__ == "__main__":

        Request = execSybaseSQL("ds_teddy_uat", "michse", "smhuat01","select * from TEDDY_USERS")

        print Request.ReturnCode()

        print Request.Outputs()

        print Request.Rows()


Sebastien.

Sebastien Michel
Front Office Technology
+33 1 44 95 62 89
3, avenue de Friedland
75008 Paris


--

This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.