# Path: g_sorcery/exceptions.py
# class DBLayoutError(GSorceryError):
#     pass
# 
# class DBStructureError(DBError):
#     pass
# 
# class FileJSONError(GSorceryError):
#     pass
# 
# class IntegrityError(DBError):
#     pass
# 
# Path: g_sorcery/fileutils.py
# class FileJSON(FileJSONData):
#     """
#     Class for JSON files. Supports custom JSON serialization
#     provided by g_sorcery.serialization.
#     """
# 
#     def read_content(self):
#         """
#         Read JSON file.
#         """
#         content = {}
#         with open(self.path, 'r') as f:
#             content = json.load(f, object_hook=deserializeHook)
#         return content
# 
#     def write_content(self, content):
#         """
#         Write JSON file.
#         """
#         with open(self.path, 'w') as f:
#             json.dump(content, f, indent=2, sort_keys=True, cls=JSONSerializer)
# 
# def hash_file(name, hasher, blocksize=65536):
#     """
#     Get a file hash.
# 
#     Args:
#         name: file name.
#         hasher: Hasher.
#         blocksize: Blocksize.
# 
#     Returns:
#         Hash value.
#     """
#     with open(name, 'rb') as f:
#         buf = f.read(blocksize)
#         while len(buf) > 0:
#             hasher.update(buf)
#             buf = f.read(blocksize)
#     return hasher.hexdigest()


import hashlib
import os
import shutil
from .exceptions import DBLayoutError, DBStructureError, FileJSONError, IntegrityError
from .fileutils import FileJSON, hash_file
    from .file_bson.file_bson import FileBSON

    def clean(self):
        """
        Remove DB files.
        """
        if os.path.exists(self.directory):
            shutil.rmtree(self.directory)
        os.makedirs(self.directory)

    def read(self):
        """
        Read DB files.

        Returns a tuple with metadata, list of categories
        and categories dictionary.
        """
        self.check_manifest()

        metadata_f = Metadata(self.directory)
        metadata = metadata_f.read()

        category_cls, _ = get_layout(metadata)

        categories_f = Categories(self.directory)
        categories = categories_f.read()

        packages = {}
        for category in categories:
            category_path = os.path.join(self.directory, category)
            if not os.path.isdir(category_path):

# Path: g_sorcery/exceptions.py
# class DBLayoutError(GSorceryError):
#     pass
# 
# class DBStructureError(DBError):
#     pass
# 
# class FileJSONError(GSorceryError):
#     pass
# 
# class IntegrityError(DBError):
#     pass
# 
# Path: g_sorcery/fileutils.py
# class FileJSON(FileJSONData):
#     """
#     Class for JSON files. Supports custom JSON serialization
#     provided by g_sorcery.serialization.
#     """
# 
#     def read_content(self):
#         """
#         Read JSON file.
#         """
#         content = {}
#         with open(self.path, 'r') as f:
#             content = json.load(f, object_hook=deserializeHook)
#         return content
# 
#     def write_content(self, content):
#         """
#         Write JSON file.
#         """
#         with open(self.path, 'w') as f:
#             json.dump(content, f, indent=2, sort_keys=True, cls=JSONSerializer)
# 
# def hash_file(name, hasher, blocksize=65536):
#     """
#     Get a file hash.
# 
#     Args:
#         name: file name.
#         hasher: Hasher.
#         blocksize: Blocksize.
# 
#     Returns:
#         Hash value.
#     """
#     with open(name, 'rb') as f:
#         buf = f.read(blocksize)
#         while len(buf) > 0:
#             hasher.update(buf)
#             buf = f.read(blocksize)
#     return hasher.hexdigest()


# Path: g_sorcery/db_layout.py
import hashlib
import os
import shutil
from .exceptions import DBLayoutError, DBStructureError, FileJSONError, IntegrityError
from .fileutils import FileJSON, hash_file
    from .file_bson.file_bson import FileBSON


    def clean(self):
        """
        Remove DB files.
        """
        if os.path.exists(self.directory):
            shutil.rmtree(self.directory)
        os.makedirs(self.directory)

    def read(self):
        """
        Read DB files.

        Returns a tuple with metadata, list of categories
        and categories dictionary.
        """
        self.check_manifest()

        metadata_f = Metadata(self.directory)
        metadata = metadata_f.read()

        category_cls, _ = get_layout(metadata)

        categories_f = Categories(self.directory)
        categories = categories_f.read()

        packages = {}
        for category in categories:
            category_path = os.path.join(self.directory, category)
            if not os.path.isdir(category_path):

                raise DBLayoutError('Empty category: ' + category)