54 return usercls |
54 return usercls |
55 |
55 |
56 def multiple_connections_unfix(): |
56 def multiple_connections_unfix(): |
57 etypescls = cwvreg.VRegistry.REGISTRY_FACTORY['etypes'] |
57 etypescls = cwvreg.VRegistry.REGISTRY_FACTORY['etypes'] |
58 etypescls.etype_class = etypescls.orig_etype_class |
58 etypescls.etype_class = etypescls.orig_etype_class |
|
59 |
59 |
60 |
60 class ConnectionProperties(object): |
61 class ConnectionProperties(object): |
61 def __init__(self, cnxtype=None, lang=None, close=True, log=False): |
62 def __init__(self, cnxtype=None, lang=None, close=True, log=False): |
62 self.cnxtype = cnxtype or 'pyro' |
63 self.cnxtype = cnxtype or 'pyro' |
63 self.lang = lang |
64 self.lang = lang |
544 self._repo.close(self.sessionid) |
545 self._repo.close(self.sessionid) |
545 del self._repo # necessary for proper garbage collection |
546 del self._repo # necessary for proper garbage collection |
546 self._closed = 1 |
547 self._closed = 1 |
547 |
548 |
548 def commit(self): |
549 def commit(self): |
549 """Commit any pending transaction to the database. Note that if the |
550 """Commit pending transaction for this connection to the repository. |
550 database supports an auto-commit feature, this must be initially off. An |
551 |
551 interface method may be provided to turn it back on. |
552 may raises `Unauthorized` or `ValidationError` if we attempted to do |
552 |
553 something we're not allowed to for security or integrity reason. |
553 Database modules that do not support transactions should implement this |
554 |
554 method with void functionality. |
555 If the transaction is undoable, a transaction id will be returned. |
555 """ |
556 """ |
556 if not self._closed is None: |
557 if not self._closed is None: |
557 raise ProgrammingError('Connection is already closed') |
558 raise ProgrammingError('Connection is already closed') |
558 self._repo.commit(self.sessionid) |
559 return self._repo.commit(self.sessionid) |
559 |
560 |
560 def rollback(self): |
561 def rollback(self): |
561 """This method is optional since not all databases provide transaction |
562 """This method is optional since not all databases provide transaction |
562 support. |
563 support. |
563 |
564 |
579 if self._closed is not None: |
580 if self._closed is not None: |
580 raise ProgrammingError('Can\'t get cursor on closed connection') |
581 raise ProgrammingError('Can\'t get cursor on closed connection') |
581 if req is None: |
582 if req is None: |
582 req = self.request() |
583 req = self.request() |
583 return self.cursor_class(self, self._repo, req=req) |
584 return self.cursor_class(self, self._repo, req=req) |
|
585 |
|
586 # undo support ############################################################ |
|
587 |
|
588 def undoable_transactions(self, ueid=None, req=None, **actionfilters): |
|
589 """Return a list of undoable transaction objects by the connection's |
|
590 user, ordered by descendant transaction time. |
|
591 |
|
592 Managers may filter according to user (eid) who has done the transaction |
|
593 using the `ueid` argument. Others will only see their own transactions. |
|
594 |
|
595 Additional filtering capabilities is provided by using the following |
|
596 named arguments: |
|
597 |
|
598 * `etype` to get only transactions creating/updating/deleting entities |
|
599 of the given type |
|
600 |
|
601 * `eid` to get only transactions applied to entity of the given eid |
|
602 |
|
603 * `action` to get only transactions doing the given action (action in |
|
604 'C', 'U', 'D', 'A', 'R'). If `etype`, action can only be 'C', 'U' or |
|
605 'D'. |
|
606 |
|
607 * `public`: when additional filtering is provided, their are by default |
|
608 only searched in 'public' actions, unless a `public` argument is given |
|
609 and set to false. |
|
610 """ |
|
611 txinfos = self._repo.undoable_transactions(self.sessionid, ueid, |
|
612 **actionfilters) |
|
613 if req is None: |
|
614 req = self.request() |
|
615 for txinfo in txinfos: |
|
616 txinfo.req = req |
|
617 return txinfos |
|
618 |
|
619 def transaction_info(self, txuuid, req=None): |
|
620 """Return transaction object for the given uid. |
|
621 |
|
622 raise `NoSuchTransaction` if not found or if session's user is not |
|
623 allowed (eg not in managers group and the transaction doesn't belong to |
|
624 him). |
|
625 """ |
|
626 txinfo = self._repo.transaction_info(self.sessionid, txuuid) |
|
627 if req is None: |
|
628 req = self.request() |
|
629 txinfo.req = req |
|
630 return txinfo |
|
631 |
|
632 def transaction_actions(self, txuuid, public=True): |
|
633 """Return an ordered list of action effectued during that transaction. |
|
634 |
|
635 If public is true, return only 'public' actions, eg not ones triggered |
|
636 under the cover by hooks, else return all actions. |
|
637 |
|
638 raise `NoSuchTransaction` if the transaction is not found or if |
|
639 session's user is not allowed (eg not in managers group and the |
|
640 transaction doesn't belong to him). |
|
641 """ |
|
642 return self._repo.transaction_actions(self.sessionid, txuuid, public) |
|
643 |
|
644 def undo_transaction(self, txuuid): |
|
645 """Undo the given transaction. Return potential restoration errors. |
|
646 |
|
647 raise `NoSuchTransaction` if not found or if session's user is not |
|
648 allowed (eg not in managers group and the transaction doesn't belong to |
|
649 him). |
|
650 """ |
|
651 return self._repo.undo_transaction(self.sessionid, txuuid) |
584 |
652 |
585 |
653 |
586 # cursor object ############################################################### |
654 # cursor object ############################################################### |
587 |
655 |
588 class Cursor(object): |
656 class Cursor(object): |