Guess which db package to use to open a db file. Return values: - None if the database file can't be read; - empty string if the file can be read but can't be recognized - the name of the dbm submodule (e.g. "ndbm" or "gnu") if recognized. Importing the given module may still
(filename)
| 96 | |
| 97 | |
| 98 | def whichdb(filename): |
| 99 | """Guess which db package to use to open a db file. |
| 100 | |
| 101 | Return values: |
| 102 | |
| 103 | - None if the database file can't be read; |
| 104 | - empty string if the file can be read but can't be recognized |
| 105 | - the name of the dbm submodule (e.g. "ndbm" or "gnu") if recognized. |
| 106 | |
| 107 | Importing the given module may still fail, and opening the |
| 108 | database using that module may still fail. |
| 109 | """ |
| 110 | |
| 111 | # Check for ndbm first -- this has a .pag and a .dir file |
| 112 | filename = os.fsencode(filename) |
| 113 | try: |
| 114 | f = io.open(filename + b".pag", "rb") |
| 115 | f.close() |
| 116 | f = io.open(filename + b".dir", "rb") |
| 117 | f.close() |
| 118 | return "dbm.ndbm" |
| 119 | except OSError: |
| 120 | # some dbm emulations based on Berkeley DB generate a .db file |
| 121 | # some do not, but they should be caught by the bsd checks |
| 122 | try: |
| 123 | f = io.open(filename + b".db", "rb") |
| 124 | f.close() |
| 125 | # guarantee we can actually open the file using dbm |
| 126 | # kind of overkill, but since we are dealing with emulations |
| 127 | # it seems like a prudent step |
| 128 | if ndbm is not None: |
| 129 | d = ndbm.open(filename) |
| 130 | d.close() |
| 131 | return "dbm.ndbm" |
| 132 | except OSError: |
| 133 | pass |
| 134 | |
| 135 | # Check for dumbdbm next -- this has a .dir and a .dat file |
| 136 | try: |
| 137 | # First check for presence of files |
| 138 | os.stat(filename + b".dat") |
| 139 | size = os.stat(filename + b".dir").st_size |
| 140 | # dumbdbm files with no keys are empty |
| 141 | if size == 0: |
| 142 | return "dbm.dumb" |
| 143 | f = io.open(filename + b".dir", "rb") |
| 144 | try: |
| 145 | if f.read(1) in (b"'", b'"'): |
| 146 | return "dbm.dumb" |
| 147 | finally: |
| 148 | f.close() |
| 149 | except OSError: |
| 150 | pass |
| 151 | |
| 152 | # See if the file exists, return None if not |
| 153 | try: |
| 154 | f = io.open(filename, "rb") |
| 155 | except OSError: |