Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/boto/sdb/db/sequence.py @ 0:26e78fe6e8c4 draft
"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author | shellac |
---|---|
date | Sat, 02 May 2020 07:14:21 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:26e78fe6e8c4 |
---|---|
1 # Copyright (c) 2010 Chris Moyer http://coredumped.org/ | |
2 # | |
3 # Permission is hereby granted, free of charge, to any person obtaining a | |
4 # copy of this software and associated documentation files (the | |
5 # "Software"), to deal in the Software without restriction, including | |
6 # without limitation the rights to use, copy, modify, merge, publish, dis- | |
7 # tribute, sublicense, and/or sell copies of the Software, and to permit | |
8 # persons to whom the Software is furnished to do so, subject to the fol- | |
9 # lowing conditions: | |
10 # | |
11 # The above copyright notice and this permission notice shall be included | |
12 # in all copies or substantial portions of the Software. | |
13 # | |
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
15 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- | |
16 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | |
17 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
18 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
20 # IN THE SOFTWARE. | |
21 | |
22 from boto.exception import SDBResponseError | |
23 from boto.compat import six | |
24 | |
25 class SequenceGenerator(object): | |
26 """Generic Sequence Generator object, this takes a single | |
27 string as the "sequence" and uses that to figure out | |
28 what the next value in a string is. For example | |
29 if you give "ABC" and pass in "A" it will give you "B", | |
30 and if you give it "C" it will give you "AA". | |
31 | |
32 If you set "rollover" to True in the above example, passing | |
33 in "C" would give you "A" again. | |
34 | |
35 The Sequence string can be a string or any iterable | |
36 that has the "index" function and is indexable. | |
37 """ | |
38 __name__ = "SequenceGenerator" | |
39 | |
40 def __init__(self, sequence_string, rollover=False): | |
41 """Create a new SequenceGenerator using the sequence_string | |
42 as how to generate the next item. | |
43 | |
44 :param sequence_string: The string or list that explains | |
45 how to generate the next item in the sequence | |
46 :type sequence_string: str,iterable | |
47 | |
48 :param rollover: Rollover instead of incrementing when | |
49 we hit the end of the sequence | |
50 :type rollover: bool | |
51 """ | |
52 self.sequence_string = sequence_string | |
53 self.sequence_length = len(sequence_string[0]) | |
54 self.rollover = rollover | |
55 self.last_item = sequence_string[-1] | |
56 self.__name__ = "%s('%s')" % (self.__class__.__name__, sequence_string) | |
57 | |
58 def __call__(self, val, last=None): | |
59 """Get the next value in the sequence""" | |
60 # If they pass us in a string that's not at least | |
61 # the lenght of our sequence, then return the | |
62 # first element in our sequence | |
63 if val is None or len(val) < self.sequence_length: | |
64 return self.sequence_string[0] | |
65 last_value = val[-self.sequence_length:] | |
66 if (not self.rollover) and (last_value == self.last_item): | |
67 val = "%s%s" % (self(val[:-self.sequence_length]), self._inc(last_value)) | |
68 else: | |
69 val = "%s%s" % (val[:-self.sequence_length], self._inc(last_value)) | |
70 return val | |
71 | |
72 def _inc(self, val): | |
73 """Increment a single value""" | |
74 assert(len(val) == self.sequence_length) | |
75 return self.sequence_string[(self.sequence_string.index(val) + 1) % len(self.sequence_string)] | |
76 | |
77 | |
78 # | |
79 # Simple Sequence Functions | |
80 # | |
81 def increment_by_one(cv=None, lv=None): | |
82 if cv is None: | |
83 return 0 | |
84 return cv + 1 | |
85 | |
86 def double(cv=None, lv=None): | |
87 if cv is None: | |
88 return 1 | |
89 return cv * 2 | |
90 | |
91 def fib(cv=1, lv=0): | |
92 """The fibonacci sequence, this incrementer uses the | |
93 last value""" | |
94 if cv is None: | |
95 cv = 1 | |
96 if lv is None: | |
97 lv = 0 | |
98 return cv + lv | |
99 | |
100 increment_string = SequenceGenerator("ABCDEFGHIJKLMNOPQRSTUVWXYZ") | |
101 | |
102 | |
103 class Sequence(object): | |
104 """A simple Sequence using the new SDB "Consistent" features | |
105 Based largly off of the "Counter" example from mitch garnaat: | |
106 http://bitbucket.org/mitch/stupidbototricks/src/tip/counter.py""" | |
107 | |
108 def __init__(self, id=None, domain_name=None, fnc=increment_by_one, init_val=None): | |
109 """Create a new Sequence, using an optional function to | |
110 increment to the next number, by default we just increment by one. | |
111 Every parameter here is optional, if you don't specify any options | |
112 then you'll get a new SequenceGenerator with a random ID stored in the | |
113 default domain that increments by one and uses the default botoweb | |
114 environment | |
115 | |
116 :param id: Optional ID (name) for this counter | |
117 :type id: str | |
118 | |
119 :param domain_name: Optional domain name to use, by default we get this out of the | |
120 environment configuration | |
121 :type domain_name:str | |
122 | |
123 :param fnc: Optional function to use for the incrementation, by default we just increment by one | |
124 There are several functions defined in this module. | |
125 Your function must accept "None" to get the initial value | |
126 :type fnc: function, str | |
127 | |
128 :param init_val: Initial value, by default this is the first element in your sequence, | |
129 but you can pass in any value, even a string if you pass in a function that uses | |
130 strings instead of ints to increment | |
131 """ | |
132 self._db = None | |
133 self._value = None | |
134 self.last_value = None | |
135 self.domain_name = domain_name | |
136 self.id = id | |
137 if init_val is None: | |
138 init_val = fnc(init_val) | |
139 | |
140 if self.id is None: | |
141 import uuid | |
142 self.id = str(uuid.uuid4()) | |
143 | |
144 self.item_type = type(fnc(None)) | |
145 self.timestamp = None | |
146 # Allow us to pass in a full name to a function | |
147 if isinstance(fnc, six.string_types): | |
148 from boto.utils import find_class | |
149 fnc = find_class(fnc) | |
150 self.fnc = fnc | |
151 | |
152 # Bootstrap the value last | |
153 if not self.val: | |
154 self.val = init_val | |
155 | |
156 def set(self, val): | |
157 """Set the value""" | |
158 import time | |
159 now = time.time() | |
160 expected_value = [] | |
161 new_val = {} | |
162 new_val['timestamp'] = now | |
163 if self._value is not None: | |
164 new_val['last_value'] = self._value | |
165 expected_value = ['current_value', str(self._value)] | |
166 new_val['current_value'] = val | |
167 try: | |
168 self.db.put_attributes(self.id, new_val, expected_value=expected_value) | |
169 self.timestamp = new_val['timestamp'] | |
170 except SDBResponseError as e: | |
171 if e.status == 409: | |
172 raise ValueError("Sequence out of sync") | |
173 else: | |
174 raise | |
175 | |
176 | |
177 def get(self): | |
178 """Get the value""" | |
179 val = self.db.get_attributes(self.id, consistent_read=True) | |
180 if val: | |
181 if 'timestamp' in val: | |
182 self.timestamp = val['timestamp'] | |
183 if 'current_value' in val: | |
184 self._value = self.item_type(val['current_value']) | |
185 if "last_value" in val and val['last_value'] is not None: | |
186 self.last_value = self.item_type(val['last_value']) | |
187 return self._value | |
188 | |
189 val = property(get, set) | |
190 | |
191 def __repr__(self): | |
192 return "%s('%s', '%s', '%s.%s', '%s')" % ( | |
193 self.__class__.__name__, | |
194 self.id, | |
195 self.domain_name, | |
196 self.fnc.__module__, self.fnc.__name__, | |
197 self.val) | |
198 | |
199 | |
200 def _connect(self): | |
201 """Connect to our domain""" | |
202 if not self._db: | |
203 import boto | |
204 sdb = boto.connect_sdb() | |
205 if not self.domain_name: | |
206 self.domain_name = boto.config.get("DB", "sequence_db", boto.config.get("DB", "db_name", "default")) | |
207 try: | |
208 self._db = sdb.get_domain(self.domain_name) | |
209 except SDBResponseError as e: | |
210 if e.status == 400: | |
211 self._db = sdb.create_domain(self.domain_name) | |
212 else: | |
213 raise | |
214 return self._db | |
215 | |
216 db = property(_connect) | |
217 | |
218 def next(self): | |
219 self.val = self.fnc(self.val, self.last_value) | |
220 return self.val | |
221 | |
222 def delete(self): | |
223 """Remove this sequence""" | |
224 self.db.delete_attributes(self.id) |