# Path: thingsboard_gateway/storage/event_storage.py
# class EventStorage(ABC):
# 
#     @abstractmethod
#     def put(self, event):
#         pass
# 
#     @abstractmethod
#     def get_event_pack(self):
#         # Returns max "10" events from pack
#         pass
# 
#     @abstractmethod
#     def event_pack_processing_done(self):
#         # Indicates that events from previous "get_event_pack" may be cleared
#         pass
# 
#     @abstractmethod
#     def stop(self):
#         # Stop the storage processing
#         pass
# 
# Path: thingsboard_gateway/storage/sqlite/database.py
# class Database(Thread):
#     """
#         What this component does:
#         - abstracts creating tables for devices.
#         - writes to database
#         - reads from database
#         - delete data older than specified in config
#         ------------- ALL OF THIS IN AN ATOMIC WAY ---------
#     """
# 
#     def __init__(self, config, processing_queue: Queue):
#         super().__init__()
#         self.setDaemon(True)
#         self.settings = StorageSettings(config)
# 
#         if not exists(self.settings.data_folder_path):
#             with open(self.settings.data_folder_path, 'w'):
#                 pass
# 
#         # Pass settings to connector
#         self.db = DatabaseConnector(self.settings)
# 
#         self.db.connect()
# 
#         # process Queue
#         self.processQueue = processing_queue
# 
#         self.__stopped = False
# 
#         self.__last_msg_check = time()
# 
#         self.msg_counter = 0
#         self.start()
# 
#     def init_table(self):
#         try:
#             self.db.execute('''CREATE TABLE IF NOT EXISTS messages (timestamp INTEGER, message TEXT); ''')
#             self.db.commit()
#         except Exception as e:
#             self.db.rollback()
#             log.exception(e)
# 
#     def run(self):
#         while True:
#             self.process()
# 
#             sleep(.2)
# 
#     def process(self):
#         try:
#             if time() - self.__last_msg_check >= self.settings.messages_ttl_check_in_hours:
#                 self.__last_msg_check = time()
#                 self.delete_data_lte(self.settings.messages_ttl_in_days)
# 
#             # Signalization so that we can spam call process()
#             if not self.__stopped and self.processQueue:
#                 while self.processQueue.qsize() > 0:
# 
#                     req = self.processQueue.get()
# 
#                     log.debug("Processing %s" % req.type)
#                     if req.type is DatabaseActionType.WRITE_DATA_STORAGE:
# 
#                         message = req.data
# 
#                         timestamp = time()
# 
#                         self.db.execute('''INSERT INTO messages (timestamp, message) VALUES (?, ?);''',
#                                         [timestamp, message])
# 
#                         self.db.commit()
#             else:
#                 log.error("Storage is closed!")
# 
#         except Exception as e:
#             self.db.rollback()
#             log.exception(e)
# 
#     def read_data(self, ts):
#         try:
#             data = self.db.execute('''SELECT message FROM messages WHERE timestamp >= ? ;''', [ts])
#             return data
#         except Exception as e:
#             self.db.rollback()
#             log.exception(e)
# 
#     def delete_data(self, ts):
#         try:
#             data = self.db.execute('''DELETE FROM messages WHERE timestamp >= ? ;''', [ts])
#             return data
#         except Exception as e:
#             self.db.rollback()
#             log.exception(e)
# 
#     def delete_data_lte(self, days):
#         try:
#             ts = (datetime.datetime.now() - datetime.timedelta(days=days)).timestamp()
#             data = self.db.execute('''DELETE FROM messages WHERE timestamp <= ? ;''', [ts])
#             return data
#         except Exception as e:
#             self.db.rollback()
#             log.exception(e)
# 
#     def setProcessQueue(self, process_queue):
#         self.processQueue = process_queue
# 
#     def closeDB(self):
#         self.db.close()
# 
# Path: thingsboard_gateway/storage/sqlite/database_request.py
# class DatabaseRequest:
#     # Wrap data and write intention to better control
#     # Writes. They need to be atomic so we don't corrupt DB
#     def __init__(self, _type: DatabaseActionType, data):
#         self.type = _type
#         self.data = data
# 
# Path: thingsboard_gateway/storage/sqlite/database_action_type.py
# class DatabaseActionType(Enum):
#     WRITE_DATA_STORAGE = auto()  # Writes do not require a response on the request


from time import time
from thingsboard_gateway.storage.event_storage import EventStorage
from thingsboard_gateway.storage.sqlite.database import Database
from queue import Queue
from thingsboard_gateway.storage.sqlite.database_request import DatabaseRequest
from thingsboard_gateway.storage.sqlite.database_action_type import DatabaseActionType
from logging import getLogger
        self.last_read = time()
        self.stopped = False

    def get_event_pack(self):
        if not self.stopped:
            self.delete_time_point = self.last_read
            data_from_storage = self.read_data(self.last_read)
            self.last_read = time()

            return [item[0] for item in data_from_storage or []]
        else:
            return []

    def event_pack_processing_done(self):
        if not self.stopped:
            self.delete_data(self.delete_time_point)

    def read_data(self, ts):
        self.db.__stopped = True
        data = self.db.read_data(ts)
        self.db.__stopped = False
        return data

    def delete_data(self, ts):
        return self.db.delete_data(ts)

    def put(self, message):
        try:
            if not self.stopped:
                _type = DatabaseActionType.WRITE_DATA_STORAGE

# Path: thingsboard_gateway/storage/event_storage.py
# class EventStorage(ABC):
# 
#     @abstractmethod
#     def put(self, event):
#         pass
# 
#     @abstractmethod
#     def get_event_pack(self):
#         # Returns max "10" events from pack
#         pass
# 
#     @abstractmethod
#     def event_pack_processing_done(self):
#         # Indicates that events from previous "get_event_pack" may be cleared
#         pass
# 
#     @abstractmethod
#     def stop(self):
#         # Stop the storage processing
#         pass
# 
# Path: thingsboard_gateway/storage/sqlite/database.py
# class Database(Thread):
#     """
#         What this component does:
#         - abstracts creating tables for devices.
#         - writes to database
#         - reads from database
#         - delete data older than specified in config
#         ------------- ALL OF THIS IN AN ATOMIC WAY ---------
#     """
# 
#     def __init__(self, config, processing_queue: Queue):
#         super().__init__()
#         self.setDaemon(True)
#         self.settings = StorageSettings(config)
# 
#         if not exists(self.settings.data_folder_path):
#             with open(self.settings.data_folder_path, 'w'):
#                 pass
# 
#         # Pass settings to connector
#         self.db = DatabaseConnector(self.settings)
# 
#         self.db.connect()
# 
#         # process Queue
#         self.processQueue = processing_queue
# 
#         self.__stopped = False
# 
#         self.__last_msg_check = time()
# 
#         self.msg_counter = 0
#         self.start()
# 
#     def init_table(self):
#         try:
#             self.db.execute('''CREATE TABLE IF NOT EXISTS messages (timestamp INTEGER, message TEXT); ''')
#             self.db.commit()
#         except Exception as e:
#             self.db.rollback()
#             log.exception(e)
# 
#     def run(self):
#         while True:
#             self.process()
# 
#             sleep(.2)
# 
#     def process(self):
#         try:
#             if time() - self.__last_msg_check >= self.settings.messages_ttl_check_in_hours:
#                 self.__last_msg_check = time()
#                 self.delete_data_lte(self.settings.messages_ttl_in_days)
# 
#             # Signalization so that we can spam call process()
#             if not self.__stopped and self.processQueue:
#                 while self.processQueue.qsize() > 0:
# 
#                     req = self.processQueue.get()
# 
#                     log.debug("Processing %s" % req.type)
#                     if req.type is DatabaseActionType.WRITE_DATA_STORAGE:
# 
#                         message = req.data
# 
#                         timestamp = time()
# 
#                         self.db.execute('''INSERT INTO messages (timestamp, message) VALUES (?, ?);''',
#                                         [timestamp, message])
# 
#                         self.db.commit()
#             else:
#                 log.error("Storage is closed!")
# 
#         except Exception as e:
#             self.db.rollback()
#             log.exception(e)
# 
#     def read_data(self, ts):
#         try:
#             data = self.db.execute('''SELECT message FROM messages WHERE timestamp >= ? ;''', [ts])
#             return data
#         except Exception as e:
#             self.db.rollback()
#             log.exception(e)
# 
#     def delete_data(self, ts):
#         try:
#             data = self.db.execute('''DELETE FROM messages WHERE timestamp >= ? ;''', [ts])
#             return data
#         except Exception as e:
#             self.db.rollback()
#             log.exception(e)
# 
#     def delete_data_lte(self, days):
#         try:
#             ts = (datetime.datetime.now() - datetime.timedelta(days=days)).timestamp()
#             data = self.db.execute('''DELETE FROM messages WHERE timestamp <= ? ;''', [ts])
#             return data
#         except Exception as e:
#             self.db.rollback()
#             log.exception(e)
# 
#     def setProcessQueue(self, process_queue):
#         self.processQueue = process_queue
# 
#     def closeDB(self):
#         self.db.close()
# 
# Path: thingsboard_gateway/storage/sqlite/database_request.py
# class DatabaseRequest:
#     # Wrap data and write intention to better control
#     # Writes. They need to be atomic so we don't corrupt DB
#     def __init__(self, _type: DatabaseActionType, data):
#         self.type = _type
#         self.data = data
# 
# Path: thingsboard_gateway/storage/sqlite/database_action_type.py
# class DatabaseActionType(Enum):
#     WRITE_DATA_STORAGE = auto()  # Writes do not require a response on the request


# Path: thingsboard_gateway/storage/sqlite/sqlite_event_storage.py
from time import time
from thingsboard_gateway.storage.event_storage import EventStorage
from thingsboard_gateway.storage.sqlite.database import Database
from queue import Queue
from thingsboard_gateway.storage.sqlite.database_request import DatabaseRequest
from thingsboard_gateway.storage.sqlite.database_action_type import DatabaseActionType
from logging import getLogger

        self.last_read = time()
        self.stopped = False

    def get_event_pack(self):
        if not self.stopped:
            self.delete_time_point = self.last_read
            data_from_storage = self.read_data(self.last_read)
            self.last_read = time()

            return [item[0] for item in data_from_storage or []]
        else:
            return []

    def event_pack_processing_done(self):
        if not self.stopped:
            self.delete_data(self.delete_time_point)

    def read_data(self, ts):
        self.db.__stopped = True
        data = self.db.read_data(ts)
        self.db.__stopped = False
        return data

    def delete_data(self, ts):
        return self.db.delete_data(ts)

    def put(self, message):
        try:
            if not self.stopped:
                _type = DatabaseActionType.WRITE_DATA_STORAGE

                request = DatabaseRequest(_type, message)