# Copyright 2015 Robin Hood # Copyright 2016 FUJITSU LIMITED # (C) Copyright 2016 Hewlett Packard Enterprise Development LP # Copyright 2018 SUSE Linux GmbH # # Licensed 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 sqlalchemy import Column from sqlalchemy.ext import compiler from sqlalchemy.sql import expression from sqlalchemy import String, DateTime, Boolean, Integer, LargeBinary, Float from sqlalchemy import MetaData from sqlalchemy import Table def get_all_metadata(): """Return metadata for full data model This metadata is used for autogenerating a complete (works on an empty database) schema migration. To ensure this mechanism keeps working please invoke any new model creation methods you add from this function as well. """ metadata = MetaData() create_a_model(metadata) create_aa_model(metadata) create_ad_model(metadata) create_am_model(metadata) create_nm_model(metadata) create_md_model(metadata) create_mde_model(metadata) create_mdd_model(metadata) create_sa_model(metadata) create_sad_model(metadata) create_sadd_model(metadata) create_nmt_model(metadata) return metadata def create_a_model(metadata=None): return Table('alarm', metadata, Column('id', String(36)), Column('alarm_definition_id', String(36)), Column('state', String(20)), Column('lifecycle_state', String(50)), Column('link', String(512)), Column('created_at', DateTime), Column('state_updated_at', DateTime), Column('updated_at', DateTime)) def create_sadd_model(metadata=None): return Table('sub_alarm_definition_dimension', metadata, Column('sub_alarm_definition_id', String(36)), Column('dimension_name', String(255)), Column('value', String(255))) def create_aa_model(metadata=None): return Table('alarm_action', metadata, Column('alarm_definition_id', String(36)), Column('alarm_state', String(20)), Column('action_id', String(36))) def create_md_model(metadata=None): return Table('metric_dimension', metadata, Column('dimension_set_id', LargeBinary), Column('name', String(255)), Column('value', String(255))) def create_mde_model(metadata=None): return Table('metric_definition', metadata, Column('id', LargeBinary), Column('name', String(255)), Column('tenant_id', String(255)), Column('region', String(255))) def create_nm_model(metadata=None): return Table('notification_method', metadata, Column('id', String(36)), Column('tenant_id', String(36)), Column('name', String(250)), Column('type', String(20)), Column('address', String(512)), Column('period', Integer), Column('created_at', DateTime), Column('updated_at', DateTime)) def create_nmt_model(metadata=None): return Table('notification_method_type', metadata, Column('name', String(20), primary_key=True)) def create_mdd_model(metadata=None): return Table('metric_definition_dimensions', metadata, Column('id', LargeBinary), Column('metric_definition_id', LargeBinary), Column('metric_dimension_set_id', LargeBinary)) def create_am_model(metadata=None): return Table('alarm_metric', metadata, Column('alarm_id', String(36)), Column('metric_definition_dimensions_id', LargeBinary)) def create_ad_model(metadata=None): return Table('alarm_definition', metadata, Column('id', String(36)), Column('tenant_id', String(36)), Column('name', String(255)), Column('description', String(255)), Column('expression', String), Column('severity', String(20)), Column('match_by', String(255)), Column('actions_enabled', Boolean), Column('created_at', DateTime), Column('updated_at', DateTime), Column('deleted_at', DateTime)) def create_sa_model(metadata=None): return Table('sub_alarm', metadata, Column('id', String(36)), Column('alarm_id', String(36)), Column('sub_expression_id', String(36)), Column('expression', String), Column('created_at', DateTime), Column('updated_at', DateTime)) def create_sad_model(metadata=None): return Table('sub_alarm_definition', metadata, Column('id', String(36)), Column('alarm_definition_id', String(36)), Column('function', String(10)), Column('metric_name', String(100)), Column('operator', String(5)), Column('threshold', Float), Column('period', Integer), Column('periods', Integer), Column('is_deterministic', Boolean), Column('created_at', DateTime), Column('updated_at', DateTime)) class group_concat(expression.ColumnElement): name = "group_concat" order_by = None separator = ',' columns = [] def __init__(self, columns, separator=',', order_by=None): self.order_by = order_by self.separator = separator self.columns = columns @compiler.compiles(group_concat, 'oracle') def _group_concat_oracle(element, compiler_, **kw): str_order_by = '' if element.order_by is not None and len(element.order_by) > 0: str_order_by = "ORDER BY {0}".format( ", ".join([compiler_.process(x) for x in element.order_by])) else: str_order_by = "ORDER BY {0}".format( ", ".join([compiler_.process(x) for x in element.columns])) return "LISTAGG({0}, '{2}') WITHIN GROUP ({1})".format( ", ".join([compiler_.process(x) for x in element.columns]), str_order_by, element.separator, ) @compiler.compiles(group_concat, 'postgresql') def _group_concat_postgresql(element, compiler_, **kw): str_order_by = '' if element.order_by is not None and len(element.order_by) > 0: str_order_by = "ORDER BY {0}".format( ", ".join([compiler_.process(x) for x in element.order_by])) return "STRING_AGG({0}, '{2}' {1})".format( ", ".join([compiler_.process(x) for x in element.columns]), str_order_by, element.separator, ) @compiler.compiles(group_concat, 'sybase') def _group_concat_sybase(element, compiler_, **kw): return "LIST({0}, '{1}')".format( ", ".join([compiler_.process(x) for x in element.columns]), element.separator, ) @compiler.compiles(group_concat, 'mysql') def _group_concat_mysql(element, compiler_, **kw): str_order_by = '' if element.order_by is not None and len(element.order_by) > 0: str_order_by = "ORDER BY {0}".format( ",".join([compiler_.process(x) for x in element.order_by])) return "GROUP_CONCAT({0} {1} SEPARATOR '{2}')".format( ", ".join([compiler_.process(x) for x in element.columns]), str_order_by, element.separator, ) @compiler.compiles(group_concat) def _group_concat_default(element, compiler_, **kw): return "GROUP_CONCAT({0}, '{1}')".format( ", ".join([compiler_.process(x) for x in element.columns]), element.separator, ) class field_sort(expression.ColumnElement): name = "field_sort" column = None fields = [] def __init__(self, column, fields): self.column = column self.fields = fields @compiler.compiles(field_sort, "mysql") def _field_sort_mysql(element, compiler_, **kw): if element.fields: return "FIELD({0}, {1})".format(compiler_.process(element.column), ", ".join(map(compiler_.process, element.fields))) else: return str(compiler_.process(element.column)) @compiler.compiles(field_sort) def _field_sort_general(element, compiler_, **kw): fields_list = [] fields = list(element.fields) if fields: fields_list.append("CASE") for idx, field in enumerate(fields): fields_list.append("WHEN {0}={1} THEN {2}".format(compiler_.process(element.column), compiler_.process(field), idx)) fields_list.append("ELSE {0}".format(len(fields))) fields_list.append("END") return " ".join(fields_list)