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

Loader   A

Complexity

Total Complexity 2

Size/Duplication

Total Lines 16
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 13
dl 0
loc 16
ccs 9
cts 9
cp 1
rs 10
c 1
b 0
f 0
wmc 2

2 Methods

Rating   Name   Duplication   Size   Complexity  
A create(Record) 0 9 1
A fillKeys(BanIp,ResultSet) 0 3 1
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-2020 Vincent Quatrevieux
18
 */
19
20
package fr.quatrevieux.araknemu.data.living.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.living.entity.BanIp;
27
import fr.quatrevieux.araknemu.data.living.repository.BanIpRepository;
28
import fr.quatrevieux.araknemu.data.transformer.Transformer;
29
import inet.ipaddr.IPAddressString;
30
31
import java.sql.ResultSet;
32
import java.sql.SQLException;
33
import java.time.Instant;
34
import java.util.Collection;
35
36
/**
37
 * SQL Implementation for {@link BanIpRepository}
38
 */
39
final class SqlBanIpRepository implements BanIpRepository {
40
    private final QueryExecutor executor;
41
    private final RepositoryUtils<BanIp> utils;
42
    private final Transformer<Instant> instantTransformer;
43
    private final Transformer<IPAddressString> ipAddressTransformer;
44
45 1
    public SqlBanIpRepository(QueryExecutor executor, Transformer<IPAddressString> ipAddressTransformer, Transformer<Instant> instantTransformer) {
46 1
        this.executor = executor;
47 1
        this.ipAddressTransformer = ipAddressTransformer;
48 1
        this.instantTransformer = instantTransformer;
49 1
        this.utils = new RepositoryUtils<>(this.executor, new Loader());
50 1
    }
51
52
    @Override
53
    public void initialize() throws RepositoryException {
54
        try {
55 1
            executor.query(
56
                "CREATE TABLE BANIP (" +
57
                    "BANIP_ID INTEGER PRIMARY KEY AUTOINCREMENT," +
58
                    "IP_ADDRESS VARCHAR(64)," +
59
                    "UPDATED_AT DATETIME," +
60
                    "EXPIRES_AT DATETIME," +
61
                    "CAUSE VARCHAR(256)," +
62
                    "BANISHER_ID INTEGER" +
63
                ")"
64
            );
65 1
            executor.query("CREATE INDEX IDX_EXPIRES_AT ON BANIP (EXPIRES_AT)");
66
        } catch (SQLException e) {
67
            throw new RepositoryException(e);
68 1
        }
69 1
    }
70
71
    @Override
72
    public void destroy() throws RepositoryException {
73
        try {
74 1
            executor.query("DROP TABLE BANIP");
75
        } catch (SQLException e) {
76
            throw new RepositoryException(e);
77 1
        }
78 1
    }
79
80
    @Override
81
    public BanIp add(BanIp entity) {
82 1
        return utils.update(
83
            "INSERT INTO BANIP (`IP_ADDRESS`, `UPDATED_AT`, `EXPIRES_AT`, `CAUSE`, `BANISHER_ID`) VALUES (?, ?, ?, ?, ?)",
84
            stmt -> {
85 1
                stmt.setString(1, ipAddressTransformer.serialize(entity.ipAddress()));
86 1
                stmt.setString(2, instantTransformer.serialize(entity.updatedAt()));
87 1
                stmt.setString(3, entity.expiresAt().map(instantTransformer::serialize).orElse(null));
88 1
                stmt.setString(4, entity.cause());
89 1
                stmt.setInt(5, entity.banisherId());
90 1
            },
91
            entity
92
        );
93
    }
94
95
    @Override
96
    public void delete(BanIp entity) {
97 1
        utils.update("DELETE FROM BANIP WHERE IP_ADDRESS = ?", stmt -> stmt.setString(1, ipAddressTransformer.serialize(entity.ipAddress())));
98 1
    }
99
100
    @Override
101
    public BanIp get(BanIp entity) throws RepositoryException {
102 1
        return utils.findOne(
103
            "SELECT * FROM BANIP WHERE BANIP_ID = ?",
104 1
            stmt -> stmt.setInt(1, entity.id())
105
        );
106
    }
107
108
    @Override
109
    public boolean has(BanIp entity) {
110 1
        return utils.aggregate(
111
            "SELECT COUNT(*) FROM BANIP WHERE BANIP_ID = ?",
112 1
            stmt -> stmt.setInt(1, entity.id())
113
        ) > 0;
114
    }
115
116
    @Override
117
    public Collection<BanIp> available() {
118 1
        return utils.findAll(
119
            "SELECT * FROM BANIP WHERE EXPIRES_AT > ? OR EXPIRES_AT IS NULL",
120 1
            stmt -> stmt.setString(1, instantTransformer.serialize(Instant.now()))
121
        );
122
    }
123
124
    @Override
125
    public Collection<BanIp> updated(Instant after) {
126 1
        return utils.findAll(
127
            "SELECT * FROM BANIP WHERE UPDATED_AT >= ?",
128 1
            stmt -> stmt.setString(1, instantTransformer.serialize(after))
129
        );
130
    }
131
132
    @Override
133
    public void disable(IPAddressString ipAddress) {
134 1
        final String now = instantTransformer.serialize(Instant.now());
135
136 1
        utils.update(
137
            "UPDATE BANIP SET UPDATED_AT = ?, EXPIRES_AT = ? WHERE IP_ADDRESS = ? AND (EXPIRES_AT >= ? OR EXPIRES_AT IS NULL)",
138
            stmt -> {
139 1
                stmt.setString(1, now);
140 1
                stmt.setString(2, now);
141 1
                stmt.setString(3, ipAddressTransformer.serialize(ipAddress));
142 1
                stmt.setString(4, now);
143 1
            }
144
        );
145 1
    }
146
147 1
    private class Loader implements RepositoryUtils.Loader<BanIp> {
148
        @Override
149
        public BanIp create(Record record) throws SQLException {
150 1
            return new BanIp(
151 1
                record.getInt("BANIP_ID"),
152 1
                record.unserialize("IP_ADDRESS", ipAddressTransformer),
153 1
                record.unserialize("UPDATED_AT", instantTransformer),
154 1
                record.nullableUnserialize("EXPIRES_AT", instantTransformer),
155 1
                record.getString("CAUSE"),
156 1
                record.getInt("BANISHER_ID")
157
            );
158
        }
159
160
        @Override
161
        public BanIp fillKeys(BanIp entity, ResultSet keys) throws SQLException {
162 1
            return entity.withId(keys.getInt(1));
163
        }
164
    }
165
}
166