• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

georgia-tech-db / eva / #850

08 Nov 2023 08:36PM UTC coverage: 0.0% (-77.0%) from 76.982%
#850

push

circleci

americast
fix metrics logic

0 of 1 new or added line in 1 file covered. (0.0%)

9789 existing lines in 252 files now uncovered.

0 of 12428 relevant lines covered (0.0%)

0.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/evadb/third_party/databases/sqlite/sqlite_handler.py
1
# coding=utf-8
2
# Copyright 2018-2023 EvaDB
3
#
4
# Licensed under the Apache License, Version 2.0 (the "License");
5
# you may not use this file except in compliance with the License.
6
# You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
UNCOV
15
import datetime
×
UNCOV
16
import sqlite3
×
17

UNCOV
18
import pandas as pd
×
19

UNCOV
20
from evadb.third_party.databases.types import (
×
21
    DBHandler,
22
    DBHandlerResponse,
23
    DBHandlerStatus,
24
)
25

26

UNCOV
27
class SQLiteHandler(DBHandler):
×
UNCOV
28
    def __init__(self, name: str, **kwargs):
×
29
        """
30
        Initialize the handler.
31
        Args:
32
            name (str): name of the DB handler instance
33
            **kwargs: arbitrary keyword arguments for establishing the connection.
34
        """
UNCOV
35
        super().__init__(name)
×
UNCOV
36
        self.database = kwargs.get("database")
×
UNCOV
37
        self.connection = None
×
38

UNCOV
39
    def connect(self):
×
40
        """
41
        Set up the connection required by the handler.
42
        Returns:
43
            DBHandlerStatus
44
        """
UNCOV
45
        try:
×
UNCOV
46
            self.connection = sqlite3.connect(
×
47
                database=self.database, isolation_level=None  # Autocommit mode.
48
            )
UNCOV
49
            return DBHandlerStatus(status=True)
×
50
        except sqlite3.Error as e:
51
            return DBHandlerStatus(status=False, error=str(e))
52

UNCOV
53
    def disconnect(self):
×
54
        """
55
        Close any existing connections.
56
        """
UNCOV
57
        if self.connection:
×
UNCOV
58
            self.connection.close()
×
59

UNCOV
60
    def get_sqlalchmey_uri(self) -> str:
×
61
        return f"sqlite:///{self.database}"
×
62

UNCOV
63
    def check_connection(self) -> DBHandlerStatus:
×
64
        """
65
        Check connection to the handler.
66
        Returns:
67
            DBHandlerStatus
68
        """
69
        if self.connection:
×
70
            return DBHandlerStatus(status=True)
×
71
        else:
72
            return DBHandlerStatus(status=False, error="Not connected to the database.")
×
73

UNCOV
74
    def get_tables(self) -> DBHandlerResponse:
×
75
        """
76
        Return the list of tables in the database.
77
        Returns:
78
            DBHandlerResponse
79
        """
80
        if not self.connection:
×
81
            return DBHandlerResponse(data=None, error="Not connected to the database.")
×
82

83
        try:
×
84
            query = "SELECT name AS table_name FROM sqlite_master WHERE type = 'table'"
×
85
            tables_df = pd.read_sql_query(query, self.connection)
×
86
            return DBHandlerResponse(data=tables_df)
×
87
        except sqlite3.Error as e:
88
            return DBHandlerResponse(data=None, error=str(e))
89

UNCOV
90
    def get_columns(self, table_name: str) -> DBHandlerResponse:
×
91
        """
92
        Returns the list of columns for the given table.
93
        Args:
94
            table_name (str): name of the table whose columns are to be retrieved.
95
        Returns:
96
            DBHandlerResponse
97
        """
98
        if not self.connection:
×
99
            return DBHandlerResponse(data=None, error="Not connected to the database.")
×
100
        """
×
101
        SQLite does not provide an in-built way to get the column names using a SELECT statement.
102
        Hence we have to use the PRAGMA command and filter the required columns.
103
        """
104
        try:
×
105
            query = f"PRAGMA table_info('{table_name}')"
×
106
            pragma_df = pd.read_sql_query(query, self.connection)
×
107
            columns_df = pragma_df[["name", "type"]].copy()
×
108
            columns_df.rename(columns={"type": "dtype"}, inplace=True)
×
109
            columns_df["dtype"] = columns_df["dtype"].apply(
×
110
                self._sqlite_to_python_types
111
            )
112

113
            return DBHandlerResponse(data=columns_df)
×
114
        except sqlite3.Error as e:
115
            return DBHandlerResponse(data=None, error=str(e))
116

UNCOV
117
    def _fetch_results_as_df(self, cursor):
×
118
        try:
×
119
            # Handling case-sensitive databases like SQLite can be tricky. Currently,
120
            # EvaDB converts all columns to lowercase, which may result in issues with
121
            # these databases. As we move forward, we are actively working on improving
122
            # this aspect within Binder.
123
            # For more information, please refer to https://github.com/georgia-tech-db/evadb/issues/1079.
124

125
            res = cursor.fetchall()
×
126
            res_df = pd.DataFrame(
×
127
                res,
128
                columns=[desc[0].lower() for desc in cursor.description]
129
                if cursor.description
130
                else [],
131
            )
132
            return res_df
×
133
        except sqlite3.ProgrammingError as e:
134
            if str(e) == "no results to fetch":
135
                return pd.DataFrame({"status": ["success"]})
136
            raise e
137

UNCOV
138
    def execute_native_query(self, query_string: str) -> DBHandlerResponse:
×
139
        """
140
        Executes the native query on the database.
141
        Args:
142
            query_string (str): query in native format
143
        Returns:
144
            DBHandlerResponse
145
        """
146
        if not self.connection:
×
147
            return DBHandlerResponse(data=None, error="Not connected to the database.")
×
148
        try:
×
149
            cursor = self.connection.cursor()
×
150
            cursor.execute(query_string)
×
151
            return DBHandlerResponse(data=self._fetch_results_as_df(cursor))
×
152
        except sqlite3.Error as e:
153
            return DBHandlerResponse(data=None, error=str(e))
154

UNCOV
155
    def _sqlite_to_python_types(self, sqlite_type: str):
×
156
        mapping = {
×
157
            "INT": int,
158
            "INTEGER": int,
159
            "TINYINT": int,
160
            "SMALLINT": int,
161
            "MEDIUMINT": int,
162
            "BIGINT": int,
163
            "UNSIGNED BIG INT": int,
164
            "INT2": int,
165
            "INT8": int,
166
            "CHARACTER": str,
167
            "VARCHAR": str,
168
            "VARYING CHARACTER": str,
169
            "NCHAR": str,
170
            "NATIVE CHARACTER": str,
171
            "NVARCHAR": str,
172
            "TEXT": str,
173
            "CLOB": str,
174
            "BLOB": bytes,
175
            "REAL": float,
176
            "DOUBLE": float,
177
            "DOUBLE PRECISION": float,
178
            "FLOAT": float,
179
            "NUMERIC": float,
180
            "DECIMAL": float,
181
            "BOOLEAN": bool,
182
            "DATE": datetime.date,
183
            "DATETIME": datetime.datetime,
184
        }
185

186
        sqlite_type = sqlite_type.split("(")[0].strip().upper()
×
187

188
        if sqlite_type in mapping:
×
189
            return mapping[sqlite_type]
×
190
        else:
191
            raise Exception(
192
                f"Unsupported column {sqlite_type} encountered in the sqlite table. Please raise a feature request!"
193
            )
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc