# Path: plenario/database.py
# def create_database(bind: Engine, database: str) -> None:
# def drop_database(bind: Engine, database: str) -> None:
# def create_extension(bind: Engine, extension: str) -> None:
# def psql(path: str) -> None:
# def postgres_session_context():
# def redshift_session_context():
# 
# Path: plenario/database.py
# def create_database(bind: Engine, database: str) -> None:
# def drop_database(bind: Engine, database: str) -> None:
# def create_extension(bind: Engine, extension: str) -> None:
# def psql(path: str) -> None:
# def postgres_session_context():
# def redshift_session_context():
# 
# Path: plenario/models/SensorNetwork.py
# class NetworkMeta(postgres_base):
#     __tablename__ = 'sensor__network_metadata'
# 
#     name = Column(String, primary_key=True)
#     nodes = relationship('NodeMeta')
#     info = Column(JSONB)
# 
#     @staticmethod
#     def index():
#         networks = postgres_session.query(NetworkMeta)
#         return [network.name.lower() for network in networks]
# 
#     def __repr__(self):
#         return '<Network {!r}>'.format(self.name)
# 
#     def tree(self):
#         sensor_tree_fn = sqla_fn.network_tree(self.name)
#         sensor_tree_result_proxy = self.query.session.execute(sensor_tree_fn)
#         return sensor_tree_result_proxy.scalar()
# 
#     def sensors(self) -> set:
# 
#         keys = []
#         for sensor in self.tree().values():
#             keys += sensor
# 
#         return set(keys)
# 
#     def features(self):
# 
#         keys = []
#         for sensor in self.tree().values():
#             for feature in sensor.values():
#                 keys += feature.values()
# 
#         return set([k.split('.')[0] for k in keys])
# 
# class FeatureMeta(postgres_base):
#     __tablename__ = 'sensor__feature_metadata'
# 
#     name = Column(String, primary_key=True)
#     networks = relationship('NetworkMeta', secondary='sensor__feature_to_network')
#     observed_properties = Column(JSONB)
# 
#     def types(self):
#         """Return a dictionary with the properties mapped to their types.
#         """
#         return {e['name']: e['type'] for e in self.observed_properties}
# 
#     def sensors(self) -> set:
#         """Return the set of sensors that report on this feature.
#         """
#         results = set()
#         for network in self.networks:
#             for node in network.tree().values():
#                 for sensor, properties in node.items():
#                     if self.name in {p.split('.')[0] for p in properties}:
#                         results.add(sensor)
# 
#         return results
# 
#     @staticmethod
#     def index(network_name=None):
#         features = []
#         for node in postgres_session.query(NodeMeta).all():
#             if network_name is None or node.sensor_network.lower() == network_name.lower():
#                 for sensor in node.sensors:
#                     for prop in sensor.observed_properties.values():
#                         features.append(prop.split('.')[0].lower())
#         return list(set(features))
# 
#     @staticmethod
#     def properties_of(feature):
#         query = postgres_session.query(FeatureMeta.observed_properties).filter(
#             FeatureMeta.name == feature)
#         return [feature + '.' + prop['name'] for prop in query.first().observed_properties]
# 
#     def mirror(self):
#         """Create feature tables in redshift for all the networks associated
#         with this feature.
#         """
#         for network in self.networks:
#             self._mirror(network.name)
# 
#     def _mirror(self, network_name: str):
#         """Create a feature table in redshift for the specified network.
#         """
#         columns = []
#         for feature in self.observed_properties:
#             column_name = feature['name']
#             column_type = database_types[feature['type'].upper()]
#             columns.append(Column(column_name, column_type, default=None))
# 
#         redshift_table = Table(
#             '{}__{}'.format(network_name, self.name),
#             redshift_base.metadata,
#             Column('node_id', String, primary_key=True),
#             Column('datetime', DateTime, primary_key=True),
#             Column('meta_id', Float, nullable=False),
#             Column('sensor', String, nullable=False),
#             *columns,
#             redshift_distkey='datetime',
#             redshift_sortkey='datetime'
#         )
# 
#         redshift_table.create()
# 
#     def __repr__(self):
#         return '<Feature {!r}>'.format(self.name)


import unittest
from sqlalchemy.exc import ProgrammingError, IntegrityError, InvalidRequestError
from plenario.database import redshift_engine
from plenario.database import postgres_session as postgres_session
from plenario.models.SensorNetwork import NetworkMeta, FeatureMeta




session = postgres_session()
objects = []


def redshift_table_exists(table_name):
    """Make an inexpensive query to the database. It the table does not exist,
    the query will cause a ProgrammingError.

    :param table_name: (string) table name
    :returns (bool) true if the table exists, false otherwise"""

    try:
        redshift_engine.execute("select '{}'::regclass".format(table_name))
        return True
    except ProgrammingError:
        return False


class TestFeatureMeta(unittest.TestCase):

    @classmethod
    def setUpClass(cls):


# Path: plenario/database.py
# def create_database(bind: Engine, database: str) -> None:
# def drop_database(bind: Engine, database: str) -> None:
# def create_extension(bind: Engine, extension: str) -> None:
# def psql(path: str) -> None:
# def postgres_session_context():
# def redshift_session_context():
# 
# Path: plenario/database.py
# def create_database(bind: Engine, database: str) -> None:
# def drop_database(bind: Engine, database: str) -> None:
# def create_extension(bind: Engine, extension: str) -> None:
# def psql(path: str) -> None:
# def postgres_session_context():
# def redshift_session_context():
# 
# Path: plenario/models/SensorNetwork.py
# class NetworkMeta(postgres_base):
#     __tablename__ = 'sensor__network_metadata'
# 
#     name = Column(String, primary_key=True)
#     nodes = relationship('NodeMeta')
#     info = Column(JSONB)
# 
#     @staticmethod
#     def index():
#         networks = postgres_session.query(NetworkMeta)
#         return [network.name.lower() for network in networks]
# 
#     def __repr__(self):
#         return '<Network {!r}>'.format(self.name)
# 
#     def tree(self):
#         sensor_tree_fn = sqla_fn.network_tree(self.name)
#         sensor_tree_result_proxy = self.query.session.execute(sensor_tree_fn)
#         return sensor_tree_result_proxy.scalar()
# 
#     def sensors(self) -> set:
# 
#         keys = []
#         for sensor in self.tree().values():
#             keys += sensor
# 
#         return set(keys)
# 
#     def features(self):
# 
#         keys = []
#         for sensor in self.tree().values():
#             for feature in sensor.values():
#                 keys += feature.values()
# 
#         return set([k.split('.')[0] for k in keys])
# 
# class FeatureMeta(postgres_base):
#     __tablename__ = 'sensor__feature_metadata'
# 
#     name = Column(String, primary_key=True)
#     networks = relationship('NetworkMeta', secondary='sensor__feature_to_network')
#     observed_properties = Column(JSONB)
# 
#     def types(self):
#         """Return a dictionary with the properties mapped to their types.
#         """
#         return {e['name']: e['type'] for e in self.observed_properties}
# 
#     def sensors(self) -> set:
#         """Return the set of sensors that report on this feature.
#         """
#         results = set()
#         for network in self.networks:
#             for node in network.tree().values():
#                 for sensor, properties in node.items():
#                     if self.name in {p.split('.')[0] for p in properties}:
#                         results.add(sensor)
# 
#         return results
# 
#     @staticmethod
#     def index(network_name=None):
#         features = []
#         for node in postgres_session.query(NodeMeta).all():
#             if network_name is None or node.sensor_network.lower() == network_name.lower():
#                 for sensor in node.sensors:
#                     for prop in sensor.observed_properties.values():
#                         features.append(prop.split('.')[0].lower())
#         return list(set(features))
# 
#     @staticmethod
#     def properties_of(feature):
#         query = postgres_session.query(FeatureMeta.observed_properties).filter(
#             FeatureMeta.name == feature)
#         return [feature + '.' + prop['name'] for prop in query.first().observed_properties]
# 
#     def mirror(self):
#         """Create feature tables in redshift for all the networks associated
#         with this feature.
#         """
#         for network in self.networks:
#             self._mirror(network.name)
# 
#     def _mirror(self, network_name: str):
#         """Create a feature table in redshift for the specified network.
#         """
#         columns = []
#         for feature in self.observed_properties:
#             column_name = feature['name']
#             column_type = database_types[feature['type'].upper()]
#             columns.append(Column(column_name, column_type, default=None))
# 
#         redshift_table = Table(
#             '{}__{}'.format(network_name, self.name),
#             redshift_base.metadata,
#             Column('node_id', String, primary_key=True),
#             Column('datetime', DateTime, primary_key=True),
#             Column('meta_id', Float, nullable=False),
#             Column('sensor', String, nullable=False),
#             *columns,
#             redshift_distkey='datetime',
#             redshift_sortkey='datetime'
#         )
# 
#         redshift_table.create()
# 
#     def __repr__(self):
#         return '<Feature {!r}>'.format(self.name)


# Path: tests/test_models/test_feature_meta.py
import unittest
from sqlalchemy.exc import ProgrammingError, IntegrityError, InvalidRequestError
from plenario.database import redshift_engine
from plenario.database import postgres_session as postgres_session
from plenario.models.SensorNetwork import NetworkMeta, FeatureMeta





session = postgres_session()
objects = []


def redshift_table_exists(table_name):
    """Make an inexpensive query to the database. It the table does not exist,
    the query will cause a ProgrammingError.

    :param table_name: (string) table name
    :returns (bool) true if the table exists, false otherwise"""

    try:
        redshift_engine.execute("select '{}'::regclass".format(table_name))
        return True
    except ProgrammingError:
        return False


class TestFeatureMeta(unittest.TestCase):

    @classmethod
    def setUpClass(cls):


        network = NetworkMeta(name='test')