# Path: voeventdb/server/database/models.py
# class Voevent(Base, OdictMixin):
#     """
#     Define the core VOEvent table.
# 
#     .. NOTE::
#         On datetimes:
#         We store datetimes 'with timezone' even though we'll use the convention
#         of storing UTC throughout (and VOEvents are UTC too).
#         This helps to make explicit what convention we're using and avoid
#         any possible timezone-naive mixups down the line.
# 
#         However, if this ever gets used at (really large!) scale, then may
#         need to be wary of issues with partitioning really large datasets, cf:
#         http://justatheory.com/computers/databases/postgresql/use-timestamptz.html
#         http://www.postgresql.org/docs/9.1/static/ddl-partitioning.html
# 
#     """
#     __tablename__ = 'voevent'
#     # Basics: Attributes or associated metadata present for almost every VOEvent:
#     id = Column(sql.Integer, primary_key=True)
#     received = Column(
#         sql.DateTime(timezone=True), nullable=False,
#         doc="Records when the packet was loaded into the database"
#     )
#     ivorn = Column(sql.String, nullable=False, unique=True, index=True)
#     stream = Column(sql.String, index=True)
#     role = Column(sql.Enum(vp.definitions.roles.observation,
#                            vp.definitions.roles.prediction,
#                            vp.definitions.roles.utility,
#                            vp.definitions.roles.test,
#                            name="roles_enum",
#                            ),
#                   index=True
#                   )
#     version = Column(sql.String)
#     # Who
#     author_ivorn = Column(sql.String)
#     author_datetime = Column(sql.DateTime(timezone=True))
#     # Finally, the raw XML. Mark this for lazy-loading, cf:
#     # http://docs.sqlalchemy.org/en/latest/orm/loading_columns.html
#     xml = deferred(Column(sql.LargeBinary))
# 
#     cites = relationship("Cite", backref=backref('voevent', order_by=id),
#                          cascade="all, delete, delete-orphan")
# 
#     coords = relationship('Coord', backref=backref('voevent', order_by=id),
#                           cascade="all, delete, delete-orphan")
# 
#     @staticmethod
#     def from_etree(root, received=pytz.UTC.localize(datetime.utcnow())):
#         """
#         Init a Voevent row from an LXML etree loaded with voevent-parse
#         """
#         ivorn = root.attrib['ivorn']
#         # Stream- Everything except before the '#' separator,
#         # with the prefix 'ivo://' removed:
#         stream = ivorn.split('#')[0][6:]
#         row = Voevent(ivorn=ivorn,
#                       role=root.attrib['role'],
#                       version=root.attrib['version'],
#                       stream=stream,
#                       xml=vp.dumps(root),
#                       received=received,
#                       )
#         row.author_datetime = _grab_xpath(root, 'Who/Date',
#                                           converter=iso8601.parse_date)
#         row.author_ivorn = _grab_xpath(root, 'Who/AuthorIVORN')
# 
#         row.cites = Cite.from_etree(root)
#         if not _has_bad_coords(root, stream):
#             try:
#                 row.coords = Coord.from_etree(root)
#             except:
#                 logger.exception(
#                     'Error loading coords for ivorn {}, coords dropped.'.format(
#                         ivorn)
#                 )
#         return row
# 
#     def _reformatted_prettydict(self, valformat=str):
#         pd = self.prettydict()
#         return '\n'.join(
#             ("{}={}".format(k, valformat(v)) for k, v in pd.iteritems()))
# 
#     def __repr__(self):
#         od = self.to_odict()
#         content = ',\n'.join(
#             ("{}={}".format(k, repr(v)) for k, v in od.iteritems()))
#         return """<Voevent({})>""".format(content)
# 
#     def __str__(self):
#         od = self.to_odict()
#         od.pop('xml')
#         content = ',\n    '.join(
#             ("{}={}".format(k, str(v)) for k, v in od.iteritems()))
#         return """<Voevent({})>""".format(content)


import iso8601
import pytest
from voeventdb.server.database.models import Voevent
        s = fixture_db_session
        dbinf = simple_populated_db
        xml_pkts = [r.xml for r in s.query(Voevent.xml).all()]
        assert xml_pkts == dbinf.insert_packets_dumps

        xml_single = s.query(Voevent.xml).filter(
            Voevent.ivorn == dbinf.insert_packets[0].attrib['ivorn']
        ).scalar()
        assert xml_single == dbinf.insert_packets_dumps[0]

    def test_datetime_comparison(self, fixture_db_session, simple_populated_db):
        s = fixture_db_session
        dbinf = simple_populated_db
        pkt_index = 5
        threshold_timestamp = iso8601.parse_date(
            dbinf.insert_packets[pkt_index].Who.Date.text)
        pkts_before_calc = 0
        pkts_before_or_same_calc = 0
        for v in simple_populated_db.insert_packets:
            whodate = iso8601.parse_date(v.Who.Date.text)
            if whodate < threshold_timestamp:
                pkts_before_calc += 1
            if whodate <= threshold_timestamp:
                pkts_before_or_same_calc += 1

        pkts_before_db = s.query(Voevent).filter(
            Voevent.author_datetime < threshold_timestamp
        ).count()
        assert pkts_before_calc == pkts_before_db


# Path: voeventdb/server/database/models.py
# class Voevent(Base, OdictMixin):
#     """
#     Define the core VOEvent table.
# 
#     .. NOTE::
#         On datetimes:
#         We store datetimes 'with timezone' even though we'll use the convention
#         of storing UTC throughout (and VOEvents are UTC too).
#         This helps to make explicit what convention we're using and avoid
#         any possible timezone-naive mixups down the line.
# 
#         However, if this ever gets used at (really large!) scale, then may
#         need to be wary of issues with partitioning really large datasets, cf:
#         http://justatheory.com/computers/databases/postgresql/use-timestamptz.html
#         http://www.postgresql.org/docs/9.1/static/ddl-partitioning.html
# 
#     """
#     __tablename__ = 'voevent'
#     # Basics: Attributes or associated metadata present for almost every VOEvent:
#     id = Column(sql.Integer, primary_key=True)
#     received = Column(
#         sql.DateTime(timezone=True), nullable=False,
#         doc="Records when the packet was loaded into the database"
#     )
#     ivorn = Column(sql.String, nullable=False, unique=True, index=True)
#     stream = Column(sql.String, index=True)
#     role = Column(sql.Enum(vp.definitions.roles.observation,
#                            vp.definitions.roles.prediction,
#                            vp.definitions.roles.utility,
#                            vp.definitions.roles.test,
#                            name="roles_enum",
#                            ),
#                   index=True
#                   )
#     version = Column(sql.String)
#     # Who
#     author_ivorn = Column(sql.String)
#     author_datetime = Column(sql.DateTime(timezone=True))
#     # Finally, the raw XML. Mark this for lazy-loading, cf:
#     # http://docs.sqlalchemy.org/en/latest/orm/loading_columns.html
#     xml = deferred(Column(sql.LargeBinary))
# 
#     cites = relationship("Cite", backref=backref('voevent', order_by=id),
#                          cascade="all, delete, delete-orphan")
# 
#     coords = relationship('Coord', backref=backref('voevent', order_by=id),
#                           cascade="all, delete, delete-orphan")
# 
#     @staticmethod
#     def from_etree(root, received=pytz.UTC.localize(datetime.utcnow())):
#         """
#         Init a Voevent row from an LXML etree loaded with voevent-parse
#         """
#         ivorn = root.attrib['ivorn']
#         # Stream- Everything except before the '#' separator,
#         # with the prefix 'ivo://' removed:
#         stream = ivorn.split('#')[0][6:]
#         row = Voevent(ivorn=ivorn,
#                       role=root.attrib['role'],
#                       version=root.attrib['version'],
#                       stream=stream,
#                       xml=vp.dumps(root),
#                       received=received,
#                       )
#         row.author_datetime = _grab_xpath(root, 'Who/Date',
#                                           converter=iso8601.parse_date)
#         row.author_ivorn = _grab_xpath(root, 'Who/AuthorIVORN')
# 
#         row.cites = Cite.from_etree(root)
#         if not _has_bad_coords(root, stream):
#             try:
#                 row.coords = Coord.from_etree(root)
#             except:
#                 logger.exception(
#                     'Error loading coords for ivorn {}, coords dropped.'.format(
#                         ivorn)
#                 )
#         return row
# 
#     def _reformatted_prettydict(self, valformat=str):
#         pd = self.prettydict()
#         return '\n'.join(
#             ("{}={}".format(k, valformat(v)) for k, v in pd.iteritems()))
# 
#     def __repr__(self):
#         od = self.to_odict()
#         content = ',\n'.join(
#             ("{}={}".format(k, repr(v)) for k, v in od.iteritems()))
#         return """<Voevent({})>""".format(content)
# 
#     def __str__(self):
#         od = self.to_odict()
#         od.pop('xml')
#         content = ',\n    '.join(
#             ("{}={}".format(k, str(v)) for k, v in od.iteritems()))
#         return """<Voevent({})>""".format(content)


# Path: voeventdb/server/tests/test_database/test_db_basic_queries.py
import iso8601
import pytest
from voeventdb.server.database.models import Voevent

        s = fixture_db_session
        dbinf = simple_populated_db
        xml_pkts = [r.xml for r in s.query(Voevent.xml).all()]
        assert xml_pkts == dbinf.insert_packets_dumps

        xml_single = s.query(Voevent.xml).filter(
            Voevent.ivorn == dbinf.insert_packets[0].attrib['ivorn']
        ).scalar()
        assert xml_single == dbinf.insert_packets_dumps[0]

    def test_datetime_comparison(self, fixture_db_session, simple_populated_db):
        s = fixture_db_session
        dbinf = simple_populated_db
        pkt_index = 5
        threshold_timestamp = iso8601.parse_date(
            dbinf.insert_packets[pkt_index].Who.Date.text)
        pkts_before_calc = 0
        pkts_before_or_same_calc = 0
        for v in simple_populated_db.insert_packets:
            whodate = iso8601.parse_date(v.Who.Date.text)
            if whodate < threshold_timestamp:
                pkts_before_calc += 1
            if whodate <= threshold_timestamp:
                pkts_before_or_same_calc += 1

        pkts_before_db = s.query(Voevent).filter(
            Voevent.author_datetime < threshold_timestamp
        ).count()
        assert pkts_before_calc == pkts_before_db


        pkts_before_or_same_db = s.query(Voevent).filter(