package org.hsweb.web.controller.system; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import org.hsweb.ezorm.rdb.meta.RDBColumnMetaData; import org.hsweb.ezorm.rdb.meta.RDBTableMetaData; import org.hsweb.ezorm.rdb.render.SqlAppender; import org.hsweb.web.bean.po.user.User; import org.hsweb.web.core.authorize.annotation.Authorize; import org.hsweb.web.core.datasource.DynamicDataSource; import org.hsweb.web.core.exception.AuthorizeForbiddenException; import org.hsweb.web.core.logger.annotation.AccessLogger; import org.hsweb.web.core.message.ResponseMessage; import org.hsweb.web.core.utils.WebUtil; import org.hsweb.web.service.system.DataBaseManagerService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.sql.SQLException; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import static org.hsweb.web.core.message.ResponseMessage.ok; @RestController @RequestMapping("/database") @Authorize(module = "database") @AccessLogger("数据库管理") public class DatabaseManagerController { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Resource private DataBaseManagerService dataBaseManagerService; @Autowired(required = false) protected DynamicDataSource dynamicDataSource; protected Map<String, List<RDBTableMetaData>> cache = new ConcurrentHashMap<>(); protected void checkDynamicDataSourceSupport() { if (dynamicDataSource == null) logger.warn("\ndynamicDataSource is not support! if you want use it,please import " + "\n<!--------------------------------------------------------->\n" + " <dependency>\n" + " <groupId>org.hsweb</groupId>\n" + " <artifactId>hsweb-web-datasource</artifactId>\n" + " </dependency>" + "\n<!--------------------------------------------------------->" + "\n to pom.xml"); } @RequestMapping(value = "/tables", method = RequestMethod.GET) @Authorize(action = "R") @AccessLogger("获取所有表结构") public ResponseMessage showTables(boolean reload) throws SQLException { List<RDBTableMetaData> cached = cache.get("default"); if (cached == null || reload) { cached = dataBaseManagerService.getTableList(); cache.put("default", cached); } return ok(cached) .include(RDBTableMetaData.class, "name", "alias", "comment", "columns") .include(RDBColumnMetaData.class, "name", "alias", "comment", "dataType","jdbcType", "javaType", "notNull", "primaryKey", "properties") .onlyData(); } @RequestMapping(value = "/exec", method = RequestMethod.POST) @AccessLogger("执行SQL") public ResponseMessage exec(@RequestBody String sql) throws Exception { return ok(dataBaseManagerService.execSql(buildSqlList(sql))); } @RequestMapping(value = "/sql/alter", method = RequestMethod.POST) @AccessLogger("查询修改表结构SQL") public ResponseMessage showAlterSql(@RequestBody JSONObject jsonObject) throws Exception { return ok(dataBaseManagerService.createAlterSql(createTableMetaDataByJson(jsonObject))); } @RequestMapping(value = "/sql/create", method = RequestMethod.POST) @AccessLogger("查询创建表结构SQL") public ResponseMessage showCreateSql(@RequestBody JSONObject jsonObject) throws Exception { return ok(dataBaseManagerService.createCreateSql(createTableMetaDataByJson(jsonObject))); } @RequestMapping(value = "/tables/{dataSourceId}", method = RequestMethod.GET) @Authorize(action = "R") @AccessLogger("指定数据源获取表结构") public ResponseMessage showTables(@PathVariable("dataSourceId") String dataSourceId, boolean reload) throws SQLException { try { checkDynamicDataSourceSupport(); DynamicDataSource.use(dataSourceId); List<RDBTableMetaData> cached = cache.get(dataSourceId); if (cached == null || reload) { cached = dataBaseManagerService.getTableList(); cache.put(dataSourceId, cached); } return ok(cached) .include(RDBTableMetaData.class, "name", "alias", "comment", "columns") .include(RDBColumnMetaData.class, "name", "alias", "comment", "jdbcType", "javaType", "dataType", "notNull", "primaryKey", "properties") .onlyData(); } finally { DynamicDataSource.useDefault(false); } } public List<String> buildSqlList(String sql) { String[] list = sql.split("[\n]"); List<SqlAppender> sqlList = new LinkedList<>(); SqlAppender[] tmp = {new SqlAppender()}; Arrays.asList(list).stream() .filter(s -> !s.startsWith("--") && s.trim().length() != 0) .forEach(s1 -> { if (s1.trim().endsWith(";")) { s1 = s1.trim(); tmp[0].add(s1.substring(0, s1.length() - 1), "\n"); sqlList.add(tmp[0]); tmp[0] = new SqlAppender(); } else { tmp[0].add(s1, "\n"); } }); if (!tmp[0].isEmpty()) sqlList.add(tmp[0]); List<String> sqlStringList = new ArrayList<>(); User user = WebUtil.getLoginUser(); for (SqlAppender appender : sqlList) { String sqlLine = appender.toString().trim(); String type = sqlLine.split("[ ]")[0]; if (!user.hasAccessModuleAction("database", type.toLowerCase())) throw new AuthorizeForbiddenException("权限不足"); sqlStringList.add(sqlLine); } return sqlStringList; } @RequestMapping(value = "/exec/{dataSourceId}", method = RequestMethod.POST) @AccessLogger("指定数据源执行SQL") public ResponseMessage exec(@PathVariable("dataSourceId") String dataSourceId, @RequestBody String sql) throws Exception { checkDynamicDataSourceSupport(); DynamicDataSource.use(dataSourceId); try { return ok(dataBaseManagerService.execSql(buildSqlList(sql))); } finally { DynamicDataSource.useDefault(false); } } @RequestMapping(value = "/sql/alter/{dataSourceId}", method = RequestMethod.POST) @AccessLogger("指定数据源查询修改表结构SQL") public ResponseMessage showAlterSql(@PathVariable("dataSourceId") String dataSourceId, @RequestBody JSONObject jsonObject) throws Exception { try { checkDynamicDataSourceSupport(); DynamicDataSource.use(dataSourceId); return ok(dataBaseManagerService.createAlterSql(createTableMetaDataByJson(jsonObject))); } finally { DynamicDataSource.useDefault(false); } } @RequestMapping(value = "/sql/create/{dataSourceId}", method = RequestMethod.POST) @AccessLogger("指定数据源查询创建表结构SQL") public ResponseMessage showCreateSql(@PathVariable("dataSourceId") String dataSourceId, @RequestBody JSONObject jsonObject) throws Exception { try { checkDynamicDataSourceSupport(); DynamicDataSource.use(dataSourceId); return ok(dataBaseManagerService.createCreateSql(createTableMetaDataByJson(jsonObject))); } finally { DynamicDataSource.useDefault(false); } } protected RDBTableMetaData createTableMetaDataByJson(JSONObject jsonObject) { RDBTableMetaData tableMetaData = new RDBTableMetaData(); tableMetaData.setName(jsonObject.getString("name")); tableMetaData.setComment(jsonObject.getString("comment")); JSONArray jsonArray = jsonObject.getJSONArray("columns"); for (int i = 0; i < jsonArray.size(); i++) { RDBColumnMetaData columnMetaData = jsonArray.getObject(i, RDBColumnMetaData.class); tableMetaData.addColumn(columnMetaData); } return tableMetaData; } }