Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

solidui datasource job #254

Merged
merged 1 commit into from
Dec 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions solidui/daos/datasource.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
from typing import Any
import logging

from solidui.extensions import db

from solidui.utils.page_info import PageInfo

from solidui.daos.base import BaseDAO
Expand All @@ -35,7 +37,7 @@ def create_data_source(cls, data_source: DataSource) -> DataSource:
return super().create(item=data_source)

@classmethod
def get_data_source_name(cls, data_source_name: int) -> DataSource:
def get_data_source_name(cls, data_source_name: str) -> DataSource:
return super().find_one_or_none(datasource_name=data_source_name)

@classmethod
Expand All @@ -57,7 +59,7 @@ def exist_data_source(cls, data_source_id: int) -> DataSource:
@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
query = db.session.query(DataSource)

# Apply filters
if name_filter is not None:
Expand All @@ -81,7 +83,7 @@ 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)
data_source = super().find_by_id(data_source_id)
if not data_source:
raise DAONotFound(message="DataSource is required")

Expand All @@ -96,7 +98,7 @@ 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)
existing_data_source = super().find_by_id(data_source.id)
if not existing_data_source:
raise DAONotFound(message="DataSource is required")

Expand Down
2 changes: 1 addition & 1 deletion solidui/daos/datasource_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class DataSourceTypeDAO(BaseDAO[DataSourceType]):
model_cls = DataSourceType

@classmethod
def all_list(cls) -> DataSourceType:
def all_list(cls) -> list[DataSourceType]:
return super().find_all()

@classmethod
Expand Down
25 changes: 25 additions & 0 deletions solidui/daos/job_element.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#
# 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 __future__ import annotations

from datetime import datetime
from typing import Optional
from solidui.daos.base import BaseDAO
from solidui.daos.exceptions import DAONotFound
from solidui.entity.core import JobElement


class JobElementDAO(BaseDAO[JobElement]):
model_cls = JobElement
25 changes: 25 additions & 0 deletions solidui/daos/job_element_page.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#
# 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 __future__ import annotations

from datetime import datetime
from typing import Optional
from solidui.daos.base import BaseDAO
from solidui.daos.exceptions import DAONotFound
from solidui.entity.core import JobElementPage


class JobElementPageDAO(BaseDAO[JobElementPage]):
model_cls = JobElementPage
38 changes: 38 additions & 0 deletions solidui/daos/job_page.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#
# 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 __future__ import annotations

from datetime import datetime
from typing import Optional
from solidui.daos.base import BaseDAO
from solidui.daos.exceptions import DAONotFound
from solidui.entity.core import JobPage
from solidui.extensions import db

class JobPageDAO(BaseDAO[JobPage]):
model_cls = JobPage

@classmethod
def query_by_name(cls, name, project_id) -> JobPage:
return db.session.query(JobPage).filter_by(name=name, project_id=project_id).first()

@classmethod
def delete_by_project_id(cls, project_id) -> None:
db.session.query(JobPage).filter_by(project_id=project_id).delete()
db.session.commit()

@classmethod
def query_job_page_parent_ids(cls, parent_id) -> list[JobPage]:
return db.session.query(JobPage).filter_by(parent_id=parent_id).all()
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,17 @@
# 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.
# limitations under the License.

from __future__ import annotations

from solidui.daos.base import BaseDAO
from solidui.entity.core import ModelType


class ModelTypeDAO(BaseDAO[ModelType]):
model_cls = ModelType

@classmethod
def get_list(cls) -> list[ModelType]:
return super().find_all()
113 changes: 112 additions & 1 deletion solidui/datasource_plugin/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,115 @@
# 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.
# limitations under the License.
from __future__ import annotations
from abc import abstractmethod, ABC
from concurrent.futures import ThreadPoolExecutor
import MySQLdb


# Base classes
class BaseJdbcClient(ABC):
def __init__(self, conn):
self.conn = conn

@abstractmethod
def get_databases(self):
pass

@abstractmethod
def get_tables(self, database):
pass

@abstractmethod
def run_query(self, sql):
pass

@abstractmethod
def generate_select_all_data_sql(self, database, table_name):
pass

def close(self):
self.conn.close()


class JdbcClientFactory(ABC):
executor = ThreadPoolExecutor(max_workers=10)

@staticmethod
def create_client(db_type, host, port, username, password, database, extra_params=None) -> BaseJdbcClient:
if extra_params is None:
extra_params = {}
if db_type == 'mysql':
conn = MySQLdb.connect(
host=host,
port=port,
user=username,
passwd=password,
db=database,
**extra_params
)

return MySQLClient(conn)
else:
raise ValueError("Unsupported database type")

@staticmethod
def run_query(client, sql: str):
def query():
try:
return client.run_query(sql)
finally:
client.close()

future = JdbcClientFactory.executor.submit(query)
return future.result()

@staticmethod
def get_databases(client):
def query():
try:
return client.get_databases()
finally:
client.close()

future = JdbcClientFactory.executor.submit(query)
return future.result()

@staticmethod
def get_tables(client, database: str):
def query():
try:
return client.get_tables(database)
finally:
client.close()

future = JdbcClientFactory.executor.submit(query)
return future.result()



class MySQLClient(BaseJdbcClient):
def get_databases(self):
cursor = self.conn.cursor()
cursor.execute("SHOW DATABASES")
return [db[0] for db in cursor]

def get_tables(self, database):
cursor = self.conn.cursor()
cursor.execute(f"SHOW TABLES FROM {database}")
return [table[0] for table in cursor]

def run_query(self, sql):
cursor = self.conn.cursor()
cursor.execute(sql)
column_names = [col[0] for col in cursor.description]
rows = [column_names] # First row is column names

for row in cursor.fetchall():
rows.append([str(col) if col is not None else None for col in row])

return rows

def generate_select_all_data_sql(self, database, table_name):
return f"SELECT * FROM {database}.{table_name}"
56 changes: 56 additions & 0 deletions solidui/views/job/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#
# 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 json
import logging
from flask import request


from solidui.daos.exceptions import DAONotFound
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


logger = logging.getLogger(__name__)


class JobRestApi(BaseSolidUIApi):
route_base = "/solidui/job"

@expose('/save/page', methods=['POST'])
@safe
def save_page(self) -> FlaskResponse:
job_element_page_data = request.json
# Logic to create job element page
# Return appropriate response
return self.response_format()

@expose('/update/page', methods=['PUT'])
@safe
def update_job_page(self) -> FlaskResponse:
job_element_page_data = request.json
# Logic to update job element page
# Return appropriate response
return self.response_format()

@expose('/query/page', methods=['GET'])
@safe
def query_job_page(self) -> FlaskResponse:
project_id = request.args.get('projectId')
page_id = request.args.get('pageId')
return self.response_format()

49 changes: 48 additions & 1 deletion solidui/views/job_page/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,51 @@
# 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.
# limitations under the License.

import json
import logging
from flask import request

from solidui.daos.exceptions import DAONotFound
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

logger = logging.getLogger(__name__)


class JobPageRestApi(BaseSolidUIApi):
route_base = "/solidui/job/page"

@expose('', methods=('POST'))
@safe
def create_job_page(self) -> FlaskResponse:
# Extract data from request

return self.response_format()

@expose('/<int:id>', methods=('PUT'))
@safe
def update_job_page(self, id) -> FlaskResponse:
"""
update job page
"""
return self.response_format()

@expose('/<int:id>', methods=('DELETE'))
@safe
def delete_job_page(self, id) -> FlaskResponse:
"""
delete job page
"""
return self.response_format()

@expose('/query/<int:project_id>', methods=('GET'))
@safe
def get_job_pages(self, project_id) -> FlaskResponse:
"""
get job page
"""
return self.response_format()
Loading
Loading