Support unicode objects for paths
Use sys.getfilesystemencoding() for encoding
This commit is contained in:
parent
b4fb12589d
commit
6277f9ab5c
5 changed files with 43 additions and 9 deletions
|
@ -8,7 +8,7 @@ Database object
|
||||||
|
|
||||||
.. py:method:: __init__(db_name, Options opts, read_only=False)
|
.. py:method:: __init__(db_name, Options opts, read_only=False)
|
||||||
|
|
||||||
:param string db_name: Name of the database to open
|
:param unicode db_name: Name of the database to open
|
||||||
:param opts: Options for this specific database
|
:param opts: Options for this specific database
|
||||||
:type opts: :py:class:`rocksdb.Options`
|
:type opts: :py:class:`rocksdb.Options`
|
||||||
:param bool read_only: If ``True`` the database is opened read-only.
|
:param bool read_only: If ``True`` the database is opened read-only.
|
||||||
|
|
|
@ -329,7 +329,7 @@ Options object
|
||||||
and the db data dir's absolute path will be used as the log file
|
and the db data dir's absolute path will be used as the log file
|
||||||
name's prefix.
|
name's prefix.
|
||||||
|
|
||||||
| *Type:* ``string``
|
| *Type:* ``unicode``
|
||||||
| *Default:* ``""``
|
| *Default:* ``""``
|
||||||
|
|
||||||
.. py:attribute:: wal_dir
|
.. py:attribute:: wal_dir
|
||||||
|
@ -340,7 +340,7 @@ Options object
|
||||||
If it is non empty, the log files will be in kept the specified dir.
|
If it is non empty, the log files will be in kept the specified dir.
|
||||||
When destroying the db, all log files in wal_dir and the dir itself is deleted
|
When destroying the db, all log files in wal_dir and the dir itself is deleted
|
||||||
|
|
||||||
| *Type:* ``string``
|
| *Type:* ``unicode``
|
||||||
| *Default:* ``""``
|
| *Default:* ``""``
|
||||||
|
|
||||||
.. py:attribute:: disable_seek_compaction
|
.. py:attribute:: disable_seek_compaction
|
||||||
|
|
|
@ -7,6 +7,7 @@ from cython.operator cimport dereference as deref
|
||||||
from cpython.string cimport PyString_AsString
|
from cpython.string cimport PyString_AsString
|
||||||
from cpython.string cimport PyString_Size
|
from cpython.string cimport PyString_Size
|
||||||
from cpython.string cimport PyString_FromString
|
from cpython.string cimport PyString_FromString
|
||||||
|
from cpython.unicode cimport PyUnicode_Decode
|
||||||
|
|
||||||
from std_memory cimport shared_ptr
|
from std_memory cimport shared_ptr
|
||||||
cimport options
|
cimport options
|
||||||
|
@ -24,6 +25,7 @@ from slice_ cimport slice_to_str
|
||||||
from slice_ cimport str_to_slice
|
from slice_ cimport str_to_slice
|
||||||
from status cimport Status
|
from status cimport Status
|
||||||
|
|
||||||
|
import sys
|
||||||
from interfaces import MergeOperator as IMergeOperator
|
from interfaces import MergeOperator as IMergeOperator
|
||||||
from interfaces import AssociativeMergeOperator as IAssociativeMergeOperator
|
from interfaces import AssociativeMergeOperator as IAssociativeMergeOperator
|
||||||
from interfaces import FilterPolicy as IFilterPolicy
|
from interfaces import FilterPolicy as IFilterPolicy
|
||||||
|
@ -64,6 +66,23 @@ cdef check_status(const Status& st):
|
||||||
######################################################
|
######################################################
|
||||||
|
|
||||||
|
|
||||||
|
cdef string bytes_to_string(bytes path) except *:
|
||||||
|
return string(PyBytes_AsString(path), PyBytes_Size(path))
|
||||||
|
|
||||||
|
## only for filsystem paths
|
||||||
|
cdef string path_to_string(object path) except *:
|
||||||
|
if isinstance(path, bytes):
|
||||||
|
return bytes_to_string(path)
|
||||||
|
if isinstance(path, unicode):
|
||||||
|
path = path.encode(sys.getfilesystemencoding())
|
||||||
|
return bytes_to_string(path)
|
||||||
|
else:
|
||||||
|
raise TypeError("Wrong type for path: %s" % path)
|
||||||
|
|
||||||
|
cdef object string_to_path(string path):
|
||||||
|
fs_encoding = sys.getfilesystemencoding()
|
||||||
|
return PyUnicode_Decode(path.c_str(), path.size(), fs_encoding, "replace")
|
||||||
|
|
||||||
## Here comes the stuff for the comparator
|
## Here comes the stuff for the comparator
|
||||||
@cython.internal
|
@cython.internal
|
||||||
cdef class PyComparator(object):
|
cdef class PyComparator(object):
|
||||||
|
@ -609,15 +628,15 @@ cdef class Options(object):
|
||||||
|
|
||||||
property db_log_dir:
|
property db_log_dir:
|
||||||
def __get__(self):
|
def __get__(self):
|
||||||
return self.opts.db_log_dir
|
return string_to_path(self.opts.db_log_dir)
|
||||||
def __set__(self, value):
|
def __set__(self, value):
|
||||||
self.opts.db_log_dir = value
|
self.opts.db_log_dir = path_to_string(value)
|
||||||
|
|
||||||
property wal_dir:
|
property wal_dir:
|
||||||
def __get__(self):
|
def __get__(self):
|
||||||
return self.opts.wal_dir
|
return string_to_path(self.opts.wal_dir)
|
||||||
def __set__(self, value):
|
def __set__(self, value):
|
||||||
self.opts.wal_dir = value
|
self.opts.wal_dir = path_to_string(value)
|
||||||
|
|
||||||
property disable_seek_compaction:
|
property disable_seek_compaction:
|
||||||
def __get__(self):
|
def __get__(self):
|
||||||
|
@ -946,14 +965,14 @@ cdef class DB(object):
|
||||||
check_status(
|
check_status(
|
||||||
db.DB_OpenForReadOnly(
|
db.DB_OpenForReadOnly(
|
||||||
deref(opts.opts),
|
deref(opts.opts),
|
||||||
db_name,
|
path_to_string(db_name),
|
||||||
cython.address(self.db),
|
cython.address(self.db),
|
||||||
False))
|
False))
|
||||||
else:
|
else:
|
||||||
check_status(
|
check_status(
|
||||||
db.DB_Open(
|
db.DB_Open(
|
||||||
deref(opts.opts),
|
deref(opts.opts),
|
||||||
db_name,
|
path_to_string(db_name),
|
||||||
cython.address(self.db)))
|
cython.address(self.db)))
|
||||||
|
|
||||||
self.opts = opts
|
self.opts = opts
|
||||||
|
|
|
@ -24,6 +24,12 @@ class TestDB(unittest.TestCase, TestHelper):
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self._close_db()
|
self._close_db()
|
||||||
|
|
||||||
|
def test_unicode_path(self):
|
||||||
|
name = b'/tmp/M\xc3\xbcnchen'.decode('utf8')
|
||||||
|
rocksdb.DB(name, rocksdb.Options(create_if_missing=True))
|
||||||
|
self.addCleanup(shutil.rmtree, name)
|
||||||
|
self.assertTrue(os.path.isdir(name))
|
||||||
|
|
||||||
def test_get_none(self):
|
def test_get_none(self):
|
||||||
self.assertIsNone(self.db.get('xxx'))
|
self.assertIsNone(self.db.get('xxx'))
|
||||||
|
|
||||||
|
|
|
@ -52,3 +52,12 @@ class TestOptions(unittest.TestCase):
|
||||||
ob = rocksdb.LRUCache(100)
|
ob = rocksdb.LRUCache(100)
|
||||||
opts.block_cache = ob
|
opts.block_cache = ob
|
||||||
self.assertEqual(ob, opts.block_cache)
|
self.assertEqual(ob, opts.block_cache)
|
||||||
|
|
||||||
|
def test_unicode_path(self):
|
||||||
|
name = b'/tmp/M\xc3\xbcnchen'.decode('utf8')
|
||||||
|
opts = rocksdb.Options()
|
||||||
|
opts.db_log_dir = name
|
||||||
|
opts.wal_dir = name
|
||||||
|
|
||||||
|
self.assertEqual(name, opts.db_log_dir)
|
||||||
|
self.assertEqual(name, opts.wal_dir)
|
||||||
|
|
Loading…
Reference in a new issue