diff --git a/README.md b/README.md
index 143ace6d..de46ab0c 100644
--- a/README.md
+++ b/README.md
@@ -10,17 +10,11 @@
-
-
-
-
-
-
-
+
diff --git a/README_CN.md b/README_CN.md
index d837e691..190639ea 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -10,9 +10,6 @@
-
-
-
@@ -61,8 +58,8 @@ AI生成图形模型
* 支持多种数据源
* 支持Huggingface space
* 支持插件机器人
-* 支持SolidUI-Model
-* 支持Large Language Model
+* 支持SolidUI模型
+* 支持大模型接入
* 容器化部署
# 快速开始
diff --git a/solidui/config.py b/solidui/config.py
index 99b7d6b9..f88e182c 100644
--- a/solidui/config.py
+++ b/solidui/config.py
@@ -60,4 +60,9 @@
# Console Log Settings
LOG_FORMAT = "%(asctime)s:%(levelname)s:%(name)s:%(message)s"
-LOG_LEVEL = "DEBUG"
\ No newline at end of file
+LOG_LEVEL = "DEBUG"
+
+PREFERRED_DATABASES: list[str] = [
+ "MySQL",
+ "SQLite",
+]
\ No newline at end of file
diff --git a/solidui/daos/datasource.py b/solidui/daos/datasource.py
index 236ba8c0..dc3a9448 100644
--- a/solidui/daos/datasource.py
+++ b/solidui/daos/datasource.py
@@ -11,9 +11,98 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+from typing import Any
+import logging
+
+from solidui.utils.page_info import PageInfo
+
from solidui.daos.base import BaseDAO
+from solidui.daos.exceptions import DAOCreateFailedError, DAOUpdateFailedError, DAONotFound, DAODeleteFailedError
from solidui.entity.core import DataSource
+logger = logging.getLogger(__name__)
+
-class DatasourceDAO(BaseDAO[DataSource]):
+class DataSourceDAO(BaseDAO[DataSource]):
model_cls = DataSource
+
+ @classmethod
+ def create_data_source(cls, data_source: DataSource) -> DataSource:
+ new_data_source = super().find_one_or_none(datasource_name=data_source.datasource_name)
+ if new_data_source is not None:
+ raise DAOCreateFailedError(message="DataSource is already exists")
+
+ return super().create(item=data_source)
+
+ @classmethod
+ def get_data_source_name(cls, data_source_name: int) -> DataSource:
+ return super().find_one_or_none(datasource_name=data_source_name)
+
+ @classmethod
+ def get_data_source_id(cls, data_source_id: int) -> DataSource:
+ return super().find_by_id(data_source_id)
+
+ @classmethod
+ def exist_data_source(cls, data_source_id: int) -> DataSource:
+ data_source = super().find_by_id(data_source_id)
+ if data_source is None:
+ raise DAONotFound(message="DataSource is null")
+
+ try:
+ return super().update(item=data_source, attributes={'expire': True})
+ except DAOUpdateFailedError as ex:
+ logger.exception(ex.exception)
+ raise ex
+
+ @classmethod
+ def get_data_source_page(cls, page_no: int, page_size: int, name_filter: str = None, type_filter: int = None,
+ expire_filter: bool = None) -> PageInfo:
+ query = cls.model_cls.query
+
+ # Apply filters
+ if name_filter is not None:
+ query = query.filter(cls.model_cls.datasource_name.like(f"%{name_filter}%"))
+ if type_filter is not None:
+ query = query.filter(cls.model_cls.datasource_type_id == type_filter)
+ if expire_filter is not None:
+ query = query.filter(cls.model_cls.expire == expire_filter)
+
+ # Apply pagination
+ pagination = query.paginate(page_no, page_size, error_out=False)
+
+ page_info = PageInfo(page_no, page_size)
+ page_info.set_total(pagination.total)
+ page_info.set_total_list(pagination.items)
+
+ return page_info
+
+ @classmethod
+ def delete_data_source(cls, data_source_id: int) -> None:
+ if data_source_id is None:
+ raise DAONotFound(message="DataSource id is required")
+
+ data_source = cls.find_by_id(data_source_id)
+ if not data_source:
+ raise DAONotFound(message="DataSource is required")
+
+ try:
+ super().delete(data_source)
+ except DAODeleteFailedError as ex:
+ logger.exception(ex.exception)
+ raise ex
+
+ @classmethod
+ def update_data_source(cls, data_source: DataSource) -> DataSource:
+ if data_source.id is None:
+ raise DAONotFound(message="DataSource id is required")
+
+ existing_data_source = cls.find_by_id(data_source.id)
+ if not existing_data_source:
+ raise DAONotFound(message="DataSource is required")
+
+ try:
+ return super().update(existing_data_source, data_source.__dict__)
+ except DAOUpdateFailedError as ex:
+ logger.exception(ex)
+ raise ex
+
diff --git a/solidui/daos/datasource_type.py b/solidui/daos/datasource_type.py
index 2aef8ab2..a8a1d9f2 100644
--- a/solidui/daos/datasource_type.py
+++ b/solidui/daos/datasource_type.py
@@ -10,4 +10,23 @@
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
-# limitations under the License.
\ No newline at end of file
+# limitations under the License.
+
+from solidui.daos.base import BaseDAO
+from solidui.daos.exceptions import DAONotFound
+from solidui.entity.core import DataSourceType
+
+
+class DataSourceTypeDAO(BaseDAO[DataSourceType]):
+ model_cls = DataSourceType
+
+ @classmethod
+ def all_list(cls) -> DataSourceType:
+ return super().find_all()
+
+ @classmethod
+ def get_id(cls, id: int) -> DataSourceType:
+ data_source_type = super().find_by_id(id)
+ if not data_source_type:
+ raise DAONotFound(message="DataSourceType not found")
+ return data_source_type
diff --git a/solidui/datasource_plugin/plugin.py b/solidui/datasource_plugin/base.py
similarity index 83%
rename from solidui/datasource_plugin/plugin.py
rename to solidui/datasource_plugin/base.py
index b587b6c7..2aef8ab2 100644
--- a/solidui/datasource_plugin/plugin.py
+++ b/solidui/datasource_plugin/base.py
@@ -10,12 +10,4 @@
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
-# limitations under the License.
-from abc import ABC, abstractmethod
-
-class Plugin(ABC):
-
- @abstractmethod
- def get_name(self):
- pass
-
+# limitations under the License.
\ No newline at end of file
diff --git a/solidui/datasource_plugin/base_jdbc_client.py b/solidui/datasource_plugin/base_jdbc_client.py
deleted file mode 100644
index 8bf7ce97..00000000
--- a/solidui/datasource_plugin/base_jdbc_client.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-import logging
-from abc import ABC, abstractmethod
-
-
-class BaseJdbcClient(ABC):
-
- def __init__(self, conn):
- self.conn = conn
- self.logger = logging.getLogger(__name__)
-
- def close_resource(self, connection, statement, result_set):
- try:
- if result_set is not None and not result_set.closed:
- result_set.close()
- if statement is not None and not statement.closed:
- statement.close()
- if connection is not None and not connection.closed:
- connection.close()
- except Exception as e:
- self.logger.warn(f"Failed to release resources: {e}")
-
- def close(self):
- self.close_resource(self.conn, None, None)
-
- @abstractmethod
- def generate_select_all_data_sql(self, database, table_name):
- pass
-
- @abstractmethod
- def get_all_databases(self):
- pass
-
- @abstractmethod
- def get_all_tables(self, database):
- pass
-
- @abstractmethod
- def get_select_result(self, sql):
- pass
-
- def get_conn(self):
- return self.conn
diff --git a/solidui/datasource_plugin/base_jdbc_client_factory.py b/solidui/datasource_plugin/base_jdbc_client_factory.py
deleted file mode 100644
index a213f3bd..00000000
--- a/solidui/datasource_plugin/base_jdbc_client_factory.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from abc import ABC, abstractmethod
-
-from .constants import *
-from .connect_dto import ConnectDTO
-
-class BaseJdbcClientFactory(ABC):
-
- def get_connect_dto(self, conn_params):
- connect_dto = ConnectDTO()
- connect_dto.host = conn_params.get(PARAM_SQL_HOST)
- connect_dto.port = conn_params.get(PARAM_SQL_PORT)
- connect_dto.username = conn_params.get(PARAM_SQL_USERNAME)
- connect_dto.password = conn_params.get(PARAM_SQL_PASSWORD)
- connect_dto.database = conn_params.get(PARAM_SQL_DATABASE)
- extra_params = conn_params.get(PARAM_SQL_EXTRA_PARAMS)
- if extra_params is None:
- connect_dto.extra_params = {}
- else:
- connect_dto.extra_params = extra_params
- return connect_dto
-
- @abstractmethod
- def create_jdbc_client(self, connect_dto):
- pass
diff --git a/solidui/datasource_plugin/connect_dto.py b/solidui/datasource_plugin/connect_dto.py
deleted file mode 100644
index 24bdd8d4..00000000
--- a/solidui/datasource_plugin/connect_dto.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-class ConnectDTO:
-
- def __init__(self):
- self.host = None
- self.port = None
- self.username = None
- self.password = None
- self.database = None
- self.driver_class_name = None
- self.extra_params = {}
diff --git a/solidui/datasource_plugin/connection_factory.py b/solidui/datasource_plugin/connection_factory.py
deleted file mode 100644
index 99e5a6e7..00000000
--- a/solidui/datasource_plugin/connection_factory.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from .plugin import Plugin
-from abc import ABC, abstractmethod
-
-class ConnectionFactory(Plugin, ABC):
-
- @abstractmethod
- def open_connection(self, host, port, username, password, database, extra_params):
- pass
diff --git a/solidui/datasource_plugin/constants.py b/solidui/datasource_plugin/constants.py
deleted file mode 100644
index a940cc9e..00000000
--- a/solidui/datasource_plugin/constants.py
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-PARAM_SQL_HOST = "host"
-PARAM_SQL_PORT = "port"
-PARAM_SQL_USERNAME = "username"
-PARAM_SQL_PASSWORD = "password"
-PARAM_SQL_EXTRA_PARAMS = "params"
-PARAM_SQL_DATABASE = "database"
-PARAM_SQL_DRIVERCLASSNAME = "driverClassName"
-
-DATASOURCE_CLASSNAME = "com.cloudorc.solidui.plugin.jdbc.%sClientFactory"
-
-DATASOURCE_TYPE_LIST = "mysql,doris"
diff --git a/solidui/datasource_plugin/data_source_utils.py b/solidui/datasource_plugin/data_source_utils.py
deleted file mode 100644
index 90917b51..00000000
--- a/solidui/datasource_plugin/data_source_utils.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-import importlib
-from types import ModuleType
-
-from constants import DATASOURCE_TYPE_LIST, DATASOURCE_CLASSNAME_FORMAT
-
-
-class DataSourceUtils:
- jdbc_client_factory_instances = {}
-
- @staticmethod
- def query_jdbc_client_factory(type_name):
-
- if type_name not in DATASOURCE_TYPE_LIST:
- raise ValueError(f"{type_name} is not supported")
-
- factory = DataSourceUtils.jdbc_client_factory_instances.get(type_name)
- if factory is None:
- class_name = DATASOURCE_CLASSNAME_FORMAT % type_name
- module_name = class_name.rsplit(".", 1)[0]
- factory_cls = getattr(importlib.import_module(module_name), class_name.split(".")[-1])
- factory = factory_cls()
- DataSourceUtils.jdbc_client_factory_instances[type_name] = factory
-
- return factory
-
- @staticmethod
- def query_jdbc_client(type_name, data_source):
-
- factory = DataSourceUtils.query_jdbc_client_factory(type_name)
-
- connect_dto = factory.get_connect_dto(data_source.params)
-
- if connect_dto:
- return factory.create_jdbc_client(connect_dto)
diff --git a/solidui/datasource_plugin/jdbc_client.py b/solidui/datasource_plugin/jdbc_client.py
deleted file mode 100644
index 4d763f6c..00000000
--- a/solidui/datasource_plugin/jdbc_client.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from abc import ABC, abstractmethod
-
-class JdbcClient(ABC):
-
- @abstractmethod
- def generate_select_all_data_sql(self, database, table_name):
- pass
-
- @abstractmethod
- def get_all_databases(self):
- pass
-
- @abstractmethod
- def get_all_tables(self, database):
- pass
-
- @abstractmethod
- def get_select_result(self, sql):
- pass
-
- @abstractmethod
- def close(self):
- pass
-
- @abstractmethod
- def get_conn(self):
- pass
diff --git a/solidui/datasource_plugin/jdbc_client_factory.py b/solidui/datasource_plugin/jdbc_client_factory.py
deleted file mode 100644
index ef5b7bea..00000000
--- a/solidui/datasource_plugin/jdbc_client_factory.py
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from abc import ABC, abstractmethod
-
-class JdbcClientFactory(ABC):
-
- @abstractmethod
- def create_jdbc_client(self, connect_dto):
- pass
-
- @abstractmethod
- def get_connect_dto(self, conn_params):
- pass
diff --git a/solidui/datasource_plugin/jdbc_client_manager.py b/solidui/datasource_plugin/jdbc_client_manager.py
deleted file mode 100644
index 6debe68d..00000000
--- a/solidui/datasource_plugin/jdbc_client_manager.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-import importlib
-
-class JdbcClientManager:
-
- @staticmethod
- def load_connection_factory(class_name):
- parts = class_name.rsplit('.', 1)
- module = importlib.import_module(parts[0])
- connection_factory_cls = getattr(module, parts[1])
- return connection_factory_cls()
diff --git a/solidui/datasource_plugin/mysql/mysql_client.py b/solidui/datasource_plugin/mysql/mysql_client.py
deleted file mode 100644
index 1b33c337..00000000
--- a/solidui/datasource_plugin/mysql/mysql_client.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from solidui.datasource_plugin.base_jdbc_client import BaseJdbcClient
-
-import mysql.connector
-
-
-class MysqlClient(BaseJdbcClient):
-
- def __init__(self, conn):
- super().__init__(conn)
-
- def generate_select_all_data_sql(self, database, table_name):
- return f"SELECT * FROM {database}.{table_name}"
-
- def get_all_databases(self):
- cursor = self.conn.cursor()
- cursor.execute("SHOW DATABASES")
- return [db[0] for db in cursor]
-
- def get_all_tables(self, database):
- cursor = self.conn.cursor()
- cursor.execute(f"SHOW TABLES FROM {database}")
- return [table[0] for table in cursor]
-
- def get_select_result(self, sql):
- cursor = self.conn.cursor()
- cursor.execute(sql)
-
- # 获取列名
- column_names = [col[0] for col in cursor.description]
-
- results = []
- results.append(column_names)
-
- # 获取结果
- for row in cursor:
- results.append(list(row))
-
- return results
diff --git a/solidui/datasource_plugin/mysql/mysql_client_factory.py b/solidui/datasource_plugin/mysql/mysql_client_factory.py
deleted file mode 100644
index 3d801626..00000000
--- a/solidui/datasource_plugin/mysql/mysql_client_factory.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-import mysql.connector
-
-from .base_jdbc_client_factory import BaseJdbcClientFactory
-from .mysql_client import MysqlClient
-
-class MysqlClientFactory(BaseJdbcClientFactory):
-
- def create_jdbc_client(self, connect_dto):
- conn = mysql.connector.connect(
- host=connect_dto.host,
- port=connect_dto.port,
- user=connect_dto.username,
- password=connect_dto.password,
- database=connect_dto.database,
- **connect_dto.extra_params
- )
- return MysqlClient(conn)
diff --git a/solidui/datasource_plugin/mysql/mysql_connection_factory.py b/solidui/datasource_plugin/mysql/mysql_connection_factory.py
deleted file mode 100644
index 3707e28e..00000000
--- a/solidui/datasource_plugin/mysql/mysql_connection_factory.py
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-import mysql.connector
-
-from .connection_factory import ConnectionFactory
-
-class MysqlConnectionFactory(ConnectionFactory):
-
- def open_connection(self, host, port, username, password, database, extra_params):
- conn = mysql.connector.connect(
- host=host,
- port=port,
- user=username,
- password=password,
- database=database,
- **extra_params
- )
- return conn
-
- def get_name(self):
- return "mysql"
diff --git a/solidui/views/datasource/api.py b/solidui/views/datasource/api.py
index 74965971..de279878 100644
--- a/solidui/views/datasource/api.py
+++ b/solidui/views/datasource/api.py
@@ -12,14 +12,195 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import logging
from flask import request
+from solidui.daos.datasource import DataSourceDAO
+from solidui.daos.datasource_type import DataSourceTypeDAO
+from solidui.daos.exceptions import DAONotFound, DAOUpdateFailedError, DAOException, DAODeleteFailedError
+from solidui.entity.core import DataSource
from solidui.errors import SolidUIErrorType
from solidui.solidui_typing import FlaskResponse
from solidui.views.base_api import BaseSolidUIApi
from flask_appbuilder.api import expose, safe
-from solidui.utils.login_utils import get_login_user
+from solidui.views.datasource.schemas import DataSourceTypeSchema, DataSourceSchema, DataSourcePageInfoSchema
+logger = logging.getLogger(__name__)
-class DatasourceRestApi(BaseSolidUIApi):
- route_base = "/solidui/datasource"
\ No newline at end of file
+
+class DataSourceRestApi(BaseSolidUIApi):
+ route_base = "/solidui/datasource"
+
+ @expose('/type/all', methods=("GET",))
+ @safe
+ def get_all_data_source_types(self) -> FlaskResponse:
+ """
+ get all data source types
+ """
+ data_list = DataSourceTypeDAO.find_all()
+ schema = DataSourceTypeSchema(many=True)
+ return self.response_format(data=schema.dump(data_list))
+
+ @expose('/key/type/', methods=("GET",))
+ @safe
+ def get_key_by_type(self, type_id) -> FlaskResponse:
+ """
+ get key definitions by type
+ """
+ data = DataSourceTypeDAO.get_id(type_id)
+ schema = DataSourceTypeSchema()
+ return self.response_format(data=schema.dump(data))
+
+ @expose('/info/json', methods=("POST",))
+ @safe
+ def insert_json_info(self) -> FlaskResponse:
+ """
+ insert json info
+ """
+ data = request.get_json()
+ data_source = DataSource(**data)
+
+ # Verify data source name and type ID
+ if not data_source.datasource_name or not data_source.datasource_type_id:
+ return self.handle_error(SolidUIErrorType.QUERY_DATASOURCE_ERROR)
+
+ try:
+ DataSourceDAO.create_data_source(data_source)
+ return self.response_format()
+
+ except DAONotFound as ex:
+ logger.exception(ex)
+ return self.handle_error(SolidUIErrorType.CREATE_DATASOURCE_ERROR)
+
+ @expose('/info//json', methods=("PUT",))
+ @safe
+ def update_json_info(self, data_source_id) -> FlaskResponse:
+ """
+ update data source in json
+ """
+ data = request.get_json()
+
+ if not data:
+ return self.handle_error(SolidUIErrorType.QUERY_DATASOURCE_ERROR)
+
+ try:
+
+ data_source = DataSource(**data)
+ data_source.id = data_source_id # Make sure the ID passed in is set to the data source object
+ DataSourceDAO.update_data_source(data_source)
+ return self.response_format()
+ except DAONotFound as ex:
+ logger.exception(ex)
+ return self.handle_error(SolidUIErrorType.QUERY_DATASOURCE_ERROR)
+ except DAOUpdateFailedError as ex:
+ logger.exception(ex)
+ return self.handle_error(SolidUIErrorType.UPDATE_DATASOURCE_ERROR)
+
+ @expose('/info/', methods=("GET",))
+ @safe
+ def get_info_by_data_source_id(self, data_source_id) -> FlaskResponse:
+ """
+ get info by data source id
+ """
+ try:
+ data_source = DataSourceDAO.get_data_source_id(data_source_id)
+ if data_source is None:
+ return self.handle_error(SolidUIErrorType.QUERY_DATASOURCE_ERROR)
+
+ schema = DataSourceSchema()
+ return self.response_format(data=schema.dump(data_source))
+ except DAOException as ex:
+ logger.exception(ex)
+ return self.handle_error(SolidUIErrorType.INTERNAL_SERVER_ERROR)
+
+ @expose('/info/name/', methods=("GET",))
+ @safe
+ def get_info_by_data_source_name(self, data_source_name) -> FlaskResponse:
+ """
+ get info by data source name
+ """
+ try:
+ data_source = DataSourceDAO.get_data_source_name(data_source_name)
+ if data_source is not None:
+ schema = DataSourceSchema()
+ return self.response_format(data=schema.dump(data_source))
+ else:
+ return self.handle_error(SolidUIErrorType.QUERY_DATASOURCE_ERROR)
+ except DAOException as ex:
+ logger.exception(ex)
+ return self.handle_error(SolidUIErrorType.INTERNAL_SERVER_ERROR)
+
+ @expose('/info/delete/', methods=("DELETE",))
+ @safe
+ def remove_data_source(self, data_source_id) -> FlaskResponse:
+ """
+ get info by data source name
+ """
+ try:
+
+ DataSourceDAO.delete_data_source(data_source_id)
+ return self.response_format()
+
+ except DAODeleteFailedError as ex:
+ logger.exception(ex)
+ return self.handle_error(SolidUIErrorType.DELETE_DATASOURCE_ERROR)
+
+ @expose('/info//expire', methods=("PUT",))
+ @safe
+ def expire_data_source(self, data_source_id) -> FlaskResponse:
+ """
+ expire data source
+ """
+ try:
+
+ DataSourceDAO.exist_data_source(data_source_id)
+ return self.response_format()
+
+ except DAOUpdateFailedError as ex:
+ logger.exception(ex)
+ return self.handle_error(SolidUIErrorType.UPDATE_DATASOURCE_ERROR)
+
+ @expose('/info', methods=("GET",))
+ @safe
+ def query_data_source(self) -> FlaskResponse:
+ """
+ query data source
+ """
+ try:
+ data_source_name = request.args.get('name', default=None, type=str)
+ data_source_type_id = request.args.get('typeId', default=None, type=int)
+ expire = request.args.get('expire', default=None, type=bool)
+ page_size = request.args.get('pageSize', default=10, type=int)
+ page_no = request.args.get('pageNo', default=1, type=int)
+
+ # Ensure page size and page number are positive integers
+ page_size = max(1, page_size)
+ page_no = max(1, page_no)
+
+ # Query and paginate data sources
+ page_info = DataSourceDAO.get_data_source_page(
+ page_no=page_no,
+ page_size=page_size,
+ name_filter=data_source_name,
+ type_filter=data_source_type_id,
+ expire_filter=expire
+ )
+
+ # Format the response
+ page_info_schema = DataSourcePageInfoSchema()
+ return self.response_format(data=page_info_schema.dump(page_info))
+
+ except DAONotFound as ex:
+ logger.exception(ex)
+ return self.handle_error(SolidUIErrorType.QUERY_DATASOURCE_ERROR)
+
+ @expose('/connect/json', methods=("POST",))
+ @safe
+ def connect(self) -> FlaskResponse:
+ """
+ connect
+ """
+ data_source_name = request.form.get('dataSourceName')
+ type_name = request.form.get('typeName', default=None)
+
+ return self.response_format()
diff --git a/solidui/views/datasource/schemas.py b/solidui/views/datasource/schemas.py
index ae59bead..87495e9b 100644
--- a/solidui/views/datasource/schemas.py
+++ b/solidui/views/datasource/schemas.py
@@ -11,4 +11,26 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+from marshmallow_sqlalchemy import SQLAlchemyAutoSchema
+from solidui.entity.core import DataSourceType, DataSource
+from marshmallow_sqlalchemy.schema import Schema
+from marshmallow_sqlalchemy.fields import fields
+
+class DataSourceTypeSchema(SQLAlchemyAutoSchema):
+ class Meta:
+ model = DataSourceType
+ load_instance = True # Optional: if you also want to use it for deserialization
+
+
+class DataSourceSchema(SQLAlchemyAutoSchema):
+ class Meta:
+ model = DataSource
+ load_instance = True # Optional: if you also want to use it for deserialization
+
+class DataSourcePageInfoSchema(Schema):
+ current_page = fields.Int()
+ page_size = fields.Int()
+ total = fields.Int()
+ total_page = fields.Int()
+ total_list = fields.Nested(DataSourceSchema, many=True)
diff --git a/solidui/views/project/api.py b/solidui/views/project/api.py
index 992109b4..bae68f01 100644
--- a/solidui/views/project/api.py
+++ b/solidui/views/project/api.py
@@ -28,6 +28,9 @@ class ProjectRestApi(BaseSolidUIApi):
@expose('', methods=("POST",))
@safe
def create(self) -> FlaskResponse:
+ """
+ create project
+ """
project_name = request.form.get('projectName')
description = request.form.get('description', default='')
@@ -50,6 +53,9 @@ def create(self) -> FlaskResponse:
@expose('/', methods=("PUT",))
@safe
def update(self, pk: int) -> FlaskResponse:
+ """
+ update project
+ """
project_name = request.form.get('projectName')
background_image = request.form.get('backgroundImage')
description = request.form.get('description')
@@ -65,7 +71,9 @@ def update(self, pk: int) -> FlaskResponse:
@expose('/queryProjectListPaging', methods=("GET",))
@safe
def query_Project_List_Paging(self) -> FlaskResponse:
-
+ """
+ query project list paging
+ """
search_name = request.args.get('searchName', default='')
page_size = request.args.get('pageSize', default=10, type=int)
page_no = request.args.get('pageNo', default=1, type=int)
@@ -79,14 +87,18 @@ def query_Project_List_Paging(self) -> FlaskResponse:
@expose('/', methods=("DELETE",))
@safe
def delete(self, pk: int) -> FlaskResponse:
-
+ """
+ delete project by id
+ """
ProjectDAO.delete_project(pk)
return self.response_format()
@expose('/', methods=("GET",))
@safe
def get(self, pk: int) -> FlaskResponse:
-
+ """
+ get project by id
+ """
project = ProjectDAO.get_project(pk)
if project:
project_schema = ProjectSchema()