mirror of
https://github.com/apache/superset.git
synced 2026-04-07 18:35:15 +00:00
110 lines
4.0 KiB
Python
110 lines
4.0 KiB
Python
# 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 datetime import datetime
|
|
from typing import Any, Optional
|
|
|
|
from sqlalchemy import types
|
|
|
|
from superset.constants import TimeGrain
|
|
from superset.db_engine_specs.base import BaseEngineSpec, DatabaseCategory
|
|
from superset.sql.parse import LimitMethod
|
|
|
|
|
|
class FirebirdEngineSpec(BaseEngineSpec):
|
|
"""Engine for Firebird"""
|
|
|
|
engine = "firebird"
|
|
engine_name = "Firebird"
|
|
|
|
metadata = {
|
|
"description": "Firebird is an open-source relational database.",
|
|
"logo": "firebird.png",
|
|
"homepage_url": "https://firebirdsql.org/",
|
|
"categories": [
|
|
DatabaseCategory.TRADITIONAL_RDBMS,
|
|
DatabaseCategory.OPEN_SOURCE,
|
|
],
|
|
"pypi_packages": ["sqlalchemy-firebird"],
|
|
"version_requirements": "sqlalchemy-firebird>=0.7.0,<0.8",
|
|
"connection_string": "firebird+fdb://{username}:{password}@{host}:{port}//{path_to_db_file}",
|
|
"default_port": 3050,
|
|
"connection_examples": [
|
|
{
|
|
"description": "Local database",
|
|
"connection_string": "firebird+fdb://SYSDBA:masterkey@192.168.86.38:3050//Library/Frameworks/Firebird.framework/Versions/A/Resources/examples/empbuild/employee.fdb",
|
|
},
|
|
],
|
|
}
|
|
|
|
# Firebird uses FIRST to limit: `SELECT FIRST 10 * FROM table`
|
|
limit_method = LimitMethod.FETCH_MANY
|
|
|
|
_time_grain_expressions = {
|
|
None: "{col}",
|
|
TimeGrain.SECOND: (
|
|
"CAST(CAST({col} AS DATE) "
|
|
"|| ' ' "
|
|
"|| EXTRACT(HOUR FROM {col}) "
|
|
"|| ':' "
|
|
"|| EXTRACT(MINUTE FROM {col}) "
|
|
"|| ':' "
|
|
"|| FLOOR(EXTRACT(SECOND FROM {col})) AS TIMESTAMP)"
|
|
),
|
|
TimeGrain.MINUTE: (
|
|
"CAST(CAST({col} AS DATE) "
|
|
"|| ' ' "
|
|
"|| EXTRACT(HOUR FROM {col}) "
|
|
"|| ':' "
|
|
"|| EXTRACT(MINUTE FROM {col}) "
|
|
"|| ':00' AS TIMESTAMP)"
|
|
),
|
|
TimeGrain.HOUR: (
|
|
"CAST(CAST({col} AS DATE) "
|
|
"|| ' ' "
|
|
"|| EXTRACT(HOUR FROM {col}) "
|
|
"|| ':00:00' AS TIMESTAMP)"
|
|
),
|
|
TimeGrain.DAY: "CAST({col} AS DATE)",
|
|
TimeGrain.MONTH: (
|
|
"CAST(EXTRACT(YEAR FROM {col}) "
|
|
"|| '-' "
|
|
"|| EXTRACT(MONTH FROM {col}) "
|
|
"|| '-01' AS DATE)"
|
|
),
|
|
TimeGrain.YEAR: "CAST(EXTRACT(YEAR FROM {col}) || '-01-01' AS DATE)",
|
|
}
|
|
|
|
@classmethod
|
|
def epoch_to_dttm(cls) -> str:
|
|
return "DATEADD(second, {col}, CAST('00:00:00' AS TIMESTAMP))"
|
|
|
|
@classmethod
|
|
def convert_dttm(
|
|
cls, target_type: str, dttm: datetime, db_extra: Optional[dict[str, Any]] = None
|
|
) -> Optional[str]:
|
|
sqla_type = cls.get_sqla_column_type(target_type)
|
|
|
|
if isinstance(sqla_type, types.Date):
|
|
return f"CAST('{dttm.date().isoformat()}' AS DATE)"
|
|
if isinstance(sqla_type, types.DateTime):
|
|
dttm_formatted = dttm.isoformat(sep=" ")
|
|
dttm_valid_precision = dttm_formatted[: len("YYYY-MM-DD HH:MM:SS.MMMM")]
|
|
return f"CAST('{dttm_valid_precision}' AS TIMESTAMP)"
|
|
if isinstance(sqla_type, types.Time):
|
|
return f"CAST('{dttm.time().isoformat()}' AS TIME)"
|
|
return None
|