dbapi.py
branchstable
changeset 5859 3da3574fe397
parent 5813 0b250d72fcfa
child 5863 4495b9bc49df
equal deleted inserted replaced
5857:1a24c62aefc5 5859:3da3574fe397
   441         if eid_key is not None:
   441         if eid_key is not None:
   442             warn('[3.8] eid_key is deprecated, you can safely remove this argument',
   442             warn('[3.8] eid_key is deprecated, you can safely remove this argument',
   443                  DeprecationWarning, stacklevel=2)
   443                  DeprecationWarning, stacklevel=2)
   444         # XXX use named argument for build_descr in case repo is < 3.8
   444         # XXX use named argument for build_descr in case repo is < 3.8
   445         rset = self._repo.execute(self._sessid, rql, args,
   445         rset = self._repo.execute(self._sessid, rql, args,
   446                                   build_descr=build_descr, txid=self._txid())
   446                                   build_descr=build_descr, **self._txid())
   447         rset.req = self.req
   447         rset.req = self.req
   448         return rset
   448         return rset
   449 
   449 
   450 
   450 
   451 class LogCursor(Cursor):
   451 class LogCursor(Cursor):
   480         self._close_on_del = getattr(cnxprops, 'close_on_del', True)
   480         self._close_on_del = getattr(cnxprops, 'close_on_del', True)
   481         self._cnxtype = getattr(cnxprops, 'cnxtype', 'pyro')
   481         self._cnxtype = getattr(cnxprops, 'cnxtype', 'pyro')
   482         if cnxprops and cnxprops.log_queries:
   482         if cnxprops and cnxprops.log_queries:
   483             self.executed_queries = []
   483             self.executed_queries = []
   484             self.cursor_class = LogCursor
   484             self.cursor_class = LogCursor
       
   485         if self._cnxtype == 'pyro':
       
   486             # check client/server compat
       
   487             if self._repo.get_versions()['cubicweb'] < (3, 8, 6):
       
   488                 self._txid = lambda cursor=None: {}
   485 
   489 
   486     def __repr__(self):
   490     def __repr__(self):
   487         if self.anonymous_connection:
   491         if self.anonymous_connection:
   488             return '<Connection %s (anonymous)>' % self.sessionid
   492             return '<Connection %s (anonymous)>' % self.sessionid
   489         return '<Connection %s>' % self.sessionid
   493         return '<Connection %s>' % self.sessionid
   497         else:
   501         else:
   498             self.rollback()
   502             self.rollback()
   499             return False #propagate the exception
   503             return False #propagate the exception
   500 
   504 
   501     def _txid(self, cursor=None): # XXX could now handle various isolation level!
   505     def _txid(self, cursor=None): # XXX could now handle various isolation level!
   502         return currentThread().getName()
   506         # return a dict as bw compat trick
       
   507         return {'txid': currentThread().getName()}
   503 
   508 
   504     def request(self):
   509     def request(self):
   505         return DBAPIRequest(self.vreg, DBAPISession(self))
   510         return DBAPIRequest(self.vreg, DBAPISession(self))
   506 
   511 
   507     def check(self):
   512     def check(self):
   634                 pass
   639                 pass
   635 
   640 
   636     def describe(self, eid):
   641     def describe(self, eid):
   637         if self._closed is not None:
   642         if self._closed is not None:
   638             raise ProgrammingError('Closed connection')
   643             raise ProgrammingError('Closed connection')
   639         return self._repo.describe(self.sessionid, eid, txid=self._txid())
   644         return self._repo.describe(self.sessionid, eid, **self._txid())
   640 
   645 
   641     def close(self):
   646     def close(self):
   642         """Close the connection now (rather than whenever __del__ is called).
   647         """Close the connection now (rather than whenever __del__ is called).
   643 
   648 
   644         The connection will be unusable from this point forward; an Error (or
   649         The connection will be unusable from this point forward; an Error (or
   647         connection.  Note that closing a connection without committing the
   652         connection.  Note that closing a connection without committing the
   648         changes first will cause an implicit rollback to be performed.
   653         changes first will cause an implicit rollback to be performed.
   649         """
   654         """
   650         if self._closed:
   655         if self._closed:
   651             raise ProgrammingError('Connection is already closed')
   656             raise ProgrammingError('Connection is already closed')
   652         self._repo.close(self.sessionid, txid=self._txid())
   657         self._repo.close(self.sessionid, **self._txid())
   653         del self._repo # necessary for proper garbage collection
   658         del self._repo # necessary for proper garbage collection
   654         self._closed = 1
   659         self._closed = 1
   655 
   660 
   656     def commit(self):
   661     def commit(self):
   657         """Commit pending transaction for this connection to the repository.
   662         """Commit pending transaction for this connection to the repository.
   661 
   666 
   662         If the transaction is undoable, a transaction id will be returned.
   667         If the transaction is undoable, a transaction id will be returned.
   663         """
   668         """
   664         if not self._closed is None:
   669         if not self._closed is None:
   665             raise ProgrammingError('Connection is already closed')
   670             raise ProgrammingError('Connection is already closed')
   666         return self._repo.commit(self.sessionid, txid=self._txid())
   671         return self._repo.commit(self.sessionid, **self._txid())
   667 
   672 
   668     def rollback(self):
   673     def rollback(self):
   669         """This method is optional since not all databases provide transaction
   674         """This method is optional since not all databases provide transaction
   670         support.
   675         support.
   671 
   676 
   674         a connection without committing the changes first will cause an implicit
   679         a connection without committing the changes first will cause an implicit
   675         rollback to be performed.
   680         rollback to be performed.
   676         """
   681         """
   677         if not self._closed is None:
   682         if not self._closed is None:
   678             raise ProgrammingError('Connection is already closed')
   683             raise ProgrammingError('Connection is already closed')
   679         self._repo.rollback(self.sessionid, txid=self._txid())
   684         self._repo.rollback(self.sessionid, **self._txid())
   680 
   685 
   681     def cursor(self, req=None):
   686     def cursor(self, req=None):
   682         """Return a new Cursor Object using the connection.
   687         """Return a new Cursor Object using the connection.
   683 
   688 
   684         On pyro connection, you should get cursor after calling if
   689         On pyro connection, you should get cursor after calling if
   714 
   719 
   715         * `public`: when additional filtering is provided, their are by default
   720         * `public`: when additional filtering is provided, their are by default
   716           only searched in 'public' actions, unless a `public` argument is given
   721           only searched in 'public' actions, unless a `public` argument is given
   717           and set to false.
   722           and set to false.
   718         """
   723         """
       
   724         actionfilters.update(self._txid())
   719         txinfos = self._repo.undoable_transactions(self.sessionid, ueid,
   725         txinfos = self._repo.undoable_transactions(self.sessionid, ueid,
   720                                                    txid=self._txid(),
       
   721                                                    **actionfilters)
   726                                                    **actionfilters)
   722         if req is None:
   727         if req is None:
   723             req = self.request()
   728             req = self.request()
   724         for txinfo in txinfos:
   729         for txinfo in txinfos:
   725             txinfo.req = req
   730             txinfo.req = req
   731         raise `NoSuchTransaction` if not found or if session's user is not
   736         raise `NoSuchTransaction` if not found or if session's user is not
   732         allowed (eg not in managers group and the transaction doesn't belong to
   737         allowed (eg not in managers group and the transaction doesn't belong to
   733         him).
   738         him).
   734         """
   739         """
   735         txinfo = self._repo.transaction_info(self.sessionid, txuuid,
   740         txinfo = self._repo.transaction_info(self.sessionid, txuuid,
   736                                              txid=self._txid())
   741                                              **self._txid())
   737         if req is None:
   742         if req is None:
   738             req = self.request()
   743             req = self.request()
   739         txinfo.req = req
   744         txinfo.req = req
   740         return txinfo
   745         return txinfo
   741 
   746 
   748         raise `NoSuchTransaction` if the transaction is not found or if
   753         raise `NoSuchTransaction` if the transaction is not found or if
   749         session's user is not allowed (eg not in managers group and the
   754         session's user is not allowed (eg not in managers group and the
   750         transaction doesn't belong to him).
   755         transaction doesn't belong to him).
   751         """
   756         """
   752         return self._repo.transaction_actions(self.sessionid, txuuid, public,
   757         return self._repo.transaction_actions(self.sessionid, txuuid, public,
   753                                               txid=self._txid())
   758                                               **self._txid())
   754 
   759 
   755     def undo_transaction(self, txuuid):
   760     def undo_transaction(self, txuuid):
   756         """Undo the given transaction. Return potential restoration errors.
   761         """Undo the given transaction. Return potential restoration errors.
   757 
   762 
   758         raise `NoSuchTransaction` if not found or if session's user is not
   763         raise `NoSuchTransaction` if not found or if session's user is not
   759         allowed (eg not in managers group and the transaction doesn't belong to
   764         allowed (eg not in managers group and the transaction doesn't belong to
   760         him).
   765         him).
   761         """
   766         """
   762         return self._repo.undo_transaction(self.sessionid, txuuid,
   767         return self._repo.undo_transaction(self.sessionid, txuuid,
   763                                            txid=self._txid())
   768                                            **self._txid())