Package Gnumed :: Package timelinelib :: Package canvas :: Package data :: Module transactions
[frames] | no frames]

Source Code for Module Gnumed.timelinelib.canvas.data.transactions

  1  # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018  Rickard Lindberg, Roger Lindberg 
  2  # 
  3  # This file is part of Timeline. 
  4  # 
  5  # Timeline is free software: you can redistribute it and/or modify 
  6  # it under the terms of the GNU General Public License as published by 
  7  # the Free Software Foundation, either version 3 of the License, or 
  8  # (at your option) any later version. 
  9  # 
 10  # Timeline is distributed in the hope that it will be useful, 
 11  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13  # GNU General Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU General Public License 
 16  # along with Timeline.  If not, see <http://www.gnu.org/licenses/>. 
 17   
 18   
 19  from timelinelib.general.observer import Observable 
20 21 22 -class Transactions(Observable):
23
24 - def __init__(self, initial_value, initial_name="", history_size=10):
25 Observable.__init__(self) 26 if history_size < 1: 27 raise ValueError("history_size is to small (must be at least 1)") 28 self._history_size = history_size 29 self._history = [(initial_name, initial_value)] 30 self._current_index = 0 31 self._current_transaction = None
32 33 @property
34 - def value(self):
35 if self._current_transaction is not None: 36 return self._current_transaction.value 37 else: 38 return self._history[self._current_index][1]
39 40 @property
41 - def status(self):
42 return ( 43 self._current_index, 44 self._current_transaction is not None, 45 list(self._history) 46 )
47
48 - def clear(self):
49 self.ensure_not_in_transaction() 50 self._history = [self._history[self._current_index]] 51 self._current_index = 0 52 self._notify()
53
54 - def move(self, index):
55 self.ensure_not_in_transaction() 56 if index < 0 or index >= len(self._history): 57 raise ValueError("Index does not exist in history") 58 self._current_index = index 59 self._notify()
60
61 - def new(self, name):
62 self._current_transaction = Transaction( 63 self, 64 name, 65 self.value, 66 self._current_transaction 67 ) 68 return self._current_transaction
69
70 - def commit(self, transaction):
71 self.ensure_is_current(transaction) 72 self._current_transaction = transaction.parent 73 if self._current_transaction is None: 74 self._history = self._history[:self._current_index + 1] 75 self._history.append((transaction.name, transaction.value)) 76 self._history = self._history[-self._history_size:] 77 self._current_index = len(self._history) - 1 78 self._notify() 79 else: 80 self._current_transaction.value = transaction.value
81
82 - def rollback(self, transaction):
83 self.ensure_is_current(transaction) 84 self._current_transaction = transaction.parent
85
86 - def ensure_is_current(self, transaction):
87 if transaction is not self._current_transaction: 88 raise TransactionError( 89 "Operation on {0!r} is not allowed " 90 "because it is not the current transaction".format( 91 transaction 92 ) 93 )
94
96 if self._current_transaction is not None: 97 raise TransactionError( 98 "Operation is not allowed " 99 "because transaction {0!r} is active".format( 100 self._current_transaction 101 ) 102 )
103
104 105 -class TransactionError(Exception):
106 pass
107
108 109 -class Transaction(object):
110
111 - def __init__(self, transactions, name, value, parent):
112 self._transactions = transactions 113 self._name = name 114 self._value = value 115 self._parent = parent
116
117 - def __repr__(self):
118 return "{0}(name={1!r}, ...)".format( 119 self.__class__.__name__, 120 self._name 121 )
122 123 @property
124 - def name(self):
125 return self._name
126 127 @property
128 - def value(self):
129 return self._value
130 131 @value.setter
132 - def value(self, value):
133 self._transactions.ensure_is_current(self) 134 self._value = value
135 136 @property
137 - def updater(self):
138 return ValueUpdater(self)
139 140 @property
141 - def parent(self):
142 return self._parent
143
144 - def commit(self):
145 self._transactions.commit(self)
146
147 - def rollback(self):
148 self._transactions.rollback(self)
149
150 - def __enter__(self):
151 return self.updater
152
153 - def __exit__(self, exc_type, exc_val, exc_tb):
154 if exc_type is None: 155 self.commit() 156 else: 157 self.rollback()
158
159 160 -class ValueUpdater(object):
161
162 - def __init__(self, transaction):
163 self._transaction = transaction
164
165 - def __getattr__(self, name):
166 def updater(*args, **kwargs): 167 self._transaction.value = getattr( 168 self._transaction.value, 169 name 170 )(*args, **kwargs)
171 return updater
172