1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package ohos.devtools.datasources.databases.databasepool; 17 18 import ohos.devtools.datasources.databases.databaseapi.DataBaseApi; 19 import ohos.devtools.datasources.utils.common.util.BeanUtil; 20 import ohos.devtools.datasources.utils.profilerlog.ProfilerLogManager; 21 import org.apache.logging.log4j.LogManager; 22 import org.apache.logging.log4j.Logger; 23 24 import java.sql.Connection; 25 import java.sql.PreparedStatement; 26 import java.sql.ResultSet; 27 import java.sql.SQLException; 28 import java.sql.Statement; 29 import java.util.ArrayList; 30 import java.util.List; 31 import java.util.Map; 32 import java.util.Optional; 33 import java.util.stream.Collectors; 34 35 import static ohos.devtools.datasources.databases.databasepool.DataTableHelper.getDeleteCondition; 36 import static ohos.devtools.datasources.databases.databasepool.DataTableHelper.mapToString; 37 import static ohos.devtools.datasources.databases.databasepool.DataTableHelper.sqlPlaceholder; 38 39 /** 40 * Provides common data table operations 41 * 42 * @since 2021/10/26 43 */ 44 public abstract class AbstractDataStore<T> extends SqlRunnable { 45 private static final Logger LOGGER = LogManager.getLogger(AbstractDataStore.class); 46 private static final String TYPE = "type"; 47 private static final String STRING = "String"; 48 49 /** 50 * Data insertion 51 * 52 * @param dataObject dataObject 53 * @param <T> <T> 54 * @return boolean 55 */ 56 @SuppressWarnings("checkstyle:JavadocMethod") insert(T dataObject)57 public <T> boolean insert(T dataObject) { 58 if (ProfilerLogManager.isInfoEnabled()) { 59 LOGGER.info("insert"); 60 } 61 if (dataObject instanceof List) { 62 return insertInDateBaseBatch((List) dataObject); 63 } 64 return insertInDataBase(dataObject); 65 } 66 67 /** 68 * Get database connection 69 * 70 * @param tableName tableName 71 * @return Optional<Connection> 72 */ getConnectByTable(String tableName)73 protected Optional<Connection> getConnectByTable(String tableName) { 74 if (ProfilerLogManager.isInfoEnabled()) { 75 LOGGER.info("getConnectByTable"); 76 } 77 return DataBaseApi.getInstance().getConnectByTable(tableName); 78 } 79 80 /** 81 * Get database connection 82 * 83 * @param dbName dbName 84 * @return Optional<Connection> 85 */ getConnectBydbName(String dbName)86 protected Optional<Connection> getConnectBydbName(String dbName) { 87 if (ProfilerLogManager.isInfoEnabled()) { 88 LOGGER.info("getConnectBydbName"); 89 } 90 return DataBaseApi.getInstance().getConnectBydbname(dbName); 91 } 92 93 /** 94 * Insert data in bulk 95 * 96 * @param dataObject dataObject 97 * @return boolean 98 */ insertInDateBaseBatch(List<T> dataObject)99 private boolean insertInDateBaseBatch(List<T> dataObject) { 100 if (ProfilerLogManager.isInfoEnabled()) { 101 LOGGER.info("insertInDateBaseBatch"); 102 } 103 Object obj = dataObject.get(0); 104 String tableName = BeanUtil.getObjectName(obj); 105 Connection connection = DataBaseApi.getInstance().getConnectByTable(tableName).get(); 106 StringBuffer insertSql = new StringBuffer("INSERT OR IGNORE INTO "); 107 List<String> attrs = BeanUtil.getObjectAttributeNames(obj); 108 String value = attrs.stream().collect(Collectors.joining(",")); 109 insertSql.append(tableName).append("(").append(value).append(") VALUES (").append(sqlPlaceholder(attrs.size())) 110 .append(")"); 111 try { 112 PreparedStatement psmt = connection.prepareStatement(insertSql.toString()); 113 for (Object data : dataObject) { 114 applyParams(psmt, data); 115 psmt.addBatch(); 116 } 117 return executeBatch(connection, psmt); 118 } catch (SQLException throwAbles) { 119 if (ProfilerLogManager.isErrorEnabled()) { 120 LOGGER.error(throwAbles.getMessage()); 121 } 122 } 123 return false; 124 } 125 applyParams(PreparedStatement statement, T data)126 private <T> void applyParams(PreparedStatement statement, T data) { 127 if (ProfilerLogManager.isInfoEnabled()) { 128 LOGGER.info("applyParams"); 129 } 130 List<Map> list = BeanUtil.getFieldsInfo(data); 131 try { 132 for (int index = 0; index < list.size(); index++) { 133 Map objMap = list.get(index); 134 Object objValue = objMap.get("value"); 135 if (String.valueOf(objMap.get(TYPE)).contains(STRING)) { 136 if (objValue instanceof String) { 137 statement.setString(index + 1, (String) objValue); 138 } 139 } else if (String.valueOf(objMap.get(TYPE)).contains("Integer")) { 140 if (objValue instanceof Integer) { 141 statement.setLong(index + 1, (int) objValue); 142 } 143 } else if (String.valueOf(objMap.get(TYPE)).contains("Long")) { 144 if (objValue instanceof Long) { 145 statement.setLong(index + 1, (long) objValue); 146 } 147 } else if (String.valueOf(objMap.get(TYPE)).contains("byte")) { 148 if (objValue instanceof byte[]) { 149 statement.setBytes(index + 1, (byte[]) objValue); 150 } 151 } else if (String.valueOf(objMap.get(TYPE)).contains("Boolean")) { 152 if (objValue instanceof Boolean) { 153 statement.setBoolean(index + 1, (boolean) objValue); 154 } 155 } else { 156 continue; 157 } 158 } 159 } catch (SQLException exception) { 160 if (ProfilerLogManager.isErrorEnabled()) { 161 LOGGER.error(exception.getMessage()); 162 } 163 } 164 } 165 insertInDataBase(T dataObject)166 private <T> boolean insertInDataBase(T dataObject) { 167 if (ProfilerLogManager.isInfoEnabled()) { 168 LOGGER.info("insertInDataBase"); 169 } 170 String tableName = BeanUtil.getObjectName(dataObject); 171 StringBuffer insertSql = new StringBuffer("INSERT OR IGNORE INTO "); 172 List<Map<String, Object>> objectInfos = BeanUtil.getFields(dataObject); 173 StringBuffer attrs = new StringBuffer(); 174 StringBuffer values = new StringBuffer(); 175 objectInfos.forEach(objectMap -> { 176 attrs.append(objectMap.get("name")).append(","); 177 if (String.valueOf(objectMap.get(TYPE)).contains(STRING)) { 178 values.append("'").append(objectMap.get("value")).append("',"); 179 } else { 180 values.append(objectMap.get("value")).append(","); 181 } 182 }); 183 insertSql.append(tableName).append("(").append(attrs.deleteCharAt(attrs.length() - 1).toString()) 184 .append(") VALUES (").append(values.deleteCharAt(values.length() - 1).toString()).append(")"); 185 Connection connection = DataBaseApi.getInstance().getConnectByTable(tableName).get(); 186 return execute(connection, insertSql.toString()); 187 } 188 189 /** 190 * Delete database 191 * 192 * @param dataObject dataObject 193 * @return boolean 194 */ delete(T dataObject)195 public boolean delete(T dataObject) { 196 if (ProfilerLogManager.isInfoEnabled()) { 197 LOGGER.info("delete"); 198 } 199 return deleteInDataBase(dataObject); 200 } 201 deleteInDataBase(T dataObject)202 private <T> boolean deleteInDataBase(T dataObject) { 203 if (ProfilerLogManager.isInfoEnabled()) { 204 LOGGER.info("deleteInDataBase"); 205 } 206 String tableName = BeanUtil.getObjectName(dataObject); 207 StringBuffer deleteSql = new StringBuffer("DELETE FROM "); 208 Map<String, Object> beanMap = BeanUtil.getFiledsInfos(dataObject); 209 deleteSql.append(tableName).append("WHERE ").append(getDeleteCondition(beanMap)).append("1 = 1"); 210 Connection connection = DataBaseApi.getInstance().getConnectByTable(tableName).get(); 211 return execute(connection, deleteSql.toString()); 212 } 213 214 /** 215 * update 216 * 217 * @param clazz clazz 218 * @param condition condition 219 * @param setValue setValue 220 * @param <T> <T> 221 * @return boolean 222 */ update(Class<T> clazz, Map<String, Object> condition, Map<String, Object> setValue)223 public <T> boolean update(Class<T> clazz, Map<String, Object> condition, Map<String, Object> setValue) { 224 if (ProfilerLogManager.isInfoEnabled()) { 225 LOGGER.info("update"); 226 } 227 StringBuffer updateSql = new StringBuffer("UPDATE "); 228 String tableName = clazz.getSimpleName(); 229 updateSql.append(tableName).append("SET").append(mapToString(setValue)).append("WHERE ").append(condition); 230 Connection connection = DataBaseApi.getInstance().getConnectByTable(tableName).get(); 231 return execute(connection, updateSql.toString()); 232 } 233 234 /** 235 * Inquire 236 * 237 * @param clazz clazz 238 * @param value value 239 * @param condition condition 240 * @param <T> T 241 * @return List <T> 242 */ select(Class<T> clazz, Map<String, Object> value, Map<String, Object> condition)243 public <T> List<T> select(Class<T> clazz, Map<String, Object> value, Map<String, Object> condition) { 244 if (ProfilerLogManager.isInfoEnabled()) { 245 LOGGER.info("select"); 246 } 247 StringBuffer selectSql = new StringBuffer("SELECT "); 248 if (value == null || value.isEmpty()) { 249 selectSql.append("*"); 250 } 251 String tableName = clazz.getSimpleName(); 252 if (condition == null || condition.isEmpty()) { 253 selectSql.append(" FROM ").append(tableName); 254 } else { 255 selectSql.append(" FROM ").append(tableName).append(" WHERE ").append(getDeleteCondition(condition)); 256 } 257 Connection connection = DataBaseApi.getInstance().getConnectByTable(tableName).get(); 258 Statement stmt = null; 259 ResultSet rs = null; 260 try { 261 stmt = connection.createStatement(); 262 rs = executeQuery(stmt, selectSql.toString()); 263 return new DataBaseRsHelp<T>().util(clazz.newInstance(), rs); 264 } catch (SQLException | IllegalAccessException | InstantiationException | NoSuchFieldException exe) { 265 LOGGER.error("select Exception: ", exe); 266 } finally { 267 close(stmt, rs, connection); 268 } 269 return new ArrayList<>(); 270 } 271 272 /** 273 * Create a table in the specified database 274 * 275 * @param dbName db Name 276 * @param tableName table Name 277 * @param params params 278 * @return boolean 279 */ createTable(String dbName, String tableName, List<String> params)280 public boolean createTable(String dbName, String tableName, List<String> params) { 281 if (ProfilerLogManager.isInfoEnabled()) { 282 LOGGER.info("createTable"); 283 } 284 DataBaseApi dataSource = DataBaseApi.getInstance(); 285 return dataSource.createTable(dbName, tableName, params); 286 } 287 288 /** 289 * Create a table in the specified database 290 * 291 * @param dbName db Name 292 * @param tableName table Name 293 * @param sql sql 294 * @return boolean 295 */ createTable(String dbName, String tableName, String sql)296 public boolean createTable(String dbName, String tableName, String sql) { 297 if (ProfilerLogManager.isInfoEnabled()) { 298 LOGGER.info("createTable"); 299 } 300 DataBaseApi dataSource = DataBaseApi.getInstance(); 301 return dataSource.createTable(dbName, tableName, sql); 302 } 303 304 /** 305 * Create an index on the specified data table 306 * 307 * @param tableName table Name 308 * @param indexName index Name 309 * @param params params 310 * @return boolean 311 */ createIndex(String tableName, String indexName, List<String> params)312 public boolean createIndex(String tableName, String indexName, List<String> params) { 313 if (ProfilerLogManager.isInfoEnabled()) { 314 LOGGER.info("createIndex"); 315 } 316 DataBaseApi dataSource = DataBaseApi.getInstance(); 317 return dataSource.createIndex(tableName, indexName, params); 318 } 319 } 320