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         }
72         catch (Exception e) {
73             logger.error(e.msg).collectException;
74             data.errorInData = true;
75         }
76         return this;
77     }
78 
79     ExitStatusType run(ref Database db) {
80         if (data.errorInData) {
81             logger.error("Invalid parameters").collectException;
82             return ExitStatusType.Errors;
83         }
84 
85         final switch (data.admin_op) {
86         case AdminOperation.none:
87             logger.error("No admin operation specified").collectException;
88             return ExitStatusType.Errors;
89         case AdminOperation.resetMutant:
90             return resetMutant(db, data.kinds,
91                     data.status, data.to_status);
92         case AdminOperation.removeMutant:
93             return removeMutant(db, data.kinds);
94         case AdminOperation.removeTestCase:
95             return removeTestCase(db,
96                     data.kinds, data.test_case_regex);
97         }
98     }
99 }
100 
101 ExitStatusType resetMutant(ref Database db, const Mutation.Kind[] kinds,
102         Mutation.Status status, Mutation.Status to_status) @safe nothrow {
103     try {
104         db.resetMutant(kinds, status, to_status);
105     }
106     catch (Exception e) {
107         logger.error(e.msg).collectException;
108         return ExitStatusType.Errors;
109     }
110 
111     return ExitStatusType.Ok;
112 }
113 
114 ExitStatusType removeMutant(ref Database db, const Mutation.Kind[] kinds) @safe nothrow {
115     try {
116         db.removeMutant(kinds);
117     }
118     catch (Exception e) {
119         logger.error(e.msg).collectException;
120         return ExitStatusType.Errors;
121     }
122 
123     return ExitStatusType.Ok;
124 }
125 
126 ExitStatusType removeTestCase(ref Database db, const Mutation.Kind[] kinds, const Regex!char regex) @safe nothrow {
127     try {
128         db.removeTestCase(regex, kinds);
129     }
130     catch (Exception e) {
131         logger.error(e.msg).collectException;
132         return ExitStatusType.Errors;
133     }
134     return ExitStatusType.Ok;
135 }