diff --git a/README.md b/README.md index 9b18e4be..b92dfe72 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ # Chat2DB -**English** | [中文](README_CN.md)· [Changelog](CHANGELOG.md) · [Doc](https://docs./) · [Report Bug](https://github.com/chat2db/Chat2DB/issues) · [PR](https://github.com/chat2db/Chat2DB/pulls) +**English** | [中文](README_CN.md)· [Changelog](CHANGELOG.md) · [Doc](https://github.com/chat2db/Chat2db-website-old/blob/main/docs/index.md) · [Report Bug](https://github.com/chat2db/Chat2DB/issues) · [PR](https://github.com/chat2db/Chat2DB/pulls) @@ -65,6 +65,8 @@ - huggingface🤗:[Chat2DB-SQL-7B](https://huggingface.co/Chat2DB/Chat2DB-SQL-7B) - modelscope:[Chat2DB-SQL-7B](https://modelscope.cn/models/Chat2DB/Chat2DB-SQL-7B/summary) +### 🎁🎁🎁 Deploy the InternLM model on Chat2DB +Thanks to [InternLM](https://github.com/InternLM/InternLM) for the strong support for this project. In the custom models of this project, multiple model weights from InternLM can be integrated. For more details, please refer to [chat2db-internlm-deploy](https://github.com/chat2db/chat2db-internlm-deploy) ## 🚀 Supported databases Chat2DB Pro supports all the following databases, including the most requested Redis feature. diff --git a/README_CN.md b/README_CN.md index 49f3abce..c2d69945 100644 --- a/README_CN.md +++ b/README_CN.md @@ -66,6 +66,8 @@ - huggingface🤗:[Chat2DB-SQL-7B](https://huggingface.co/Chat2DB/Chat2DB-SQL-7B) - modelscope:[Chat2DB-SQL-7B](https://modelscope.cn/models/Chat2DB/Chat2DB-SQL-7B/summary) +### 🎁🎁🎁 在Chat2DB上即成InternLM模型 +感谢InternLM对本项目的大力支持,在本项目中的自定义模型中,可以集成InternLM的多个模型权重,具体请参考[chat2db-internlm-deploy](https://github.com/chat2db/chat2db-internlm-deploy) ## 🚀 支持的数据库 Chat2DB Pro支持以下所有数据库,包括备受期待的Redis功能。 diff --git a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/type/PostgreSQLColumnTypeEnum.java b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/type/PostgreSQLColumnTypeEnum.java index c0f96f0e..cb2c4d74 100644 --- a/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/type/PostgreSQLColumnTypeEnum.java +++ b/chat2db-server/chat2db-plugins/chat2db-postgresql/src/main/java/ai/chat2db/plugin/postgresql/type/PostgreSQLColumnTypeEnum.java @@ -23,7 +23,7 @@ public enum PostgreSQLColumnTypeEnum implements ColumnBuilder { CIDR("CIDR", false, false, true, false, false, false, true, true, false, false), CIRCLE("CIRCLE", false, false, true, false, false, false, true, true, false, false), DATE("DATE", false, false, true, false, false, false, true, true, false, false), - DECIMAL("DECIMAL", true, false, true, false, false, false, true, true, false, false), + DECIMAL("DECIMAL", true, true, true, false, false, false, true, true, false, false), FLOAT4("FLOAT4", false, false, true, false, false, false, true, true, false, false), FLOAT8("FLOAT8", false, false, true, false, false, false, true, true, false, false), INET("INET", false, false, true, false, false, false, true, true, false, false), @@ -37,7 +37,7 @@ public enum PostgreSQLColumnTypeEnum implements ColumnBuilder { LSEG("LSEG", false, false, true, false, false, false, true, true, false, false), MACADDR("MACADDR", false, false, true, false, false, false, true, true, false, false), MONEY("MONEY", false, false, true, false, false, false, true, true, false, false), - NUMERIC("NUMERIC", true, false, true, false, false, false, true, true, false, false), + NUMERIC("NUMERIC", true, true, true, false, false, false, true, true, false, false), PATH("PATH", false, false, true, false, false, false, true, true, false, false), POINT("POINT", false, false, true, false, false, false, true, true, false, false), POLYGON("POLYGON", false, false, true, false, false, false, true, true, false, false), diff --git a/chat2db-server/chat2db-server-start/src/test/java/ai/chat2db/server/start/test/core/TriggerServiceTest.java b/chat2db-server/chat2db-server-start/src/test/java/ai/chat2db/server/start/test/core/TriggerServiceTest.java new file mode 100644 index 00000000..5406404d --- /dev/null +++ b/chat2db-server/chat2db-server-start/src/test/java/ai/chat2db/server/start/test/core/TriggerServiceTest.java @@ -0,0 +1,82 @@ +package ai.chat2db.server.start.test.core; + +import ai.chat2db.server.domain.api.service.TriggerService; +import ai.chat2db.server.domain.repository.Dbutils; +import ai.chat2db.server.start.test.TestApplication; +import ai.chat2db.server.start.test.dialect.DialectProperties; +import ai.chat2db.server.start.test.dialect.TestUtils; +import ai.chat2db.server.tools.base.wrapper.result.DataResult; +import ai.chat2db.server.tools.base.wrapper.result.ListResult; +import ai.chat2db.server.tools.common.model.Context; +import ai.chat2db.server.tools.common.model.LoginUser; +import ai.chat2db.server.tools.common.util.ContextUtils; +import ai.chat2db.spi.model.Trigger; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +/** + * @author Juechen + * @version : TriggerServiceTest.java + */ +public class TriggerServiceTest extends TestApplication { + + @Autowired + private TriggerService triggerService; + + @Autowired + private List dialectPropertiesList; + + @Test + public void testTriggers() { + userLoginIdentity(false,9L); + + for (DialectProperties dialectProperties : dialectPropertiesList) { + Long dataSourceId = TestUtils.nextLong(); + Long consoleId = TestUtils.nextLong(); + TestUtils.buildContext(dialectProperties, dataSourceId, consoleId); + + if (dialectProperties.getDbType().equalsIgnoreCase("mysql")) { + String databaseName = "ali_dbhub_test"; + ListResult triggers = triggerService.triggers(databaseName, ""); + for (Trigger trigger : triggers.getData()) { + DataResult detail = triggerService.detail(databaseName, "", trigger.getTriggerName()); + System.out.println(detail.getData()); + } + Assertions.assertTrue(triggers.getSuccess(), triggers.getErrorMessage()); + } else if (dialectProperties.getDbType().equalsIgnoreCase("postgresql")) { + String databaseName = "ali_dbhub_test"; + ListResult triggers = triggerService.triggers(databaseName, "test"); + for (Trigger trigger : triggers.getData()) { + DataResult detail = triggerService.detail(databaseName, "test", trigger.getTriggerName()); + System.out.println(detail.getData()); + } + Assertions.assertTrue(triggers.getSuccess(), triggers.getErrorMessage()); + } else if (dialectProperties.getDbType().equalsIgnoreCase("oracle")) { + String schemaName = "TEST_USER"; + ListResult triggers = triggerService.triggers("", schemaName); + for (Trigger trigger : triggers.getData()) { + DataResult detail = triggerService.detail("", schemaName, trigger.getTriggerName()); + System.out.println(detail.getData()); + } + Assertions.assertTrue(triggers.getSuccess(), triggers.getErrorMessage()); + } + } + } + + /** + * Save the current user identity (administrator or normal user) and user ID to the context and database session for subsequent use. + * + * @param isAdmin + * @param userId + */ + private static void userLoginIdentity(boolean isAdmin, Long userId) { + Context context = Context.builder().loginUser( + LoginUser.builder().admin(isAdmin).id(userId).build() + ).build(); + ContextUtils.setContext(context); + Dbutils.setSession(); + } +} diff --git a/chat2db-server/chat2db-server-start/src/test/java/ai/chat2db/server/start/test/core/UserServiceTest.java b/chat2db-server/chat2db-server-start/src/test/java/ai/chat2db/server/start/test/core/UserServiceTest.java new file mode 100644 index 00000000..b750d6b2 --- /dev/null +++ b/chat2db-server/chat2db-server-start/src/test/java/ai/chat2db/server/start/test/core/UserServiceTest.java @@ -0,0 +1,118 @@ +package ai.chat2db.server.start.test.core; + +import ai.chat2db.server.domain.api.model.User; +import ai.chat2db.server.domain.api.param.user.UserCreateParam; +import ai.chat2db.server.domain.api.param.user.UserPageQueryParam; +import ai.chat2db.server.domain.api.param.user.UserSelector; +import ai.chat2db.server.domain.api.param.user.UserUpdateParam; +import ai.chat2db.server.domain.api.service.UserService; +import ai.chat2db.server.domain.repository.Dbutils; +import ai.chat2db.server.start.test.TestApplication; +import ai.chat2db.server.tools.base.wrapper.result.ActionResult; +import ai.chat2db.server.tools.base.wrapper.result.DataResult; +import ai.chat2db.server.tools.base.wrapper.result.PageResult; +import ai.chat2db.server.tools.common.model.Context; +import ai.chat2db.server.tools.common.model.LoginUser; +import ai.chat2db.server.tools.common.util.ContextUtils; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @author Juechen + * @version : UserServiceTest.java + */ +public class UserServiceTest extends TestApplication { + + @Autowired + private UserService userService; + + @Test + public void testAllMethods() { + userLoginIdentity(false,8L); + + UserCreateParam userCreateParam = new UserCreateParam(); + userCreateParam.setUserName("test_username08"); + userCreateParam.setEmail("123456789@gmail.com"); + userCreateParam.setPassword("123456"); + userCreateParam.setRoleCode("TEST"); + userCreateParam.setStatus("VALID"); + userCreateParam.setNickName("test_username686"); + DataResult dataResult = userService.create(userCreateParam); + System.out.println("create id:" + dataResult.getData()); + Assertions.assertTrue(dataResult.getSuccess(),dataResult.getErrorMessage()); + + DataResult query = userService.query(dataResult.getData()); + System.out.println("Specify id:" + query.getData()); + Assertions.assertTrue(query.getSuccess(),query.getErrorMessage()); + + DataResult user_name = userService.query("_desktop_default_user_name"); + System.out.println("Specify user_name: " + user_name.getData()); + Assertions.assertTrue(user_name.getSuccess(),user_name.getErrorMessage()); + + UserPageQueryParam param = new UserPageQueryParam(); + param.setPageNo(1); + param.setPageSize(8); + param.setEnableReturnCount(false); + param.setSearchKey(""); + UserSelector selector = new UserSelector(); + selector.setModifiedUser(false); + + PageResult result = userService.pageQuery(param, selector); + for (User user : result.getData()) { + System.out.println("list:" + user); + } + Assertions.assertTrue(result.getSuccess(),result.getErrorMessage()); + + // if id is 1, an BusinessException will be thrown + ActionResult actionResult = userService.delete(dataResult.getData()); + Assertions.assertTrue(actionResult.getSuccess(),actionResult.getErrorMessage()); + + PageResult pageQuery = userService.pageQuery(param, selector); + for (User user : pageQuery.getData()) { + System.out.println("After deletion list:" + user); + } + Assertions.assertTrue(pageQuery.getSuccess(),pageQuery.getErrorMessage()); + + } + + @Test + public void testUpdate() { + userLoginIdentity(false,8L); + + UserUpdateParam userUpdateParam = new UserUpdateParam(); + // If the id is 1, a "user.canNotOperateSystemAccount" exception will be thrown. + // userUpdateParam.setId(1L); + userUpdateParam.setId(3L); + userUpdateParam.setRoleCode("TEST05"); + userUpdateParam.setStatus("INVALID"); + userUpdateParam.setEmail("385962@gmail.com"); + userUpdateParam.setPassword("385962"); + + DataResult query = userService.query(userUpdateParam.getId()); + System.out.println("Original data :" + query.getData()); + Assertions.assertTrue(query.getSuccess(),query.getErrorMessage()); + + DataResult update = userService.update(userUpdateParam); + System.out.println("update id :" + update.getData()); + Assertions.assertTrue(update.getSuccess(),update.getErrorMessage()); + + DataResult result = userService.query(userUpdateParam.getId()); + System.out.println("update data :" + result.getData()); + Assertions.assertTrue(result.getSuccess(),result.getErrorMessage()); + } + + /** + * Save the current user identity (administrator or normal user) and user ID to the context and database session for subsequent use. + * + * @param isAdmin + * @param userId + */ + private static void userLoginIdentity(boolean isAdmin, Long userId) { + Context context = Context.builder().loginUser( + LoginUser.builder().admin(isAdmin).id(userId).build() + ).build(); + ContextUtils.setContext(context); + Dbutils.setSession(); + } +} diff --git a/chat2db-server/chat2db-server-start/src/test/java/ai/chat2db/server/start/test/core/ViewServiceTest.java b/chat2db-server/chat2db-server-start/src/test/java/ai/chat2db/server/start/test/core/ViewServiceTest.java new file mode 100644 index 00000000..c7cb9bbe --- /dev/null +++ b/chat2db-server/chat2db-server-start/src/test/java/ai/chat2db/server/start/test/core/ViewServiceTest.java @@ -0,0 +1,83 @@ +package ai.chat2db.server.start.test.core; + +import ai.chat2db.server.domain.api.service.ViewService; +import ai.chat2db.server.domain.repository.Dbutils; +import ai.chat2db.server.start.test.TestApplication; +import ai.chat2db.server.start.test.dialect.DialectProperties; +import ai.chat2db.server.start.test.dialect.TestUtils; +import ai.chat2db.server.tools.base.wrapper.result.DataResult; +import ai.chat2db.server.tools.base.wrapper.result.ListResult; +import ai.chat2db.server.tools.common.model.Context; +import ai.chat2db.server.tools.common.model.LoginUser; +import ai.chat2db.server.tools.common.util.ContextUtils; +import ai.chat2db.spi.model.Table; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +/** + * @author Juechen + * @version : ViewServiceTest.java + */ +public class ViewServiceTest extends TestApplication { + + @Autowired + private ViewService viewService; + + @Autowired + private List dialectPropertiesList; + + @Test + public void testViews() { + userLoginIdentity(false, 9L); + + for (DialectProperties dialectProperties : dialectPropertiesList) { + Long dataSourceId = TestUtils.nextLong(); + Long consoleId = TestUtils.nextLong(); + TestUtils.buildContext(dialectProperties, dataSourceId, consoleId); + + if (dialectProperties.getDbType().equalsIgnoreCase("mysql")) { + String databaseName = "ali_dbhub_test"; + ListResult views = viewService.views(databaseName, null); + for (Table table : views.getData()) { + DataResult
detail = viewService.detail(databaseName, null, table.getName()); + System.out.println("mysql:" + detail.getData()); + } + Assertions.assertTrue(views.getSuccess(),views.getErrorMessage()); + } else if (dialectProperties.getDbType().equalsIgnoreCase("postgresql")) { + String databaseName = "ali_dbhub_test"; + String schemaName = "test"; + ListResult
views = viewService.views(databaseName, schemaName); + for (Table table : views.getData()) { + DataResult
detail = viewService.detail(databaseName, schemaName, table.getName()); + System.out.println("postgresql:" + detail.getData()); + } + Assertions.assertTrue(views.getSuccess(),views.getErrorMessage()); + } else if (dialectProperties.getDbType().equalsIgnoreCase("oracle")) { + String schemaName = "TEST_USER"; + ListResult
views = viewService.views("", schemaName); + for (Table table : views.getData()) { + DataResult
detail = viewService.detail("", schemaName, table.getName()); + System.out.println("oracle:" + detail.getData()); + } + Assertions.assertTrue(views.getSuccess(),views.getErrorMessage()); + } + } + } + + /** + * Save the current user identity (administrator or normal user) and user ID to the context and database session for subsequent use. + * + * @param isAdmin + * @param userId + */ + private static void userLoginIdentity(boolean isAdmin, Long userId) { + Context context = Context.builder().loginUser( + LoginUser.builder().admin(isAdmin).id(userId).build() + ).build(); + ContextUtils.setContext(context); + Dbutils.setSession(); + } +} diff --git a/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/RdbDmlExportController.java b/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/RdbDmlExportController.java index 0f554a2c..a9014f25 100644 --- a/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/RdbDmlExportController.java +++ b/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/RdbDmlExportController.java @@ -5,6 +5,7 @@ import java.io.PrintWriter; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import ai.chat2db.spi.SqlBuilder; @@ -84,7 +85,7 @@ public class RdbDmlExportController { ExportTypeEnum exportType = EasyEnumUtils.getEnum(ExportTypeEnum.class, request.getExportType()); String sql; if (exportSize == ExportSizeEnum.CURRENT_PAGE) { - sql = request.getSql(); + sql = request.getOriginalSql() + " LIMIT " + request.getPageSize() + " OFFSET " + (request.getPageNo() - 1) * request.getPageSize(); } else { sql = request.getOriginalSql(); } @@ -154,12 +155,20 @@ public class RdbDmlExportController { SqlBuilder sqlBuilder = Chat2DBContext.getMetaData().getSqlBuilder(); try (PrintWriter printWriter = response.getWriter()) { List headerColumns = Lists.newArrayList(); + List headers = new ArrayList<>(); InsertWrapper insertWrapper = new InsertWrapper(); SQLExecutor.getInstance().execute(Chat2DBContext.getConnection(), sql, headerList -> { headerList.forEach(sqlIdentifierExpr -> headerColumns.add(sqlIdentifierExpr.getName())); } , dataList -> { + for (String header : headerColumns) { + SQLIdentifierExpr expr = new SQLIdentifierExpr(header); + expr.setName(header); + headers.add(expr); + } + insertWrapper.setHeaderList(headers); + SQLInsertStatement sqlInsertStatement = new SQLInsertStatement(); sqlInsertStatement.setDbType(dbType); sqlInsertStatement.setTableSource(new SQLExprTableSource(tableName)); diff --git a/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/request/DataExportRequest.java b/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/request/DataExportRequest.java index c4f02e7d..747040ab 100644 --- a/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/request/DataExportRequest.java +++ b/chat2db-server/chat2db-server-web/chat2db-server-web-api/src/main/java/ai/chat2db/server/web/api/controller/rdb/request/DataExportRequest.java @@ -23,6 +23,9 @@ public class DataExportRequest extends DataSourceBaseRequest { */ private String originalSql; + private Integer pageNo; + private Integer pageSize; + /** * export type *