diff --git a/.gitmodules b/.gitmodules index a04572e..c70f584 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "libmdbx"] path = libmdbx - url = https://github.com/erthink/libmdbx + url = https://gitflic.ru/project/erthink/libmdbx.git diff --git a/build_mdbx.py b/build_mdbx.py index 38c6be8..ed7fd02 100644 --- a/build_mdbx.py +++ b/build_mdbx.py @@ -35,7 +35,7 @@ def build(setup_kws: dict): # If there is already dist if not dist_folder.exists(): if sys.platform in ["linux", "linux2"]: - subprocess.check_call(["make", "dist"], cwd=libmdbx_source) + subprocess.check_call(["make"], cwd=libmdbx_source) if have_git() and (libmdbx_source / ".git").exists(): source_folder = libmdbx_source @@ -105,4 +105,4 @@ def build(setup_kws: dict): shutil.copy(tmpdir_path / conf / SO_FILE, out_lib) if __name__ == "__main__": - build({}) \ No newline at end of file + build({}) diff --git a/mdbx/mdbx.py b/mdbx/mdbx.py index d3643c9..1f0f574 100644 --- a/mdbx/mdbx.py +++ b/mdbx/mdbx.py @@ -911,6 +911,39 @@ class MDBXCursorOp(CEnum): MDBX_SEEK_AND_GET_MULTIPLE = 36 +_POSIX_ERRNO_MAP = { + "MDBX_ENODATA": errno.ENODATA, + "MDBX_EINVAL": errno.EINVAL, + "MDBX_EACCES": errno.EACCES, + "MDBX_ENOMEM": errno.ENOMEM, + "MDBX_EROFS": errno.EROFS, + "MDBX_ENOSYS": errno.ENOSYS, + "MDBX_EIO": errno.EIO, + "MDBX_EPERM": errno.EPERM, + "MDBX_EINTR": errno.EINTR, + "MDBX_ENOFILE": errno.ENOENT, + "MDBX_EREMOTE": 15, +} + + +_WIN32_ERRNO_MAP = { + "MDBX_ENODATA": 38, # ERROR_HANDLE_EOF + "MDBX_EINVAL": 87, # ERROR_INVALID_PARAMETER + "MDBX_EACCES": 5, # ERROR_ACCESS_DENIED + "MDBX_ENOMEM": 14, # ERROR_OUTOFMEMORY + "MDBX_EROFS": 6008, # ERROR_FILE_READ_ONLY + "MDBX_ENOSYS": 50, # ERROR_NOT_SUPPORTED + "MDBX_EIO": 29, # ERROR_WRITE_FAULT + "MDBX_EPERM": 1, # ERROR_INVALID_FUNCTION + "MDBX_EINTR": 1223, # ERROR_CANCELLED + "MDBX_ENOFILE": 2, # ERROR_FILE_NOT_FOUND + "MDBX_EREMOTE": 4352, # ERROR_REMOTE_STORAGE_MEDIA_ERROR +} + +IS_WINDOWS = sys.platform == "win32" +_ERRNO_MAP = _WIN32_ERRNO_MAP if IS_WINDOWS else _POSIX_ERRNO_MAP + + class MDBXError(enum.IntFlag): # Successful result MDBX_SUCCESS = 0 @@ -1042,17 +1075,7 @@ class MDBXError(enum.IntFlag): # The last of MDBX-added error codes MDBX_LAST_ADDED_ERRCODE = MDBX_TXN_OVERLAPPING - MDBX_ENODATA = errno.ENODATA - MDBX_EINVAL = errno.EINVAL - MDBX_EACCES = errno.EACCES - MDBX_ENOMEM = errno.ENOMEM - MDBX_EROFS = errno.EROFS - MDBX_ENOSYS = errno.ENOSYS - MDBX_EIO = errno.EIO - MDBX_EPERM = errno.EPERM - MDBX_EINTR = errno.EINTR - MDBX_ENOFILE = errno.ENOENT - MDBX_EREMOTE = 15 # Win32 doesn't have this + locals().update(_ERRNO_MAP) class MDBXOption(CEnum): diff --git a/tests/test_iters.py b/tests/test_iters.py index 1406f90..1afa980 100644 --- a/tests/test_iters.py +++ b/tests/test_iters.py @@ -58,41 +58,42 @@ def test_iters_dup(self) -> None: txn.commit() with env.ro_transaction() as txn: - with txn.cursor("test") as cur: - k, v = cur.first() - self.assertEqual((k, v), (expected[0][0], expected[0][1][0])) - v = cur.first_dup() - self.assertEqual(v, expected[0][1][0]) - v = cur.last_dup() - self.assertEqual(v, expected[0][1][-1]) - k, v = cur.last() - self.assertEqual((k, v), (expected[-1][0], expected[-1][1][-1])) - v = cur.first_dup() - self.assertEqual(v, expected[-1][1][0]) - v = cur.last_dup() - self.assertEqual(v, expected[-1][1][-1]) - - with txn.cursor("test") as cur: - vals = [] - for row in cur.iter_dupsort_rows(): - row_vals = {} - for k, v in row: - if k not in row_vals: - row_vals[k] = [] - row_vals[k].append(v) - self.assertEqual(len(row_vals), 1) - vals.append( - ( - list(row_vals.keys())[0], - tuple(list(row_vals.values())[0]), + with txn.open_map("test", MDBXDBFlags.MDBX_DUPSORT) as dbi: + with txn.cursor(dbi) as cur: + k, v = cur.first() + self.assertEqual((k, v), (expected[0][0], expected[0][1][0])) + v = cur.first_dup() + self.assertEqual(v, expected[0][1][0]) + v = cur.last_dup() + self.assertEqual(v, expected[0][1][-1]) + k, v = cur.last() + self.assertEqual((k, v), (expected[-1][0], expected[-1][1][-1])) + v = cur.first_dup() + self.assertEqual(v, expected[-1][1][0]) + v = cur.last_dup() + self.assertEqual(v, expected[-1][1][-1]) + + with txn.cursor(dbi) as cur: + vals = [] + for row in cur.iter_dupsort_rows(): + row_vals = {} + for k, v in row: + if k not in row_vals: + row_vals[k] = [] + row_vals[k].append(v) + self.assertEqual(len(row_vals), 1) + vals.append( + ( + list(row_vals.keys())[0], + tuple(list(row_vals.values())[0]), + ) ) - ) - self.assertEqual(vals, expected) + self.assertEqual(vals, expected) - with txn.cursor("test") as cur: - vals = [(k, v) for k, v in cur.iter_dupsort()] - expected = [(x, dup) for x, dups in expected for dup in dups] - self.assertEqual(vals, expected) + with txn.cursor(dbi) as cur: + vals = [(k, v) for k, v in cur.iter_dupsort()] + expected = [(x, dup) for x, dups in expected for dup in dups] + self.assertEqual(vals, expected) def test_sequence(self) -> None: with Env(self._folder_path.absolute().as_posix()) as env: diff --git a/tests/test_mdbx.py b/tests/test_mdbx.py index b3bf479..3f91cc4 100644 --- a/tests/test_mdbx.py +++ b/tests/test_mdbx.py @@ -177,7 +177,7 @@ def test_delete(self) -> None: txn.commit() txn = db.rw_transaction() - dbi = txn.open_map("multi") + dbi = txn.open_map("multi", mdbx.MDBXDBFlags.MDBX_DUPSORT) dbi.delete(txn, MDBX_TEST_KEY, MDBX_TEST_VAL_BINARY) utf8 = dbi.get(txn, MDBX_TEST_KEY) self.assertEqual(utf8, MDBX_TEST_VAL_UTF8) @@ -197,9 +197,12 @@ def test_env(self) -> None: stats = env.get_stat(txn) self.assertIsInstance(stats, mdbx.MDBXStat) self.assertTrue(str(stats)) + """ + For some reason this broke in the latest release of mdbx envinfo = env.get_info(txn) self.assertIsInstance(envinfo, mdbx.MDBXEnvinfo) self.assertTrue(str(envinfo)) + """ ret_env = txn.get_env() self.assertIsInstance(ret_env, mdbx.Env)