getUpdateConnection()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
1
/*
2
 * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3
 * by the @authors tag. See the copyright.txt in the distribution for a
4
 * full listing of individual contributors.
5
 *
6
 * This is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU Lesser General Public License as
8
 * published by the Free Software Foundation; either version 2.1 of
9
 * the License, or (at your option) any later version.
10
 *
11
 * This software is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
 * Lesser General Public License for more details.
15
 */
16
package com.strider.datadefender.database;
17
18
import java.lang.reflect.InvocationTargetException;
19
import java.sql.Connection;
20
import java.sql.SQLException;
21
22
import com.strider.datadefender.DataDefenderException;
23
import com.strider.datadefender.DbConfig;
24
import com.strider.datadefender.DbConfig.Vendor;
25
import com.strider.datadefender.database.metadata.IMetaData;
26
import com.strider.datadefender.database.metadata.MetaData;
27
import com.strider.datadefender.database.metadata.MySqlMetaData;
28
import com.strider.datadefender.database.sqlbuilder.ISqlBuilder;
29
import com.strider.datadefender.database.sqlbuilder.SqlBuilder;
30
import com.strider.datadefender.database.sqlbuilder.MsSqlBuilder;
31
import com.strider.datadefender.database.sqlbuilder.OracleSqlBuilder;
32
import com.strider.datadefender.utils.ICloseableNoException;
33
34
import lombok.extern.log4j.Log4j2;
35
36
/**
37
 * Aggregate all the various db factories.
38
 *
39
 * Will handle the 'pooling' of connections (currently only one).
40
 *
41
 * All clients should close the connection by calling the close() method of the
42
 * AutoCloseable interface.
43
 *
44
 * @author Akira Matsuo
45
 */
46
public interface IDbFactory extends ICloseableNoException {
47
48
    ISqlBuilder createSQLBuilder() throws DataDefenderException;
49
    IMetaData fetchMetaData() throws DataDefenderException;
50
    Connection getConnection();
51
    Connection getUpdateConnection();
52
    String getVendorName();
53
54
    /**
55
     * Implements the common logic of getting/closing database connections
56
     */
57
    @Log4j2
58
    static abstract class DbFactory implements IDbFactory {
59
60
        private final Connection connection;
61
        protected Connection updateConnection;
62
        private final Vendor vendor;
63
64 1
        DbFactory(Vendor vendorName) throws DataDefenderException {
65 1
            log.info("Connecting to database");
66 1
            connection = createConnection();
67
            updateConnection = connection;
68
            vendor = vendorName;
69
        }
70
71
        @Override
72
        public void close() {
73
            if (connection != null) {
74
                try {
75
                    connection.close();
76
                } catch (SQLException e) {
77
                    log.error(e.getMessage(), e);
78
                }
79
            }
80
            if (updateConnection != null && updateConnection != connection) {
81
                try {
82
                    updateConnection.close();
83
                } catch (SQLException e) {
84
                    log.error(e.getMessage(), e);
85
                }
86
            }
87
        }
88
89
        public abstract Connection createConnection() throws DataDefenderException;
90
91
        @Override
92
        public Connection getConnection() {
93
            return connection;
94
        }
95
96
        @Override
97
        public Connection getUpdateConnection() {
98
            return updateConnection;
99
        }
100
101
        @Override
102
        public String getVendorName() {
103
            return vendor.name();
104
        }
105
    }
106
107
    /**
108
     * Generic method handling creation of a DBFactory anonymous instance for
109
     * supported database vendors.
110
     *
111
     * @param <D>
112
     * @param <M>
113
     * @param <S>
114
     * @param config
115
     * @param connection
116
     * @param metaData
117
     * @param builder
118
     * @return
119
     * @throws DataDefenderException
120
     */
121 1
    private static <D extends IDbConnection, M extends IMetaData, S extends ISqlBuilder> DbFactory getFactoryWith(
122
        final DbConfig config,
123
        Class<D> connection,
124
        Class<M> metaData,
125
        Class<S> builder
126
    ) throws DataDefenderException {
127 1
        return new DbFactory(config.getVendor()) {
128 1
            @Override
129
            public Connection createConnection() throws DataDefenderException {
130 1
                try {
131 1
                    return connection.getConstructor(DbConfig.class).newInstance(config).connect();
132
                } catch (NoSuchMethodException|InstantiationException|IllegalAccessException|InvocationTargetException e) {
133
                    throw new DataDefenderException("", e);
134
                }
135
            }
136
            @Override
137
            public IMetaData fetchMetaData() throws DataDefenderException {
138
                try {
139
                    return metaData.getConstructor(DbConfig.class, Connection.class).newInstance(config, getConnection());
140
                } catch (NoSuchMethodException|InstantiationException|IllegalAccessException|InvocationTargetException e) {
141
                    throw new DataDefenderException("", e);
142
                }
143
            }
144
            @Override
145
            public ISqlBuilder createSQLBuilder() throws DataDefenderException {
146
                try {
147
                    return builder.getConstructor(DbConfig.class).newInstance(config);
148
                } catch (NoSuchMethodException|InstantiationException|IllegalAccessException|InvocationTargetException e) {
149
                    throw new DataDefenderException("", e);
150
                }
151
            }
152
        };
153
    }
154
155
    /**
156
     * Creates and returns an IDBFactory instance for the given rdbms.
157
     *
158
     * @param config
159
     * @return db factory instance
160
     * @throws DatabaseAnonymizerException
161
     */
162 2
    public static IDbFactory get(final DbConfig config) throws DataDefenderException {
163
164 4
        if (config.getVendor() == Vendor.MYSQL || config.getVendor() == Vendor.H2) {
165 1
            DbFactory factory = getFactoryWith(config, DbConnection.class, MySqlMetaData.class, SqlBuilder.class);
166
            // create separate connection for updates
167
            factory.updateConnection = factory.createConnection();
168
            return factory;
169 2
        } else if (config.getVendor() == Vendor.SQLSERVER) {
170
            return getFactoryWith(config, MsSqlDbConnection.class, MetaData.class, MsSqlBuilder.class);
171 2
        } else if (config.getVendor() == Vendor.ORACLE) {
172
            return getFactoryWith(config, DbConnection.class, MetaData.class, OracleSqlBuilder.class);
173 2
        } else if (config.getVendor() == Vendor.POSTGRESQL) {
174
            return getFactoryWith(config, DbConnection.class, MetaData.class, SqlBuilder.class);
175
        }
176 1
        throw new IllegalArgumentException("Database " + config.getVendor() + " is not supported");
177
    }
178
}
179