Repository: mindsdb/mindsdb

Issue:
[New Integration]: Integration With TimeScaleDB
### Is there an existing integration?

- [X] I have searched the existing integrations.

### Use Case

TimescaleDB is an open-source developed by Timescale Inc. It is written in C and extends PostgreSQL. TimescaleDB supports standard SQL queries and is a relational database.Additional SQL functions and table structures provide support for time series data oriented towards storage, performance, and analysis facilities for data-at-scale. Performance characteristics have been compared to InfluxDB Time-based data partitioning provides for improved query execution and performance when used for time oriented applications.

### Motivation

As PostgreSQL is already working with mindsdb .
TimeScaleDB is time series extension of PostgreSQL also it works faster than PostgreSQL .

### Implementation

_No response_

### Anything else?

_No response_


Discussion:

Resolving patch:
diff --git a/mindsdb/integrations/handlers/timescaledb_handler/__about__.py b/mindsdb/integrations/handlers/timescaledb_handler/__about__.py
new file mode 100644
--- /dev/null
+++ b/mindsdb/integrations/handlers/timescaledb_handler/__about__.py
@@ -0,0 +1,9 @@
+__title__ = 'MindsDB TimeScaleDB handler'
+__package_name__ = 'mindsdb_timescaledb_handler'
+__version__ = '0.0.1'
+__description__ = "MindsDB handler for TimeScaleDB"
+__author__ = 'Parthiv MAkwana'
+__github__ = 'https://github.com/mindsdb/mindsdb'
+__pypi__ = 'https://pypi.org/project/mindsdb/'
+__license__ = 'GPL-3.0'
+__copyright__ = 'Copyright 2022- mindsdb'
diff --git a/mindsdb/integrations/handlers/timescaledb_handler/__init__.py b/mindsdb/integrations/handlers/timescaledb_handler/__init__.py
new file mode 100644
--- /dev/null
+++ b/mindsdb/integrations/handlers/timescaledb_handler/__init__.py
@@ -0,0 +1,19 @@
+from mindsdb.integrations.libs.const import HANDLER_TYPE
+
+from .__about__ import __version__ as version, __description__ as description
+try:
+    from .timescaledb_handler import PostgresHandler as Handler
+    import_error = None
+except Exception as e:
+    Handler = None
+    import_error = e
+
+title = 'TimeScaleDB'
+name = 'timescaledb'
+type = HANDLER_TYPE.DATA
+icon_path = 'icon.svg'
+
+__all__ = [
+    'Handler', 'version', 'name', 'type', 'title',
+    'description', 'import_error', 'icon_path'
+]
diff --git a/mindsdb/integrations/handlers/timescaledb_handler/timescaledb_handler.py b/mindsdb/integrations/handlers/timescaledb_handler/timescaledb_handler.py
new file mode 100644
--- /dev/null
+++ b/mindsdb/integrations/handlers/timescaledb_handler/timescaledb_handler.py
@@ -0,0 +1,46 @@
+from ..postgres_handler import Handler as PostgresHandler
+from collections import OrderedDict
+from mindsdb.integrations.libs.const import HANDLER_CONNECTION_ARG_TYPE as ARG_TYPE
+
+
+class TimeScaleDBHandler(PostgresHandler):
+    name = 'timescaledb'
+
+    def __init__(self, name, **kwargs):
+        super().__init__(name, **kwargs)
+
+
+
+
+connection_args = OrderedDict(
+    host={
+        'type': ARG_TYPE.STR,
+        'description': 'The host name or IP address of the TimeScaleDB server/database.'
+    },
+    database={
+        'type': ARG_TYPE.STR,
+        'description': """
+            The database name to use when connecting with the TimeScaleDB server.
+        """
+    },
+    user={
+        'type': ARG_TYPE.STR,
+        'description': 'The user name used to authenticate with the TimeScaleDB server.'
+    },
+    password={
+        'type': ARG_TYPE.STR,
+        'description': 'The password to authenticate the user with the TimeScaleDB server.'
+    },
+    port={
+        'type': ARG_TYPE.INT,
+        'description': 'Specify port to connect TimeScaleDB '
+    }
+)
+
+connection_args_example = OrderedDict(
+    host='127.0.0.1',
+    port=36806,
+    password='P455W0rD',
+    user='tsdbadmin',
+    database="tsdb"
+)


Test patch:
diff --git a/mindsdb/integrations/handlers/timescaledb_handler/tests/__init__.py b/mindsdb/integrations/handlers/timescaledb_handler/tests/__init__.py
new file mode 100644
diff --git a/mindsdb/integrations/handlers/timescaledb_handler/tests/test_timescaledb_handler.py b/mindsdb/integrations/handlers/timescaledb_handler/tests/test_timescaledb_handler.py
new file mode 100644
--- /dev/null
+++ b/mindsdb/integrations/handlers/timescaledb_handler/tests/test_timescaledb_handler.py
@@ -0,0 +1,51 @@
+import unittest
+from mindsdb.integrations.handlers.timescaledb_handler.timescaledb_handler import TimeScaleDBHandler
+from mindsdb.api.mysql.mysql_proxy.libs.constants.response_type import RESPONSE_TYPE
+
+
+class TimeScaleDBHandlerTest(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        cls.kwargs = {
+            "host": "localhost",
+            "port": 36806,
+            "user": "USERNAME",
+            "password": "P455W0rd",
+            "database": "tsdb"
+        }
+        cls.handler = TimeScaleDBHandler('test_timescaledb_handler', connection_data=cls.kwargs)
+
+    def test_0_connect(self):
+         self.handler.connect()
+
+    
+
+    def test_1_drop_table(self):
+        res = self.handler.query("DROP TABLE IF EXISTS LOVE;")
+        assert res.type is  not RESPONSE_TYPE.ERROR 
+
+
+    def test_2_create_table(self):
+        res = self.handler.query("CREATE TABLE IF NOT EXISTS LOVE (LOVER varchar(20));")
+        assert res.type is not  RESPONSE_TYPE.ERROR 
+    
+    def test_3_insert(self):
+        res = self.handler.query("INSERT INTO LOVE VALUES('Hari');")
+        assert res.type is not  RESPONSE_TYPE.ERROR 
+    
+    def test_4_get_tables(self):
+        tables = self.handler.get_tables()
+        assert tables.type is   RESPONSE_TYPE.TABLE
+
+ 
+    def test_5_select_query(self):
+        query = "SELECT * FROM LOVE;"
+        result = self.handler.native_query(query)
+        assert result.type is   RESPONSE_TYPE.TABLE
+
+    def test_5_check_connection(self):
+         self.handler.check_connection()
+
+        
+if __name__ == '__main__':
+    unittest.main()
\ No newline at end of file