Skip to content

Commit aa6d35d

Browse files
committed
Merge pull request #1131 from wasade/single-sql-conn
The single conn: forks with corks in the eye
2 parents f76c96e + c3c599c commit aa6d35d

File tree

4 files changed

+63
-29
lines changed

4 files changed

+63
-29
lines changed

qiita_core/util.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ def setUp(self):
8080
@reset_test_database
8181
def tearDown(self):
8282
super(DecoratedClass, self).tearDown()
83-
del self.conn_handler
8483

8584
return DecoratedClass
8685
return class_modifier

qiita_db/environment_manager.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ def drop_environment(ask_for_confirmation):
265265
do_drop = True
266266

267267
if do_drop:
268+
SQLConnectionHandler.close()
268269
admin_conn = SQLConnectionHandler(admin='admin_without_database')
269270
admin_conn.set_autocommit('on')
270271
admin_conn.execute('DROP DATABASE %s' % qiita_config.database)

qiita_db/sql_connection.py

Lines changed: 57 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,38 @@ class SQLConnectionHandler(object):
122122
2275: str, # cstring
123123
}
124124

125+
_user_args = {
126+
'user': qiita_config.user,
127+
'password': qiita_config.password,
128+
'database': qiita_config.database,
129+
'host': qiita_config.host,
130+
'port': qiita_config.port}
131+
132+
_admin_args = {
133+
'user': qiita_config.admin_user,
134+
'password': qiita_config.admin_password,
135+
'database': qiita_config.database,
136+
'host': qiita_config.host,
137+
'port': qiita_config.port}
138+
139+
_admin_nodb_args = {
140+
'user': qiita_config.admin_user,
141+
'password': qiita_config.admin_password,
142+
'host': qiita_config.host,
143+
'port': qiita_config.port}
144+
145+
_user_conn = None
146+
_admin_conn = None
147+
_admin_nodb_conn = None
148+
149+
_conn_map = {'no_admin': '_user_conn',
150+
'admin_with_database': '_admin_conn',
151+
'admin_without_database': '_admin_nodb_conn'}
152+
153+
_args_map = {'no_admin': '_user_args',
154+
'admin_with_database': '_admin_args',
155+
'admin_without_database': '_admin_nodb_args'}
156+
125157
"""Encapsulates the DB connection with the Postgres DB
126158
127159
Parameters
@@ -142,39 +174,25 @@ def __init__(self, admin='no_admin'):
142174
"'admin_without_database'}")
143175

144176
self.admin = admin
177+
178+
self._conn_attr = self._conn_map[self.admin]
179+
self._args_attr = self._args_map[self.admin]
180+
self._conn_args = getattr(SQLConnectionHandler, self._args_attr)
181+
self._connection = getattr(SQLConnectionHandler, self._conn_attr)
145182
self._open_connection()
183+
146184
# queues for transaction blocks. Format is {str: list} where the str
147185
# is the queue name and the list is the queue of SQL commands
148186
self.queues = {}
149187

150-
def __del__(self):
151-
# make sure if connection close fails it doesn't raise error
152-
# should only error if connection already closed
153-
try:
154-
self._connection.close()
155-
except:
156-
pass
157-
158188
def _open_connection(self):
159-
# connection string arguments for a normal user
160-
args = {
161-
'user': qiita_config.user,
162-
'password': qiita_config.password,
163-
'database': qiita_config.database,
164-
'host': qiita_config.host,
165-
'port': qiita_config.port}
166-
167-
# if this is an admin user, use the admin credentials
168-
if self.admin != 'no_admin':
169-
args['user'] = qiita_config.admin_user
170-
args['password'] = qiita_config.admin_password
171-
172-
# Do not connect to a particular database unless requested
173-
if self.admin == 'admin_without_database':
174-
del args['database']
189+
# if the connection has been created and is not closed
190+
if self._connection is not None and self._connection.closed == 0:
191+
return
175192

176193
try:
177-
self._connection = connect(**args)
194+
setattr(SQLConnectionHandler, self._conn_attr,
195+
connect(**self._conn_args))
178196
except OperationalError as e:
179197
# catch threee known common exceptions and raise runtime errors
180198
try:
@@ -202,6 +220,19 @@ def _open_connection(self):
202220
'\n\n\t%s\n%s For more information, review `INSTALL.md`'
203221
' in the Qiita installation base directory.')
204222
raise RuntimeError(ebase % (e.message, etext))
223+
else:
224+
self._connection = getattr(SQLConnectionHandler, self._conn_attr)
225+
226+
@staticmethod
227+
def close():
228+
if SQLConnectionHandler._user_conn is not None:
229+
SQLConnectionHandler._user_conn.close()
230+
231+
if SQLConnectionHandler._admin_conn is not None:
232+
SQLConnectionHandler._admin_conn.close()
233+
234+
if SQLConnectionHandler._admin_nodb_conn is not None:
235+
SQLConnectionHandler._admin_nodb_conn.close()
205236

206237
@contextmanager
207238
def get_postgres_cursor(self):
@@ -213,9 +244,7 @@ def get_postgres_cursor(self):
213244
214245
Raises a QiitaDBConnectionError if the cursor cannot be created
215246
"""
216-
if self._connection.closed:
217-
# Currently defaults to non-admin connection
218-
self._open_connection()
247+
self._open_connection()
219248

220249
try:
221250
with self._connection.cursor(cursor_factory=DictCursor) as cur:

qiita_db/test/test_sql_connection.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ def test_create_queue(self):
1111
self.conn_handler.create_queue("toy_queue")
1212
self.assertEqual(self.conn_handler.list_queues(), ["toy_queue"])
1313

14+
def test_close(self):
15+
self.assertEqual(self.conn_handler._user_conn.closed, 0)
16+
self.conn_handler.close()
17+
self.assertNotEqual(self.conn_handler._user_conn.closed, 0)
18+
1419
def test_run_queue(self):
1520
self.conn_handler.create_queue("toy_queue")
1621
self.conn_handler.add_to_queue(

0 commit comments

Comments
 (0)