Passed
Branch master (6b380a)
by Vincent
13:11
created

create(Record)   A

Complexity

Conditions 1

Size

Total Lines 6
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 6
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
/*
2
 * This file is part of Araknemu.
3
 *
4
 * Araknemu is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU Lesser General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * Araknemu is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public License
15
 * along with Araknemu.  If not, see <https://www.gnu.org/licenses/>.
16
 *
17
 * Copyright (c) 2017-2019 Vincent Quatrevieux
18
 */
19
20
package fr.quatrevieux.araknemu.data.world.repository.implementation.sql;
21
22
import fr.quatrevieux.araknemu.core.dbal.executor.QueryExecutor;
23
import fr.quatrevieux.araknemu.core.dbal.repository.Record;
24
import fr.quatrevieux.araknemu.core.dbal.repository.RepositoryException;
25
import fr.quatrevieux.araknemu.core.dbal.repository.RepositoryUtils;
26
import fr.quatrevieux.araknemu.data.world.entity.environment.npc.Question;
27
import fr.quatrevieux.araknemu.data.world.entity.environment.npc.ResponseAction;
28
import fr.quatrevieux.araknemu.data.world.repository.environment.npc.ResponseActionRepository;
29
import org.apache.commons.lang3.StringUtils;
30
31
import java.sql.ResultSet;
32
import java.sql.SQLException;
33
import java.util.Collections;
34
import java.util.List;
35
import java.util.Map;
36
import java.util.stream.Collectors;
37
38
/**
39
 * Response action repository implementation for SQL database
40
 *
41
 * @see ResponseAction
42
 */
43
final class SqlResponseActionRepository implements ResponseActionRepository {
44
    private final QueryExecutor executor;
45
    private final RepositoryUtils<ResponseAction> utils;
46
47 1
    public SqlResponseActionRepository(QueryExecutor executor) {
48 1
        this.executor = executor;
49
50 1
        utils = new RepositoryUtils<>(this.executor, new Loader());
51 1
    }
52
53
    @Override
54
    public void initialize() throws RepositoryException {
55
        try {
56 1
            executor.query(
57
                "CREATE TABLE NPC_RESPONSE_ACTION(" +
58
                    "RESPONSE_ID INTEGER," +
59
                    "ACTION VARCHAR(12)," +
60
                    "ARGUMENTS VARCHAR(255)," +
61
                    "PRIMARY KEY (RESPONSE_ID, ACTION)" +
62
                ")"
63
            );
64
        } catch (SQLException e) {
65
            throw new RepositoryException(e);
66 1
        }
67 1
    }
68
69
    @Override
70
    public void destroy() throws RepositoryException {
71
        try {
72 1
            executor.query("DROP TABLE NPC_RESPONSE_ACTION");
73
        } catch (SQLException e) {
74
            throw new RepositoryException(e);
75 1
        }
76 1
    }
77
78
    @Override
79
    public ResponseAction get(ResponseAction entity) throws RepositoryException {
80 1
        return utils.findOne(
81
            "SELECT * FROM NPC_RESPONSE_ACTION WHERE RESPONSE_ID = ? AND ACTION = ?",
82
            stmt -> {
83 1
                stmt.setInt(1, entity.responseId());
84 1
                stmt.setString(2, entity.action());
85 1
            }
86
        );
87
    }
88
89
    @Override
90
    public boolean has(ResponseAction entity) throws RepositoryException {
91 1
        return utils.aggregate(
92
            "SELECT COUNT(*) FROM NPC_RESPONSE_ACTION WHERE RESPONSE_ID = ? AND ACTION = ?",
93
            stmt -> {
94 1
                stmt.setInt(1, entity.responseId());
95 1
                stmt.setString(2, entity.action());
96 1
            }
97
        ) > 0;
98
    }
99
100
    @Override
101
    public Map<Integer, List<ResponseAction>> all() throws RepositoryException {
102 1
        return
103
            utils
104 1
                .findAll("SELECT * FROM NPC_RESPONSE_ACTION")
105 1
                .stream()
106 1
                .collect(Collectors.groupingBy(ResponseAction::responseId))
107
        ;
108
    }
109
110
    @Override
111
    @SuppressWarnings("array.access.unsafe.high.constant") // checker do not handle switch case
112
    public Map<Integer, List<ResponseAction>> byQuestion(Question question) {
113 1
        switch (question.responseIds().length) {
114
            case 0:
115 1
                return Collections.emptyMap();
116
117
            case 1:
118 1
                final List<ResponseAction> ras = utils.findAll(
119
                    "SELECT * FROM NPC_RESPONSE_ACTION WHERE RESPONSE_ID = ?",
120 1
                    rs -> rs.setInt(1, question.responseIds()[0])
121
                );
122
123 1
                return ras.isEmpty() ? Collections.emptyMap() : Collections.singletonMap(question.responseIds()[0], ras);
124
125
            default:
126 1
                return utils.findAll(
127 1
                        "SELECT * FROM NPC_RESPONSE_ACTION WHERE RESPONSE_ID IN(" + StringUtils.repeat("?, ", question.responseIds().length - 1) + "?)",
128
                        rs -> {
129 1
                            for (int i = 0; i < question.responseIds().length; ++i) {
130 1
                                rs.setInt(i + 1, question.responseIds()[i]);
131
                            }
132 1
                        }
133
                    )
134 1
                    .stream()
135 1
                    .collect(Collectors.groupingBy(ResponseAction::responseId))
136
                ;
137
        }
138
    }
139
140
    private static class Loader implements RepositoryUtils.Loader<ResponseAction> {
0 ignored issues
show
Comprehensibility introduced by
Class or interface names should not shadow other classes or interfaces. In general, shadowing is a bad practice as it makes code harder to understand. Consider renaming this class.
Loading history...
141
        @Override
142
        public ResponseAction create(Record record) throws SQLException {
143 1
            return new ResponseAction(
144 1
                record.getInt("RESPONSE_ID"),
145 1
                record.getString("ACTION"),
146 1
                record.getString("ARGUMENTS")
147
            );
148
        }
149
150
        @Override
151
        public ResponseAction fillKeys(ResponseAction entity, ResultSet keys) {
152
            throw new RepositoryException("Read-only entity");
153
        }
154
    }
155
}
156