o bA@sfdZddlmZddlmZmZGdddeZGdddZGdd d Z Gd d d Z d d gZ d S) zg An asynchronous mapping to U{DB-API 2.0}. )threads)logreflectc@seZdZdZdS)ConnectionLostzb This exception means that a db connection has been lost. Client code may try again. N)__name__ __module__ __qualname____doc__r r ;/usr/lib/python3/dist-packages/twisted/enterprise/adbapi.pyrsrc@s8eZdZdZddZddZddZdd Zd d Zd S) Connectiona  A wrapper for a DB-API connection instance. The wrapper passes almost everything to the wrapped connection and so has the same API. However, the L{Connection} knows about its pool and also handle reconnecting should when the real connection dies. cCs||_d|_|dSN)_pool _connection reconnect)selfpoolr r r __init__ zConnection.__init__cCsdSr r rr r r close$szConnection.closecCs|jjs |jdSz|j|j}||jj||jWdSt y7t ddYnw|j |j|jj rHt dt)NRollback failedzConnection lost.)rrrrollbackcursorexecutegood_sqlrcommit BaseExceptionrerr disconnectnoisymsgr)rcursr r r r.s"      zConnection.rollbackcCs(|jdur |j|j|j|_dSr )rrrconnectrr r r rDs zConnection.reconnectcC t|j|Sr )getattrrrnamer r r __getattr__I zConnection.__getattr__N) rrrr rrrrr(r r r r r s  r c@s<eZdZdZdZddZddZddZd d Zd d Z dS) Transactiona A lightweight wrapper for a DB-API 'cursor' object. Relays attribute access to the DB cursor. That is, you can call C{execute()}, C{fetchall()}, etc., and they will be called on the underlying DB-API cursor object. Attributes will also be retrieved from there. NcCs||_||_|dSr )rrreopen)rr connectionr r r rYrzTransaction.__init__cCs|j}d|_|dSr )_cursorr)rr-r r r r^rzTransaction.closecCsx|jdur |z |j|_WdSty&|jjstddYnw|jj r0t d||j|_dS)NzCursor creation failedzConnection lost, reconnecting) r-rrrrrrrrr r!rr r r r+cs    zTransaction.reopencCs|jd|_dSr )rrr-rr r r rvs  zTransaction.reconnectcCr$r )r%r-r&r r r r(zr)zTransaction.__getattr__) rrrr r-rrr+rr(r r r r r*Ms  r*c@seZdZdZdZdZdZdZdZ dZ dZ dZ dZ eZeZdZdd Zd d Zd d ZddZddZddZddZddZddZddZddZddZd d!Zd"d#Z d$d%Z!d&d'Z"d(d)Z#d*d+Z$dS),ConnectionPoola Represent a pool of connections to a DB-API 2.0 compliant database. @ivar connectionFactory: factory for connections, default to L{Connection}. @type connectionFactory: any callable. @ivar transactionFactory: factory for transactions, default to L{Transaction}. @type transactionFactory: any callable @ivar shutdownID: L{None} or a handle on the shutdown event trigger which will be used to stop the connection pool workers when the reactor stops. @ivar _reactor: The reactor which will be used to schedule startup and shutdown events. @type _reactor: L{IReactorCore} provider z-min max name noisy openfun reconnect good_sqlFNzselect 1c Os||_t||_t|jdddkrtdt|jdddkr%td|d d}|dur5dd lm }||_ ||_ ||_ |j D]}d |}||vrWt||||||=qAt|j|j|_t|j|j|_i|_dd lm}m}|j|_||j|j|_|j |j|_dS) a Create a new L{ConnectionPool}. Any positional or keyword arguments other than those documented here are passed to the DB-API object when connecting. Use these arguments to pass database names, usernames, passwords, etc. @param dbapiName: an import string to use to obtain a DB-API compatible module (e.g. C{'pyPgSQL.PgSQL'}) @keyword cp_min: the minimum number of connections in pool (default 3) @keyword cp_max: the maximum number of connections in pool (default 5) @keyword cp_noisy: generate informational log messages during operation (default C{False}) @keyword cp_openfun: a callback invoked after every C{connect()} on the underlying DB-API object. The callback is passed a new DB-API connection object. This callback can setup per-connection state such as charset, timezone, etc. @keyword cp_reconnect: detect connections which have failed and reconnect (default C{False}). Failed connections may result in L{ConnectionLost} exceptions, which indicate the query may need to be re-sent. @keyword cp_good_sql: an sql query which should always succeed and change no state (default C{'select 1'}) @keyword cp_reactor: use this reactor instead of the global reactor (added in Twisted 10.2). @type cp_reactor: L{IReactorCore} provider apilevelNz2.0z'DB API module not DB API 2.0 compliant. threadsafetyrz+DB API module not sufficiently thread-safe. cp_reactor)reactorcp_) threadable threadpool) dbapiNamer namedModuledbapir%rr!poptwisted.internetr5_reactorconnargsconnkwCP_ARGSsetattrminmax connectionstwisted.pythonr7r8 getThreadIDthreadID ThreadPoolcallWhenRunning_startstartID) rr9r?r@r5argcpArgr7r8r r r rs2#       zConnectionPool.__init__cCsd|_|Sr )rLstartrr r r rKszConnectionPool._startcCs2|js|j|jdd|j|_d|_dSdS)z Start the connection pool. If you are using the reactor normally, this function does *not* need to be called. duringshutdownTN)runningr8rOr>addSystemEventTrigger finalClose shutdownIDrr r r rOs  zConnectionPool.startcO$tj|j|j|j|g|Ri|S)a Execute a function with a database connection and return the result. @param func: A callable object of one argument which will be executed in a thread with a connection from the pool. It will be passed as its first argument a L{Connection} instance (whose interface is mostly identical to that of a connection object for your DB-API module of choice), and its results will be returned as a L{Deferred}. If the method raises an exception the transaction will be rolled back. Otherwise, the transaction will be committed. B{Note} that this function is B{not} run in the main thread: it must be threadsafe. @param args: positional arguments to be passed to func @param kw: keyword arguments to be passed to func @return: a L{Deferred} which will fire the return value of C{func(Transaction(...), *args, **kw)}, or a L{twisted.python.failure.Failure}. )rdeferToThreadPoolr>r8_runWithConnection)rfuncargskwr r r runWithConnectionsz ConnectionPool.runWithConnectionc Osj||}z||g|Ri|}||WSty4z|Wty3tddYwwNr)connectionFactoryrrrrr)rrYrZr[connresultr r r rXs    z!ConnectionPool._runWithConnectioncOrV)a Interact with the database and return the result. The 'interaction' is a callable object which will be executed in a thread using a pooled connection. It will be passed an L{Transaction} object as an argument (whose interface is identical to that of the database cursor for your DB-API module of choice), and its results will be returned as a L{Deferred}. If running the method raises an exception, the transaction will be rolled back. If the method returns a value, the transaction will be committed. NOTE that the function you pass is *not* run in the main thread: you may have to worry about thread-safety in the function you pass to this if it tries to use non-local objects. @param interaction: a callable object whose first argument is an L{adbapi.Transaction}. @param args: additional positional arguments to be passed to interaction @param kw: keyword arguments to be passed to interaction @return: a Deferred which will fire the return value of C{interaction(Transaction(...), *args, **kw)}, or a L{twisted.python.failure.Failure}. )rrWr>r8_runInteraction)r interactionrZr[r r r runInteraction$szConnectionPool.runInteractioncO|j|jg|Ri|S)aY Execute an SQL query and return the result. A DB-API cursor which will be invoked with C{cursor.execute(*args, **kw)}. The exact nature of the arguments will depend on the specific flavor of DB-API being used, but the first argument in C{*args} be an SQL statement. The result of a subsequent C{cursor.fetchall()} will be fired to the L{Deferred} which is returned. If either the 'execute' or 'fetchall' methods raise an exception, the transaction will be rolled back and a L{twisted.python.failure.Failure} returned. The C{*args} and C{**kw} arguments will be passed to the DB-API cursor's 'execute' method. @return: a L{Deferred} which will fire the return value of a DB-API cursor's 'fetchall' method, or a L{twisted.python.failure.Failure}. )rc _runQueryrrZr[r r r runQueryIszConnectionPool.runQuerycOrd)aK Execute an SQL query and return L{None}. A DB-API cursor which will be invoked with C{cursor.execute(*args, **kw)}. The exact nature of the arguments will depend on the specific flavor of DB-API being used, but the first argument in C{*args} will be an SQL statement. This method will not attempt to fetch any results from the query and is thus suitable for C{INSERT}, C{DELETE}, and other SQL statements which do not return values. If the 'execute' method raises an exception, the transaction will be rolled back and a L{Failure} returned. The C{*args} and C{*kw} arguments will be passed to the DB-API cursor's 'execute' method. @return: a L{Deferred} which will fire with L{None} or a L{twisted.python.failure.Failure}. )rc _runOperationrfr r r runOperation]szConnectionPool.runOperationcCs@|jr |j|jd|_|jr|j|jd|_|dS)zC Close all pool connections and shutdown the pool. N)rUr>removeSystemEventTriggerrLrTrr r r rrs zConnectionPool.closecCs>d|_|jd|_|jD]}||q|jdS)zE This should only be called by the shutdown trigger. NF)rUr8stoprRrEvalues_closeclearrr_r r r rT~s   zConnectionPool.finalClosecCsl|}|j|}|dur4|jrtd|j|jj|j i|j }|j dur/| |||j|<|S)a Return a database connection when one becomes available. This method blocks and should be run in a thread from the internal threadpool. Don't call this method directly from non-threaded code. Using this method outside the external threadpool may exceed the maximum number of connections in the pool. @return: a database connection from the pool. Nzadbapi connecting: ) rHrEgetr rr!r9r;r#r?r@openfun)rtidr_r r r r#s    zConnectionPool.connectcCsB|}||j|urtd|dur|||j|=dSdS)a Disconnect a database connection associated with this pool. Note: This function should only be used by the same thread which called L{ConnectionPool.connect}. As with C{connect}, this function is not used in normal non-threaded Twisted code. zwrong connection for threadN)rHrErp Exceptionrm)rr_rrr r r rs  zConnectionPool.disconnectcCsH|jr td|jz|WdSty#tddYdSw)Nzadbapi closing: zConnection close failed)r rr!r9rrrror r r rms zConnectionPool._closec Os~||}|||}z||g|Ri|}|||WSty>z|Wty=tddYwwr])r^transactionFactoryrrrrrr)rrbrZr[r_transr`r r r ras     zConnectionPool._runInteractioncOs|j|i||Sr )rfetchallrrurZr[r r r reszConnectionPool._runQuerycOs|j|i|dSr )rrwr r r rhszConnectionPool._runOperationc Cs&|j|j|j|j|j|j|j|jdS)Nr9rCrDr rrr?r@rxrr r r __getstate__szConnectionPool.__getstate__cCs(||_|j|jg|jRi|jdSr )__dict__rr9r?r@)rstater r r __setstate__s"zConnectionPool.__setstate__)%rrrr splitrAr rCrDr'rqrrrRr r^r*rtrUrrKrOr\rXrcrgrirrTr#rrmrarerhryr|r r r r r.~s@G %   r.N) r r=rrFrrrsrr r*r.__all__r r r r s 71 b