• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

openmrs / openmrs-core / 22357542761

24 Feb 2026 03:26PM UTC coverage: 65.393% (-0.01%) from 65.405%
22357542761

push

github

web-flow
TRUNK-6571 - Fix Java 8 Build Issues (#5840)

4 of 4 new or added lines in 2 files covered. (100.0%)

236 existing lines in 3 files now uncovered.

23798 of 36392 relevant lines covered (65.39%)

0.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.3
/api/src/main/java/org/openmrs/util/DatabaseUtil.java
1
/**
2
 * This Source Code Form is subject to the terms of the Mozilla Public License,
3
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4
 * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
5
 * the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
6
 *
7
 * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
8
 * graphic logo is a trademark of OpenMRS Inc.
9
 */
10
package org.openmrs.util;
11

12
import java.sql.Connection;
13
import java.sql.PreparedStatement;
14
import java.sql.ResultSet;
15
import java.sql.ResultSetMetaData;
16
import java.sql.SQLException;
17
import java.util.ArrayList;
18
import java.util.Arrays;
19
import java.util.HashSet;
20
import java.util.List;
21
import java.util.Set;
22

23
import org.hibernate.Session;
24
import org.openmrs.api.db.DAOException;
25
import org.slf4j.Logger;
26
import org.slf4j.LoggerFactory;
27
import org.springframework.util.StringUtils;
28

29
/**
30
 * Utility class that provides database related methods
31
 *
32
 * @since 1.6
33
 */
34
public class DatabaseUtil {
35

36
        private DatabaseUtil() {
37
        }
38

39
        private static final String MYSQL_DRIVER = "com.mysql.cj.jdbc.Driver";
40
        private static final String MYSQL_LEGACY_DRIVER = "com.mysql.jdbc.Driver";
41
        private static final String MARIADB_DRIVER = "org.mariadb.jdbc.Driver";
42
        private static final String POSTGRESQL_DRIVER = "org.postgresql.Driver";
43
        private static final String H2_DRIVER = "org.h2.Driver";
44
        private static final String HSQLDB_DRIVER = "org.hsqldb.jdbcDriver";
45
        private static final String ORACLE_DRIVER = "oracle.jdbc.driver.OracleDriver";
46
        private static final String JTDS_DRIVER = "net.sourceforge.jtds.jdbc.Driver";
47
        private static final String SQLSERVER_DRIVER = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
48
        
49
        private static final List<String> ALLOWED_JDBC_DRIVERS = Arrays.asList(
1✔
50
                MYSQL_DRIVER, MYSQL_LEGACY_DRIVER, MARIADB_DRIVER, POSTGRESQL_DRIVER, H2_DRIVER, HSQLDB_DRIVER, ORACLE_DRIVER, SQLSERVER_DRIVER, JTDS_DRIVER
51
        );
52
        
53
        private static final Logger log = LoggerFactory.getLogger(DatabaseUtil.class);
1✔
54

55
        public static final String ORDER_ENTRY_UPGRADE_SETTINGS_FILENAME = "order_entry_upgrade_settings.txt";
56

57
        /**
58
         * Executes the passed SQL query, enforcing select only if that parameter is set Load the jdbc
59
         * driver class for the database which is specified by the connectionUrl and connectionDriver
60
         * parameters <br>
61
         * <br>
62
         * This is only needed when loading up a jdbc connection manually for the first time. This is
63
         * not needed by most users and development practices with the openmrs API.
64
         *
65
         * @param connectionUrl the connection url for the database, such as
66
         * "jdbc:mysql://localhost:3306/..."
67
         * @param connectionDriver the database driver class name, such as "com.mysql.cj.jdbc.Driver"
68
         * @throws ClassNotFoundException
69
         */
70
        public static String loadDatabaseDriver(String connectionUrl, String connectionDriver) throws ClassNotFoundException {
71
                if (StringUtils.hasText(connectionDriver)) {
×
72
                        if (!ALLOWED_JDBC_DRIVERS.contains(connectionDriver)) {
×
73
                                log.error("Attempted to load an unauthorized database driver: {}", connectionDriver);
×
74
                                throw new IllegalArgumentException("Database driver '" + connectionDriver + "' is not an allowed driver.");
×
75
                        }
76
                        Class.forName(connectionDriver);
×
77
                        log.debug("set user defined Database driver class: " + connectionDriver);
×
78
                } else {
79
                        if (connectionUrl.contains("jdbc:mysql")) {
×
80
                                Class.forName(MYSQL_DRIVER);
×
81
                                connectionDriver = MYSQL_DRIVER;
×
UNCOV
82
                        } else if (connectionUrl.contains("jdbc:mariadb")) {
×
UNCOV
83
                                Class.forName(MARIADB_DRIVER);
×
84
                                connectionDriver = MARIADB_DRIVER;
×
85
                        } else if (connectionUrl.contains("jdbc:hsqldb")) {
×
UNCOV
86
                                Class.forName(HSQLDB_DRIVER);
×
UNCOV
87
                                connectionDriver = HSQLDB_DRIVER;
×
UNCOV
88
                        } else if (connectionUrl.contains("jdbc:postgresql")) {
×
UNCOV
89
                                Class.forName(POSTGRESQL_DRIVER);
×
UNCOV
90
                                connectionDriver = POSTGRESQL_DRIVER;
×
UNCOV
91
                        } else if (connectionUrl.contains("jdbc:oracle")) {
×
UNCOV
92
                                Class.forName(ORACLE_DRIVER);
×
UNCOV
93
                                connectionDriver = ORACLE_DRIVER;
×
UNCOV
94
                        } else if (connectionUrl.contains("jdbc:jtds")) {
×
UNCOV
95
                                Class.forName(JTDS_DRIVER);
×
UNCOV
96
                                connectionDriver = JTDS_DRIVER;
×
UNCOV
97
                        } else if (connectionUrl.contains("sqlserver")) {
×
UNCOV
98
                                Class.forName(SQLSERVER_DRIVER);
×
UNCOV
99
                                connectionDriver = SQLSERVER_DRIVER;
×
UNCOV
100
                        } else if (connectionUrl.contains("jdbc:h2")) {
×
UNCOV
101
                                Class.forName(H2_DRIVER);
×
UNCOV
102
                                connectionDriver = H2_DRIVER;
×
103
                        }
104
                }
UNCOV
105
                log.info("Set database driver class as " + connectionDriver);
×
UNCOV
106
                return connectionDriver;
×
107
        }
108
        
109
        /**
110
         * Executes the passed SQL query, enforcing select only if that parameter is set for given Session
111
         */
112
        public static List<List<Object>> executeSQL(Session session, String sql, boolean selectOnly) throws DAOException {
113
                sql = sql.trim();
1✔
114
                boolean dataManipulation = checkQueryForManipulationCommands(sql, selectOnly);
1✔
115
                
116
                final List<List<Object>> result = new ArrayList<>();
1✔
117
                final String query = sql;
1✔
118
                final boolean sessionDataManipulation = dataManipulation;
1✔
119
                
120
                session.doWork(conn -> populateResultsFromSQLQuery(conn, query, sessionDataManipulation, result));
1✔
121
                
122
                return result;
1✔
123
        }
124
        
125
        /**
126
         * Executes the passed SQL query, enforcing select only if that parameter is set for given Connection
127
         */
128
        public static List<List<Object>> executeSQL(Connection conn, String sql, boolean selectOnly) throws DAOException {
129
                sql = sql.trim();
1✔
130
                boolean dataManipulation = checkQueryForManipulationCommands(sql, selectOnly);
1✔
131
                List<List<Object>> result = new ArrayList<>();
1✔
132
                populateResultsFromSQLQuery(conn, sql, dataManipulation, result);
1✔
133
                return result;
1✔
134
        }
135
        
136
        private static boolean checkQueryForManipulationCommands(String sql, boolean selectOnly) {
137
                boolean dataManipulation = false;
1✔
138
                
139
                String sqlLower = sql.toLowerCase();
1✔
140
                if (sqlLower.startsWith("insert") || sqlLower.startsWith("update") || sqlLower.startsWith("delete")
1✔
141
                        || sqlLower.startsWith("alter") || sqlLower.startsWith("drop") || sqlLower.startsWith("create")
1✔
142
                        || sqlLower.startsWith("rename")) {
1✔
143
                        dataManipulation = true;
1✔
144
                }
145
                
146
                if (selectOnly && dataManipulation) {
1✔
UNCOV
147
                        throw new IllegalArgumentException("Illegal command(s) found in query string");
×
148
                }
149
                return dataManipulation;
1✔
150
        }
151
        
152
        private static void populateResultsFromSQLQuery(Connection conn, String sql, boolean dataManipulation,
153
                List<List<Object>> results) {
154
                PreparedStatement ps = null;
1✔
155
                try {
156
                        ps = conn.prepareStatement(sql);
1✔
157
                        if (dataManipulation) {
1✔
158
                                Integer i = ps.executeUpdate();
1✔
159
                                List<Object> row = new ArrayList<>();
1✔
160
                                row.add(i);
1✔
161
                                results.add(row);
1✔
162
                        } else {
1✔
163
                                ResultSet resultSet = ps.executeQuery();
1✔
164
                                
165
                                ResultSetMetaData rmd = resultSet.getMetaData();
1✔
166
                                int columnCount = rmd.getColumnCount();
1✔
167
                                
168
                                while (resultSet.next()) {
1✔
169
                                        List<Object> rowObjects = new ArrayList<>();
1✔
170
                                        for (int x = 1; x <= columnCount; x++) {
1✔
171
                                                rowObjects.add(resultSet.getObject(x));
1✔
172
                                        }
173
                                        results.add(rowObjects);
1✔
174
                                }
1✔
175
                        }
176
                }
UNCOV
177
                catch (Exception e) {
×
UNCOV
178
                        log.debug("Error while running sql: " + sql, e);
×
UNCOV
179
                        throw new DAOException("Error while running sql: " + sql + " . Message: " + e.getMessage(), e);
×
180
                }
181
                finally {
182
                        if (ps != null) {
1✔
183
                                try {
184
                                        ps.close();
1✔
185
                                }
UNCOV
186
                                catch (SQLException e) {
×
UNCOV
187
                                        log.error("Error generated while closing statement", e);
×
188
                                }
1✔
189
                        }
190
                }
191
        }
1✔
192
        
193
        /**
194
         * Gets all unique values excluding nulls in the specified column and table
195
         *
196
         * @param columnName the column
197
         * @param tableName  the table
198
         * @param connection
199
         * @return set of unique values
200
         * @throws Exception
201
         */
202
        public static <T> Set<T> getUniqueNonNullColumnValues(String columnName, String tableName, Class<T> type,
203
                Connection connection) throws Exception {
204
                Set<T> uniqueValues = new HashSet<>();
1✔
205
                final String alias = "unique_values";
1✔
206
                String select = "SELECT DISTINCT " + columnName + " AS " + alias + " FROM " + tableName + " WHERE " + columnName
1✔
207
                        + " IS NOT NULL";
208
                List<List<Object>> rows = DatabaseUtil.executeSQL(connection, select, true);
1✔
209
                for (List<Object> row : rows) {
1✔
210
                        //There can only be one column since we are selecting one
211
                        uniqueValues.add((T) row.get(0));
1✔
212
                }
1✔
213
                
214
                return uniqueValues;
1✔
215
        }
216
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc