Mercurial > p > roundup > code
comparison roundup/hyperdb.py @ 8305:a81a3cd067fa
Generate savepoint only if necessary
Now some methods got an additional 'allow_abort' parameter. By default
this is True. When False the postgres backend generates a savepoint.
The methods are called with allow_abort=False from some of the cgi
methods which can produce a traceback when called with data from the
web-interface.
| author | Ralf Schlatterbeck <rsc@runtux.com> |
|---|---|
| date | Sat, 01 Mar 2025 18:55:54 +0100 |
| parents | 24549122f9b1 |
| children | 370689471a08 |
comparison
equal
deleted
inserted
replaced
| 8304:24549122f9b1 | 8305:a81a3cd067fa |
|---|---|
| 1063 def unserialise(self, classname, node): | 1063 def unserialise(self, classname, node): |
| 1064 """Decode the marshalled node data | 1064 """Decode the marshalled node data |
| 1065 """ | 1065 """ |
| 1066 return node | 1066 return node |
| 1067 | 1067 |
| 1068 def getnode(self, classname, nodeid): | 1068 def getnode(self, classname, nodeid, allow_abort=True): |
| 1069 """Get a node from the database. | 1069 """Get a node from the database. |
| 1070 | 1070 |
| 1071 'cache' exists for backwards compatibility, and is not used. | 1071 'cache' exists for backwards compatibility, and is not used. |
| 1072 'allow_abort' determines if we allow that the current | |
| 1073 transaction is aborted due to a data error (e.g. invalid nodeid). | |
| 1072 """ | 1074 """ |
| 1073 raise NotImplementedError | 1075 raise NotImplementedError |
| 1074 | 1076 |
| 1075 def hasnode(self, classname, nodeid): | 1077 def hasnode(self, classname, nodeid): |
| 1076 """Determine if the database has a given node. | 1078 """Determine if the database has a given node. |
| 1233 If an id in a link or multilink property does not refer to a valid | 1235 If an id in a link or multilink property does not refer to a valid |
| 1234 node, an IndexError is raised. | 1236 node, an IndexError is raised. |
| 1235 """ | 1237 """ |
| 1236 raise NotImplementedError | 1238 raise NotImplementedError |
| 1237 | 1239 |
| 1238 def get(self, nodeid, propname, default=_marker, cache=1): | 1240 def get(self, nodeid, propname, default=_marker, cache=1, allow_abort=True): |
| 1239 """Get the value of a property on an existing node of this class. | 1241 """Get the value of a property on an existing node of this class. |
| 1240 | 1242 |
| 1241 'nodeid' must be the id of an existing node of this class or an | 1243 'nodeid' must be the id of an existing node of this class or an |
| 1242 IndexError is raised. 'propname' must be the name of a property | 1244 IndexError is raised. 'propname' must be the name of a property |
| 1243 of this class or a KeyError is raised. | 1245 of this class or a KeyError is raised. |
| 1244 | 1246 |
| 1245 'cache' exists for backwards compatibility, and is not used. | 1247 'cache' exists for backwards compatibility, and is not used. |
| 1248 'allow_abort' determines if we allow that the current | |
| 1249 transaction is aborted due to a data error (e.g. invalid nodeid). | |
| 1246 """ | 1250 """ |
| 1247 raise NotImplementedError | 1251 raise NotImplementedError |
| 1248 | 1252 |
| 1249 # not in spec | 1253 # not in spec |
| 1250 def getnode(self, nodeid): | 1254 def getnode(self, nodeid): |
| 1298 | 1302 |
| 1299 Make node available for all operations like it was before retirement. | 1303 Make node available for all operations like it was before retirement. |
| 1300 """ | 1304 """ |
| 1301 raise NotImplementedError | 1305 raise NotImplementedError |
| 1302 | 1306 |
| 1303 def is_retired(self, nodeid): | 1307 def is_retired(self, nodeid, allow_abort=True): |
| 1304 """Return true if the node is rerired | 1308 """Return true if the node is rerired |
| 1309 'allow_abort' specifies if we allow the transaction to be | |
| 1310 aborted if a syntactically invalid nodeid is passed. | |
| 1305 """ | 1311 """ |
| 1306 raise NotImplementedError | 1312 raise NotImplementedError |
| 1307 | 1313 |
| 1308 def destroy(self, nodeid): | 1314 def destroy(self, nodeid): |
| 1309 """Destroy a node. | 1315 """Destroy a node. |
| 2180 | 2186 |
| 2181 dest = self.exportFilename(dirname, nodeid) | 2187 dest = self.exportFilename(dirname, nodeid) |
| 2182 ensureParentsExist(dest) | 2188 ensureParentsExist(dest) |
| 2183 shutil.copyfile(source, dest) | 2189 shutil.copyfile(source, dest) |
| 2184 | 2190 |
| 2185 def get(self, nodeid, propname, default=_marker, cache=1): | 2191 def get(self, nodeid, propname, default=_marker, cache=1, allow_abort=True): |
| 2186 """ Trap the content propname and get it from the file | 2192 """ Trap the content propname and get it from the file |
| 2187 | 2193 |
| 2188 'cache' exists for backwards compatibility, and is not used. | 2194 'cache' exists for backwards compatibility, and is not used. |
| 2195 | |
| 2196 'allow_abort' determines if we allow that the current | |
| 2197 transaction is aborted due to a data error (e.g. invalid nodeid). | |
| 2189 """ | 2198 """ |
| 2190 poss_msg = 'Possibly an access right configuration problem.' | 2199 poss_msg = 'Possibly an access right configuration problem.' |
| 2191 if propname == 'content': | 2200 if propname == 'content': |
| 2192 try: | 2201 try: |
| 2193 return b2s(self.db.getfile(self.classname, nodeid, None)) | 2202 return b2s(self.db.getfile(self.classname, nodeid, None)) |
| 2210 None)).hexdigest()) # nosec - bandit md5 use ok | 2219 None)).hexdigest()) # nosec - bandit md5 use ok |
| 2211 elif propname == 'binary_content': | 2220 elif propname == 'binary_content': |
| 2212 return self.db.getfile(self.classname, nodeid, None) | 2221 return self.db.getfile(self.classname, nodeid, None) |
| 2213 | 2222 |
| 2214 if default is not _marker: | 2223 if default is not _marker: |
| 2215 return self.subclass.get(self, nodeid, propname, default) | 2224 return self.subclass.get(self, nodeid, propname, default, |
| 2225 allow_abort=allow_abort) | |
| 2216 else: | 2226 else: |
| 2217 return self.subclass.get(self, nodeid, propname) | 2227 return self.subclass.get(self, nodeid, propname, |
| 2228 allow_abort=allow_abort) | |
| 2218 | 2229 |
| 2219 def import_files(self, dirname, nodeid): | 2230 def import_files(self, dirname, nodeid): |
| 2220 """ Import the "content" property as a file | 2231 """ Import the "content" property as a file |
| 2221 """ | 2232 """ |
| 2222 source = self.exportFilename(dirname, nodeid) | 2233 source = self.exportFilename(dirname, nodeid) |
