Passed
Pull Request — master (#2)
by Yang
02:09
created

Python.LocalDB.query.check_value()   A

Complexity

Conditions 4

Size

Total Lines 42
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 18
dl 0
loc 42
rs 9.5
c 0
b 0
f 0
cc 4
nop 4
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_schema
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
10
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...
11
    """
12
    Check if a subject exist in the given database and given table
13
    :param database_path: path to the SQLite database
14
    :param table_name: the name of the table being queried
15
    :param ColumnName: the column being queried
16
    :param ColumnValue: the value of the column being checked
17
    :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 (108/100).

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

Loading history...
18
    """
19
    logger = logging.getLogger('LORISQuery_CheckSubjectExist')
20
21
22
    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...
23
24
    # check if path is a file and exist.
25
    if not SQLPath.is_file():
26
        logger.info('SQLite database file does not exist!')
27
        return False
28
29
    # Try to connect the database to start the process:
30
    try:
31
        # Create on Connecting to the database file
32
        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...
33
        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...
34
35
        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 (109/100).

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

Loading history...
36
37
        # 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 (149/100).

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

Loading history...
38
        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 (160/100).

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

Loading history...
39
40
        result_rows = c.fetchall()
41
42
    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...
43
        raise IOError()
44
45
    # Closing the connection to the database file
46
    ConnectedDatabase.close()
47
48
    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...
49
        return True, result_rows
50
    else:
51
        return False, result_rows
52
53
54
def create_entry(database_path, table_name, key_field, key_field_value):
55
    """
56
    A general function to create 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 (135/100).

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

Loading history...
57
    Note it MUST be the keyfield.
58
    :param database_path: path to the database
59
    :param table_name: name of the table
60
    :param key_field: KeyFiled in the table to be created
61
    :param key_field_value: value of the key_field to be created. 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
62
    :return: if the entry has been successfully created.
63
    """
64
    logger = logging.getLogger('LORISQuery_CreateSubject')
65
66
    # if SQL already exist, quit script.
67
    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...
68
69
    # check if path is a file and exist.
70
    if not SQLPath.is_file():
71
        logger.info('SQLite database file does not exist!')
72
        return False
73
74
    # Try to connect the database to start the process:
75
    try:
76
        # Create on Connecting to the database file
77
        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...
78
        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...
79
80
        logger.info('Creating new record in SQLite database.')
81
82
        # 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 (131/100).

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

Loading history...
83
        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 (138/100).

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

Loading history...
84
    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...
85
        raise IOError()
86
87
    # Closing the connection to the database file
88
    ConnectedDatabase.commit()
89
    ConnectedDatabase.close()
90
    return True
91
92
93
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...
94
    """
95
    A general function to create 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 (135/100).

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

Loading history...
96
    :param database_path:
97
    :param table_name:
98
    :param key_field:
99
    :param key_field_value:
100
    :param field:
101
    :param field_value:
102
    :return:
103
    """
104
105
    logger = logging.getLogger('LORISQuery_CreateSubject')
106
107
    # if SQL already exist, quit script.
108
    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...
109
110
    # check if path is a file and exist.
111
    if not SQLPath.is_file():
112
        logger.info('SQLite database file does not exist!')
113
        return False
114
115
    # Try to connect the database to start the process:
116
    try:
117
        # Create on Connecting to the database file
118
        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...
119
        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...
120
121
        logger.info('Update records in SQLite database.')
122
123
        # 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 (156/100).

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

Loading history...
124
        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 (148/100).

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

Loading history...
125
126
    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...
127
        raise IOError()
128
129
    # Closing the connection to the database file
130
    ConnectedDatabase.commit()
131
    ConnectedDatabase.close()
132
133
134
def check_header(database_path, table_name):
135
    """
136
    Finds the table, connect to it, and then return the header.
137
    :param database_path:
138
    :param table_name:
139
    :return:
140
    """
141
142
    logger = logging.getLogger('SQLite check_header check')
0 ignored issues
show
Unused Code introduced by
The variable logger seems to be unused.
Loading history...
143
144
    table_header = None
145
146
    try:
147
        # Create on Connecting to the database file
148
        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...
149
150
        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...
151
        c.execute('PRAGMA TABLE_INFO({})'.format(table_name))
152
153
        table_header = c.fetchall()
154
155
        ConnectedDatabase.commit()
156
        ConnectedDatabase.close()
157
158
        return table_header  # zero indexed, LIST class of tuple of 5 elements.
159
160
    except IOError:
161
        return None
162
163
164
def check_header_index(database_path, table_name, field):
165
    """
166
    Parse the list of the header and then check it against the field provided to return the index.
167
    :param database_path:
168
    :param table_name:
169
    :param field:
170
    :return:
171
    """
172
173
    try:
174
        header_list = 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 (108/100).

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

Loading history...
175
176
        if header_list is not None:
177
            global header_index
0 ignored issues
show
Bug introduced by
Global variable 'header_index' undefined at the module level
Loading history...
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...
178
            for table_column in header_list:
179
                if table_column[1] == field:      # 1 is field name.
180
                    global header_index
0 ignored issues
show
Bug introduced by
Global variable 'header_index' undefined at the module level
Loading history...
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...
181
                    header_index = table_column[0]    # 0 is the index
182
                    break
183
            return header_index
184
    except IOError:
185
        return None
186
187
def validateLocalTableAndSchema(database_path, table_name, field):
0 ignored issues
show
Coding Style Naming introduced by
The name validateLocalTableAndSchema does not conform to the function 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...
188
    """
189
    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 (127/100).

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

Loading history...
190
    :param database_path:
191
    :param table_name:
192
    :param field: the string of the field name that is to be searched.
193
    :return:
194
    """
195
    logger = logging.getLogger('LORISQuery_validateLocalTableAndSchema')
196
    field_table_index = -1
197
    field_schema_index = -2
198
199
200
    # Schema check: note that schema contains keyfield
201
    if field not in CNBP_schema:
202
        return False, "Current planned schema does not contain " + field
203
    else:
204
        field_schema_index = CNBP_schema.index(field)
205
206
    # Table header check: table also must contain keyfield
207
    try:
208
        field_table_index = check_header_index(database_path, table_name, field)
209
        if field_table_index is None:
210
            return False, "SQLite table HEADER does not contain " + field
211
        else:
212
            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 (103/100).

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

Loading history...
213
    except IOError:
214
        return False, "Database not reachable"
215
216
    if field_table_index < 0 or field_schema_index < 0:
217
        return False, "Check program for bugs. Default values not modified"
218
219
    # 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 (113/100).

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

Loading history...
220
    if field_table_index != field_schema_index:
221
        return False, "Schema & Table definition not matching"
222
223
    return True, "Database and Schema congruently support this field and its position"
224
225
226
#if __name__ == '__main__':
227
0 ignored issues
show
coding-style introduced by
Trailing newlines
Loading history...
228