ϪfA~dZddlmZddlmZmZGddeZGddZGdd Z Gd d Z d d gZ y ) zg An asynchronous mapping to U{DB-API 2.0}. )threads)logreflectceZdZdZy)ConnectionLostzb This exception means that a db connection has been lost. Client code may try again. N)__name__ __module__ __qualname____doc__;/usr/lib/python3/dist-packages/twisted/enterprise/adbapi.pyrrsr rc.eZdZdZdZdZdZdZdZy) 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. c@||_d|_|jyN)_pool _connection reconnect)selfpools r__init__zConnection.__init__s  r cyrr rs rclosezConnection.close$s r cl|jjs|jjy |jj|jj }|j |jj |j|jjy#t$rtjddYnwxYw|jj|j|jjrtjdt)NRollback failedzConnection lost.)rrrrollbackcursorexecutegood_sqlrcommit BaseExceptionrerr disconnectnoisymsgr)rcurss rrzConnection.rollback.szz##    % % '  -    % % '##**,D LL,, - JJL    # # %  - GGD+ , - d../ ::   GG& 'sBB77CCc|j%|jj|j|jj|_yr)rrr%connectrs rrzConnection.reconnectDs;    ' JJ ! !$"2"2 3::--/r c.t|j|Sr)getattrrrnames r __getattr__zConnection.__getattr__Ist''..r N) rr r r rrrrr/r r rrrs   ,0 /r rc2eZdZdZdZdZdZdZdZdZ y) 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. Nc@||_||_|jyr)rrreopen)rr connections rrzTransaction.__init__Ys % r cJ|j}d|_|jyr)_cursorr)rr6s rrzTransaction.close^s,,  r c|j|j |jj|_y#t$r0|j j stjddYnwxYw|j jrtjd|j |jj|_y)NzCursor creation failedzConnection lost, reconnecting) r6rrrr#rrrr$r&r'rs rr3zTransaction.reopencs << # JJL 8++224DL  8::''67  8 ::   GG3 4 ''..0 s>6A76A7cF|jjd|_yr)rrr6rs rrzTransaction.reconnectvs ""$ r c.t|j|Sr)r,r6r-s rr/zTransaction.__getattr__zst||T**r ) rr r r r6rrr3rr/r r rr1r1Ms'G  1&+r r1ceZdZdZdj ZdZdZdZdZ dZ dZ dZ dZ eZeZdZdZd Zd Zd Zd Zd ZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#dZ$y)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:||_tj||_t |jdddk7rt j dt |jdddkrt j d|jd d}|dd lm }||_ ||_ ||_ |jD]}d |}||vs t||||||=!t|j|j |_t!|j|j |_i|_dd lm}m}|j*|_|j/|j|j |_|jj1|j2|_y) 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.internetrC_reactorconnargsconnkwCP_ARGSsetattrminmax connectionstwisted.pythonrErF getThreadIDthreadID ThreadPoolcallWhenRunning_startstartID) rrGrMrNrCargcpArgrErFs rrzConnectionPool.__init__sKF#((3 4::z4 0E 9 GG= > 4::~q 1A 5 GGA B**\40 ? 0    << "C#KEc6%=15M  " txx*txx* :".. $//$((C}}44T[[A r c0d|_|jSr)rZstartrs rrYzConnectionPool._starts zz|r c|jsN|jj|jj dd|j |_d|_yy)z Start the connection pool. If you are using the reactor normally, this function does *not* need to be called. duringshutdownTN)runningrFr^rLaddSystemEventTrigger finalClose shutdownIDrs rr^zConnectionPool.startsJ|| OO ! ! #"mmAA*dooDO DL r cvtj|j|j|j|g|i|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}. )rdeferToThreadPoolrLrF_runWithConnection)rfuncargskws rrunWithConnectionz ConnectionPool.runWithConnections>,(( MM4??D,C,CT LP TV  r c|j|} ||g|i|}|j|S#t$r8 |j#t$rt j ddYwxYwwxYwNr)connectionFactoryr"r#rrr$)rrirjrkconnresults rrhz!ConnectionPool._runWithConnections~%%d+ $,,,F KKMM  1  ! 1/0  1 s,1 A2A  A2 A.+A2-A..A2cvtj|j|j|j|g|i|S)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}. )rrgrLrF_runInteraction)r interactionrjrks rrunInteractionzConnectionPool.runInteraction$sE8(( MM OO         r cB|j|jg|i|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}. )ru _runQueryrrjrks rrunQueryzConnectionPool.runQueryIs%$#t""4>>?D?B??r cB|j|jg|i|S)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}. )ru _runOperationrxs r runOperationzConnectionPool.runOperation]s'&#t""4#5#5CCCCr c|jr,|jj|jd|_|jr,|jj|jd|_|j y)zC Close all pool connections and shutdown the pool. N)rerLremoveSystemEventTriggerrZrdrs rrzConnectionPool.closersV ?? MM 2 24?? C"DO << MM 2 24<< @DL r cd|_|jjd|_|jj D]}|j ||jjy)zE This should only be called by the shutdown trigger. NF)rerFstoprbrSvalues_closeclearrrps rrdzConnectionPool.finalClose~s^  $$++- D KK    r ct|j}|jj|}||jr"t j d|j |jj|ji|j}|j|j|||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. zadbapi connecting: ) rVrSgetr&rr'rGrIr*rMrNopenfun)rtidrps rr*zConnectionPool.connectsmmo##C( <zz-dnn-=>?%4::%%t}}D DD||' T"$(D  S ! r c|j}||jj|ur td||j ||j|=yy)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)rVrSr Exceptionr)rrprs rr%zConnectionPool.disconnectsYmmo t''++C0 09: :   KK   % r c|jr"tjd|j |j y#t $rtj ddYywxYw)Nzadbapi closing: zConnection close failed)r&rr'rGrr#r$rs rrzConnectionPool._closesN :: GG&t~~&67 8 5 JJL 5 GGD3 4 5sAA#"A#c.|j|}|j||} ||g|i|}|j|j|S#t$r8 |j #t$rt jddYwxYwwxYwrn)rotransactionFactoryrr"r#rrr$)rrtrjrkrptransrqs rrszConnectionPool._runInteractions%%d+''d3  444F KKM KKMM  1  ! 1/0  1 s/-A BA.-B.B BBBcF|j|i||jSr)r fetchallrrrjrks rrwzConnectionPool._runQuerys" t"r"~~r c(|j|i|yr)r rs rr{zConnectionPool._runOperations t"r"r c |j|j|j|j|j|j |j |jdS)NrGrQrRr&rr!rMrNrrs r __getstate__zConnectionPool.__getstate__sD8888ZZ  kk  r cz||_|j|jg|ji|jyr)__dict__rrGrMrN)rstates r __setstate__zConnectionPool.__setstate__s-  dnnDt}}D Dr )%rr r r splitrOr&rQrRr.rrr!rbrror1rrerrYr^rlrhruryr|rrdr*r%rrsrwr{rrr r rr;r;~s&>CCEG E C C DGIHG"$JEBN   4 # J@(D*  !. &5  #  Er r;N) r rKrrTrrrrrr1r;__all__r r rrsP  %'Y4/4/n.+.+b]E]E@ * +r