Passed
Pull Request — master (#3)
by Yang
04:58
created

LocalDB_query.check_header_index()   A

Complexity

Conditions 5

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 14
nop 3
dl 0
loc 23
rs 9.2333
c 0
b 0
f 0
1
import sys
0 ignored issues
show
Coding Style introduced by
This module should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
2
import logging
3
import sqlite3
4
from pathlib import Path
5
from LocalDB.schema import CNBP_blueprint
0 ignored issues
show
Bug introduced by
The name schema does not seem to exist in module LocalDB.
Loading history...
introduced by
Unable to import 'LocalDB.schema'
Loading history...
6
7
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
8
9
class LocalDB_query:
0 ignored issues
show
Coding Style Naming introduced by
The name LocalDB_query does not conform to the class naming conventions ([A-Z_][a-zA-Z0-9]+$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style introduced by
This class should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
Unused Code introduced by
The variable __class__ seems to be unused.
Loading history...
10
11
    @staticmethod
12
    def check_value(database_path, table_name, ColumnName, ColumnValue):
0 ignored issues
show
Coding Style Naming introduced by
The name ColumnName does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
The name ColumnValue does not conform to the argument naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
13
        """
14
        Check if a subject exist in the given database and given table
15
        :param database_path: path to the SQLite database
16
        :param table_name: the name of the table being queried
17
        :param ColumnName: the column being queried
18
        :param ColumnValue: the value of the column being checked
19
        :return: boolean on if this is ever found in the given database in the given table, in the given column.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (112/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
20
        """
21
        logger = logging.getLogger('LORISQuery_CheckSubjectExist')
22
23
24
        SQLPath = Path(database_path)
0 ignored issues
show
Coding Style Naming introduced by
The name SQLPath does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
25
26
        # check if path is a file and exist.
27
        if not SQLPath.is_file():
28
            logger.info('SQLite database file does not exist!')
29
            return False
30
31
        # Try to connect the database to start the process:
32
        try:
33
            # Create on Connecting to the database file
34
            ConnectedDatabase = sqlite3.connect(database_path)
0 ignored issues
show
Coding Style Naming introduced by
The name ConnectedDatabase does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
35
            c = ConnectedDatabase.cursor()
0 ignored issues
show
Coding Style Naming introduced by
The name c does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
36
37
            logger.info("Checking key value: " + str(ColumnValue) + " in " + ColumnName + " in SQLite database.")
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (113/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
38
39
            # Creating a new SQLite table_name with DBKey column (inspired by: https://sebastianraschka.com/Articles/2014_sqlite_in_python_tutorial.html)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (153/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
40
            c.execute('SELECT * FROM {table_name} WHERE {columnname}="{columnvalue}"'.format(table_name=table_name, columnname=ColumnName, columnvalue=ColumnValue))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (164/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
41
42
            result_rows = c.fetchall()
43
44
        except Exception as e:
0 ignored issues
show
Coding Style Naming introduced by
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
45
            logger.info(e)
46
            raise IOError()
47
48
        # Closing the connection to the database file
49
        ConnectedDatabase.close()
50
51
        if len(result_rows) > 0:
0 ignored issues
show
unused-code introduced by
Unnecessary "else" after "return"
Loading history...
Unused Code introduced by
Do not use len(SEQUENCE) as condition value
Loading history...
52
            return True, result_rows
53
        else:
54
            return False, result_rows
55
56
    @staticmethod
57
    def create_entry(database_path, table_name, key_field, key_field_value):
58
        """
59
        A general function to database entries into the database BY providing the name of the KEYValue field and KEYvalue value to be created
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (141/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
60
        Note it MUST be the keyfield.
61
        :param database_path: path to the database
62
        :param table_name: name of the table
63
        :param key_field: KeyFiled in the table to be created
64
        :param key_field_value: value of the key_field to be created.
65
        :return: if the entry has been successfully created.
66
        """
67
        logger = logging.getLogger('LORISQuery_CreateSubject')
68
69
        # if SQL already exist, quit script.
70
        SQLPath = Path(database_path)
0 ignored issues
show
Coding Style Naming introduced by
The name SQLPath does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
71
72
        # check if path is a file and exist.
73
        if not SQLPath.is_file():
74
            logger.info('SQLite database file does not exist!')
75
            return False
76
77
        # Try to connect the database to start the process:
78
        try:
79
            # Create on Connecting to the database file
80
            ConnectedDatabase = sqlite3.connect(database_path)
0 ignored issues
show
Coding Style Naming introduced by
The name ConnectedDatabase does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
81
            c = ConnectedDatabase.cursor()
0 ignored issues
show
Coding Style Naming introduced by
The name c does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
82
83
            logger.info('Creating new record in SQLite database.')
84
85
            # Creating a new SQLite record row (inspired by: https://sebastianraschka.com/Articles/2014_sqlite_in_python_tutorial.html)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (135/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
86
            c.execute('INSERT OR IGNORE INTO {tn} ({field}) VALUES ("{value}")'.format(tn=table_name, field=key_field, value=key_field_value))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (142/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
87
        except Exception as e:
0 ignored issues
show
Coding Style Naming introduced by
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
88
            logger.info(e)
89
            raise IOError()
90
91
        # Closing the connection to the database file
92
        ConnectedDatabase.commit()
93
        ConnectedDatabase.close()
94
        return True
95
96
    @staticmethod
97
    def update_entry(database_path, table_name, key_field, key_field_value, field, field_value):
0 ignored issues
show
best-practice introduced by
Too many arguments (6/5)
Loading history...
98
        """
99
        A general function to database entries into the database BY providing the name of the KEYValue field and KEYvalue value to be created
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (141/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
100
        :param database_path:
101
        :param table_name:
102
        :param key_field:
103
        :param key_field_value:
104
        :param field:
105
        :param field_value:
106
        :return:
107
        """
108
109
        logger = logging.getLogger('LORISQuery_CreateSubject')
110
111
        # if SQL already exist, quit script.
112
        SQLPath = Path(database_path)
0 ignored issues
show
Coding Style Naming introduced by
The name SQLPath does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
113
114
        # check if path is a file and exist.
115
        if not SQLPath.is_file():
116
            logger.info('SQLite database file does not exist!')
117
            return False
118
119
        # Try to connect the database to start the process:
120
        try:
121
            # Create on Connecting to the database file
122
            ConnectedDatabase = sqlite3.connect(database_path)
0 ignored issues
show
Coding Style Naming introduced by
The name ConnectedDatabase does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
123
            c = ConnectedDatabase.cursor()
0 ignored issues
show
Coding Style Naming introduced by
The name c does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
124
125
            logger.info('Update records in SQLite database.')
126
127
            # Update SQLite record row where key field values are found (inspired by: https://sebastianraschka.com/Articles/2014_sqlite_in_python_tutorial.html)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (160/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
128
            c.execute('UPDATE {tn} SET {f}="{fv}" WHERE {kf}="{kfv}"'.format(tn=table_name, f=field, fv=field_value, kf=key_field, kfv=key_field_value))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (152/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
129
130
        except Exception as e:
0 ignored issues
show
Coding Style Naming introduced by
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Unused Code introduced by
The variable e seems to be unused.
Loading history...
131
            raise IOError()
132
133
        # Closing the connection to the database file
134
        ConnectedDatabase.commit()
135
        ConnectedDatabase.close()
136
137
    @staticmethod
138
    def check_header(database_path, table_name):
139
        """
140
        Finds the table, connect to it, and then return the header.
141
        :param database_path:
142
        :param table_name:
143
        :return:
144
        """
145
146
        logger = logging.getLogger('SQLite check_header check')
147
148
        table_header = None
149
150
        try:
151
            # Create on Connecting to the database file
152
            ConnectedDatabase = sqlite3.connect(database_path)
0 ignored issues
show
Coding Style Naming introduced by
The name ConnectedDatabase does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
153
154
            c = ConnectedDatabase.cursor()
0 ignored issues
show
Coding Style Naming introduced by
The name c does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
155
            c.execute('PRAGMA TABLE_INFO({})'.format(table_name))
156
157
            table_header = c.fetchall()
158
159
            ConnectedDatabase.commit()
160
            ConnectedDatabase.close()
161
162
            return table_header  # zero indexed, LIST class of tuple of 5 elements.
163
164
        except IOError as e:
0 ignored issues
show
Coding Style Naming introduced by
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
165
            logger.info(e)
166
            return table_header
167
168
    @staticmethod
169
    def check_header_index(database_path, table_name, field):
170
        """
171
        Parse the list of the header and then check it against the field provided to return the index.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (102/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
172
        :param database_path:
173
        :param table_name:
174
        :param field:
175
        :return:
176
        """
177
178
        try:
179
            header_list = LocalDB_query.check_header(database_path, table_name)  # header list is a list of 5 elements tuples.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (126/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
180
181
            if header_list is not None:
182
                global header_index
0 ignored issues
show
Coding Style Naming introduced by
The name header_index does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Bug introduced by
Global variable 'header_index' undefined at the module level
Loading history...
183
                for table_column in header_list:
184
                    if table_column[1] == field:      # 1 is field name.
185
                        global header_index
0 ignored issues
show
Coding Style Naming introduced by
The name header_index does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Bug introduced by
Global variable 'header_index' undefined at the module level
Loading history...
186
                        header_index = table_column[0]    # 0 is the index
187
                        break
188
                return header_index
189
        except IOError:
190
            return None
191
192
    @staticmethod
193
    def validateLocalTableAndSchema(database_path, table_name, field):
0 ignored issues
show
Coding Style Naming introduced by
The name validateLocalTableAndSchema does not conform to the method naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
194
        """
195
        Does a comprehensitve check to ensure the field, 1) exist in the schema, 2) exist in the local table and then are the SAME!
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (131/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
196
        :param database_path:
197
        :param table_name:
198
        :param field: the string of the field name that is to be searched.
199
        :return:
200
        """
201
        logger = logging.getLogger('LORISQuery_validateLocalTableAndSchema')
202
        field_table_index = -1
203
        field_schema_index = -2
204
205
206
        # Schema check: note that schema contains keyfield
207
        if field not in CNBP_blueprint.schema:
208
            return False, "Current planned schema does not contain " + field
209
        else:
210
            field_schema_index = CNBP_blueprint.schema.index(field)
211
212
        # Table header check: table also must contain keyfield
213
        try:
214
            field_table_index = LocalDB_query.check_header_index(database_path, table_name, field)
215
            if field_table_index is None:
216
                return False, "SQLite table HEADER does not contain " + field
217
            else:
218
                logger.info("SQLite table HEADER for the field " + field + " is " + str(field_table_index))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (107/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
219
        except IOError:
220
            return False, "Database not reachable"
221
222
        if field_table_index < 0 or field_schema_index < 0:
223
            return False, "Check program for bugs. Default values not modified"
224
225
        # This ensure we checking the right column for field information by validating against both schema and table.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (117/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
226
        if field_table_index != field_schema_index:
227
            return False, "Schema & Table definition not matching"
228
229
        return True, "Database and Schema congruently support this field and its position"
230
231
232
#if __name__ == '__main__':
233
0 ignored issues
show
coding-style introduced by
Trailing newlines
Loading history...
234