Skip to content

Commit 39d15d2

Browse files
committed
Merge pull request #1059 from antgonza/delete-sample-template
delete sample template
2 parents 8c6a90d + 3a76380 commit 39d15d2

File tree

8 files changed

+176
-49
lines changed

8 files changed

+176
-49
lines changed

qiita_db/metadata_template/base_metadata_template.py

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -772,43 +772,6 @@ def _add_common_creation_steps_to_queue(cls, md_template, obj_id,
772772
', '.join(["%s"] * len(headers))),
773773
values, many=True)
774774

775-
@classmethod
776-
def delete(cls, id_):
777-
r"""Deletes the table from the database
778-
779-
Parameters
780-
----------
781-
id_ : obj
782-
The object identifier
783-
784-
Raises
785-
------
786-
QiitaDBUnknownIDError
787-
If no metadata_template with id id_ exists
788-
"""
789-
cls._check_subclass()
790-
if not cls.exists(id_):
791-
raise QiitaDBUnknownIDError(id_, cls.__name__)
792-
793-
table_name = cls._table_name(id_)
794-
conn_handler = SQLConnectionHandler()
795-
796-
# Delete the sample template filepaths
797-
conn_handler.execute(
798-
"DELETE FROM qiita.sample_template_filepath WHERE "
799-
"study_id = %s", (id_, ))
800-
801-
conn_handler.execute(
802-
"DROP TABLE qiita.{0}".format(table_name))
803-
conn_handler.execute(
804-
"DELETE FROM qiita.{0} where {1} = %s".format(cls._table,
805-
cls._id_column),
806-
(id_,))
807-
conn_handler.execute(
808-
"DELETE FROM qiita.{0} where {1} = %s".format(cls._column_table,
809-
cls._id_column),
810-
(id_,))
811-
812775
@classmethod
813776
def exists(cls, obj_id):
814777
r"""Checks if already exists a MetadataTemplate for the provided object

qiita_db/metadata_template/sample_template.py

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
from qiita_core.exceptions import IncompetentQiitaDeveloperError
1919
from qiita_db.exceptions import (QiitaDBDuplicateError, QiitaDBError,
20-
QiitaDBWarning)
20+
QiitaDBWarning, QiitaDBUnknownIDError)
2121
from qiita_db.sql_connection import SQLConnectionHandler
2222
from qiita_db.util import (get_table_cols, get_required_sample_info_status,
2323
get_mountpoint, scrub_data)
@@ -152,6 +152,63 @@ def create(cls, md_template, study):
152152

153153
return st
154154

155+
@classmethod
156+
def delete(cls, id_):
157+
r"""Deletes the table from the database
158+
159+
Parameters
160+
----------
161+
id_ : integer
162+
The object identifier
163+
164+
Raises
165+
------
166+
QiitaDBUnknownIDError
167+
If no sample template with id id_ exists
168+
QiitaDBError
169+
If the study that owns this sample template has raw datas
170+
"""
171+
cls._check_subclass()
172+
173+
if not cls.exists(id_):
174+
raise QiitaDBUnknownIDError(id_, cls.__name__)
175+
176+
raw_datas = [str(rd) for rd in Study(cls(id_).study_id).raw_data()]
177+
if raw_datas:
178+
raise QiitaDBError("Sample template can not be erased because "
179+
"there are raw datas (%s) associated." %
180+
', '.join(raw_datas))
181+
182+
table_name = cls._table_name(id_)
183+
conn_handler = SQLConnectionHandler()
184+
185+
# Delete the sample template filepaths
186+
queue = "delete_sample_template_%d" % id_
187+
conn_handler.create_queue(queue)
188+
189+
conn_handler.add_to_queue(
190+
queue,
191+
"DELETE FROM qiita.sample_template_filepath WHERE study_id = %s",
192+
(id_, ))
193+
194+
conn_handler.add_to_queue(
195+
queue,
196+
"DROP TABLE qiita.{0}".format(table_name))
197+
198+
conn_handler.add_to_queue(
199+
queue,
200+
"DELETE FROM qiita.{0} where {1} = %s".format(cls._table,
201+
cls._id_column),
202+
(id_,))
203+
204+
conn_handler.add_to_queue(
205+
queue,
206+
"DELETE FROM qiita.{0} where {1} = %s".format(cls._column_table,
207+
cls._id_column),
208+
(id_,))
209+
210+
conn_handler.execute_queue(queue)
211+
155212
@property
156213
def study_id(self):
157214
"""Gets the study id with which this sample template is associated

qiita_db/metadata_template/test/test_base_metadata_template.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
from unittest import TestCase, main
1010

11-
from qiita_core.util import qiita_test_checker
1211
from qiita_core.exceptions import IncompetentQiitaDeveloperError
1312
from qiita_db.study import Study
1413
from qiita_db.metadata_template.base_metadata_template import (
@@ -64,12 +63,5 @@ def test_clean_validate_template(self):
6463
MetadataTemplate._clean_validate_template(None, 1, None, None)
6564

6665

67-
@qiita_test_checker()
68-
class TestMetadataTemplateReadWrite(TestCase):
69-
def test_delete(self):
70-
"""delete raises an error because it's not called from a subclass"""
71-
with self.assertRaises(IncompetentQiitaDeveloperError):
72-
MetadataTemplate.delete(1)
73-
7466
if __name__ == '__main__':
7567
main()

qiita_db/metadata_template/test/test_sample_template.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,20 +1229,26 @@ def test_create_already_prefixed_samples(self):
12291229

12301230
def test_delete(self):
12311231
"""Deletes Sample template 1"""
1232-
SampleTemplate.create(self.metadata, self.new_study)
1233-
SampleTemplate.delete(2)
1232+
st = SampleTemplate.create(self.metadata, self.new_study)
1233+
SampleTemplate.delete(st.id)
1234+
12341235
obs = self.conn_handler.execute_fetchall(
12351236
"SELECT * FROM qiita.required_sample_info WHERE study_id=2")
12361237
exp = []
12371238
self.assertEqual(obs, exp)
1239+
12381240
obs = self.conn_handler.execute_fetchall(
12391241
"SELECT * FROM qiita.study_sample_columns WHERE study_id=2")
12401242
exp = []
12411243
self.assertEqual(obs, exp)
1244+
12421245
with self.assertRaises(QiitaDBExecutionError):
12431246
self.conn_handler.execute_fetchall(
12441247
"SELECT * FROM qiita.sample_2")
12451248

1249+
with self.assertRaises(QiitaDBError):
1250+
SampleTemplate.delete(1)
1251+
12461252
def test_delete_unkonwn_id_error(self):
12471253
"""Try to delete a non existent prep template"""
12481254
with self.assertRaises(QiitaDBUnknownIDError):

qiita_pet/handlers/study_handlers/description_handlers.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,33 @@ def display_template(self, study, user, msg, msg_level, full_access,
640640
sub_tab=sub_tab,
641641
prep_tab=prep_tab)
642642

643+
def delete_sample_template(self, study, user, callback):
644+
"""Delete sample template
645+
646+
Parameters
647+
----------
648+
study : Study
649+
The current study object
650+
user : User
651+
The current user object
652+
callback : function
653+
The callback function to call with the results once the processing
654+
is done
655+
"""
656+
sample_template_id = int(self.get_argument('sample_template_id'))
657+
658+
try:
659+
SampleTemplate.delete(sample_template_id)
660+
msg = ("Sample template %d has been deleted from study: "
661+
"<b><i>%s</i></b>" % (sample_template_id, study.title))
662+
msg_level = "success"
663+
except Exception as e:
664+
msg = "Couldn't remove %d sample template: %s" % (
665+
sample_template_id, str(e))
666+
msg_level = "danger"
667+
668+
callback((msg, msg_level, 'study_information_tab', None, None))
669+
643670
def delete_raw_data(self, study, user, callback):
644671
"""Delete the selected raw data
645672
@@ -781,6 +808,7 @@ def post(self, study_id):
781808
request_approval=self.request_approval,
782809
make_sandbox=self.make_sandbox,
783810
update_investigation_type=self.update_investigation_type,
811+
delete_sample_template=self.delete_sample_template,
784812
delete_raw_data=self.delete_raw_data,
785813
delete_prep_template=self.delete_prep_template,
786814
delete_preprocessed_data=self.delete_preprocessed_data,

qiita_pet/templates/study_description.html

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,25 @@
184184
form.submit();
185185
}
186186

187+
function delete_sample_template() {
188+
sample_template_id = {{study.sample_template}};
189+
if (confirm('Are you sure you want to delete sample template ID: ' + sample_template_id + '?')) {
190+
var form = $("<form>")
191+
.attr("action", window.location.href)
192+
.attr("method", "post")
193+
.append($("<input>")
194+
.attr("type", "hidden")
195+
.attr("name", "sample_template_id")
196+
.attr("value", sample_template_id))
197+
.append($("<input>")
198+
.attr("type", "hidden")
199+
.attr("name", "action")
200+
.attr("value", "delete_sample_template"));
201+
$("body").append(form);
202+
form.submit();
203+
}
204+
}
205+
187206
function delete_raw_data(raw_data_filetype, raw_data_id) {
188207
if (confirm('Are you sure you want to delete raw data: ' + raw_data_filetype + ' (ID: ' + raw_data_id + ')?')) {
189208
var form = $("<form>")
@@ -537,7 +556,9 @@ <h2><i>{{study_alias}}</i></h2>
537556

538557
<!-- Nav tabs -->
539558
<ul class="nav nav-tabs" role="tablist" id="myTab">
540-
<li class="active"><a href="#study_information_tab" role="tab" data-toggle="tab">Study information</a></li>
559+
<li class="active">
560+
<a href="#study_information_tab" role="tab" data-toggle="tab">Study information</a>
561+
</li>
541562
{% if show_data_tabs %}
542563
<li><a href="#raw_data_tab" role="tab" data-toggle="tab">Raw data</a></li>
543564
<li><a href="#preprocessed_data_tab" role="tab" data-toggle="tab">Preprocessed data</a></li>

qiita_pet/templates/study_description_templates/study_information_tab.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@
4343

4444
<table>
4545
<tr>
46+
{% if not sample_templates %}
4647
<td>
4748
<a class="btn btn-primary" onclick="process_sample_template();">Process sample template</a>
4849
</td>
4950
<td>&nbsp; &nbsp;</td>
51+
{% end %}
5052
{% if sample_templates %}
5153
<td>
5254
<a class="btn btn-primary" onclick="update_sample_template();">Update sample template</a>
@@ -55,6 +57,10 @@
5557
<td>
5658
<a class="btn btn-primary" onclick="extend_sample_template();">Add samples to study</a>
5759
</td>
60+
<td>&nbsp; &nbsp;</td>
61+
<td>
62+
<a class="btn btn-danger glyphicon glyphicon-trash" onclick="delete_sample_template();"></a>
63+
</td>
5864
{% end %}
5965
</table>
6066
</div>

qiita_pet/test/test_study_handlers.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,5 +382,59 @@ class TestEBISubmitHandler(TestHandlerBase):
382382
pass
383383

384384

385+
class TestDelete(TestHandlerBase):
386+
database = True
387+
388+
def test_delete_sample_template(self):
389+
response = self.post('/study/description/1',
390+
{'sample_template_id': 1,
391+
'action': 'delete_sample_template'})
392+
self.assertEqual(response.code, 200)
393+
394+
# checking that the action was sent
395+
self.assertIn("Sample template can not be erased because there are "
396+
"raw datas", response.body)
397+
398+
def test_delete_raw_data(self):
399+
response = self.post('/study/description/1',
400+
{'raw_data_id': 1,
401+
'action': 'delete_raw_data'})
402+
self.assertEqual(response.code, 200)
403+
404+
# checking that the action was sent
405+
self.assertIn("Raw data 1 has prep template(s) associated so it can't "
406+
"be erased", response.body)
407+
408+
def test_delete_prep_template(self):
409+
response = self.post('/study/description/1',
410+
{'prep_template_id': 1,
411+
'action': 'delete_prep_template'})
412+
self.assertEqual(response.code, 200)
413+
414+
# checking that the action was sent
415+
self.assertIn('Cannot remove prep template 1 because a preprocessed '
416+
'data has been already generated using it.',
417+
response.body)
418+
419+
def test_delete_preprocessed_data(self):
420+
response = self.post('/study/description/1',
421+
{'preprocessed_data_id': 1,
422+
'action': 'delete_preprocessed_data'})
423+
self.assertEqual(response.code, 200)
424+
425+
# checking that the action was sent
426+
self.assertIn('Illegal operation on non sandboxed preprocessed data',
427+
response.body)
428+
429+
def test_delete_processed_data(self):
430+
response = self.post('/study/description/1',
431+
{'processed_data_id': 1,
432+
'action': 'delete_processed_data'})
433+
self.assertEqual(response.code, 200)
434+
435+
# checking that the action was sent
436+
self.assertIn('Illegal operation on non sandboxed processed data',
437+
response.body)
438+
385439
if __name__ == "__main__":
386440
main()

0 commit comments

Comments
 (0)