| 31 | error = OSError |
| 32 | |
| 33 | class _Database(collections.abc.MutableMapping): |
| 34 | |
| 35 | # The on-disk directory and data files can remain in mutually |
| 36 | # inconsistent states for an arbitrarily long time (see comments |
| 37 | # at the end of __setitem__). This is only repaired when _commit() |
| 38 | # gets called. One place _commit() gets called is from __del__(), |
| 39 | # and if that occurs at program shutdown time, module globals may |
| 40 | # already have gotten rebound to None. Since it's crucial that |
| 41 | # _commit() finish successfully, we can't ignore shutdown races |
| 42 | # here, and _commit() must not reference any globals. |
| 43 | _os = _os # for _commit() |
| 44 | _io = _io # for _commit() |
| 45 | |
| 46 | def __init__(self, filebasename, mode, flag='c'): |
| 47 | filebasename = self._os.fsencode(filebasename) |
| 48 | self._mode = mode |
| 49 | self._readonly = (flag == 'r') |
| 50 | |
| 51 | # The directory file is a text file. Each line looks like |
| 52 | # "%r, (%d, %d)\n" % (key, pos, siz) |
| 53 | # where key is the string key, pos is the offset into the dat |
| 54 | # file of the associated value's first byte, and siz is the number |
| 55 | # of bytes in the associated value. |
| 56 | self._dirfile = filebasename + b'.dir' |
| 57 | |
| 58 | # The data file is a binary file pointed into by the directory |
| 59 | # file, and holds the values associated with keys. Each value |
| 60 | # begins at a _BLOCKSIZE-aligned byte offset, and is a raw |
| 61 | # binary 8-bit string value. |
| 62 | self._datfile = filebasename + b'.dat' |
| 63 | self._bakfile = filebasename + b'.bak' |
| 64 | |
| 65 | # The index is an in-memory dict, mirroring the directory file. |
| 66 | self._index = None # maps keys to (pos, siz) pairs |
| 67 | |
| 68 | # Handle the creation |
| 69 | self._create(flag) |
| 70 | self._update(flag) |
| 71 | |
| 72 | def _create(self, flag): |
| 73 | if flag == 'n': |
| 74 | for filename in (self._datfile, self._bakfile, self._dirfile): |
| 75 | try: |
| 76 | _os.remove(filename) |
| 77 | except OSError: |
| 78 | pass |
| 79 | # Mod by Jack: create data file if needed |
| 80 | try: |
| 81 | f = _io.open(self._datfile, 'r', encoding="Latin-1") |
| 82 | except OSError: |
| 83 | if flag not in ('c', 'n'): |
| 84 | raise |
| 85 | with _io.open(self._datfile, 'w', encoding="Latin-1") as f: |
| 86 | self._chmod(self._datfile) |
| 87 | else: |
| 88 | f.close() |
| 89 | |
| 90 | # Read directory file into the in-memory index dict. |
no outgoing calls
no test coverage detected
searching dependent graphs…