| # 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 typing import List |
| |
| from .constants import TSDataType, ColumnCategory, TSEncoding, Compressor |
| |
| |
| class TimeseriesSchema: |
| """ |
| Metadata schema for a time series (name, data type, encoding, compression). |
| """ |
| |
| timeseries_name = None |
| data_type = None |
| encoding_type = None |
| compression_type = None |
| |
| def __init__(self, timeseries_name: str, data_type: TSDataType, encoding_type: TSEncoding = TSEncoding.PLAIN, |
| compression_type: Compressor = Compressor.UNCOMPRESSED): |
| self.timeseries_name = timeseries_name |
| self.data_type = data_type |
| self.encoding_type = encoding_type |
| self.compression_type = compression_type |
| |
| def get_timeseries_name(self): |
| return self.timeseries_name |
| |
| def get_data_type(self): |
| return self.data_type |
| |
| def get_encoding_type(self): |
| return self.encoding_type |
| |
| def get_compression_type(self): |
| return self.compression_type |
| |
| |
| class DeviceSchema: |
| """Represents a device entity containing multiple time series.""" |
| |
| device_name = None |
| timeseries_list = None |
| |
| def __init__(self, device_name: str, timeseries_list: List[TimeseriesSchema]): |
| self.device_name = device_name |
| self.timeseries_list = timeseries_list |
| |
| def get_device_name(self): |
| return self.device_name |
| |
| def get_timeseries_list(self): |
| return self.timeseries_list |
| |
| |
| class ColumnSchema: |
| """Defines schema for a table column (name, datatype, category).""" |
| |
| column_name = None |
| data_type = None |
| |
| def __init__(self, column_name: str, data_type: TSDataType, category: ColumnCategory = ColumnCategory.FIELD): |
| if column_name is None or len(column_name) == 0: |
| raise ValueError("Column name cannot be None") |
| self.column_name = column_name.lower() |
| if data_type is None: |
| raise ValueError("Data type cannot be None") |
| self.data_type = data_type |
| self.category = category |
| |
| def __repr__(self) -> str: |
| return f"ColumnSchema({self.column_name}, {self.data_type.name}, {self.category.name})" |
| |
| def get_column_name(self): |
| return self.column_name |
| |
| def get_data_type(self): |
| return self.data_type |
| |
| def get_category(self): |
| return self.category |
| |
| |
| class TableSchema: |
| """Schema definition for a table structure.""" |
| table_name = None |
| columns = None |
| |
| def __init__(self, table_name: str, columns: List[ColumnSchema]): |
| if table_name is None or len(table_name) == 0: |
| raise ValueError("Table name cannot be None") |
| self.table_name = table_name.lower() |
| if len(columns) == 0: |
| raise ValueError("Columns cannot be empty") |
| self.columns = columns |
| |
| def get_table_name(self): |
| return self.table_name |
| |
| def get_columns(self): |
| return self.columns |
| |
| def get_column_names(self): |
| return [name.get_column_name() for name in self.columns] |
| |
| def __repr__(self) -> str: |
| return f"TableSchema({self.table_name}, {self.columns})" |
| |
| |
| class ResultSetMetaData: |
| """Metadata container for query result sets (columns, types, table name).""" |
| column_list = None |
| data_types = None |
| table_name = None |
| |
| def __init__(self, column_list: List[str], data_types: List[TSDataType]): |
| self.column_list = column_list |
| self.data_types = data_types |
| |
| def set_table_name(self, table_name: str): |
| self.table_name = table_name |
| |
| def get_data_type(self, column_index: int) -> TSDataType: |
| if column_index < 1 or column_index > len(self.column_list): |
| raise OverflowError |
| return self.data_types[column_index - 1] |
| |
| def get_column_name(self, column_index: int) -> str: |
| if column_index < 1 or column_index > len(self.column_list): |
| raise OverflowError |
| return self.column_list[column_index - 1] |
| |
| def get_column_name_index(self, column_name: str, is_tree: bool = False) -> int: |
| """ |
| For Tree model, column is full path, column_name means sensor_name. |
| For Table model, column is just column name. |
| """ |
| if is_tree: |
| return self.column_list.index(self.table_name + "." + column_name) + 1 |
| else: |
| return self.column_list.index(column_name) + 1 |
| |
| def get_column_num(self): |
| return len(self.column_list) |
| |
| def get_column_list(self): |
| return self.column_list |
| |
| def get_data_type_list(self): |
| return self.data_types |