1 /**
2 Copyright: Copyright (c) 2018, Joakim Brännström. All rights reserved.
3 License: MPL-2
4 Author: Joakim Brännström (joakim.brannstrom@gmx.com)
5 
6 This Source Code Form is subject to the terms of the Mozilla Public License,
7 v.2.0. If a copy of the MPL was not distributed with this file, You can obtain
8 one at http://mozilla.org/MPL/2.0/.
9 
10 This module contains functionality to administrate the database
11 */
12 module dextool.plugin.mutate.backend.admin;
13 
14 import std.exception : collectException;
15 import logger = std.experimental.logger;
16 
17 import dextool.type;
18 
19 import dextool.plugin.mutate.type : MutationKind, AdminOperation;
20 import dextool.plugin.mutate.backend.database : Database;
21 import dextool.plugin.mutate.backend.type : Mutation;
22 
23 auto makeAdmin() {
24     return BuildAdmin();
25 }
26 
27 private:
28 
29 import std.regex : regex, Regex;
30 
31 struct BuildAdmin {
32 @safe:
33 nothrow:
34     private struct InternalData {
35         bool errorInData;
36 
37         AdminOperation admin_op;
38         Mutation.Kind[] kinds;
39         Mutation.Status status;
40         Mutation.Status to_status;
41         Regex!char test_case_regex;
42     }
43 
44     private InternalData data;
45 
46     auto operation(AdminOperation v) {
47         data.admin_op = v;
48         return this;
49     }
50 
51     auto mutations(MutationKind[] v) {
52         import dextool.plugin.mutate.backend.utility;
53 
54         data.kinds = toInternal(v);
55         return this;
56     }
57 
58     auto fromStatus(Mutation.Status v) {
59         data.status = v;
60         return this;
61     }
62 
63     auto toStatus(Mutation.Status v) {
64         data.to_status = v;
65         return this;
66     }
67 
68     auto testCaseRegex(string v) {
69         try {
70             data.test_case_regex = regex(v);
71         } catch (Exception e) {
72             logger.error(e.msg).collectException;
73             data.errorInData = true;
74         }
75         return this;
76     }
77 
78     ExitStatusType run(ref Database db) {
79         if (data.errorInData) {
80             logger.error("Invalid parameters").collectException;
81             return ExitStatusType.Errors;
82         }
83 
84         final switch (data.admin_op) {
85         case AdminOperation.none:
86             logger.error("No admin operation specified").collectException;
87             return ExitStatusType.Errors;
88         case AdminOperation.resetMutant:
89             return resetMutant(db, data.kinds,
90                     data.status, data.to_status);
91         case AdminOperation.removeMutant:
92             return removeMutant(db, data.kinds);
93         case AdminOperation.removeTestCase:
94             return removeTestCase(db,
95                     data.kinds, data.test_case_regex);
96         }
97     }
98 }
99 
100 ExitStatusType resetMutant(ref Database db, const Mutation.Kind[] kinds,
101         Mutation.Status status, Mutation.Status to_status) @safe nothrow {
102     try {
103         db.resetMutant(kinds, status, to_status);
104     } catch (Exception e) {
105         logger.error(e.msg).collectException;
106         return ExitStatusType.Errors;
107     }
108 
109     return ExitStatusType.Ok;
110 }
111 
112 ExitStatusType removeMutant(ref Database db, const Mutation.Kind[] kinds) @safe nothrow {
113     try {
114         db.removeMutant(kinds);
115     } catch (Exception e) {
116         logger.error(e.msg).collectException;
117         return ExitStatusType.Errors;
118     }
119 
120     return ExitStatusType.Ok;
121 }
122 
123 ExitStatusType removeTestCase(ref Database db, const Mutation.Kind[] kinds, const Regex!char regex) @safe nothrow {
124     try {
125         db.removeTestCase(regex, kinds);
126     } catch (Exception e) {
127         logger.error(e.msg).collectException;
128         return ExitStatusType.Errors;
129     }
130     return ExitStatusType.Ok;
131 }