# Path: featureflow/data.py
# class InMemoryDatabase(Database):
#     def __init__(self, key_builder=None):
#         super(InMemoryDatabase, self).__init__(key_builder=key_builder)
#         self._dict = dict()
# 
#     def write_stream(self, key, content_type):
#         bio = BytesIO()
#         self._dict[key] = bio
# 
#         def hijacked_close():
#             bio.seek(0)
#             self._dict[key] = bio.read()
#             bio._old_close()
# 
#         bio._old_close = bio.close
#         bio.close = hijacked_close
#         return bio
# 
#     def read_stream(self, key):
#         return IOWithLength(self._dict[key])
# 
#     def size(self, key):
#         return len(self._dict[key])
# 
#     def iter_ids(self):
#         seen = set()
#         for key in list(self._dict.keys()):
#             _id, _, _ = self.key_builder.decompose(key)
#             if _id in seen:
#                 continue
#             yield _id
#             seen.add(_id)
# 
#     def __contains__(self, key):
#         return key in self._dict
# 
#     def __delitem__(self, key):
#         del self._dict[key]
# 
# class UserSpecifiedIdProvider(IdProvider):
#     def __init__(self, key=None):
#         super(UserSpecifiedIdProvider, self).__init__()
#         if not key:
#             raise ValueError('key must be provided')
#         self._key = key
# 
#     def new_id(self, **kwargs):
#         return kwargs[self._key]
# 
# class FileSystemDatabase(Database):
#     def __init__(self, path=None, key_builder=None, createdirs=False):
#         super(FileSystemDatabase, self).__init__(key_builder=key_builder)
#         self._path = path
#         if createdirs and not os.path.exists(self._path):
#             os.makedirs(self._path)
# 
#     def write_stream(self, key, content_type):
#         return LazyFile(os.path.join(self._path, key))
# 
#     def read_stream(self, key):
#         try:
#             return open(os.path.join(self._path, key), 'rb')
#         except IOError:
#             raise KeyError(key)
# 
#     def size(self, key):
#         path = os.path.join(self._path, key)
#         try:
#             return os.stat(path).st_size
#         except OSError:
#             raise KeyError(key)
# 
#     def iter_ids(self):
#         seen = set()
#         for fn in os.listdir(self._path):
#             _id, _, _ = self.key_builder.decompose(fn)
#             if _id in seen:
#                 continue
#             yield _id
#             seen.add(_id)
# 
#     def __contains__(self, key):
#         path = os.path.join(self._path, key)
#         return os.path.exists(path)
# 
#     def __delitem__(self, key):
#         path = os.path.join(self._path, key)
#         os.remove(path)
# 
# class StringDelimitedKeyBuilder(KeyBuilder):
#     def __init__(self, seperator=':'):
#         super(StringDelimitedKeyBuilder, self).__init__()
#         self._seperator = seperator
# 
#     def build(self, *args):
#         return self._seperator.join(str(x) for x in args)
# 
#     def decompose(self, composed):
#         return composed.split(self._seperator)


import unittest2
import shutil
from uuid import uuid4
from .data import \
    InMemoryDatabase, UserSpecifiedIdProvider, FileSystemDatabase, \
    StringDelimitedKeyBuilder
                path=self._path,
                key_builder=self._key_builder,
                createdirs=createdirs)

    def test_creates_path_when_asked(self):
        db = self._make_db(createdirs=True)
        with db.write_stream('key', 'text/plain') as s:
            s.write('text')

        with db.read_stream('key') as s:
            self.assertEqual(b'text', s.read())

    def test_does_not_create_path_when_not_asked(self):
        db = self._make_db(createdirs=False)

        def write():
            with db.write_stream('key', 'text/plain') as f:
                f.write('value')

        self.assertRaises(IOError, write)

    def test_key_does_not_exist_when_no_bytes_written(self):
        db = self._make_db(createdirs=True)
        with db.write_stream('key', 'text/plain') as s:
            pass
        self.assertFalse('key' in db)

    def test_key_does_not_exist_when_no_zero_bytes_written(self):
        db = self._make_db(createdirs=True)
        with db.write_stream('key', 'text/plain') as s:

# Path: featureflow/data.py
# class InMemoryDatabase(Database):
#     def __init__(self, key_builder=None):
#         super(InMemoryDatabase, self).__init__(key_builder=key_builder)
#         self._dict = dict()
# 
#     def write_stream(self, key, content_type):
#         bio = BytesIO()
#         self._dict[key] = bio
# 
#         def hijacked_close():
#             bio.seek(0)
#             self._dict[key] = bio.read()
#             bio._old_close()
# 
#         bio._old_close = bio.close
#         bio.close = hijacked_close
#         return bio
# 
#     def read_stream(self, key):
#         return IOWithLength(self._dict[key])
# 
#     def size(self, key):
#         return len(self._dict[key])
# 
#     def iter_ids(self):
#         seen = set()
#         for key in list(self._dict.keys()):
#             _id, _, _ = self.key_builder.decompose(key)
#             if _id in seen:
#                 continue
#             yield _id
#             seen.add(_id)
# 
#     def __contains__(self, key):
#         return key in self._dict
# 
#     def __delitem__(self, key):
#         del self._dict[key]
# 
# class UserSpecifiedIdProvider(IdProvider):
#     def __init__(self, key=None):
#         super(UserSpecifiedIdProvider, self).__init__()
#         if not key:
#             raise ValueError('key must be provided')
#         self._key = key
# 
#     def new_id(self, **kwargs):
#         return kwargs[self._key]
# 
# class FileSystemDatabase(Database):
#     def __init__(self, path=None, key_builder=None, createdirs=False):
#         super(FileSystemDatabase, self).__init__(key_builder=key_builder)
#         self._path = path
#         if createdirs and not os.path.exists(self._path):
#             os.makedirs(self._path)
# 
#     def write_stream(self, key, content_type):
#         return LazyFile(os.path.join(self._path, key))
# 
#     def read_stream(self, key):
#         try:
#             return open(os.path.join(self._path, key), 'rb')
#         except IOError:
#             raise KeyError(key)
# 
#     def size(self, key):
#         path = os.path.join(self._path, key)
#         try:
#             return os.stat(path).st_size
#         except OSError:
#             raise KeyError(key)
# 
#     def iter_ids(self):
#         seen = set()
#         for fn in os.listdir(self._path):
#             _id, _, _ = self.key_builder.decompose(fn)
#             if _id in seen:
#                 continue
#             yield _id
#             seen.add(_id)
# 
#     def __contains__(self, key):
#         path = os.path.join(self._path, key)
#         return os.path.exists(path)
# 
#     def __delitem__(self, key):
#         path = os.path.join(self._path, key)
#         os.remove(path)
# 
# class StringDelimitedKeyBuilder(KeyBuilder):
#     def __init__(self, seperator=':'):
#         super(StringDelimitedKeyBuilder, self).__init__()
#         self._seperator = seperator
# 
#     def build(self, *args):
#         return self._seperator.join(str(x) for x in args)
# 
#     def decompose(self, composed):
#         return composed.split(self._seperator)


# Path: featureflow/test_data.py
import unittest2
import shutil
from uuid import uuid4
from .data import \
    InMemoryDatabase, UserSpecifiedIdProvider, FileSystemDatabase, \
    StringDelimitedKeyBuilder

                path=self._path,
                key_builder=self._key_builder,
                createdirs=createdirs)

    def test_creates_path_when_asked(self):
        db = self._make_db(createdirs=True)
        with db.write_stream('key', 'text/plain') as s:
            s.write('text')

        with db.read_stream('key') as s:
            self.assertEqual(b'text', s.read())

    def test_does_not_create_path_when_not_asked(self):
        db = self._make_db(createdirs=False)

        def write():
            with db.write_stream('key', 'text/plain') as f:
                f.write('value')

        self.assertRaises(IOError, write)

    def test_key_does_not_exist_when_no_bytes_written(self):
        db = self._make_db(createdirs=True)
        with db.write_stream('key', 'text/plain') as s:
            pass
        self.assertFalse('key' in db)

    def test_key_does_not_exist_when_no_zero_bytes_written(self):
        db = self._make_db(createdirs=True)
        with db.write_stream('key', 'text/plain') as s:

            s.write('')