# Path: flask_blogging/storage.py
# class Storage(object):
# 
#     def save_post(self, title, text, user_id, tags, draft=False,
#                   post_date=None, last_modified_date=None, meta_data=None,
#                   post_id=None):
#         """
#         Persist the blog post data. If ``post_id`` is ``None`` or ``post_id``
#         is invalid, the post must be inserted into the storage. If ``post_id``
#         is a valid id, then the data must be updated.
# 
#         :param title: The title of the blog post
#         :type title: str
#         :param text: The text of the blog post
#         :type text: str
#         :param user_id: The user identifier
#         :type user_id: str
#         :param tags: A list of tags
#         :type tags: list
#         :param draft: If the post is a draft of if needs to be published.
#         :type draft: bool
#         :param post_date: (Optional) The date the blog was posted (default
#          datetime.datetime.utcnow())
#         :type post_date: datetime.datetime
#         :param last_modified_date: (Optional) The date when blog was last
#          modified  (default datetime.datetime.utcnow())
#         :type last_modified_date: datetime.datetime
#         :param meta_data: The meta data for the blog post
#         :type meta_data: dict
#         :param post_id: The post identifier. This should be ``None`` for an
#          insert call, and a valid value for update.
#         :type post_id: int
# 
#         :return: The post_id value, in case of a successful insert or update.
#         Return ``None`` if there were errors.
#         """
#         raise NotImplementedError("This method needs to be implemented by "
#                                   "the inheriting class")
# 
#     def get_post_by_id(self, post_id):
#         """
#         Fetch the blog post given by ``post_id``
# 
#         :param post_id: The post identifier for the blog post
#         :type post_id: int
#         :return: If the ``post_id`` is valid, the post data is retrieved,
#         else returns ``None``.
#         """
#         raise NotImplementedError("This method needs to be implemented by the "
#                                   "inheriting class")
# 
#     def get_posts(self, count=10, offset=0, recent=True,  tag=None,
#                   user_id=None, include_draft=False):
#         """
#         Get posts given by filter criteria
# 
#         :param count: The number of posts to retrieve (default 10). If count
#          is ``None``, all posts are returned.
#         :type count: int
#         :param offset: The number of posts to offset (default 0)
#         :type offset: int
#         :param recent: Order by recent posts or not
#         :type recent: bool
#         :param tag: Filter by a specific tag
#         :type tag: str
#         :param user_id: Filter by a specific user
#         :type user_id: str
#         :param include_draft: Whether to include posts marked as draft or not
#         :type include_draft: bool
# 
#         :return: A list of posts, with each element a dict containing values
#          for the following keys: (title, text, draft, post_date,
#          last_modified_date). If count is ``None``, then all the posts are
#          returned.
#         """
#         raise NotImplementedError("This method needs to be implemented by the "
#                                   "inheriting class")
# 
#     def count_posts(self, tag=None, user_id=None, include_draft=False):
#         """
#         Returns the total number of posts for the give filter
# 
#         :param tag: Filter by a specific tag
#         :type tag: str
#         :param user_id: Filter by a specific user
#         :type user_id: str
#         :param include_draft: Whether to include posts marked as draft or not
#         :type include_draft: bool
#         :return: The number of posts for the given filter.
#         """
#         raise NotImplementedError("This method needs to be implemented by the "
#                                   "inheriting class")
# 
#     def delete_post(self, post_id):
#         """
#         Delete the post defined by ``post_id``
# 
#         :param post_id: The identifier corresponding to a post
#         :type post_id: int
#         :return: Returns True if the post was successfully deleted and False
#          otherwise.
#         """
#         raise NotImplementedError("This method needs to be implemented by the "
#                                   "inheriting class")
# 
#     @classmethod
#     def normalize_tags(cls, tags):
#         return [cls.normalize_tag(tag) for tag in tags]
# 
#     @staticmethod
#     def normalize_tag(tag):
#         return tag.upper().strip()
# 
# Path: flask_blogging/signals.py



    from builtins import str
from collections import defaultdict, OrderedDict
from sqlalchemy.ext.automap import automap_base
from .storage import Storage
from .signals import sqla_initialized
import sys
import logging
import sqlalchemy as sqla
import datetime
        :type db: object
        :param bind: (Optional) Reference the database to bind for multiple
        database scenario with binds
        :type bind: str
        """
        self._bind = bind
        if db:
            self._engine = db.get_engine(db.get_app(), bind=self._bind)
            self._metadata = db.metadata
        else:
            if engine is None:
                raise ValueError("Both db and engine args cannot be None")
            self._engine = engine
            self._metadata = metadata or sqla.MetaData()
        self._info = {} if self._bind is None else {"bind_key": self._bind}
        self._table_prefix = table_prefix

        self._metadata.reflect(bind=self._engine)
        self._create_all_tables()

        # automap base and restrict to the required tables here.
        table_suffix = ['post', 'tag', 'user_posts', 'tag_posts']
        table_names = [self._table_name(t) for t in table_suffix]
        self._metadata.create_all(bind=self._engine, tables=self.all_tables)
        meta = sqla.MetaData()
        meta.reflect(bind=self._engine, only=table_names)
        self._Base = automap_base(metadata=meta)
        self._Base.prepare()
        self._inject_models()


# Path: flask_blogging/storage.py
# class Storage(object):
# 
#     def save_post(self, title, text, user_id, tags, draft=False,
#                   post_date=None, last_modified_date=None, meta_data=None,
#                   post_id=None):
#         """
#         Persist the blog post data. If ``post_id`` is ``None`` or ``post_id``
#         is invalid, the post must be inserted into the storage. If ``post_id``
#         is a valid id, then the data must be updated.
# 
#         :param title: The title of the blog post
#         :type title: str
#         :param text: The text of the blog post
#         :type text: str
#         :param user_id: The user identifier
#         :type user_id: str
#         :param tags: A list of tags
#         :type tags: list
#         :param draft: If the post is a draft of if needs to be published.
#         :type draft: bool
#         :param post_date: (Optional) The date the blog was posted (default
#          datetime.datetime.utcnow())
#         :type post_date: datetime.datetime
#         :param last_modified_date: (Optional) The date when blog was last
#          modified  (default datetime.datetime.utcnow())
#         :type last_modified_date: datetime.datetime
#         :param meta_data: The meta data for the blog post
#         :type meta_data: dict
#         :param post_id: The post identifier. This should be ``None`` for an
#          insert call, and a valid value for update.
#         :type post_id: int
# 
#         :return: The post_id value, in case of a successful insert or update.
#         Return ``None`` if there were errors.
#         """
#         raise NotImplementedError("This method needs to be implemented by "
#                                   "the inheriting class")
# 
#     def get_post_by_id(self, post_id):
#         """
#         Fetch the blog post given by ``post_id``
# 
#         :param post_id: The post identifier for the blog post
#         :type post_id: int
#         :return: If the ``post_id`` is valid, the post data is retrieved,
#         else returns ``None``.
#         """
#         raise NotImplementedError("This method needs to be implemented by the "
#                                   "inheriting class")
# 
#     def get_posts(self, count=10, offset=0, recent=True,  tag=None,
#                   user_id=None, include_draft=False):
#         """
#         Get posts given by filter criteria
# 
#         :param count: The number of posts to retrieve (default 10). If count
#          is ``None``, all posts are returned.
#         :type count: int
#         :param offset: The number of posts to offset (default 0)
#         :type offset: int
#         :param recent: Order by recent posts or not
#         :type recent: bool
#         :param tag: Filter by a specific tag
#         :type tag: str
#         :param user_id: Filter by a specific user
#         :type user_id: str
#         :param include_draft: Whether to include posts marked as draft or not
#         :type include_draft: bool
# 
#         :return: A list of posts, with each element a dict containing values
#          for the following keys: (title, text, draft, post_date,
#          last_modified_date). If count is ``None``, then all the posts are
#          returned.
#         """
#         raise NotImplementedError("This method needs to be implemented by the "
#                                   "inheriting class")
# 
#     def count_posts(self, tag=None, user_id=None, include_draft=False):
#         """
#         Returns the total number of posts for the give filter
# 
#         :param tag: Filter by a specific tag
#         :type tag: str
#         :param user_id: Filter by a specific user
#         :type user_id: str
#         :param include_draft: Whether to include posts marked as draft or not
#         :type include_draft: bool
#         :return: The number of posts for the given filter.
#         """
#         raise NotImplementedError("This method needs to be implemented by the "
#                                   "inheriting class")
# 
#     def delete_post(self, post_id):
#         """
#         Delete the post defined by ``post_id``
# 
#         :param post_id: The identifier corresponding to a post
#         :type post_id: int
#         :return: Returns True if the post was successfully deleted and False
#          otherwise.
#         """
#         raise NotImplementedError("This method needs to be implemented by the "
#                                   "inheriting class")
# 
#     @classmethod
#     def normalize_tags(cls, tags):
#         return [cls.normalize_tag(tag) for tag in tags]
# 
#     @staticmethod
#     def normalize_tag(tag):
#         return tag.upper().strip()
# 
# Path: flask_blogging/signals.py



# Path: flask_blogging/sqlastorage.py
    from builtins import str
from collections import defaultdict, OrderedDict
from sqlalchemy.ext.automap import automap_base
from .storage import Storage
from .signals import sqla_initialized
import sys
import logging
import sqlalchemy as sqla
import datetime

        :type db: object
        :param bind: (Optional) Reference the database to bind for multiple
        database scenario with binds
        :type bind: str
        """
        self._bind = bind
        if db:
            self._engine = db.get_engine(db.get_app(), bind=self._bind)
            self._metadata = db.metadata
        else:
            if engine is None:
                raise ValueError("Both db and engine args cannot be None")
            self._engine = engine
            self._metadata = metadata or sqla.MetaData()
        self._info = {} if self._bind is None else {"bind_key": self._bind}
        self._table_prefix = table_prefix

        self._metadata.reflect(bind=self._engine)
        self._create_all_tables()

        # automap base and restrict to the required tables here.
        table_suffix = ['post', 'tag', 'user_posts', 'tag_posts']
        table_names = [self._table_name(t) for t in table_suffix]
        self._metadata.create_all(bind=self._engine, tables=self.all_tables)
        meta = sqla.MetaData()
        meta.reflect(bind=self._engine, only=table_names)
        self._Base = automap_base(metadata=meta)
        self._Base.prepare()
        self._inject_models()


        sqla_initialized.send(self, engine=self._engine,