|
64 | 64 |
|
65 | 65 | #---------------------------------------------------------------------- |
66 | 66 |
|
67 | | -import sys, os |
68 | | - |
69 | | -# for backwards compatibility with python versions older than 2.3, the |
70 | | -# iterator interface is dynamically defined and added using a mixin |
71 | | -# class. old python can't tokenize it due to the yield keyword. |
72 | | -if sys.version >= '2.3': |
73 | | - import UserDict |
74 | | - from weakref import ref |
75 | | - exec(""" |
| 67 | +import sys, os, UserDict |
| 68 | +from weakref import ref |
| 69 | + |
76 | 70 | class _iter_mixin(UserDict.DictMixin): |
77 | 71 | def _make_iter_cursor(self): |
78 | 72 | cur = _DeadlockWrap(self.db.cursor) |
@@ -145,10 +139,6 @@ def iteritems(self): |
145 | 139 | except _bsddb.DBCursorClosedError: |
146 | 140 | # the database was modified during iteration. abort. |
147 | 141 | return |
148 | | -""") |
149 | | -else: |
150 | | - class _iter_mixin: pass |
151 | | - |
152 | 142 |
|
153 | 143 | class _DBWithCursor(_iter_mixin): |
154 | 144 | """ |
@@ -290,6 +280,138 @@ def sync(self): |
290 | 280 | self._checkOpen() |
291 | 281 | return _DeadlockWrap(self.db.sync) |
292 | 282 |
|
| 283 | +class _ExposedProperties: |
| 284 | + @property |
| 285 | + def _cursor_refs(self): |
| 286 | + return self.db._cursor_refs |
| 287 | + |
| 288 | +class StringKeys(UserDict.DictMixin, _ExposedProperties): |
| 289 | + """Wrapper around DB object that automatically encodes |
| 290 | + all keys as UTF-8; the keys must be strings.""" |
| 291 | + |
| 292 | + def __init__(self, db): |
| 293 | + self.db = db |
| 294 | + |
| 295 | + def __len__(self): |
| 296 | + return len(self.db) |
| 297 | + |
| 298 | + def __getitem__(self, key): |
| 299 | + return self.db[key.encode("utf-8")] |
| 300 | + |
| 301 | + def __setitem__(self, key, value): |
| 302 | + self.db[key.encode("utf-8")] = value |
| 303 | + |
| 304 | + def __delitem__(self, key): |
| 305 | + del self.db[key.encode("utf-8")] |
| 306 | + |
| 307 | + def __iter__(self): |
| 308 | + for k in self.db: |
| 309 | + yield k.decode("utf-8") |
| 310 | + |
| 311 | + def close(self): |
| 312 | + self.db.close() |
| 313 | + |
| 314 | + def keys(self): |
| 315 | + for k in self.db.keys(): |
| 316 | + yield k.decode("utf-8") |
| 317 | + |
| 318 | + def has_key(self, key): |
| 319 | + return self.db.has_key(key.encode("utf-8")) |
| 320 | + |
| 321 | + __contains__ = has_key |
| 322 | + |
| 323 | + def values(self): |
| 324 | + return self.db.values() |
| 325 | + |
| 326 | + def items(self): |
| 327 | + for k,v in self.db.items(): |
| 328 | + yield k.decode("utf-8"), v |
| 329 | + |
| 330 | + def set_location(self, key): |
| 331 | + return self.db.set_location(key.encode("utf-8")) |
| 332 | + |
| 333 | + def next(self): |
| 334 | + key, value = self.db.next() |
| 335 | + return key.decode("utf-8"), value |
| 336 | + |
| 337 | + def previous(self): |
| 338 | + key, value = self.db.previous() |
| 339 | + return key.decode("utf-8"), value |
| 340 | + |
| 341 | + def first(self): |
| 342 | + key, value = self.db.first() |
| 343 | + return key.decode("utf-8"), value |
| 344 | + |
| 345 | + def last(self): |
| 346 | + key, value = self.db.last() |
| 347 | + return key.decode("utf-8"), value |
| 348 | + |
| 349 | + def sync(self): |
| 350 | + return self.db.sync() |
| 351 | + |
| 352 | +class StringValues(UserDict.DictMixin, _ExposedProperties): |
| 353 | + """Wrapper around DB object that automatically encodes |
| 354 | + all keys as UTF-8; the keys must be strings.""" |
| 355 | + |
| 356 | + def __init__(self, db): |
| 357 | + self.db = db |
| 358 | + |
| 359 | + def __len__(self): |
| 360 | + return len(self.db) |
| 361 | + |
| 362 | + def __getitem__(self, key): |
| 363 | + return self.db[key].decode("utf-8") |
| 364 | + |
| 365 | + def __setitem__(self, key, value): |
| 366 | + self.db[key] = value.encode("utf-8") |
| 367 | + |
| 368 | + def __delitem__(self, key): |
| 369 | + del self.db[key] |
| 370 | + |
| 371 | + def __iter__(self): |
| 372 | + return iter(self.db) |
| 373 | + |
| 374 | + def close(self): |
| 375 | + self.db.close() |
| 376 | + |
| 377 | + def keys(self): |
| 378 | + return self.db.keys() |
| 379 | + |
| 380 | + def has_key(self, key): |
| 381 | + return self.db.has_key(key) |
| 382 | + |
| 383 | + __contains__ = has_key |
| 384 | + |
| 385 | + def values(self): |
| 386 | + for v in self.db.values(): |
| 387 | + yield v.decode("utf-8") |
| 388 | + |
| 389 | + def items(self): |
| 390 | + for k,v in self.db.items(): |
| 391 | + yield k, v.decode("utf-8") |
| 392 | + |
| 393 | + def set_location(self, key): |
| 394 | + return self.db.set_location(key) |
| 395 | + |
| 396 | + def next(self): |
| 397 | + key, value = self.db.next() |
| 398 | + return key, value.decode("utf-8") |
| 399 | + |
| 400 | + def previous(self): |
| 401 | + key, value = self.db.previous() |
| 402 | + return key, value.decode("utf-8") |
| 403 | + |
| 404 | + def first(self): |
| 405 | + key, value = self.db.first() |
| 406 | + return key, value.decode("utf-8") |
| 407 | + |
| 408 | + def last(self): |
| 409 | + key, value = self.db.last() |
| 410 | + return key, value.decode("utf-8") |
| 411 | + |
| 412 | + def sync(self): |
| 413 | + return self.db.sync() |
| 414 | + |
293 | 415 |
|
294 | 416 | #---------------------------------------------------------------------- |
295 | 417 | # Compatibility object factory functions |
@@ -375,7 +497,7 @@ def _checkflag(flag, file): |
375 | 497 | if file is not None and os.path.isfile(file): |
376 | 498 | os.unlink(file) |
377 | 499 | else: |
378 | | - raise error, "flags should be one of 'r', 'w', 'c' or 'n'" |
| 500 | + raise error, "flags should be one of 'r', 'w', 'c' or 'n', not "+repr(flag) |
379 | 501 | return flags | db.DB_THREAD |
380 | 502 |
|
381 | 503 | #---------------------------------------------------------------------- |
|
0 commit comments