committed by
GitHub
68 changed files with 5 additions and 7769 deletions
@ -1,187 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.device_by_tenant_and_name; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.device_by_tenant_and_search_text; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.device_by_tenant_by_type_and_search_text; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.device_by_customer_and_search_text; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.device_by_customer_by_type_and_search_text; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.device_types_by_tenant; |
|||
|
|||
DROP TABLE IF EXISTS thingsboard.device; |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.device ( |
|||
id timeuuid, |
|||
tenant_id timeuuid, |
|||
customer_id timeuuid, |
|||
name text, |
|||
type text, |
|||
search_text text, |
|||
additional_info text, |
|||
PRIMARY KEY (id, tenant_id, customer_id, type) |
|||
); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_tenant_and_name AS |
|||
SELECT * |
|||
from thingsboard.device |
|||
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL |
|||
PRIMARY KEY ( tenant_id, name, id, customer_id, type) |
|||
WITH CLUSTERING ORDER BY ( name ASC, id DESC, customer_id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_tenant_and_search_text AS |
|||
SELECT * |
|||
from thingsboard.device |
|||
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL |
|||
PRIMARY KEY ( tenant_id, search_text, id, customer_id, type) |
|||
WITH CLUSTERING ORDER BY ( search_text ASC, id DESC, customer_id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_tenant_by_type_and_search_text AS |
|||
SELECT * |
|||
from thingsboard.device |
|||
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL |
|||
PRIMARY KEY ( tenant_id, type, search_text, id, customer_id) |
|||
WITH CLUSTERING ORDER BY ( type ASC, search_text ASC, id DESC, customer_id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_customer_and_search_text AS |
|||
SELECT * |
|||
from thingsboard.device |
|||
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL |
|||
PRIMARY KEY ( customer_id, tenant_id, search_text, id, type ) |
|||
WITH CLUSTERING ORDER BY ( tenant_id DESC, search_text ASC, id DESC ); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.device_by_customer_by_type_and_search_text AS |
|||
SELECT * |
|||
from thingsboard.device |
|||
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL |
|||
PRIMARY KEY ( customer_id, tenant_id, type, search_text, id ) |
|||
WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC ); |
|||
|
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.asset_by_tenant_and_name; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.asset_by_tenant_and_search_text; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.asset_by_tenant_by_type_and_search_text; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.asset_by_customer_and_search_text; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.asset_by_customer_by_type_and_search_text; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.asset_types_by_tenant; |
|||
|
|||
DROP TABLE IF EXISTS thingsboard.asset; |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.asset ( |
|||
id timeuuid, |
|||
tenant_id timeuuid, |
|||
customer_id timeuuid, |
|||
name text, |
|||
type text, |
|||
search_text text, |
|||
additional_info text, |
|||
PRIMARY KEY (id, tenant_id, customer_id, type) |
|||
); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.asset_by_tenant_and_name AS |
|||
SELECT * |
|||
from thingsboard.asset |
|||
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND name IS NOT NULL AND id IS NOT NULL |
|||
PRIMARY KEY ( tenant_id, name, id, customer_id, type) |
|||
WITH CLUSTERING ORDER BY ( name ASC, id DESC, customer_id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.asset_by_tenant_and_search_text AS |
|||
SELECT * |
|||
from thingsboard.asset |
|||
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL |
|||
PRIMARY KEY ( tenant_id, search_text, id, customer_id, type) |
|||
WITH CLUSTERING ORDER BY ( search_text ASC, id DESC, customer_id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.asset_by_tenant_by_type_and_search_text AS |
|||
SELECT * |
|||
from thingsboard.asset |
|||
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL |
|||
PRIMARY KEY ( tenant_id, type, search_text, id, customer_id) |
|||
WITH CLUSTERING ORDER BY ( type ASC, search_text ASC, id DESC, customer_id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.asset_by_customer_and_search_text AS |
|||
SELECT * |
|||
from thingsboard.asset |
|||
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL |
|||
PRIMARY KEY ( customer_id, tenant_id, search_text, id, type ) |
|||
WITH CLUSTERING ORDER BY ( tenant_id DESC, search_text ASC, id DESC ); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.asset_by_customer_by_type_and_search_text AS |
|||
SELECT * |
|||
from thingsboard.asset |
|||
WHERE tenant_id IS NOT NULL AND customer_id IS NOT NULL AND type IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL |
|||
PRIMARY KEY ( customer_id, tenant_id, type, search_text, id ) |
|||
WITH CLUSTERING ORDER BY ( tenant_id DESC, type ASC, search_text ASC, id DESC ); |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.entity_subtype ( |
|||
tenant_id timeuuid, |
|||
entity_type text, // (DEVICE, ASSET) |
|||
type text, |
|||
PRIMARY KEY (tenant_id, entity_type, type) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.alarm ( |
|||
id timeuuid, |
|||
tenant_id timeuuid, |
|||
type text, |
|||
originator_id timeuuid, |
|||
originator_type text, |
|||
severity text, |
|||
status text, |
|||
start_ts bigint, |
|||
end_ts bigint, |
|||
ack_ts bigint, |
|||
clear_ts bigint, |
|||
details text, |
|||
propagate boolean, |
|||
PRIMARY KEY ((tenant_id, originator_id, originator_type), type, id) |
|||
) WITH CLUSTERING ORDER BY ( type ASC, id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.alarm_by_id AS |
|||
SELECT * |
|||
from thingsboard.alarm |
|||
WHERE tenant_id IS NOT NULL AND originator_id IS NOT NULL AND originator_type IS NOT NULL AND type IS NOT NULL |
|||
AND type IS NOT NULL AND id IS NOT NULL |
|||
PRIMARY KEY (id, tenant_id, originator_id, originator_type, type) |
|||
WITH CLUSTERING ORDER BY ( tenant_id ASC, originator_id ASC, originator_type ASC, type ASC); |
|||
|
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.relation_by_type_and_child_type; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.reverse_relation; |
|||
|
|||
DROP TABLE IF EXISTS thingsboard.relation; |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.relation ( |
|||
from_id timeuuid, |
|||
from_type text, |
|||
to_id timeuuid, |
|||
to_type text, |
|||
relation_type_group text, |
|||
relation_type text, |
|||
additional_info text, |
|||
PRIMARY KEY ((from_id, from_type), relation_type_group, relation_type, to_id, to_type) |
|||
) WITH CLUSTERING ORDER BY ( relation_type_group ASC, relation_type ASC, to_id ASC, to_type ASC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.relation_by_type_and_child_type AS |
|||
SELECT * |
|||
from thingsboard.relation |
|||
WHERE from_id IS NOT NULL AND from_type IS NOT NULL AND relation_type_group IS NOT NULL AND relation_type IS NOT NULL AND to_id IS NOT NULL AND to_type IS NOT NULL |
|||
PRIMARY KEY ((from_id, from_type), relation_type_group, relation_type, to_type, to_id) |
|||
WITH CLUSTERING ORDER BY ( relation_type_group ASC, relation_type ASC, to_type ASC, to_id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.reverse_relation AS |
|||
SELECT * |
|||
from thingsboard.relation |
|||
WHERE from_id IS NOT NULL AND from_type IS NOT NULL AND relation_type_group IS NOT NULL AND relation_type IS NOT NULL AND to_id IS NOT NULL AND to_type IS NOT NULL |
|||
PRIMARY KEY ((to_id, to_type), relation_type_group, relation_type, from_id, from_type) |
|||
WITH CLUSTERING ORDER BY ( relation_type_group ASC, relation_type ASC, from_id ASC, from_type ASC); |
|||
@ -1,17 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
ALTER TABLE ts_kv_latest ALTER COLUMN str_v SET DATA TYPE varchar(10000000); |
|||
@ -1,112 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.audit_log_by_entity_id ( |
|||
tenant_id timeuuid, |
|||
id timeuuid, |
|||
customer_id timeuuid, |
|||
entity_id timeuuid, |
|||
entity_type text, |
|||
entity_name text, |
|||
user_id timeuuid, |
|||
user_name text, |
|||
action_type text, |
|||
action_data text, |
|||
action_status text, |
|||
action_failure_details text, |
|||
PRIMARY KEY ((tenant_id, entity_id, entity_type), id) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.audit_log_by_customer_id ( |
|||
tenant_id timeuuid, |
|||
id timeuuid, |
|||
customer_id timeuuid, |
|||
entity_id timeuuid, |
|||
entity_type text, |
|||
entity_name text, |
|||
user_id timeuuid, |
|||
user_name text, |
|||
action_type text, |
|||
action_data text, |
|||
action_status text, |
|||
action_failure_details text, |
|||
PRIMARY KEY ((tenant_id, customer_id), id) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.audit_log_by_user_id ( |
|||
tenant_id timeuuid, |
|||
id timeuuid, |
|||
customer_id timeuuid, |
|||
entity_id timeuuid, |
|||
entity_type text, |
|||
entity_name text, |
|||
user_id timeuuid, |
|||
user_name text, |
|||
action_type text, |
|||
action_data text, |
|||
action_status text, |
|||
action_failure_details text, |
|||
PRIMARY KEY ((tenant_id, user_id), id) |
|||
); |
|||
|
|||
|
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.audit_log_by_tenant_id ( |
|||
tenant_id timeuuid, |
|||
id timeuuid, |
|||
partition bigint, |
|||
customer_id timeuuid, |
|||
entity_id timeuuid, |
|||
entity_type text, |
|||
entity_name text, |
|||
user_id timeuuid, |
|||
user_name text, |
|||
action_type text, |
|||
action_data text, |
|||
action_status text, |
|||
action_failure_details text, |
|||
PRIMARY KEY ((tenant_id, partition), id) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.audit_log_by_tenant_id_partitions ( |
|||
tenant_id timeuuid, |
|||
partition bigint, |
|||
PRIMARY KEY (( tenant_id ), partition) |
|||
) WITH CLUSTERING ORDER BY ( partition ASC ) |
|||
AND compaction = { 'class' : 'LeveledCompactionStrategy' }; |
|||
|
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.dashboard_by_tenant_and_search_text; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.dashboard_by_customer_and_search_text; |
|||
|
|||
DROP TABLE IF EXISTS thingsboard.dashboard; |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.dashboard ( |
|||
id timeuuid, |
|||
tenant_id timeuuid, |
|||
title text, |
|||
search_text text, |
|||
assigned_customers text, |
|||
configuration text, |
|||
PRIMARY KEY (id, tenant_id) |
|||
); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.dashboard_by_tenant_and_search_text AS |
|||
SELECT * |
|||
from thingsboard.dashboard |
|||
WHERE tenant_id IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL |
|||
PRIMARY KEY ( tenant_id, search_text, id ) |
|||
WITH CLUSTERING ORDER BY ( search_text ASC, id DESC ); |
|||
|
|||
@ -1,41 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE TABLE IF NOT EXISTS audit_log ( |
|||
id varchar(31) NOT NULL CONSTRAINT audit_log_pkey PRIMARY KEY, |
|||
tenant_id varchar(31), |
|||
customer_id varchar(31), |
|||
entity_id varchar(31), |
|||
entity_type varchar(255), |
|||
entity_name varchar(255), |
|||
user_id varchar(31), |
|||
user_name varchar(255), |
|||
action_type varchar(255), |
|||
action_data varchar(1000000), |
|||
action_status varchar(255), |
|||
action_failure_details varchar(1000000) |
|||
); |
|||
|
|||
DROP TABLE IF EXISTS dashboard; |
|||
|
|||
CREATE TABLE IF NOT EXISTS dashboard ( |
|||
id varchar(31) NOT NULL CONSTRAINT dashboard_pkey PRIMARY KEY, |
|||
configuration varchar(10000000), |
|||
assigned_customers varchar(1000000), |
|||
search_text varchar(255), |
|||
tenant_id varchar(31), |
|||
title varchar(255) |
|||
); |
|||
@ -1,103 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.msg_queue ( |
|||
node_id timeuuid, |
|||
cluster_partition bigint, |
|||
ts_partition bigint, |
|||
ts bigint, |
|||
msg blob, |
|||
PRIMARY KEY ((node_id, cluster_partition, ts_partition), ts)) |
|||
WITH CLUSTERING ORDER BY (ts DESC) |
|||
AND compaction = { |
|||
'class': 'org.apache.cassandra.db.compaction.DateTieredCompactionStrategy', |
|||
'min_threshold': '5', |
|||
'base_time_seconds': '43200', |
|||
'max_window_size_seconds': '43200', |
|||
'tombstone_threshold': '0.9', |
|||
'unchecked_tombstone_compaction': 'true' |
|||
}; |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.msg_ack_queue ( |
|||
node_id timeuuid, |
|||
cluster_partition bigint, |
|||
ts_partition bigint, |
|||
msg_id timeuuid, |
|||
PRIMARY KEY ((node_id, cluster_partition, ts_partition), msg_id)) |
|||
WITH CLUSTERING ORDER BY (msg_id DESC) |
|||
AND compaction = { |
|||
'class': 'org.apache.cassandra.db.compaction.DateTieredCompactionStrategy', |
|||
'min_threshold': '5', |
|||
'base_time_seconds': '43200', |
|||
'max_window_size_seconds': '43200', |
|||
'tombstone_threshold': '0.9', |
|||
'unchecked_tombstone_compaction': 'true' |
|||
}; |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.processed_msg_partitions ( |
|||
node_id timeuuid, |
|||
cluster_partition bigint, |
|||
ts_partition bigint, |
|||
PRIMARY KEY ((node_id, cluster_partition), ts_partition)) |
|||
WITH CLUSTERING ORDER BY (ts_partition DESC) |
|||
AND compaction = { |
|||
'class': 'org.apache.cassandra.db.compaction.DateTieredCompactionStrategy', |
|||
'min_threshold': '5', |
|||
'base_time_seconds': '43200', |
|||
'max_window_size_seconds': '43200', |
|||
'tombstone_threshold': '0.9', |
|||
'unchecked_tombstone_compaction': 'true' |
|||
}; |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.rule_chain ( |
|||
id uuid, |
|||
tenant_id uuid, |
|||
name text, |
|||
search_text text, |
|||
first_rule_node_id uuid, |
|||
root boolean, |
|||
debug_mode boolean, |
|||
configuration text, |
|||
additional_info text, |
|||
PRIMARY KEY (id, tenant_id) |
|||
); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.rule_chain_by_tenant_and_search_text AS |
|||
SELECT * |
|||
from thingsboard.rule_chain |
|||
WHERE tenant_id IS NOT NULL AND search_text IS NOT NULL AND id IS NOT NULL |
|||
PRIMARY KEY ( tenant_id, search_text, id ) |
|||
WITH CLUSTERING ORDER BY ( search_text ASC, id DESC ); |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.rule_node ( |
|||
id uuid, |
|||
rule_chain_id uuid, |
|||
type text, |
|||
name text, |
|||
debug_mode boolean, |
|||
search_text text, |
|||
configuration text, |
|||
additional_info text, |
|||
PRIMARY KEY (id) |
|||
); |
|||
|
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.rule_by_plugin_token; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.rule_by_tenant_and_search_text; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.plugin_by_api_token; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.plugin_by_tenant_and_search_text; |
|||
|
|||
DROP TABLE IF EXISTS thingsboard.rule; |
|||
DROP TABLE IF EXISTS thingsboard.plugin; |
|||
@ -1,44 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE TABLE IF NOT EXISTS rule_chain ( |
|||
id varchar(31) NOT NULL CONSTRAINT rule_chain_pkey PRIMARY KEY, |
|||
additional_info varchar, |
|||
configuration varchar(10000000), |
|||
name varchar(255), |
|||
first_rule_node_id varchar(31), |
|||
root boolean, |
|||
debug_mode boolean, |
|||
search_text varchar(255), |
|||
tenant_id varchar(31) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS rule_node ( |
|||
id varchar(31) NOT NULL CONSTRAINT rule_node_pkey PRIMARY KEY, |
|||
rule_chain_id varchar(31), |
|||
additional_info varchar, |
|||
configuration varchar(10000000), |
|||
type varchar(255), |
|||
name varchar(255), |
|||
debug_mode boolean, |
|||
search_text varchar(255) |
|||
); |
|||
|
|||
DROP TABLE rule; |
|||
DROP TABLE plugin; |
|||
|
|||
DELETE FROM alarm WHERE originator_type = 3 OR originator_type = 4; |
|||
UPDATE alarm SET originator_type = (originator_type - 2) where originator_type > 2; |
|||
@ -1,74 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.entity_views ( |
|||
id timeuuid, |
|||
entity_id timeuuid, |
|||
entity_type text, |
|||
tenant_id timeuuid, |
|||
customer_id timeuuid, |
|||
name text, |
|||
keys text, |
|||
start_ts bigint, |
|||
end_ts bigint, |
|||
search_text text, |
|||
additional_info text, |
|||
PRIMARY KEY (id, entity_id, tenant_id, customer_id) |
|||
); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_and_name AS |
|||
SELECT * |
|||
from thingsboard.entity_views |
|||
WHERE tenant_id IS NOT NULL |
|||
AND entity_id IS NOT NULL |
|||
AND customer_id IS NOT NULL |
|||
AND name IS NOT NULL |
|||
AND id IS NOT NULL |
|||
PRIMARY KEY (tenant_id, name, id, customer_id, entity_id) |
|||
WITH CLUSTERING ORDER BY (name ASC, id DESC, customer_id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_and_search_text AS |
|||
SELECT * |
|||
from thingsboard.entity_views |
|||
WHERE tenant_id IS NOT NULL |
|||
AND entity_id IS NOT NULL |
|||
AND customer_id IS NOT NULL |
|||
AND search_text IS NOT NULL |
|||
AND id IS NOT NULL |
|||
PRIMARY KEY (tenant_id, search_text, id, customer_id, entity_id) |
|||
WITH CLUSTERING ORDER BY (search_text ASC, id DESC, customer_id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_and_customer AS |
|||
SELECT * |
|||
from thingsboard.entity_views |
|||
WHERE tenant_id IS NOT NULL |
|||
AND customer_id IS NOT NULL |
|||
AND entity_id IS NOT NULL |
|||
AND search_text IS NOT NULL |
|||
AND id IS NOT NULL |
|||
PRIMARY KEY (tenant_id, customer_id, search_text, id, entity_id) |
|||
WITH CLUSTERING ORDER BY (customer_id DESC, search_text ASC, id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_and_entity_id AS |
|||
SELECT * |
|||
from thingsboard.entity_views |
|||
WHERE tenant_id IS NOT NULL |
|||
AND customer_id IS NOT NULL |
|||
AND entity_id IS NOT NULL |
|||
AND search_text IS NOT NULL |
|||
AND id IS NOT NULL |
|||
PRIMARY KEY (tenant_id, entity_id, customer_id, search_text, id) |
|||
WITH CLUSTERING ORDER BY (entity_id DESC, customer_id DESC, search_text ASC, id DESC); |
|||
@ -1,29 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE TABLE IF NOT EXISTS entity_views ( |
|||
id varchar(31) NOT NULL CONSTRAINT entity_views_pkey PRIMARY KEY, |
|||
entity_id varchar(31), |
|||
entity_type varchar(255), |
|||
tenant_id varchar(31), |
|||
customer_id varchar(31), |
|||
name varchar(255), |
|||
keys varchar(255), |
|||
start_ts bigint, |
|||
end_ts bigint, |
|||
search_text varchar(255), |
|||
additional_info varchar |
|||
); |
|||
@ -1,110 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.entity_view_by_tenant_and_name; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.entity_view_by_tenant_and_search_text; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.entity_view_by_tenant_and_customer; |
|||
DROP MATERIALIZED VIEW IF EXISTS thingsboard.entity_view_by_tenant_and_entity_id; |
|||
|
|||
DROP TABLE IF EXISTS thingsboard.entity_views; |
|||
|
|||
CREATE TABLE IF NOT EXISTS thingsboard.entity_view ( |
|||
id timeuuid, |
|||
entity_id timeuuid, |
|||
entity_type text, |
|||
tenant_id timeuuid, |
|||
customer_id timeuuid, |
|||
name text, |
|||
type text, |
|||
keys text, |
|||
start_ts bigint, |
|||
end_ts bigint, |
|||
search_text text, |
|||
additional_info text, |
|||
PRIMARY KEY (id, entity_id, tenant_id, customer_id, type) |
|||
); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_and_name AS |
|||
SELECT * |
|||
from thingsboard.entity_view |
|||
WHERE tenant_id IS NOT NULL |
|||
AND entity_id IS NOT NULL |
|||
AND customer_id IS NOT NULL |
|||
AND type IS NOT NULL |
|||
AND name IS NOT NULL |
|||
AND id IS NOT NULL |
|||
PRIMARY KEY (tenant_id, name, id, customer_id, entity_id, type) |
|||
WITH CLUSTERING ORDER BY (name ASC, id DESC, customer_id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_and_search_text AS |
|||
SELECT * |
|||
from thingsboard.entity_view |
|||
WHERE tenant_id IS NOT NULL |
|||
AND entity_id IS NOT NULL |
|||
AND customer_id IS NOT NULL |
|||
AND type IS NOT NULL |
|||
AND search_text IS NOT NULL |
|||
AND id IS NOT NULL |
|||
PRIMARY KEY (tenant_id, search_text, id, customer_id, entity_id, type) |
|||
WITH CLUSTERING ORDER BY (search_text ASC, id DESC, customer_id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_by_type_and_search_text AS |
|||
SELECT * |
|||
from thingsboard.entity_view |
|||
WHERE tenant_id IS NOT NULL |
|||
AND entity_id IS NOT NULL |
|||
AND customer_id IS NOT NULL |
|||
AND type IS NOT NULL |
|||
AND search_text IS NOT NULL |
|||
AND id IS NOT NULL |
|||
PRIMARY KEY (tenant_id, type, search_text, id, customer_id, entity_id) |
|||
WITH CLUSTERING ORDER BY (type ASC, search_text ASC, id DESC, customer_id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_and_customer AS |
|||
SELECT * |
|||
from thingsboard.entity_view |
|||
WHERE tenant_id IS NOT NULL |
|||
AND customer_id IS NOT NULL |
|||
AND entity_id IS NOT NULL |
|||
AND type IS NOT NULL |
|||
AND search_text IS NOT NULL |
|||
AND id IS NOT NULL |
|||
PRIMARY KEY (tenant_id, customer_id, search_text, id, entity_id, type) |
|||
WITH CLUSTERING ORDER BY (customer_id DESC, search_text ASC, id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_and_customer_and_type AS |
|||
SELECT * |
|||
from thingsboard.entity_view |
|||
WHERE tenant_id IS NOT NULL |
|||
AND customer_id IS NOT NULL |
|||
AND entity_id IS NOT NULL |
|||
AND type IS NOT NULL |
|||
AND search_text IS NOT NULL |
|||
AND id IS NOT NULL |
|||
PRIMARY KEY (tenant_id, type, customer_id, search_text, id, entity_id) |
|||
WITH CLUSTERING ORDER BY (type ASC, customer_id DESC, search_text ASC, id DESC); |
|||
|
|||
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_view_by_tenant_and_entity_id AS |
|||
SELECT * |
|||
from thingsboard.entity_view |
|||
WHERE tenant_id IS NOT NULL |
|||
AND customer_id IS NOT NULL |
|||
AND entity_id IS NOT NULL |
|||
AND type IS NOT NULL |
|||
AND search_text IS NOT NULL |
|||
AND id IS NOT NULL |
|||
PRIMARY KEY (tenant_id, entity_id, customer_id, search_text, id, type) |
|||
WITH CLUSTERING ORDER BY (entity_id DESC, customer_id DESC, search_text ASC, id DESC); |
|||
@ -1,32 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
DROP TABLE IF EXISTS entity_views; |
|||
|
|||
CREATE TABLE IF NOT EXISTS entity_view ( |
|||
id varchar(31) NOT NULL CONSTRAINT entity_view_pkey PRIMARY KEY, |
|||
entity_id varchar(31), |
|||
entity_type varchar(255), |
|||
tenant_id varchar(31), |
|||
customer_id varchar(31), |
|||
type varchar(255), |
|||
name varchar(255), |
|||
keys varchar(255), |
|||
start_ts bigint, |
|||
end_ts bigint, |
|||
search_text varchar(255), |
|||
additional_info varchar |
|||
); |
|||
@ -1,19 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
ALTER TABLE component_descriptor ADD UNIQUE (clazz); |
|||
|
|||
ALTER TABLE entity_view ALTER COLUMN keys SET DATA TYPE varchar(10000000); |
|||
@ -1,17 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
ALTER TABLE event ALTER COLUMN body SET DATA TYPE varchar(10000000); |
|||
@ -1,23 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_alarm_originator_alarm_type ON alarm(tenant_id, type, originator_type, originator_id); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_event_type_entity_id ON event(tenant_id, event_type, entity_type, entity_id); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_relation_to_id ON relation(relation_type_group, to_type, to_id); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_relation_from_id ON relation(relation_type_group, from_type, from_id); |
|||
@ -1,31 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
DROP INDEX IF EXISTS idx_alarm_originator_alarm_type; |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_alarm_originator_alarm_type ON alarm(originator_id, type, start_ts DESC); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_device_customer_id ON device(tenant_id, customer_id); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_device_customer_id_and_type ON device(tenant_id, customer_id, type); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_device_type ON device(tenant_id, type); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_asset_customer_id ON asset(tenant_id, customer_id); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_asset_customer_id_and_type ON asset(tenant_id, customer_id, type); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_asset_type ON asset(tenant_id, type); |
|||
@ -1,209 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE OR REPLACE PROCEDURE drop_partitions_by_max_ttl(IN partition_type varchar, IN system_ttl bigint, INOUT deleted bigint) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
max_tenant_ttl bigint; |
|||
max_customer_ttl bigint; |
|||
max_ttl bigint; |
|||
date timestamp; |
|||
partition_by_max_ttl_date varchar; |
|||
partition_by_max_ttl_month varchar; |
|||
partition_by_max_ttl_day varchar; |
|||
partition_by_max_ttl_year varchar; |
|||
partition varchar; |
|||
partition_year integer; |
|||
partition_month integer; |
|||
partition_day integer; |
|||
|
|||
BEGIN |
|||
SELECT max(attribute_kv.long_v) |
|||
FROM tenant |
|||
INNER JOIN attribute_kv ON tenant.id = attribute_kv.entity_id |
|||
WHERE attribute_kv.attribute_key = 'TTL' |
|||
into max_tenant_ttl; |
|||
SELECT max(attribute_kv.long_v) |
|||
FROM customer |
|||
INNER JOIN attribute_kv ON customer.id = attribute_kv.entity_id |
|||
WHERE attribute_kv.attribute_key = 'TTL' |
|||
into max_customer_ttl; |
|||
max_ttl := GREATEST(system_ttl, max_customer_ttl, max_tenant_ttl); |
|||
if max_ttl IS NOT NULL AND max_ttl > 0 THEN |
|||
date := to_timestamp(EXTRACT(EPOCH FROM current_timestamp) - max_ttl); |
|||
partition_by_max_ttl_date := get_partition_by_max_ttl_date(partition_type, date); |
|||
RAISE NOTICE 'Date by max ttl: %', date; |
|||
RAISE NOTICE 'Partition by max ttl: %', partition_by_max_ttl_date; |
|||
IF partition_by_max_ttl_date IS NOT NULL THEN |
|||
CASE |
|||
WHEN partition_type = 'DAYS' THEN |
|||
partition_by_max_ttl_year := SPLIT_PART(partition_by_max_ttl_date, '_', 3); |
|||
partition_by_max_ttl_month := SPLIT_PART(partition_by_max_ttl_date, '_', 4); |
|||
partition_by_max_ttl_day := SPLIT_PART(partition_by_max_ttl_date, '_', 5); |
|||
WHEN partition_type = 'MONTHS' THEN |
|||
partition_by_max_ttl_year := SPLIT_PART(partition_by_max_ttl_date, '_', 3); |
|||
partition_by_max_ttl_month := SPLIT_PART(partition_by_max_ttl_date, '_', 4); |
|||
ELSE |
|||
partition_by_max_ttl_year := SPLIT_PART(partition_by_max_ttl_date, '_', 3); |
|||
END CASE; |
|||
IF partition_by_max_ttl_year IS NULL THEN |
|||
RAISE NOTICE 'Failed to remove partitions by max ttl date due to partition_by_max_ttl_year is null!'; |
|||
ELSE |
|||
IF partition_type = 'YEARS' THEN |
|||
FOR partition IN SELECT tablename |
|||
FROM pg_tables |
|||
WHERE schemaname = 'public' |
|||
AND tablename like 'ts_kv_' || '%' |
|||
AND tablename != 'ts_kv_latest' |
|||
AND tablename != 'ts_kv_dictionary' |
|||
AND tablename != 'ts_kv_indefinite' |
|||
AND tablename != partition_by_max_ttl_date |
|||
LOOP |
|||
partition_year := SPLIT_PART(partition, '_', 3)::integer; |
|||
IF partition_year < partition_by_max_ttl_year::integer THEN |
|||
RAISE NOTICE 'Partition to delete by max ttl: %', partition; |
|||
EXECUTE format('DROP TABLE IF EXISTS %I', partition); |
|||
deleted := deleted + 1; |
|||
END IF; |
|||
END LOOP; |
|||
ELSE |
|||
IF partition_type = 'MONTHS' THEN |
|||
IF partition_by_max_ttl_month IS NULL THEN |
|||
RAISE NOTICE 'Failed to remove months partitions by max ttl date due to partition_by_max_ttl_month is null!'; |
|||
ELSE |
|||
FOR partition IN SELECT tablename |
|||
FROM pg_tables |
|||
WHERE schemaname = 'public' |
|||
AND tablename like 'ts_kv_' || '%' |
|||
AND tablename != 'ts_kv_latest' |
|||
AND tablename != 'ts_kv_dictionary' |
|||
AND tablename != 'ts_kv_indefinite' |
|||
AND tablename != partition_by_max_ttl_date |
|||
LOOP |
|||
partition_year := SPLIT_PART(partition, '_', 3)::integer; |
|||
IF partition_year > partition_by_max_ttl_year::integer THEN |
|||
RAISE NOTICE 'Skip iteration! Partition: % is valid!', partition; |
|||
CONTINUE; |
|||
ELSE |
|||
IF partition_year < partition_by_max_ttl_year::integer THEN |
|||
RAISE NOTICE 'Partition to delete by max ttl: %', partition; |
|||
EXECUTE format('DROP TABLE IF EXISTS %I', partition); |
|||
deleted := deleted + 1; |
|||
ELSE |
|||
partition_month := SPLIT_PART(partition, '_', 4)::integer; |
|||
IF partition_year = partition_by_max_ttl_year::integer THEN |
|||
IF partition_month >= partition_by_max_ttl_month::integer THEN |
|||
RAISE NOTICE 'Skip iteration! Partition: % is valid!', partition; |
|||
CONTINUE; |
|||
ELSE |
|||
RAISE NOTICE 'Partition to delete by max ttl: %', partition; |
|||
EXECUTE format('DROP TABLE IF EXISTS %I', partition); |
|||
deleted := deleted + 1; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END LOOP; |
|||
END IF; |
|||
ELSE |
|||
IF partition_type = 'DAYS' THEN |
|||
IF partition_by_max_ttl_month IS NULL THEN |
|||
RAISE NOTICE 'Failed to remove days partitions by max ttl date due to partition_by_max_ttl_month is null!'; |
|||
ELSE |
|||
IF partition_by_max_ttl_day IS NULL THEN |
|||
RAISE NOTICE 'Failed to remove days partitions by max ttl date due to partition_by_max_ttl_day is null!'; |
|||
ELSE |
|||
FOR partition IN SELECT tablename |
|||
FROM pg_tables |
|||
WHERE schemaname = 'public' |
|||
AND tablename like 'ts_kv_' || '%' |
|||
AND tablename != 'ts_kv_latest' |
|||
AND tablename != 'ts_kv_dictionary' |
|||
AND tablename != 'ts_kv_indefinite' |
|||
AND tablename != partition_by_max_ttl_date |
|||
LOOP |
|||
partition_year := SPLIT_PART(partition, '_', 3)::integer; |
|||
IF partition_year > partition_by_max_ttl_year::integer THEN |
|||
RAISE NOTICE 'Skip iteration! Partition: % is valid!', partition; |
|||
CONTINUE; |
|||
ELSE |
|||
IF partition_year < partition_by_max_ttl_year::integer THEN |
|||
RAISE NOTICE 'Partition to delete by max ttl: %', partition; |
|||
EXECUTE format('DROP TABLE IF EXISTS %I', partition); |
|||
deleted := deleted + 1; |
|||
ELSE |
|||
partition_month := SPLIT_PART(partition, '_', 4)::integer; |
|||
IF partition_month > partition_by_max_ttl_month::integer THEN |
|||
RAISE NOTICE 'Skip iteration! Partition: % is valid!', partition; |
|||
CONTINUE; |
|||
ELSE |
|||
IF partition_month < partition_by_max_ttl_month::integer THEN |
|||
RAISE NOTICE 'Partition to delete by max ttl: %', partition; |
|||
EXECUTE format('DROP TABLE IF EXISTS %I', partition); |
|||
deleted := deleted + 1; |
|||
ELSE |
|||
partition_day := SPLIT_PART(partition, '_', 5)::integer; |
|||
IF partition_day >= partition_by_max_ttl_day::integer THEN |
|||
RAISE NOTICE 'Skip iteration! Partition: % is valid!', partition; |
|||
CONTINUE; |
|||
ELSE |
|||
IF partition_day < partition_by_max_ttl_day::integer THEN |
|||
RAISE NOTICE 'Partition to delete by max ttl: %', partition; |
|||
EXECUTE format('DROP TABLE IF EXISTS %I', partition); |
|||
deleted := deleted + 1; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END LOOP; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END |
|||
$$; |
|||
|
|||
CREATE OR REPLACE FUNCTION get_partition_by_max_ttl_date(IN partition_type varchar, IN date timestamp, OUT partition varchar) AS |
|||
$$ |
|||
BEGIN |
|||
CASE |
|||
WHEN partition_type = 'DAYS' THEN |
|||
partition := 'ts_kv_' || to_char(date, 'yyyy') || '_' || to_char(date, 'MM') || '_' || to_char(date, 'dd'); |
|||
WHEN partition_type = 'MONTHS' THEN |
|||
partition := 'ts_kv_' || to_char(date, 'yyyy') || '_' || to_char(date, 'MM'); |
|||
WHEN partition_type = 'YEARS' THEN |
|||
partition := 'ts_kv_' || to_char(date, 'yyyy'); |
|||
ELSE |
|||
partition := NULL; |
|||
END CASE; |
|||
IF partition IS NOT NULL THEN |
|||
IF NOT EXISTS(SELECT |
|||
FROM pg_tables |
|||
WHERE schemaname = 'public' |
|||
AND tablename = partition) THEN |
|||
partition := NULL; |
|||
RAISE NOTICE 'Failed to found partition by ttl'; |
|||
END IF; |
|||
END IF; |
|||
END; |
|||
$$ LANGUAGE plpgsql; |
|||
@ -1,359 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
-- call create_partition_ts_kv_table(); |
|||
|
|||
CREATE OR REPLACE PROCEDURE create_partition_ts_kv_table() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
|
|||
BEGIN |
|||
ALTER TABLE ts_kv |
|||
DROP CONSTRAINT IF EXISTS ts_kv_unq_key; |
|||
ALTER TABLE ts_kv |
|||
DROP CONSTRAINT IF EXISTS ts_kv_pkey; |
|||
ALTER TABLE ts_kv |
|||
ADD CONSTRAINT ts_kv_pkey PRIMARY KEY (entity_type, entity_id, key, ts); |
|||
ALTER TABLE ts_kv |
|||
RENAME TO ts_kv_old; |
|||
ALTER TABLE ts_kv_old |
|||
RENAME CONSTRAINT ts_kv_pkey TO ts_kv_pkey_old; |
|||
CREATE TABLE IF NOT EXISTS ts_kv |
|||
( |
|||
LIKE ts_kv_old |
|||
) |
|||
PARTITION BY RANGE (ts); |
|||
ALTER TABLE ts_kv |
|||
DROP COLUMN entity_type; |
|||
ALTER TABLE ts_kv |
|||
ALTER COLUMN entity_id TYPE uuid USING entity_id::uuid; |
|||
ALTER TABLE ts_kv |
|||
ALTER COLUMN key TYPE integer USING key::integer; |
|||
ALTER TABLE ts_kv |
|||
ADD CONSTRAINT ts_kv_pkey PRIMARY KEY (entity_id, key, ts); |
|||
CREATE TABLE IF NOT EXISTS ts_kv_indefinite PARTITION OF ts_kv DEFAULT; |
|||
END; |
|||
$$; |
|||
|
|||
-- call create_new_ts_kv_latest_table(); |
|||
|
|||
CREATE OR REPLACE PROCEDURE create_new_ts_kv_latest_table() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
|
|||
BEGIN |
|||
IF NOT EXISTS(SELECT FROM pg_tables WHERE schemaname = 'public' AND tablename = 'ts_kv_latest_old') THEN |
|||
ALTER TABLE ts_kv_latest |
|||
DROP CONSTRAINT IF EXISTS ts_kv_latest_unq_key; |
|||
ALTER TABLE ts_kv_latest |
|||
DROP CONSTRAINT IF EXISTS ts_kv_latest_pkey; |
|||
ALTER TABLE ts_kv_latest |
|||
ADD CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_type, entity_id, key); |
|||
ALTER TABLE ts_kv_latest |
|||
RENAME TO ts_kv_latest_old; |
|||
ALTER TABLE ts_kv_latest_old |
|||
RENAME CONSTRAINT ts_kv_latest_pkey TO ts_kv_latest_pkey_old; |
|||
CREATE TABLE IF NOT EXISTS ts_kv_latest |
|||
( |
|||
LIKE ts_kv_latest_old |
|||
); |
|||
ALTER TABLE ts_kv_latest |
|||
DROP COLUMN entity_type; |
|||
ALTER TABLE ts_kv_latest |
|||
ALTER COLUMN entity_id TYPE uuid USING entity_id::uuid; |
|||
ALTER TABLE ts_kv_latest |
|||
ALTER COLUMN key TYPE integer USING key::integer; |
|||
ALTER TABLE ts_kv_latest |
|||
ADD CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key); |
|||
ELSE |
|||
RAISE NOTICE 'ts_kv_latest_old table already exists!'; |
|||
IF NOT EXISTS(SELECT FROM pg_tables WHERE schemaname = 'public' AND tablename = 'ts_kv_latest') THEN |
|||
CREATE TABLE IF NOT EXISTS ts_kv_latest |
|||
( |
|||
entity_id uuid NOT NULL, |
|||
key int NOT NULL, |
|||
ts bigint NOT NULL, |
|||
bool_v boolean, |
|||
str_v varchar(10000000), |
|||
long_v bigint, |
|||
dbl_v double precision, |
|||
json_v json, |
|||
CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key) |
|||
); |
|||
END IF; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
CREATE OR REPLACE FUNCTION get_partitions_data(IN partition_type varchar) |
|||
RETURNS |
|||
TABLE |
|||
( |
|||
partition_date text, |
|||
from_ts bigint, |
|||
to_ts bigint |
|||
) |
|||
AS |
|||
$$ |
|||
BEGIN |
|||
CASE |
|||
WHEN partition_type = 'DAYS' THEN |
|||
RETURN QUERY SELECT day_date.day AS partition_date, |
|||
(extract(epoch from (day_date.day)::timestamp) * 1000)::bigint AS from_ts, |
|||
(extract(epoch from (day_date.day::date + INTERVAL '1 DAY')::timestamp) * |
|||
1000)::bigint AS to_ts |
|||
FROM (SELECT DISTINCT TO_CHAR(TO_TIMESTAMP(ts / 1000), 'YYYY_MM_DD') AS day |
|||
FROM ts_kv_old) AS day_date; |
|||
WHEN partition_type = 'MONTHS' THEN |
|||
RETURN QUERY SELECT SUBSTRING(month_date.first_date, 1, 7) AS partition_date, |
|||
(extract(epoch from (month_date.first_date)::timestamp) * 1000)::bigint AS from_ts, |
|||
(extract(epoch from (month_date.first_date::date + INTERVAL '1 MONTH')::timestamp) * |
|||
1000)::bigint AS to_ts |
|||
FROM (SELECT DISTINCT TO_CHAR(TO_TIMESTAMP(ts / 1000), 'YYYY_MM_01') AS first_date |
|||
FROM ts_kv_old) AS month_date; |
|||
WHEN partition_type = 'YEARS' THEN |
|||
RETURN QUERY SELECT SUBSTRING(year_date.year, 1, 4) AS partition_date, |
|||
(extract(epoch from (year_date.year)::timestamp) * 1000)::bigint AS from_ts, |
|||
(extract(epoch from (year_date.year::date + INTERVAL '1 YEAR')::timestamp) * |
|||
1000)::bigint AS to_ts |
|||
FROM (SELECT DISTINCT TO_CHAR(TO_TIMESTAMP(ts / 1000), 'YYYY_01_01') AS year |
|||
FROM ts_kv_old) AS year_date; |
|||
ELSE |
|||
RAISE EXCEPTION 'Failed to parse partitioning property: % !', partition_type; |
|||
END CASE; |
|||
END; |
|||
$$ LANGUAGE plpgsql; |
|||
|
|||
-- call create_partitions(); |
|||
|
|||
CREATE OR REPLACE PROCEDURE create_partitions(IN partition_type varchar) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
|
|||
DECLARE |
|||
partition_date varchar; |
|||
from_ts bigint; |
|||
to_ts bigint; |
|||
partitions_cursor CURSOR FOR SELECT * |
|||
FROM get_partitions_data(partition_type); |
|||
BEGIN |
|||
OPEN partitions_cursor; |
|||
LOOP |
|||
FETCH partitions_cursor INTO partition_date, from_ts, to_ts; |
|||
EXIT WHEN NOT FOUND; |
|||
EXECUTE 'CREATE TABLE IF NOT EXISTS ts_kv_' || partition_date || |
|||
' PARTITION OF ts_kv FOR VALUES FROM (' || from_ts || |
|||
') TO (' || to_ts || ');'; |
|||
RAISE NOTICE 'A partition % has been created!',CONCAT('ts_kv_', partition_date); |
|||
END LOOP; |
|||
|
|||
CLOSE partitions_cursor; |
|||
END; |
|||
$$; |
|||
|
|||
-- call create_ts_kv_dictionary_table(); |
|||
|
|||
CREATE OR REPLACE PROCEDURE create_ts_kv_dictionary_table() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
|
|||
BEGIN |
|||
CREATE TABLE IF NOT EXISTS ts_kv_dictionary |
|||
( |
|||
key varchar(255) NOT NULL, |
|||
key_id serial UNIQUE, |
|||
CONSTRAINT ts_key_id_pkey PRIMARY KEY (key) |
|||
); |
|||
END; |
|||
$$; |
|||
|
|||
-- call insert_into_dictionary(); |
|||
|
|||
CREATE OR REPLACE PROCEDURE insert_into_dictionary() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
|
|||
DECLARE |
|||
insert_record RECORD; |
|||
key_cursor CURSOR FOR SELECT DISTINCT key |
|||
FROM ts_kv_old |
|||
ORDER BY key; |
|||
BEGIN |
|||
OPEN key_cursor; |
|||
LOOP |
|||
FETCH key_cursor INTO insert_record; |
|||
EXIT WHEN NOT FOUND; |
|||
IF NOT EXISTS(SELECT key FROM ts_kv_dictionary WHERE key = insert_record.key) THEN |
|||
INSERT INTO ts_kv_dictionary(key) VALUES (insert_record.key); |
|||
RAISE NOTICE 'Key: % has been inserted into the dictionary!',insert_record.key; |
|||
ELSE |
|||
RAISE NOTICE 'Key: % already exists in the dictionary!',insert_record.key; |
|||
END IF; |
|||
END LOOP; |
|||
CLOSE key_cursor; |
|||
END; |
|||
$$; |
|||
|
|||
CREATE OR REPLACE FUNCTION to_uuid(IN entity_id varchar, OUT uuid_id uuid) AS |
|||
$$ |
|||
BEGIN |
|||
uuid_id := substring(entity_id, 8, 8) || '-' || substring(entity_id, 4, 4) || '-1' || substring(entity_id, 1, 3) || |
|||
'-' || substring(entity_id, 16, 4) || '-' || substring(entity_id, 20, 12); |
|||
END; |
|||
$$ LANGUAGE plpgsql; |
|||
|
|||
CREATE OR REPLACE PROCEDURE insert_into_ts_kv(IN path_to_file varchar) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
BEGIN |
|||
EXECUTE format('COPY (SELECT to_uuid(entity_id) AS entity_id, |
|||
ts_kv_records.key AS key, |
|||
ts_kv_records.ts AS ts, |
|||
ts_kv_records.bool_v AS bool_v, |
|||
ts_kv_records.str_v AS str_v, |
|||
ts_kv_records.long_v AS long_v, |
|||
ts_kv_records.dbl_v AS dbl_v |
|||
FROM (SELECT entity_id AS entity_id, |
|||
key_id AS key, |
|||
ts, |
|||
bool_v, |
|||
str_v, |
|||
long_v, |
|||
dbl_v |
|||
FROM ts_kv_old |
|||
INNER JOIN ts_kv_dictionary ON (ts_kv_old.key = ts_kv_dictionary.key)) AS ts_kv_records) TO %L;', |
|||
path_to_file); |
|||
EXECUTE format('COPY ts_kv FROM %L', path_to_file); |
|||
END |
|||
$$; |
|||
|
|||
-- call insert_into_ts_kv_latest(); |
|||
|
|||
CREATE OR REPLACE PROCEDURE insert_into_ts_kv_latest(IN path_to_file varchar) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
BEGIN |
|||
EXECUTE format('COPY (SELECT to_uuid(entity_id) AS entity_id, |
|||
ts_kv_latest_records.key AS key, |
|||
ts_kv_latest_records.ts AS ts, |
|||
ts_kv_latest_records.bool_v AS bool_v, |
|||
ts_kv_latest_records.str_v AS str_v, |
|||
ts_kv_latest_records.long_v AS long_v, |
|||
ts_kv_latest_records.dbl_v AS dbl_v |
|||
FROM (SELECT entity_id AS entity_id, |
|||
key_id AS key, |
|||
ts, |
|||
bool_v, |
|||
str_v, |
|||
long_v, |
|||
dbl_v |
|||
FROM ts_kv_latest_old |
|||
INNER JOIN ts_kv_dictionary ON (ts_kv_latest_old.key = ts_kv_dictionary.key)) AS ts_kv_latest_records) TO %L;', |
|||
path_to_file); |
|||
EXECUTE format('COPY ts_kv_latest FROM %L', path_to_file); |
|||
END; |
|||
$$; |
|||
|
|||
-- call insert_into_ts_kv_cursor(); |
|||
|
|||
CREATE OR REPLACE PROCEDURE insert_into_ts_kv_cursor() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
insert_size CONSTANT integer := 10000; |
|||
insert_counter integer DEFAULT 0; |
|||
insert_record RECORD; |
|||
insert_cursor CURSOR FOR SELECT to_uuid(entity_id) AS entity_id, |
|||
ts_kv_records.key AS key, |
|||
ts_kv_records.ts AS ts, |
|||
ts_kv_records.bool_v AS bool_v, |
|||
ts_kv_records.str_v AS str_v, |
|||
ts_kv_records.long_v AS long_v, |
|||
ts_kv_records.dbl_v AS dbl_v |
|||
FROM (SELECT entity_id AS entity_id, |
|||
key_id AS key, |
|||
ts, |
|||
bool_v, |
|||
str_v, |
|||
long_v, |
|||
dbl_v |
|||
FROM ts_kv_old |
|||
INNER JOIN ts_kv_dictionary ON (ts_kv_old.key = ts_kv_dictionary.key)) AS ts_kv_records; |
|||
BEGIN |
|||
OPEN insert_cursor; |
|||
LOOP |
|||
insert_counter := insert_counter + 1; |
|||
FETCH insert_cursor INTO insert_record; |
|||
IF NOT FOUND THEN |
|||
RAISE NOTICE '% records have been inserted into the partitioned ts_kv!',insert_counter - 1; |
|||
EXIT; |
|||
END IF; |
|||
INSERT INTO ts_kv(entity_id, key, ts, bool_v, str_v, long_v, dbl_v) |
|||
VALUES (insert_record.entity_id, insert_record.key, insert_record.ts, insert_record.bool_v, insert_record.str_v, |
|||
insert_record.long_v, insert_record.dbl_v); |
|||
IF MOD(insert_counter, insert_size) = 0 THEN |
|||
RAISE NOTICE '% records have been inserted into the partitioned ts_kv!',insert_counter; |
|||
END IF; |
|||
END LOOP; |
|||
CLOSE insert_cursor; |
|||
END; |
|||
$$; |
|||
|
|||
-- call insert_into_ts_kv_latest_cursor(); |
|||
|
|||
CREATE OR REPLACE PROCEDURE insert_into_ts_kv_latest_cursor() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
insert_size CONSTANT integer := 10000; |
|||
insert_counter integer DEFAULT 0; |
|||
insert_record RECORD; |
|||
insert_cursor CURSOR FOR SELECT to_uuid(entity_id) AS entity_id, |
|||
ts_kv_latest_records.key AS key, |
|||
ts_kv_latest_records.ts AS ts, |
|||
ts_kv_latest_records.bool_v AS bool_v, |
|||
ts_kv_latest_records.str_v AS str_v, |
|||
ts_kv_latest_records.long_v AS long_v, |
|||
ts_kv_latest_records.dbl_v AS dbl_v |
|||
FROM (SELECT entity_id AS entity_id, |
|||
key_id AS key, |
|||
ts, |
|||
bool_v, |
|||
str_v, |
|||
long_v, |
|||
dbl_v |
|||
FROM ts_kv_latest_old |
|||
INNER JOIN ts_kv_dictionary ON (ts_kv_latest_old.key = ts_kv_dictionary.key)) AS ts_kv_latest_records; |
|||
BEGIN |
|||
OPEN insert_cursor; |
|||
LOOP |
|||
insert_counter := insert_counter + 1; |
|||
FETCH insert_cursor INTO insert_record; |
|||
IF NOT FOUND THEN |
|||
RAISE NOTICE '% records have been inserted into the ts_kv_latest!',insert_counter - 1; |
|||
EXIT; |
|||
END IF; |
|||
INSERT INTO ts_kv_latest(entity_id, key, ts, bool_v, str_v, long_v, dbl_v) |
|||
VALUES (insert_record.entity_id, insert_record.key, insert_record.ts, insert_record.bool_v, insert_record.str_v, |
|||
insert_record.long_v, insert_record.dbl_v); |
|||
IF MOD(insert_counter, insert_size) = 0 THEN |
|||
RAISE NOTICE '% records have been inserted into the ts_kv_latest!',insert_counter; |
|||
END IF; |
|||
END LOOP; |
|||
CLOSE insert_cursor; |
|||
END; |
|||
$$; |
|||
|
|||
@ -1,208 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
-- call create_new_ts_kv_table(); |
|||
|
|||
CREATE OR REPLACE PROCEDURE create_new_ts_kv_table() LANGUAGE plpgsql AS $$ |
|||
|
|||
BEGIN |
|||
ALTER TABLE tenant_ts_kv |
|||
RENAME TO tenant_ts_kv_old; |
|||
CREATE TABLE IF NOT EXISTS ts_kv |
|||
( |
|||
LIKE tenant_ts_kv_old |
|||
); |
|||
ALTER TABLE ts_kv ALTER COLUMN entity_id TYPE uuid USING entity_id::uuid; |
|||
ALTER TABLE ts_kv ALTER COLUMN key TYPE integer USING key::integer; |
|||
ALTER INDEX ts_kv_pkey RENAME TO tenant_ts_kv_pkey_old; |
|||
ALTER INDEX idx_tenant_ts_kv RENAME TO idx_tenant_ts_kv_old; |
|||
ALTER INDEX tenant_ts_kv_ts_idx RENAME TO tenant_ts_kv_ts_idx_old; |
|||
ALTER TABLE ts_kv ADD CONSTRAINT ts_kv_pkey PRIMARY KEY(entity_id, key, ts); |
|||
-- CREATE INDEX IF NOT EXISTS ts_kv_ts_idx ON ts_kv(ts DESC); |
|||
ALTER TABLE ts_kv DROP COLUMN IF EXISTS tenant_id; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- call create_ts_kv_latest_table(); |
|||
|
|||
CREATE OR REPLACE PROCEDURE create_ts_kv_latest_table() LANGUAGE plpgsql AS $$ |
|||
|
|||
BEGIN |
|||
CREATE TABLE IF NOT EXISTS ts_kv_latest |
|||
( |
|||
entity_id uuid NOT NULL, |
|||
key int NOT NULL, |
|||
ts bigint NOT NULL, |
|||
bool_v boolean, |
|||
str_v varchar(10000000), |
|||
long_v bigint, |
|||
dbl_v double precision, |
|||
CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key) |
|||
); |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- call create_ts_kv_dictionary_table(); |
|||
|
|||
CREATE OR REPLACE PROCEDURE create_ts_kv_dictionary_table() LANGUAGE plpgsql AS $$ |
|||
|
|||
BEGIN |
|||
CREATE TABLE IF NOT EXISTS ts_kv_dictionary |
|||
( |
|||
key varchar(255) NOT NULL, |
|||
key_id serial UNIQUE, |
|||
CONSTRAINT ts_key_id_pkey PRIMARY KEY (key) |
|||
); |
|||
END; |
|||
$$; |
|||
|
|||
-- call insert_into_dictionary(); |
|||
|
|||
CREATE OR REPLACE PROCEDURE insert_into_dictionary() LANGUAGE plpgsql AS $$ |
|||
|
|||
DECLARE |
|||
insert_record RECORD; |
|||
key_cursor CURSOR FOR SELECT DISTINCT key |
|||
FROM tenant_ts_kv_old |
|||
ORDER BY key; |
|||
BEGIN |
|||
OPEN key_cursor; |
|||
LOOP |
|||
FETCH key_cursor INTO insert_record; |
|||
EXIT WHEN NOT FOUND; |
|||
IF NOT EXISTS(SELECT key FROM ts_kv_dictionary WHERE key = insert_record.key) THEN |
|||
INSERT INTO ts_kv_dictionary(key) VALUES (insert_record.key); |
|||
RAISE NOTICE 'Key: % has been inserted into the dictionary!',insert_record.key; |
|||
ELSE |
|||
RAISE NOTICE 'Key: % already exists in the dictionary!',insert_record.key; |
|||
END IF; |
|||
END LOOP; |
|||
CLOSE key_cursor; |
|||
END; |
|||
$$; |
|||
|
|||
CREATE OR REPLACE FUNCTION to_uuid(IN entity_id varchar, OUT uuid_id uuid) AS |
|||
$$ |
|||
BEGIN |
|||
uuid_id := substring(entity_id, 8, 8) || '-' || substring(entity_id, 4, 4) || '-1' || substring(entity_id, 1, 3) || |
|||
'-' || substring(entity_id, 16, 4) || '-' || substring(entity_id, 20, 12); |
|||
END; |
|||
$$ LANGUAGE plpgsql; |
|||
|
|||
-- call insert_into_ts_kv(); |
|||
|
|||
CREATE OR REPLACE PROCEDURE insert_into_ts_kv(IN path_to_file varchar) LANGUAGE plpgsql AS $$ |
|||
BEGIN |
|||
|
|||
EXECUTE format ('COPY (SELECT to_uuid(entity_id) AS entity_id, |
|||
new_ts_kv_records.key AS key, |
|||
new_ts_kv_records.ts AS ts, |
|||
new_ts_kv_records.bool_v AS bool_v, |
|||
new_ts_kv_records.str_v AS str_v, |
|||
new_ts_kv_records.long_v AS long_v, |
|||
new_ts_kv_records.dbl_v AS dbl_v |
|||
FROM (SELECT entity_id AS entity_id, |
|||
key_id AS key, |
|||
ts, |
|||
bool_v, |
|||
str_v, |
|||
long_v, |
|||
dbl_v |
|||
FROM tenant_ts_kv_old |
|||
INNER JOIN ts_kv_dictionary ON (tenant_ts_kv_old.key = ts_kv_dictionary.key)) AS new_ts_kv_records) TO %L;', path_to_file); |
|||
EXECUTE format ('COPY ts_kv FROM %L', path_to_file); |
|||
END; |
|||
$$; |
|||
|
|||
-- call insert_into_ts_kv_latest(); |
|||
|
|||
CREATE OR REPLACE PROCEDURE insert_into_ts_kv_latest() LANGUAGE plpgsql AS $$ |
|||
|
|||
DECLARE |
|||
insert_size CONSTANT integer := 10000; |
|||
insert_counter integer DEFAULT 0; |
|||
latest_record RECORD; |
|||
insert_record RECORD; |
|||
insert_cursor CURSOR FOR SELECT |
|||
latest_records.key AS key, |
|||
latest_records.entity_id AS entity_id, |
|||
latest_records.ts AS ts |
|||
FROM (SELECT DISTINCT key AS key, entity_id AS entity_id, MAX(ts) AS ts FROM ts_kv GROUP BY key, entity_id) AS latest_records; |
|||
BEGIN |
|||
OPEN insert_cursor; |
|||
LOOP |
|||
insert_counter := insert_counter + 1; |
|||
FETCH insert_cursor INTO latest_record; |
|||
IF NOT FOUND THEN |
|||
RAISE NOTICE '% records have been inserted into the ts_kv_latest table!',insert_counter - 1; |
|||
EXIT; |
|||
END IF; |
|||
SELECT entity_id AS entity_id, key AS key, ts AS ts, bool_v AS bool_v, str_v AS str_v, long_v AS long_v, dbl_v AS dbl_v INTO insert_record FROM ts_kv WHERE entity_id = latest_record.entity_id AND key = latest_record.key AND ts = latest_record.ts; |
|||
INSERT INTO ts_kv_latest(entity_id, key, ts, bool_v, str_v, long_v, dbl_v) |
|||
VALUES (insert_record.entity_id, insert_record.key, insert_record.ts, insert_record.bool_v, insert_record.str_v, insert_record.long_v, insert_record.dbl_v); |
|||
IF MOD(insert_counter, insert_size) = 0 THEN |
|||
RAISE NOTICE '% records have been inserted into the ts_kv_latest table!',insert_counter; |
|||
END IF; |
|||
END LOOP; |
|||
CLOSE insert_cursor; |
|||
END; |
|||
$$; |
|||
|
|||
-- call insert_into_ts_kv_cursor(); |
|||
|
|||
CREATE OR REPLACE PROCEDURE insert_into_ts_kv_cursor() LANGUAGE plpgsql AS $$ |
|||
|
|||
DECLARE |
|||
insert_size CONSTANT integer := 10000; |
|||
insert_counter integer DEFAULT 0; |
|||
insert_record RECORD; |
|||
insert_cursor CURSOR FOR SELECT to_uuid(entity_id) AS entity_id, |
|||
new_ts_kv_records.key AS key, |
|||
new_ts_kv_records.ts AS ts, |
|||
new_ts_kv_records.bool_v AS bool_v, |
|||
new_ts_kv_records.str_v AS str_v, |
|||
new_ts_kv_records.long_v AS long_v, |
|||
new_ts_kv_records.dbl_v AS dbl_v |
|||
FROM (SELECT entity_id AS entity_id, |
|||
key_id AS key, |
|||
ts, |
|||
bool_v, |
|||
str_v, |
|||
long_v, |
|||
dbl_v |
|||
FROM tenant_ts_kv_old |
|||
INNER JOIN ts_kv_dictionary ON (tenant_ts_kv_old.key = ts_kv_dictionary.key)) AS new_ts_kv_records; |
|||
BEGIN |
|||
OPEN insert_cursor; |
|||
LOOP |
|||
insert_counter := insert_counter + 1; |
|||
FETCH insert_cursor INTO insert_record; |
|||
IF NOT FOUND THEN |
|||
RAISE NOTICE '% records have been inserted into the new ts_kv table!',insert_counter - 1; |
|||
EXIT; |
|||
END IF; |
|||
INSERT INTO ts_kv(entity_id, key, ts, bool_v, str_v, long_v, dbl_v) |
|||
VALUES (insert_record.entity_id, insert_record.key, insert_record.ts, insert_record.bool_v, insert_record.str_v, |
|||
insert_record.long_v, insert_record.dbl_v); |
|||
IF MOD(insert_counter, insert_size) = 0 THEN |
|||
RAISE NOTICE '% records have been inserted into the new ts_kv table!',insert_counter; |
|||
END IF; |
|||
END LOOP; |
|||
CLOSE insert_cursor; |
|||
END; |
|||
$$; |
|||
@ -1,150 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE OR REPLACE FUNCTION to_uuid(IN entity_id varchar, OUT uuid_id uuid) AS |
|||
$$ |
|||
BEGIN |
|||
uuid_id := substring(entity_id, 8, 8) || '-' || substring(entity_id, 4, 4) || '-1' || substring(entity_id, 1, 3) || |
|||
'-' || substring(entity_id, 16, 4) || '-' || substring(entity_id, 20, 12); |
|||
END; |
|||
$$ LANGUAGE plpgsql; |
|||
|
|||
CREATE OR REPLACE FUNCTION delete_device_records_from_ts_kv(tenant_id uuid, customer_id uuid, ttl bigint, |
|||
OUT deleted bigint) AS |
|||
$$ |
|||
BEGIN |
|||
EXECUTE format( |
|||
'WITH deleted AS (DELETE FROM ts_kv WHERE entity_id IN (SELECT device.id as entity_id FROM device WHERE tenant_id = %L and customer_id = %L) AND ts < %L::bigint RETURNING *) SELECT count(*) FROM deleted', |
|||
tenant_id, customer_id, ttl) into deleted; |
|||
END; |
|||
$$ LANGUAGE plpgsql; |
|||
|
|||
CREATE OR REPLACE FUNCTION delete_asset_records_from_ts_kv(tenant_id uuid, customer_id uuid, ttl bigint, |
|||
OUT deleted bigint) AS |
|||
$$ |
|||
BEGIN |
|||
EXECUTE format( |
|||
'WITH deleted AS (DELETE FROM ts_kv WHERE entity_id IN (SELECT asset.id as entity_id FROM asset WHERE tenant_id = %L and customer_id = %L) AND ts < %L::bigint RETURNING *) SELECT count(*) FROM deleted', |
|||
tenant_id, customer_id, ttl) into deleted; |
|||
END; |
|||
$$ LANGUAGE plpgsql; |
|||
|
|||
CREATE OR REPLACE FUNCTION delete_customer_records_from_ts_kv(tenant_id uuid, customer_id uuid, ttl bigint, |
|||
OUT deleted bigint) AS |
|||
$$ |
|||
BEGIN |
|||
EXECUTE format( |
|||
'WITH deleted AS (DELETE FROM ts_kv WHERE entity_id IN (SELECT customer.id as entity_id FROM customer WHERE tenant_id = %L and id = %L) AND ts < %L::bigint RETURNING *) SELECT count(*) FROM deleted', |
|||
tenant_id, customer_id, ttl) into deleted; |
|||
END; |
|||
$$ LANGUAGE plpgsql; |
|||
|
|||
CREATE OR REPLACE PROCEDURE cleanup_timeseries_by_ttl(IN null_uuid uuid, |
|||
IN system_ttl bigint, INOUT deleted bigint) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
tenant_cursor CURSOR FOR select tenant.id as tenant_id |
|||
from tenant; |
|||
tenant_id_record uuid; |
|||
customer_id_record uuid; |
|||
tenant_ttl bigint; |
|||
customer_ttl bigint; |
|||
deleted_for_entities bigint; |
|||
tenant_ttl_ts bigint; |
|||
customer_ttl_ts bigint; |
|||
BEGIN |
|||
OPEN tenant_cursor; |
|||
FETCH tenant_cursor INTO tenant_id_record; |
|||
WHILE FOUND |
|||
LOOP |
|||
EXECUTE format( |
|||
'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = %L', |
|||
tenant_id_record, 'TTL') INTO tenant_ttl; |
|||
if tenant_ttl IS NULL THEN |
|||
tenant_ttl := system_ttl; |
|||
END IF; |
|||
IF tenant_ttl > 0 THEN |
|||
tenant_ttl_ts := (EXTRACT(EPOCH FROM current_timestamp) * 1000 - tenant_ttl::bigint * 1000)::bigint; |
|||
deleted_for_entities := delete_device_records_from_ts_kv(tenant_id_record, null_uuid, tenant_ttl_ts); |
|||
deleted := deleted + deleted_for_entities; |
|||
RAISE NOTICE '% telemetry removed for devices where tenant_id = %', deleted_for_entities, tenant_id_record; |
|||
deleted_for_entities := delete_asset_records_from_ts_kv(tenant_id_record, null_uuid, tenant_ttl_ts); |
|||
deleted := deleted + deleted_for_entities; |
|||
RAISE NOTICE '% telemetry removed for assets where tenant_id = %', deleted_for_entities, tenant_id_record; |
|||
END IF; |
|||
FOR customer_id_record IN |
|||
SELECT customer.id AS customer_id FROM customer WHERE customer.tenant_id = tenant_id_record |
|||
LOOP |
|||
EXECUTE format( |
|||
'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = %L', |
|||
customer_id_record, 'TTL') INTO customer_ttl; |
|||
IF customer_ttl IS NULL THEN |
|||
customer_ttl_ts := tenant_ttl_ts; |
|||
ELSE |
|||
IF customer_ttl > 0 THEN |
|||
customer_ttl_ts := |
|||
(EXTRACT(EPOCH FROM current_timestamp) * 1000 - |
|||
customer_ttl::bigint * 1000)::bigint; |
|||
END IF; |
|||
END IF; |
|||
IF customer_ttl_ts IS NOT NULL AND customer_ttl_ts > 0 THEN |
|||
deleted_for_entities := |
|||
delete_customer_records_from_ts_kv(tenant_id_record, customer_id_record, |
|||
customer_ttl_ts); |
|||
deleted := deleted + deleted_for_entities; |
|||
RAISE NOTICE '% telemetry removed for customer with id = % where tenant_id = %', deleted_for_entities, customer_id_record, tenant_id_record; |
|||
deleted_for_entities := |
|||
delete_device_records_from_ts_kv(tenant_id_record, customer_id_record, |
|||
customer_ttl_ts); |
|||
deleted := deleted + deleted_for_entities; |
|||
RAISE NOTICE '% telemetry removed for devices where tenant_id = % and customer_id = %', deleted_for_entities, tenant_id_record, customer_id_record; |
|||
deleted_for_entities := delete_asset_records_from_ts_kv(tenant_id_record, |
|||
customer_id_record, |
|||
customer_ttl_ts); |
|||
deleted := deleted + deleted_for_entities; |
|||
RAISE NOTICE '% telemetry removed for assets where tenant_id = % and customer_id = %', deleted_for_entities, tenant_id_record, customer_id_record; |
|||
END IF; |
|||
END LOOP; |
|||
FETCH tenant_cursor INTO tenant_id_record; |
|||
END LOOP; |
|||
END |
|||
$$; |
|||
|
|||
CREATE OR REPLACE PROCEDURE cleanup_events_by_ttl(IN ttl bigint, IN debug_ttl bigint, INOUT deleted bigint) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
ttl_ts bigint; |
|||
debug_ttl_ts bigint; |
|||
ttl_deleted_count bigint DEFAULT 0; |
|||
debug_ttl_deleted_count bigint DEFAULT 0; |
|||
BEGIN |
|||
IF ttl > 0 THEN |
|||
ttl_ts := (EXTRACT(EPOCH FROM current_timestamp) * 1000 - ttl::bigint * 1000)::bigint; |
|||
EXECUTE format( |
|||
'WITH deleted AS (DELETE FROM event WHERE ts < %L::bigint AND (event_type != %L::varchar AND event_type != %L::varchar) RETURNING *) SELECT count(*) FROM deleted', ttl_ts, 'DEBUG_RULE_NODE', 'DEBUG_RULE_CHAIN') into ttl_deleted_count; |
|||
END IF; |
|||
IF debug_ttl > 0 THEN |
|||
debug_ttl_ts := (EXTRACT(EPOCH FROM current_timestamp) * 1000 - debug_ttl::bigint * 1000)::bigint; |
|||
EXECUTE format( |
|||
'WITH deleted AS (DELETE FROM event WHERE ts < %L::bigint AND (event_type = %L::varchar OR event_type = %L::varchar) RETURNING *) SELECT count(*) FROM deleted', debug_ttl_ts, 'DEBUG_RULE_NODE', 'DEBUG_RULE_CHAIN') into debug_ttl_deleted_count; |
|||
END IF; |
|||
RAISE NOTICE 'Events removed by ttl: %', ttl_deleted_count; |
|||
RAISE NOTICE 'Debug Events removed by ttl: %', debug_ttl_deleted_count; |
|||
deleted := ttl_deleted_count + debug_ttl_deleted_count; |
|||
END |
|||
$$; |
|||
@ -1,878 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE OR REPLACE FUNCTION to_uuid(IN entity_id varchar, OUT uuid_id uuid) AS |
|||
$$ |
|||
BEGIN |
|||
uuid_id := substring(entity_id, 8, 8) || '-' || substring(entity_id, 4, 4) || '-1' || substring(entity_id, 1, 3) || |
|||
'-' || substring(entity_id, 16, 4) || '-' || substring(entity_id, 20, 12); |
|||
END; |
|||
$$ LANGUAGE plpgsql; |
|||
|
|||
CREATE OR REPLACE FUNCTION extract_ts(uuid UUID) RETURNS BIGINT AS |
|||
$$ |
|||
DECLARE |
|||
bytes bytea; |
|||
BEGIN |
|||
bytes := uuid_send(uuid); |
|||
RETURN |
|||
( |
|||
( |
|||
(get_byte(bytes, 0)::bigint << 24) | |
|||
(get_byte(bytes, 1)::bigint << 16) | |
|||
(get_byte(bytes, 2)::bigint << 8) | |
|||
(get_byte(bytes, 3)::bigint << 0) |
|||
) + ( |
|||
((get_byte(bytes, 4)::bigint << 8 | |
|||
get_byte(bytes, 5)::bigint)) << 32 |
|||
) + ( |
|||
(((get_byte(bytes, 6)::bigint & 15) << 8 | get_byte(bytes, 7)::bigint) & 4095) << 48 |
|||
) - 122192928000000000 |
|||
) / 10000::double precision; |
|||
END |
|||
$$ LANGUAGE plpgsql |
|||
IMMUTABLE |
|||
PARALLEL SAFE |
|||
RETURNS NULL ON NULL INPUT; |
|||
|
|||
|
|||
CREATE OR REPLACE FUNCTION column_type_to_uuid(table_name varchar, column_name varchar) RETURNS VOID |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
BEGIN |
|||
execute format('ALTER TABLE %s RENAME COLUMN %s TO old_%s;', table_name, column_name, column_name); |
|||
execute format('ALTER TABLE %s ADD COLUMN %s UUID;', table_name, column_name); |
|||
execute format('UPDATE %s SET %s = to_uuid(old_%s) WHERE old_%s is not null;', table_name, column_name, column_name, column_name); |
|||
execute format('ALTER TABLE %s DROP COLUMN old_%s;', table_name, column_name); |
|||
END; |
|||
$$; |
|||
|
|||
CREATE OR REPLACE FUNCTION get_column_type(table_name varchar, column_name varchar, OUT data_type varchar) RETURNS varchar |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
BEGIN |
|||
execute (format('SELECT data_type from information_schema.columns where table_name = %L and column_name = %L', |
|||
table_name, column_name)) INTO data_type; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
CREATE OR REPLACE PROCEDURE drop_all_idx() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
BEGIN |
|||
DROP INDEX IF EXISTS idx_alarm_originator_alarm_type; |
|||
DROP INDEX IF EXISTS idx_alarm_originator_created_time; |
|||
DROP INDEX IF EXISTS idx_alarm_tenant_created_time; |
|||
DROP INDEX IF EXISTS idx_event_type_entity_id; |
|||
DROP INDEX IF EXISTS idx_relation_to_id; |
|||
DROP INDEX IF EXISTS idx_relation_from_id; |
|||
DROP INDEX IF EXISTS idx_device_customer_id; |
|||
DROP INDEX IF EXISTS idx_device_customer_id_and_type; |
|||
DROP INDEX IF EXISTS idx_device_type; |
|||
DROP INDEX IF EXISTS idx_asset_customer_id; |
|||
DROP INDEX IF EXISTS idx_asset_customer_id_and_type; |
|||
DROP INDEX IF EXISTS idx_asset_type; |
|||
DROP INDEX IF EXISTS idx_attribute_kv_by_key_and_last_update_ts; |
|||
END; |
|||
$$; |
|||
|
|||
CREATE OR REPLACE PROCEDURE create_all_idx() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
BEGIN |
|||
CREATE INDEX IF NOT EXISTS idx_alarm_originator_alarm_type ON alarm(originator_id, type, start_ts DESC); |
|||
CREATE INDEX IF NOT EXISTS idx_alarm_originator_created_time ON alarm(originator_id, created_time DESC); |
|||
CREATE INDEX IF NOT EXISTS idx_alarm_tenant_created_time ON alarm(tenant_id, created_time DESC); |
|||
CREATE INDEX IF NOT EXISTS idx_event_type_entity_id ON event(tenant_id, event_type, entity_type, entity_id); |
|||
CREATE INDEX IF NOT EXISTS idx_relation_to_id ON relation(relation_type_group, to_type, to_id); |
|||
CREATE INDEX IF NOT EXISTS idx_relation_from_id ON relation(relation_type_group, from_type, from_id); |
|||
CREATE INDEX IF NOT EXISTS idx_device_customer_id ON device(tenant_id, customer_id); |
|||
CREATE INDEX IF NOT EXISTS idx_device_customer_id_and_type ON device(tenant_id, customer_id, type); |
|||
CREATE INDEX IF NOT EXISTS idx_device_type ON device(tenant_id, type); |
|||
CREATE INDEX IF NOT EXISTS idx_asset_customer_id ON asset(tenant_id, customer_id); |
|||
CREATE INDEX IF NOT EXISTS idx_asset_customer_id_and_type ON asset(tenant_id, customer_id, type); |
|||
CREATE INDEX IF NOT EXISTS idx_asset_type ON asset(tenant_id, type); |
|||
CREATE INDEX IF NOT EXISTS idx_attribute_kv_by_key_and_last_update_ts ON attribute_kv(entity_id, attribute_key, last_update_ts desc); |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- admin_settings |
|||
CREATE OR REPLACE PROCEDURE update_admin_settings() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'admin_settings'; |
|||
column_id varchar := 'id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE admin_settings DROP CONSTRAINT admin_settings_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE admin_settings ADD CONSTRAINT admin_settings_pkey PRIMARY KEY (id); |
|||
ALTER TABLE admin_settings ADD COLUMN created_time BIGINT; |
|||
UPDATE admin_settings SET created_time = extract_ts(id) WHERE id is not null; |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- alarm |
|||
CREATE OR REPLACE PROCEDURE update_alarm() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'alarm'; |
|||
column_id varchar := 'id'; |
|||
column_originator_id varchar := 'originator_id'; |
|||
column_tenant_id varchar := 'tenant_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE alarm DROP CONSTRAINT alarm_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE alarm ADD COLUMN created_time BIGINT; |
|||
UPDATE alarm SET created_time = extract_ts(id) WHERE id is not null; |
|||
ALTER TABLE alarm ADD CONSTRAINT alarm_pkey PRIMARY KEY (id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_originator_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_originator_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_originator_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_originator_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_tenant_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_tenant_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_tenant_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_tenant_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- asset |
|||
CREATE OR REPLACE PROCEDURE update_asset() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'asset'; |
|||
column_id varchar := 'id'; |
|||
column_customer_id varchar := 'customer_id'; |
|||
column_tenant_id varchar := 'tenant_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE asset DROP CONSTRAINT asset_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE asset ADD COLUMN created_time BIGINT; |
|||
UPDATE asset SET created_time = extract_ts(id) WHERE id is not null; |
|||
ALTER TABLE asset ADD CONSTRAINT asset_pkey PRIMARY KEY (id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_customer_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_customer_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_customer_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_customer_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_tenant_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE asset DROP CONSTRAINT asset_name_unq_key; |
|||
PERFORM column_type_to_uuid(table_name, column_tenant_id); |
|||
ALTER TABLE asset ADD CONSTRAINT asset_name_unq_key UNIQUE (tenant_id, name); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_tenant_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_tenant_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
-- attribute_kv |
|||
CREATE OR REPLACE PROCEDURE update_attribute_kv() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'attribute_kv'; |
|||
column_entity_id varchar := 'entity_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_entity_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE attribute_kv DROP CONSTRAINT attribute_kv_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_entity_id); |
|||
ALTER TABLE attribute_kv ADD CONSTRAINT attribute_kv_pkey PRIMARY KEY (entity_type, entity_id, attribute_type, attribute_key); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_entity_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_entity_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
-- audit_log |
|||
CREATE OR REPLACE PROCEDURE update_audit_log() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'audit_log'; |
|||
column_id varchar := 'id'; |
|||
column_customer_id varchar := 'customer_id'; |
|||
column_tenant_id varchar := 'tenant_id'; |
|||
column_entity_id varchar := 'entity_id'; |
|||
column_user_id varchar := 'user_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE audit_log DROP CONSTRAINT audit_log_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE audit_log ADD COLUMN created_time BIGINT; |
|||
UPDATE audit_log SET created_time = extract_ts(id) WHERE id is not null; |
|||
ALTER TABLE audit_log ADD CONSTRAINT audit_log_pkey PRIMARY KEY (id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_customer_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_customer_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_customer_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_customer_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_tenant_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_tenant_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_tenant_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_tenant_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_entity_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_entity_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_entity_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_entity_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_user_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_user_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_user_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_user_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- component_descriptor |
|||
CREATE OR REPLACE PROCEDURE update_component_descriptor() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'component_descriptor'; |
|||
column_id varchar := 'id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE component_descriptor DROP CONSTRAINT component_descriptor_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE component_descriptor ADD CONSTRAINT component_descriptor_pkey PRIMARY KEY (id); |
|||
ALTER TABLE component_descriptor ADD COLUMN created_time BIGINT; |
|||
UPDATE component_descriptor SET created_time = extract_ts(id) WHERE id is not null; |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
-- customer |
|||
CREATE OR REPLACE PROCEDURE update_customer() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'customer'; |
|||
column_id varchar := 'id'; |
|||
column_tenant_id varchar := 'tenant_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE customer DROP CONSTRAINT customer_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE customer ADD CONSTRAINT customer_pkey PRIMARY KEY (id); |
|||
ALTER TABLE customer ADD COLUMN created_time BIGINT; |
|||
UPDATE customer SET created_time = extract_ts(id) WHERE id is not null; |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_tenant_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_tenant_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_tenant_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_tenant_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- dashboard |
|||
CREATE OR REPLACE PROCEDURE update_dashboard() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'dashboard'; |
|||
column_id varchar := 'id'; |
|||
column_tenant_id varchar := 'tenant_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE dashboard DROP CONSTRAINT dashboard_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE dashboard ADD CONSTRAINT dashboard_pkey PRIMARY KEY (id); |
|||
ALTER TABLE dashboard ADD COLUMN created_time BIGINT; |
|||
UPDATE dashboard SET created_time = extract_ts(id) WHERE id is not null; |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_tenant_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_tenant_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_tenant_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_tenant_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
-- device |
|||
CREATE OR REPLACE PROCEDURE update_device() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'device'; |
|||
column_id varchar := 'id'; |
|||
column_customer_id varchar := 'customer_id'; |
|||
column_tenant_id varchar := 'tenant_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE device DROP CONSTRAINT device_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE device ADD COLUMN created_time BIGINT; |
|||
UPDATE device SET created_time = extract_ts(id) WHERE id is not null; |
|||
ALTER TABLE device ADD CONSTRAINT device_pkey PRIMARY KEY (id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_customer_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_customer_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_customer_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_customer_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_tenant_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE device DROP CONSTRAINT device_name_unq_key; |
|||
PERFORM column_type_to_uuid(table_name, column_tenant_id); |
|||
ALTER TABLE device ADD CONSTRAINT device_name_unq_key UNIQUE (tenant_id, name); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_tenant_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_tenant_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- device_credentials |
|||
CREATE OR REPLACE PROCEDURE update_device_credentials() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'device_credentials'; |
|||
column_id varchar := 'id'; |
|||
column_device_id varchar := 'device_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE device_credentials DROP CONSTRAINT device_credentials_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE device_credentials ADD COLUMN created_time BIGINT; |
|||
UPDATE device_credentials SET created_time = extract_ts(id) WHERE id is not null; |
|||
ALTER TABLE device_credentials ADD CONSTRAINT device_credentials_pkey PRIMARY KEY (id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_device_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE device_credentials DROP CONSTRAINT IF EXISTS device_credentials_device_id_unq_key; |
|||
PERFORM column_type_to_uuid(table_name, column_device_id); |
|||
-- remove duplicate credentials with same device_id |
|||
DELETE from device_credentials where id in ( |
|||
select dc.id |
|||
from ( |
|||
SELECT id, device_id, |
|||
ROW_NUMBER() OVER ( |
|||
PARTITION BY |
|||
device_id |
|||
ORDER BY |
|||
created_time DESC |
|||
) row_num |
|||
FROM |
|||
device_credentials |
|||
) as dc |
|||
WHERE dc.row_num > 1 |
|||
); |
|||
ALTER TABLE device_credentials ADD CONSTRAINT device_credentials_device_id_unq_key UNIQUE (device_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_device_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_device_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- event |
|||
CREATE OR REPLACE PROCEDURE update_event() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'event'; |
|||
column_id varchar := 'id'; |
|||
column_entity_id varchar := 'entity_id'; |
|||
column_tenant_id varchar := 'tenant_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE event DROP CONSTRAINT event_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE event ADD COLUMN created_time BIGINT; |
|||
UPDATE event SET created_time = extract_ts(id) WHERE id is not null; |
|||
ALTER TABLE event ADD CONSTRAINT event_pkey PRIMARY KEY (id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
|
|||
ALTER TABLE event DROP CONSTRAINT event_unq_key; |
|||
|
|||
data_type := get_column_type(table_name, column_entity_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_entity_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_entity_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_entity_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_tenant_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_tenant_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_tenant_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_tenant_id; |
|||
END IF; |
|||
|
|||
ALTER TABLE event ADD CONSTRAINT event_unq_key UNIQUE (tenant_id, entity_type, entity_id, event_type, event_uid); |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- relation |
|||
CREATE OR REPLACE PROCEDURE update_relation() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'relation'; |
|||
column_from_id varchar := 'from_id'; |
|||
column_to_id varchar := 'to_id'; |
|||
BEGIN |
|||
ALTER TABLE relation DROP CONSTRAINT relation_pkey; |
|||
|
|||
data_type := get_column_type(table_name, column_from_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_from_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_from_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_from_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_to_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_to_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_to_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_to_id; |
|||
END IF; |
|||
|
|||
ALTER TABLE relation ADD CONSTRAINT relation_pkey PRIMARY KEY (from_id, from_type, relation_type_group, relation_type, to_id, to_type); |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- tb_user |
|||
CREATE OR REPLACE PROCEDURE update_tb_user() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'tb_user'; |
|||
column_id varchar := 'id'; |
|||
column_customer_id varchar := 'customer_id'; |
|||
column_tenant_id varchar := 'tenant_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE tb_user DROP CONSTRAINT tb_user_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE tb_user ADD COLUMN created_time BIGINT; |
|||
UPDATE tb_user SET created_time = extract_ts(id) WHERE id is not null; |
|||
ALTER TABLE tb_user ADD CONSTRAINT tb_user_pkey PRIMARY KEY (id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_customer_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_customer_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_customer_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_customer_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_tenant_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_tenant_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_tenant_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_tenant_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- tenant |
|||
CREATE OR REPLACE PROCEDURE update_tenant() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'tenant'; |
|||
column_id varchar := 'id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE tenant DROP CONSTRAINT tenant_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE tenant ADD COLUMN created_time BIGINT; |
|||
UPDATE tenant SET created_time = extract_ts(id) WHERE id is not null; |
|||
ALTER TABLE tenant ADD CONSTRAINT tenant_pkey PRIMARY KEY (id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- user_credentials |
|||
CREATE OR REPLACE PROCEDURE update_user_credentials() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'user_credentials'; |
|||
column_id varchar := 'id'; |
|||
column_user_id varchar := 'user_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE user_credentials DROP CONSTRAINT user_credentials_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE user_credentials ADD COLUMN created_time BIGINT; |
|||
UPDATE user_credentials SET created_time = extract_ts(id) WHERE id is not null; |
|||
ALTER TABLE user_credentials ADD CONSTRAINT user_credentials_pkey PRIMARY KEY (id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_user_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE user_credentials DROP CONSTRAINT user_credentials_user_id_key; |
|||
ALTER TABLE user_credentials RENAME COLUMN user_id TO old_user_id; |
|||
ALTER TABLE user_credentials ADD COLUMN user_id UUID UNIQUE; |
|||
UPDATE user_credentials SET user_id = to_uuid(old_user_id) WHERE old_user_id is not null; |
|||
ALTER TABLE user_credentials DROP COLUMN old_user_id; |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_user_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_user_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- widget_type |
|||
CREATE OR REPLACE PROCEDURE update_widget_type() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'widget_type'; |
|||
column_id varchar := 'id'; |
|||
column_tenant_id varchar := 'tenant_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE widget_type DROP CONSTRAINT widget_type_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE widget_type ADD COLUMN created_time BIGINT; |
|||
UPDATE widget_type SET created_time = extract_ts(id) WHERE id is not null; |
|||
ALTER TABLE widget_type ADD CONSTRAINT widget_type_pkey PRIMARY KEY (id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_tenant_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_tenant_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_tenant_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_tenant_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- widgets_bundle |
|||
CREATE OR REPLACE PROCEDURE update_widgets_bundle() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'widgets_bundle'; |
|||
column_id varchar := 'id'; |
|||
column_tenant_id varchar := 'tenant_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE widgets_bundle DROP CONSTRAINT widgets_bundle_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE widgets_bundle ADD COLUMN created_time BIGINT; |
|||
UPDATE widgets_bundle SET created_time = extract_ts(id) WHERE id is not null; |
|||
ALTER TABLE widgets_bundle ADD CONSTRAINT widgets_bundle_pkey PRIMARY KEY (id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_tenant_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_tenant_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_tenant_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_tenant_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- rule_chain |
|||
CREATE OR REPLACE PROCEDURE update_rule_chain() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'rule_chain'; |
|||
column_id varchar := 'id'; |
|||
column_first_rule_node_id varchar := 'first_rule_node_id'; |
|||
column_tenant_id varchar := 'tenant_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE rule_chain DROP CONSTRAINT rule_chain_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE rule_chain ADD COLUMN created_time BIGINT; |
|||
UPDATE rule_chain SET created_time = extract_ts(id) WHERE id is not null; |
|||
ALTER TABLE rule_chain ADD CONSTRAINT rule_chain_pkey PRIMARY KEY (id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_first_rule_node_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_first_rule_node_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_first_rule_node_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_first_rule_node_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_tenant_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_tenant_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_tenant_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_tenant_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- rule_node |
|||
CREATE OR REPLACE PROCEDURE update_rule_node() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'rule_node'; |
|||
column_id varchar := 'id'; |
|||
column_rule_chain_id varchar := 'rule_chain_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE rule_node DROP CONSTRAINT rule_node_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE rule_node ADD COLUMN created_time BIGINT; |
|||
UPDATE rule_node SET created_time = extract_ts(id) WHERE id is not null; |
|||
ALTER TABLE rule_node ADD CONSTRAINT rule_node_pkey PRIMARY KEY (id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_rule_chain_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_rule_chain_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_rule_chain_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_rule_chain_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
-- entity_view |
|||
CREATE OR REPLACE PROCEDURE update_entity_view() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
data_type varchar; |
|||
table_name varchar := 'entity_view'; |
|||
column_id varchar := 'id'; |
|||
column_entity_id varchar := 'entity_id'; |
|||
column_tenant_id varchar := 'tenant_id'; |
|||
column_customer_id varchar := 'customer_id'; |
|||
BEGIN |
|||
data_type := get_column_type(table_name, column_id); |
|||
IF data_type = 'character varying' THEN |
|||
ALTER TABLE entity_view DROP CONSTRAINT entity_view_pkey; |
|||
PERFORM column_type_to_uuid(table_name, column_id); |
|||
ALTER TABLE entity_view ADD COLUMN created_time BIGINT; |
|||
UPDATE entity_view SET created_time = extract_ts(id) WHERE id is not null; |
|||
ALTER TABLE entity_view ADD CONSTRAINT entity_view_pkey PRIMARY KEY (id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_entity_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_entity_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_entity_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_entity_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_tenant_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_tenant_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_tenant_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_tenant_id; |
|||
END IF; |
|||
|
|||
data_type := get_column_type(table_name, column_customer_id); |
|||
IF data_type = 'character varying' THEN |
|||
PERFORM column_type_to_uuid(table_name, column_customer_id); |
|||
RAISE NOTICE 'Table % column % updated!', table_name, column_customer_id; |
|||
ELSE |
|||
RAISE NOTICE 'Table % column % already updated!', table_name, column_customer_id; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
CREATE TABLE IF NOT EXISTS ts_kv_latest |
|||
( |
|||
entity_id uuid NOT NULL, |
|||
key int NOT NULL, |
|||
ts bigint NOT NULL, |
|||
bool_v boolean, |
|||
str_v varchar(10000000), |
|||
long_v bigint, |
|||
dbl_v double precision, |
|||
json_v json, |
|||
CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS ts_kv_dictionary |
|||
( |
|||
key varchar(255) NOT NULL, |
|||
key_id serial UNIQUE, |
|||
CONSTRAINT ts_key_id_pkey PRIMARY KEY (key) |
|||
); |
|||
@ -1,17 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_alarm_tenant_alarm_type_created_time ON alarm(tenant_id, type, created_time DESC); |
|||
@ -1,28 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
DROP PROCEDURE IF EXISTS update_tenant_profiles; |
|||
DROP PROCEDURE IF EXISTS update_device_profiles; |
|||
|
|||
ALTER TABLE tenant ALTER COLUMN tenant_profile_id SET NOT NULL; |
|||
ALTER TABLE tenant DROP CONSTRAINT IF EXISTS fk_tenant_profile; |
|||
ALTER TABLE tenant ADD CONSTRAINT fk_tenant_profile FOREIGN KEY (tenant_profile_id) REFERENCES tenant_profile(id); |
|||
ALTER TABLE tenant DROP COLUMN IF EXISTS isolated_tb_core; |
|||
ALTER TABLE tenant DROP COLUMN IF EXISTS isolated_tb_rule_engine; |
|||
|
|||
ALTER TABLE device ALTER COLUMN device_profile_id SET NOT NULL; |
|||
ALTER TABLE device DROP CONSTRAINT IF EXISTS fk_device_profile; |
|||
ALTER TABLE device ADD CONSTRAINT fk_device_profile FOREIGN KEY (device_profile_id) REFERENCES device_profile(id); |
|||
@ -1,154 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE TABLE IF NOT EXISTS oauth2_client_registration_info ( |
|||
id uuid NOT NULL CONSTRAINT oauth2_client_registration_info_pkey PRIMARY KEY, |
|||
enabled boolean, |
|||
created_time bigint NOT NULL, |
|||
additional_info varchar, |
|||
client_id varchar(255), |
|||
client_secret varchar(255), |
|||
authorization_uri varchar(255), |
|||
token_uri varchar(255), |
|||
scope varchar(255), |
|||
user_info_uri varchar(255), |
|||
user_name_attribute_name varchar(255), |
|||
jwk_set_uri varchar(255), |
|||
client_authentication_method varchar(255), |
|||
login_button_label varchar(255), |
|||
login_button_icon varchar(255), |
|||
allow_user_creation boolean, |
|||
activate_user boolean, |
|||
type varchar(31), |
|||
basic_email_attribute_key varchar(31), |
|||
basic_first_name_attribute_key varchar(31), |
|||
basic_last_name_attribute_key varchar(31), |
|||
basic_tenant_name_strategy varchar(31), |
|||
basic_tenant_name_pattern varchar(255), |
|||
basic_customer_name_pattern varchar(255), |
|||
basic_default_dashboard_name varchar(255), |
|||
basic_always_full_screen boolean, |
|||
custom_url varchar(255), |
|||
custom_username varchar(255), |
|||
custom_password varchar(255), |
|||
custom_send_token boolean |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS oauth2_client_registration ( |
|||
id uuid NOT NULL CONSTRAINT oauth2_client_registration_pkey PRIMARY KEY, |
|||
created_time bigint NOT NULL, |
|||
domain_name varchar(255), |
|||
domain_scheme varchar(31), |
|||
client_registration_info_id uuid |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS oauth2_client_registration_template ( |
|||
id uuid NOT NULL CONSTRAINT oauth2_client_registration_template_pkey PRIMARY KEY, |
|||
created_time bigint NOT NULL, |
|||
additional_info varchar, |
|||
provider_id varchar(255), |
|||
authorization_uri varchar(255), |
|||
token_uri varchar(255), |
|||
scope varchar(255), |
|||
user_info_uri varchar(255), |
|||
user_name_attribute_name varchar(255), |
|||
jwk_set_uri varchar(255), |
|||
client_authentication_method varchar(255), |
|||
type varchar(31), |
|||
basic_email_attribute_key varchar(31), |
|||
basic_first_name_attribute_key varchar(31), |
|||
basic_last_name_attribute_key varchar(31), |
|||
basic_tenant_name_strategy varchar(31), |
|||
basic_tenant_name_pattern varchar(255), |
|||
basic_customer_name_pattern varchar(255), |
|||
basic_default_dashboard_name varchar(255), |
|||
basic_always_full_screen boolean, |
|||
comment varchar, |
|||
login_button_icon varchar(255), |
|||
login_button_label varchar(255), |
|||
help_link varchar(255), |
|||
CONSTRAINT oauth2_template_provider_id_unq_key UNIQUE (provider_id) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS device_profile ( |
|||
id uuid NOT NULL CONSTRAINT device_profile_pkey PRIMARY KEY, |
|||
created_time bigint NOT NULL, |
|||
name varchar(255), |
|||
type varchar(255), |
|||
transport_type varchar(255), |
|||
provision_type varchar(255), |
|||
profile_data jsonb, |
|||
description varchar, |
|||
search_text varchar(255), |
|||
is_default boolean, |
|||
tenant_id uuid, |
|||
default_rule_chain_id uuid, |
|||
default_queue_name varchar(255), |
|||
provision_device_key varchar, |
|||
CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name), |
|||
CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key), |
|||
CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS tenant_profile ( |
|||
id uuid NOT NULL CONSTRAINT tenant_profile_pkey PRIMARY KEY, |
|||
created_time bigint NOT NULL, |
|||
name varchar(255), |
|||
profile_data jsonb, |
|||
description varchar, |
|||
search_text varchar(255), |
|||
is_default boolean, |
|||
isolated_tb_core boolean, |
|||
isolated_tb_rule_engine boolean, |
|||
CONSTRAINT tenant_profile_name_unq_key UNIQUE (name) |
|||
); |
|||
|
|||
CREATE OR REPLACE PROCEDURE update_tenant_profiles() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
BEGIN |
|||
UPDATE tenant as t SET tenant_profile_id = p.id |
|||
FROM |
|||
(SELECT id from tenant_profile WHERE isolated_tb_core = false AND isolated_tb_rule_engine = false) as p |
|||
WHERE t.tenant_profile_id IS NULL AND t.isolated_tb_core = false AND t.isolated_tb_rule_engine = false; |
|||
|
|||
UPDATE tenant as t SET tenant_profile_id = p.id |
|||
FROM |
|||
(SELECT id from tenant_profile WHERE isolated_tb_core = true AND isolated_tb_rule_engine = false) as p |
|||
WHERE t.tenant_profile_id IS NULL AND t.isolated_tb_core = true AND t.isolated_tb_rule_engine = false; |
|||
|
|||
UPDATE tenant as t SET tenant_profile_id = p.id |
|||
FROM |
|||
(SELECT id from tenant_profile WHERE isolated_tb_core = false AND isolated_tb_rule_engine = true) as p |
|||
WHERE t.tenant_profile_id IS NULL AND t.isolated_tb_core = false AND t.isolated_tb_rule_engine = true; |
|||
|
|||
UPDATE tenant as t SET tenant_profile_id = p.id |
|||
FROM |
|||
(SELECT id from tenant_profile WHERE isolated_tb_core = true AND isolated_tb_rule_engine = true) as p |
|||
WHERE t.tenant_profile_id IS NULL AND t.isolated_tb_core = true AND t.isolated_tb_rule_engine = true; |
|||
END; |
|||
$$; |
|||
|
|||
CREATE OR REPLACE PROCEDURE update_device_profiles() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
BEGIN |
|||
UPDATE device as d SET device_profile_id = p.id, device_data = '{"configuration":{"type":"DEFAULT"}, "transportConfiguration":{"type":"DEFAULT"}}' |
|||
FROM |
|||
(SELECT id, tenant_id, name from device_profile) as p |
|||
WHERE d.device_profile_id IS NULL AND p.tenant_id = d.tenant_id AND d.type = p.name; |
|||
END; |
|||
$$; |
|||
@ -1,23 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
ALTER TABLE widget_type |
|||
ADD COLUMN IF NOT EXISTS image varchar (1000000), |
|||
ADD COLUMN IF NOT EXISTS description varchar (255); |
|||
|
|||
ALTER TABLE widgets_bundle |
|||
ADD COLUMN IF NOT EXISTS image varchar (1000000), |
|||
ADD COLUMN IF NOT EXISTS description varchar (255); |
|||
@ -1,87 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE OR REPLACE PROCEDURE cleanup_timeseries_by_ttl(IN null_uuid uuid, |
|||
IN system_ttl bigint, INOUT deleted bigint) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
tenant_cursor CURSOR FOR select tenant.id as tenant_id |
|||
from tenant; |
|||
tenant_id_record uuid; |
|||
customer_id_record uuid; |
|||
tenant_ttl bigint; |
|||
customer_ttl bigint; |
|||
deleted_for_entities bigint; |
|||
tenant_ttl_ts bigint; |
|||
customer_ttl_ts bigint; |
|||
BEGIN |
|||
OPEN tenant_cursor; |
|||
FETCH tenant_cursor INTO tenant_id_record; |
|||
WHILE FOUND |
|||
LOOP |
|||
EXECUTE format( |
|||
'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = %L', |
|||
tenant_id_record, 'TTL') INTO tenant_ttl; |
|||
if tenant_ttl IS NULL THEN |
|||
tenant_ttl := system_ttl; |
|||
END IF; |
|||
IF tenant_ttl > 0 THEN |
|||
tenant_ttl_ts := (EXTRACT(EPOCH FROM current_timestamp) * 1000 - tenant_ttl::bigint * 1000)::bigint; |
|||
deleted_for_entities := delete_device_records_from_ts_kv(tenant_id_record, null_uuid, tenant_ttl_ts); |
|||
deleted := deleted + deleted_for_entities; |
|||
RAISE NOTICE '% telemetry removed for devices where tenant_id = %', deleted_for_entities, tenant_id_record; |
|||
deleted_for_entities := delete_asset_records_from_ts_kv(tenant_id_record, null_uuid, tenant_ttl_ts); |
|||
deleted := deleted + deleted_for_entities; |
|||
RAISE NOTICE '% telemetry removed for assets where tenant_id = %', deleted_for_entities, tenant_id_record; |
|||
END IF; |
|||
FOR customer_id_record IN |
|||
SELECT customer.id AS customer_id FROM customer WHERE customer.tenant_id = tenant_id_record |
|||
LOOP |
|||
EXECUTE format( |
|||
'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = %L', |
|||
customer_id_record, 'TTL') INTO customer_ttl; |
|||
IF customer_ttl IS NULL THEN |
|||
customer_ttl_ts := tenant_ttl_ts; |
|||
ELSE |
|||
IF customer_ttl > 0 THEN |
|||
customer_ttl_ts := |
|||
(EXTRACT(EPOCH FROM current_timestamp) * 1000 - |
|||
customer_ttl::bigint * 1000)::bigint; |
|||
END IF; |
|||
END IF; |
|||
IF customer_ttl_ts IS NOT NULL AND customer_ttl_ts > 0 THEN |
|||
deleted_for_entities := |
|||
delete_customer_records_from_ts_kv(tenant_id_record, customer_id_record, |
|||
customer_ttl_ts); |
|||
deleted := deleted + deleted_for_entities; |
|||
RAISE NOTICE '% telemetry removed for customer with id = % where tenant_id = %', deleted_for_entities, customer_id_record, tenant_id_record; |
|||
deleted_for_entities := |
|||
delete_device_records_from_ts_kv(tenant_id_record, customer_id_record, |
|||
customer_ttl_ts); |
|||
deleted := deleted + deleted_for_entities; |
|||
RAISE NOTICE '% telemetry removed for devices where tenant_id = % and customer_id = %', deleted_for_entities, tenant_id_record, customer_id_record; |
|||
deleted_for_entities := delete_asset_records_from_ts_kv(tenant_id_record, |
|||
customer_id_record, |
|||
customer_ttl_ts); |
|||
deleted := deleted + deleted_for_entities; |
|||
RAISE NOTICE '% telemetry removed for assets where tenant_id = % and customer_id = %', deleted_for_entities, tenant_id_record, customer_id_record; |
|||
END IF; |
|||
END LOOP; |
|||
FETCH tenant_cursor INTO tenant_id_record; |
|||
END LOOP; |
|||
END |
|||
$$; |
|||
@ -1,216 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE TABLE IF NOT EXISTS edge ( |
|||
id uuid NOT NULL CONSTRAINT edge_pkey PRIMARY KEY, |
|||
created_time bigint NOT NULL, |
|||
additional_info varchar, |
|||
customer_id uuid, |
|||
root_rule_chain_id uuid, |
|||
type varchar(255), |
|||
name varchar(255), |
|||
label varchar(255), |
|||
routing_key varchar(255), |
|||
secret varchar(255), |
|||
edge_license_key varchar(30), |
|||
cloud_endpoint varchar(255), |
|||
search_text varchar(255), |
|||
tenant_id uuid, |
|||
CONSTRAINT edge_name_unq_key UNIQUE (tenant_id, name), |
|||
CONSTRAINT edge_routing_key_unq_key UNIQUE (routing_key) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS edge_event ( |
|||
id uuid NOT NULL CONSTRAINT edge_event_pkey PRIMARY KEY, |
|||
created_time bigint NOT NULL, |
|||
edge_id uuid, |
|||
edge_event_type varchar(255), |
|||
edge_event_uid varchar(255), |
|||
entity_id uuid, |
|||
edge_event_action varchar(255), |
|||
body varchar(10000000), |
|||
tenant_id uuid, |
|||
ts bigint NOT NULL |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS resource ( |
|||
id uuid NOT NULL CONSTRAINT resource_pkey PRIMARY KEY, |
|||
created_time bigint NOT NULL, |
|||
tenant_id uuid NOT NULL, |
|||
title varchar(255) NOT NULL, |
|||
resource_type varchar(32) NOT NULL, |
|||
resource_key varchar(255) NOT NULL, |
|||
search_text varchar(255), |
|||
file_name varchar(255) NOT NULL, |
|||
data varchar, |
|||
CONSTRAINT resource_unq_key UNIQUE (tenant_id, resource_type, resource_key) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS ota_package ( |
|||
id uuid NOT NULL CONSTRAINT ota_package_pkey PRIMARY KEY, |
|||
created_time bigint NOT NULL, |
|||
tenant_id uuid NOT NULL, |
|||
device_profile_id uuid, |
|||
type varchar(32) NOT NULL, |
|||
title varchar(255) NOT NULL, |
|||
version varchar(255) NOT NULL, |
|||
tag varchar(255), |
|||
url varchar(255), |
|||
file_name varchar(255), |
|||
content_type varchar(255), |
|||
checksum_algorithm varchar(32), |
|||
checksum varchar(1020), |
|||
data oid, |
|||
data_size bigint, |
|||
additional_info varchar, |
|||
search_text varchar(255), |
|||
CONSTRAINT ota_package_tenant_title_version_unq_key UNIQUE (tenant_id, title, version) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS oauth2_params ( |
|||
id uuid NOT NULL CONSTRAINT oauth2_params_pkey PRIMARY KEY, |
|||
enabled boolean, |
|||
tenant_id uuid, |
|||
created_time bigint NOT NULL |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS oauth2_registration ( |
|||
id uuid NOT NULL CONSTRAINT oauth2_registration_pkey PRIMARY KEY, |
|||
oauth2_params_id uuid NOT NULL, |
|||
created_time bigint NOT NULL, |
|||
additional_info varchar, |
|||
client_id varchar(255), |
|||
client_secret varchar(2048), |
|||
authorization_uri varchar(255), |
|||
token_uri varchar(255), |
|||
scope varchar(255), |
|||
platforms varchar(255), |
|||
user_info_uri varchar(255), |
|||
user_name_attribute_name varchar(255), |
|||
jwk_set_uri varchar(255), |
|||
client_authentication_method varchar(255), |
|||
login_button_label varchar(255), |
|||
login_button_icon varchar(255), |
|||
allow_user_creation boolean, |
|||
activate_user boolean, |
|||
type varchar(31), |
|||
basic_email_attribute_key varchar(31), |
|||
basic_first_name_attribute_key varchar(31), |
|||
basic_last_name_attribute_key varchar(31), |
|||
basic_tenant_name_strategy varchar(31), |
|||
basic_tenant_name_pattern varchar(255), |
|||
basic_customer_name_pattern varchar(255), |
|||
basic_default_dashboard_name varchar(255), |
|||
basic_always_full_screen boolean, |
|||
custom_url varchar(255), |
|||
custom_username varchar(255), |
|||
custom_password varchar(255), |
|||
custom_send_token boolean, |
|||
CONSTRAINT fk_registration_oauth2_params FOREIGN KEY (oauth2_params_id) REFERENCES oauth2_params(id) ON DELETE CASCADE |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS oauth2_domain ( |
|||
id uuid NOT NULL CONSTRAINT oauth2_domain_pkey PRIMARY KEY, |
|||
oauth2_params_id uuid NOT NULL, |
|||
created_time bigint NOT NULL, |
|||
domain_name varchar(255), |
|||
domain_scheme varchar(31), |
|||
CONSTRAINT fk_domain_oauth2_params FOREIGN KEY (oauth2_params_id) REFERENCES oauth2_params(id) ON DELETE CASCADE, |
|||
CONSTRAINT oauth2_domain_unq_key UNIQUE (oauth2_params_id, domain_name, domain_scheme) |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS oauth2_mobile ( |
|||
id uuid NOT NULL CONSTRAINT oauth2_mobile_pkey PRIMARY KEY, |
|||
oauth2_params_id uuid NOT NULL, |
|||
created_time bigint NOT NULL, |
|||
pkg_name varchar(255), |
|||
app_secret varchar(2048), |
|||
CONSTRAINT fk_mobile_oauth2_params FOREIGN KEY (oauth2_params_id) REFERENCES oauth2_params(id) ON DELETE CASCADE, |
|||
CONSTRAINT oauth2_mobile_unq_key UNIQUE (oauth2_params_id, pkg_name) |
|||
); |
|||
|
|||
ALTER TABLE dashboard |
|||
ADD COLUMN IF NOT EXISTS image varchar(1000000), |
|||
ADD COLUMN IF NOT EXISTS mobile_hide boolean DEFAULT false, |
|||
ADD COLUMN IF NOT EXISTS mobile_order int; |
|||
|
|||
ALTER TABLE device_profile |
|||
ADD COLUMN IF NOT EXISTS image varchar(1000000), |
|||
ADD COLUMN IF NOT EXISTS firmware_id uuid, |
|||
ADD COLUMN IF NOT EXISTS software_id uuid, |
|||
ADD COLUMN IF NOT EXISTS default_dashboard_id uuid; |
|||
|
|||
ALTER TABLE device |
|||
ADD COLUMN IF NOT EXISTS firmware_id uuid, |
|||
ADD COLUMN IF NOT EXISTS software_id uuid; |
|||
|
|||
ALTER TABLE alarm |
|||
ADD COLUMN IF NOT EXISTS customer_id uuid; |
|||
|
|||
DELETE FROM relation WHERE from_type = 'TENANT' AND relation_type_group = 'RULE_CHAIN'; |
|||
|
|||
DO $$ |
|||
BEGIN |
|||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_firmware_device_profile') THEN |
|||
ALTER TABLE device_profile |
|||
ADD CONSTRAINT fk_firmware_device_profile |
|||
FOREIGN KEY (firmware_id) REFERENCES ota_package(id); |
|||
END IF; |
|||
|
|||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_software_device_profile') THEN |
|||
ALTER TABLE device_profile |
|||
ADD CONSTRAINT fk_software_device_profile |
|||
FOREIGN KEY (firmware_id) REFERENCES ota_package(id); |
|||
END IF; |
|||
|
|||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_default_dashboard_device_profile') THEN |
|||
ALTER TABLE device_profile |
|||
ADD CONSTRAINT fk_default_dashboard_device_profile |
|||
FOREIGN KEY (default_dashboard_id) REFERENCES dashboard(id); |
|||
END IF; |
|||
|
|||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_firmware_device') THEN |
|||
ALTER TABLE device |
|||
ADD CONSTRAINT fk_firmware_device |
|||
FOREIGN KEY (firmware_id) REFERENCES ota_package(id); |
|||
END IF; |
|||
|
|||
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_software_device') THEN |
|||
ALTER TABLE device |
|||
ADD CONSTRAINT fk_software_device |
|||
FOREIGN KEY (firmware_id) REFERENCES ota_package(id); |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
ALTER TABLE api_usage_state |
|||
ADD COLUMN IF NOT EXISTS alarm_exec VARCHAR(32); |
|||
UPDATE api_usage_state SET alarm_exec = 'ENABLED' WHERE alarm_exec IS NULL; |
|||
|
|||
CREATE TABLE IF NOT EXISTS rpc ( |
|||
id uuid NOT NULL CONSTRAINT rpc_pkey PRIMARY KEY, |
|||
created_time bigint NOT NULL, |
|||
tenant_id uuid NOT NULL, |
|||
device_id uuid NOT NULL, |
|||
expiration_time bigint NOT NULL, |
|||
request varchar(10000000) NOT NULL, |
|||
response varchar(10000000), |
|||
additional_info varchar(10000000), |
|||
status varchar(255) NOT NULL |
|||
); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_rpc_tenant_id_device_id ON rpc(tenant_id, device_id); |
|||
@ -1,90 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
-- PROCEDURE: public.cleanup_events_by_ttl(bigint, bigint, bigint) |
|||
|
|||
DROP PROCEDURE IF EXISTS public.cleanup_events_by_ttl(bigint, bigint, bigint); |
|||
|
|||
CREATE OR REPLACE PROCEDURE public.cleanup_events_by_ttl( |
|||
ttl bigint, |
|||
debug_ttl bigint, |
|||
INOUT deleted bigint) |
|||
LANGUAGE 'plpgsql' |
|||
AS $BODY$ |
|||
DECLARE |
|||
ttl_ts bigint; |
|||
debug_ttl_ts bigint; |
|||
ttl_deleted_count bigint DEFAULT 0; |
|||
debug_ttl_deleted_count bigint DEFAULT 0; |
|||
BEGIN |
|||
IF ttl > 0 THEN |
|||
ttl_ts := (EXTRACT(EPOCH FROM current_timestamp) * 1000 - ttl::bigint * 1000)::bigint; |
|||
|
|||
DELETE FROM event |
|||
WHERE ts < ttl_ts |
|||
AND NOT event_type IN ('DEBUG_RULE_NODE', 'DEBUG_RULE_CHAIN', 'DEBUG_CONVERTER', 'DEBUG_INTEGRATION'); |
|||
|
|||
GET DIAGNOSTICS ttl_deleted_count = ROW_COUNT; |
|||
END IF; |
|||
|
|||
IF debug_ttl > 0 THEN |
|||
debug_ttl_ts := (EXTRACT(EPOCH FROM current_timestamp) * 1000 - debug_ttl::bigint * 1000)::bigint; |
|||
|
|||
DELETE FROM event |
|||
WHERE ts < debug_ttl_ts |
|||
AND event_type IN ('DEBUG_RULE_NODE', 'DEBUG_RULE_CHAIN', 'DEBUG_CONVERTER', 'DEBUG_INTEGRATION'); |
|||
|
|||
GET DIAGNOSTICS debug_ttl_deleted_count = ROW_COUNT; |
|||
END IF; |
|||
|
|||
RAISE NOTICE 'Events removed by ttl: %', ttl_deleted_count; |
|||
RAISE NOTICE 'Debug Events removed by ttl: %', debug_ttl_deleted_count; |
|||
deleted := ttl_deleted_count + debug_ttl_deleted_count; |
|||
END |
|||
$BODY$; |
|||
|
|||
|
|||
-- Index: idx_event_ts |
|||
|
|||
DROP INDEX IF EXISTS public.idx_event_ts; |
|||
|
|||
-- Hint: add CONCURRENTLY to CREATE INDEX query in case of more then 1 million records or during live update |
|||
-- CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_event_ts |
|||
CREATE INDEX IF NOT EXISTS idx_event_ts |
|||
ON public.event |
|||
(ts DESC NULLS LAST) |
|||
WITH (FILLFACTOR=95); |
|||
|
|||
COMMENT ON INDEX public.idx_event_ts |
|||
IS 'This index helps to delete events by TTL using timestamp'; |
|||
|
|||
|
|||
-- Index: idx_event_tenant_entity_type_entity_event_type_created_time_des |
|||
|
|||
DROP INDEX IF EXISTS public.idx_event_tenant_entity_type_entity_event_type_created_time_des; |
|||
|
|||
-- CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_event_tenant_entity_type_entity_event_type_created_time_des |
|||
CREATE INDEX IF NOT EXISTS idx_event_tenant_entity_type_entity_event_type_created_time_des |
|||
ON public.event |
|||
(tenant_id ASC, entity_type ASC, entity_id ASC, event_type ASC, created_time DESC NULLS LAST) |
|||
WITH (FILLFACTOR=95); |
|||
|
|||
COMMENT ON INDEX public.idx_event_tenant_entity_type_entity_event_type_created_time_des |
|||
IS 'This index helps to open latest events on UI fast'; |
|||
|
|||
-- Index: idx_event_type_entity_id |
|||
-- Description: replaced with more suitable idx_event_tenant_entity_type_entity_event_type_created_time_des |
|||
DROP INDEX IF EXISTS public.idx_event_type_entity_id; |
|||
@ -1,32 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE OR REPLACE PROCEDURE cleanup_edge_events_by_ttl(IN ttl bigint, INOUT deleted bigint) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
ttl_ts bigint; |
|||
ttl_deleted_count bigint DEFAULT 0; |
|||
BEGIN |
|||
IF ttl > 0 THEN |
|||
ttl_ts := (EXTRACT(EPOCH FROM current_timestamp) * 1000 - ttl::bigint * 1000)::bigint; |
|||
EXECUTE format( |
|||
'WITH deleted AS (DELETE FROM edge_event WHERE ts < %L::bigint RETURNING *) SELECT count(*) FROM deleted', ttl_ts) into ttl_deleted_count; |
|||
END IF; |
|||
RAISE NOTICE 'Edge events removed by ttl: %', ttl_deleted_count; |
|||
deleted := ttl_deleted_count; |
|||
END |
|||
$$; |
|||
@ -1,71 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE TABLE IF NOT EXISTS entity_alarm ( |
|||
tenant_id uuid NOT NULL, |
|||
entity_type varchar(32), |
|||
entity_id uuid NOT NULL, |
|||
created_time bigint NOT NULL, |
|||
alarm_type varchar(255) NOT NULL, |
|||
customer_id uuid, |
|||
alarm_id uuid, |
|||
CONSTRAINT entity_alarm_pkey PRIMARY KEY (entity_id, alarm_id), |
|||
CONSTRAINT fk_entity_alarm_id FOREIGN KEY (alarm_id) REFERENCES alarm(id) ON DELETE CASCADE |
|||
); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_alarm_tenant_status_created_time ON alarm(tenant_id, status, created_time DESC); |
|||
CREATE INDEX IF NOT EXISTS idx_entity_alarm_created_time ON entity_alarm(tenant_id, entity_id, created_time DESC); |
|||
CREATE INDEX IF NOT EXISTS idx_entity_alarm_alarm_id ON entity_alarm(alarm_id); |
|||
|
|||
INSERT INTO entity_alarm(tenant_id, entity_type, entity_id, created_time, alarm_type, customer_id, alarm_id) |
|||
SELECT tenant_id, |
|||
CASE |
|||
WHEN originator_type = 0 THEN 'TENANT' |
|||
WHEN originator_type = 1 THEN 'CUSTOMER' |
|||
WHEN originator_type = 2 THEN 'USER' |
|||
WHEN originator_type = 3 THEN 'DASHBOARD' |
|||
WHEN originator_type = 4 THEN 'ASSET' |
|||
WHEN originator_type = 5 THEN 'DEVICE' |
|||
WHEN originator_type = 6 THEN 'ALARM' |
|||
WHEN originator_type = 7 THEN 'RULE_CHAIN' |
|||
WHEN originator_type = 8 THEN 'RULE_NODE' |
|||
WHEN originator_type = 9 THEN 'ENTITY_VIEW' |
|||
WHEN originator_type = 10 THEN 'WIDGETS_BUNDLE' |
|||
WHEN originator_type = 11 THEN 'WIDGET_TYPE' |
|||
WHEN originator_type = 12 THEN 'TENANT_PROFILE' |
|||
WHEN originator_type = 13 THEN 'DEVICE_PROFILE' |
|||
WHEN originator_type = 14 THEN 'API_USAGE_STATE' |
|||
WHEN originator_type = 15 THEN 'TB_RESOURCE' |
|||
WHEN originator_type = 16 THEN 'OTA_PACKAGE' |
|||
WHEN originator_type = 17 THEN 'EDGE' |
|||
WHEN originator_type = 18 THEN 'RPC' |
|||
else 'UNKNOWN' |
|||
END, |
|||
originator_id, |
|||
created_time, |
|||
type, |
|||
customer_id, |
|||
id |
|||
FROM alarm |
|||
ON CONFLICT DO NOTHING; |
|||
|
|||
INSERT INTO entity_alarm(tenant_id, entity_type, entity_id, created_time, alarm_type, customer_id, alarm_id) |
|||
SELECT a.tenant_id, r.from_type, r.from_id, created_time, type, customer_id, id |
|||
FROM alarm a |
|||
INNER JOIN relation r ON r.relation_type_group = 'ALARM' and r.relation_type = 'ANY' and a.id = r.to_id |
|||
ON CONFLICT DO NOTHING; |
|||
|
|||
DELETE FROM relation r WHERE r.relation_type_group = 'ALARM'; |
|||
@ -1,213 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
|
|||
CREATE OR REPLACE PROCEDURE update_profile_bootstrap() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
|
|||
BEGIN |
|||
|
|||
UPDATE device_profile |
|||
SET profile_data = jsonb_set( |
|||
profile_data, |
|||
'{transportConfiguration}', |
|||
get_bootstrap( |
|||
profile_data::jsonb #> '{transportConfiguration}', |
|||
subquery.publickey_bs, |
|||
subquery.publickey_lw, |
|||
profile_data::json #>> '{transportConfiguration, bootstrap, bootstrapServer, securityMode}', |
|||
profile_data::json #>> '{transportConfiguration, bootstrap, lwm2mServer, securityMode}'), |
|||
true) |
|||
FROM ( |
|||
SELECT id, |
|||
encode( |
|||
decode(profile_data::json #> '{transportConfiguration,bootstrap,bootstrapServer}' ->> |
|||
'serverPublicKey', 'hex')::bytea, 'base64') AS publickey_bs, |
|||
encode( |
|||
decode(profile_data::json #> '{transportConfiguration,bootstrap,lwm2mServer}' ->> |
|||
'serverPublicKey', 'hex')::bytea, 'base64') AS publickey_lw |
|||
FROM device_profile |
|||
WHERE transport_type = 'LWM2M' |
|||
) AS subquery |
|||
WHERE device_profile.id = subquery.id |
|||
AND subquery.publickey_bs IS NOT NULL |
|||
AND subquery.publickey_lw IS NOT NULL; |
|||
|
|||
END; |
|||
$$; |
|||
|
|||
CREATE OR REPLACE FUNCTION get_bootstrap(transport_configuration_in jsonb, publickey_bs text, |
|||
publickey_lw text, security_mode_bs text, |
|||
security_mode_lw text) RETURNS jsonb AS |
|||
$$ |
|||
|
|||
DECLARE |
|||
bootstrap_new jsonb; |
|||
bootstrap_in jsonb; |
|||
|
|||
BEGIN |
|||
|
|||
IF security_mode_lw IS NULL THEN |
|||
security_mode_lw := 'NO_SEC'; |
|||
END IF; |
|||
|
|||
IF security_mode_bs IS NULL THEN |
|||
security_mode_bs := 'NO_SEC'; |
|||
END IF; |
|||
|
|||
bootstrap_in := transport_configuration_in::jsonb #> '{bootstrap}'; |
|||
bootstrap_new := json_build_array( |
|||
json_build_object('shortServerId', bootstrap_in::json #> '{bootstrapServer}' -> 'serverId', |
|||
'securityMode', security_mode_bs, |
|||
'binding', bootstrap_in::json #> '{servers}' ->> 'binding', |
|||
'lifetime', bootstrap_in::json #> '{servers}' -> 'lifetime', |
|||
'notifIfDisabled', bootstrap_in::json #> '{servers}' -> 'notifIfDisabled', |
|||
'defaultMinPeriod', bootstrap_in::json #> '{servers}' -> 'defaultMinPeriod', |
|||
'host', bootstrap_in::json #> '{bootstrapServer}' ->> 'host', |
|||
'port', bootstrap_in::json #> '{bootstrapServer}' -> 'port', |
|||
'serverPublicKey', publickey_bs, |
|||
'bootstrapServerIs', true, |
|||
'clientHoldOffTime', bootstrap_in::json #> '{bootstrapServer}' -> 'clientHoldOffTime', |
|||
'bootstrapServerAccountTimeout', |
|||
bootstrap_in::json #> '{bootstrapServer}' -> 'bootstrapServerAccountTimeout' |
|||
), |
|||
json_build_object('shortServerId', bootstrap_in::json #> '{lwm2mServer}' -> 'serverId', |
|||
'securityMode', security_mode_lw, |
|||
'binding', bootstrap_in::json #> '{servers}' ->> 'binding', |
|||
'lifetime', bootstrap_in::json #> '{servers}' -> 'lifetime', |
|||
'notifIfDisabled', bootstrap_in::json #> '{servers}' -> 'notifIfDisabled', |
|||
'defaultMinPeriod', bootstrap_in::json #> '{servers}' -> 'defaultMinPeriod', |
|||
'host', bootstrap_in::json #> '{lwm2mServer}' ->> 'host', |
|||
'port', bootstrap_in::json #> '{lwm2mServer}' -> 'port', |
|||
'serverPublicKey', publickey_lw, |
|||
'bootstrapServerIs', false, |
|||
'clientHoldOffTime', bootstrap_in::json #> '{lwm2mServer}' -> 'clientHoldOffTime', |
|||
'bootstrapServerAccountTimeout', |
|||
bootstrap_in::json #> '{lwm2mServer}' -> 'bootstrapServerAccountTimeout' |
|||
) |
|||
); |
|||
RETURN jsonb_set( |
|||
transport_configuration_in, |
|||
'{bootstrap}', |
|||
bootstrap_new, |
|||
true) || '{"bootstrapServerUpdateEnable": true}'; |
|||
|
|||
END; |
|||
$$ LANGUAGE plpgsql; |
|||
|
|||
CREATE OR REPLACE PROCEDURE update_device_credentials_to_base64_and_bootstrap() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
|
|||
BEGIN |
|||
|
|||
UPDATE device_credentials |
|||
SET credentials_value = get_device_and_bootstrap(credentials_value::text) |
|||
WHERE credentials_type = 'LWM2M_CREDENTIALS'; |
|||
END; |
|||
$$; |
|||
|
|||
CREATE OR REPLACE FUNCTION get_device_and_bootstrap(IN credentials_value text, OUT credentials_value_new text) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
client_secret_key text; |
|||
client_public_key_or_id text; |
|||
client_key_value_object jsonb; |
|||
client_bootstrap_server_value_object jsonb; |
|||
client_bootstrap_server_object jsonb; |
|||
client_bootstrap_object jsonb; |
|||
|
|||
BEGIN |
|||
credentials_value_new := credentials_value; |
|||
IF credentials_value::jsonb #> '{client}' ->> 'securityConfigClientMode' = 'RPK' AND |
|||
NULLIF((credentials_value::jsonb #> '{client}' ->> 'key' ~ '^[0-9a-fA-F]+$')::text, 'false') = 'true' THEN |
|||
client_public_key_or_id := encode(decode(credentials_value::jsonb #> '{client}' ->> 'key', 'hex')::bytea, 'base64'); |
|||
client_key_value_object := json_build_object( |
|||
'endpoint', credentials_value::jsonb #> '{client}' ->> 'endpoint', |
|||
'securityConfigClientMode', credentials_value::jsonb #> '{client}' ->> 'securityConfigClientMode', |
|||
'key', client_public_key_or_id); |
|||
credentials_value_new := |
|||
credentials_value_new::jsonb || json_build_object('client', client_key_value_object)::jsonb; |
|||
END IF; |
|||
IF credentials_value::jsonb #> '{client}' ->> 'securityConfigClientMode' = 'X509' AND |
|||
NULLIF((credentials_value::jsonb #> '{client}' ->> 'cert' ~ '^[0-9a-fA-F]+$')::text, 'false') = 'true' THEN |
|||
client_public_key_or_id := |
|||
encode(decode(credentials_value::jsonb #> '{client}' ->> 'cert', 'hex')::bytea, 'base64'); |
|||
client_key_value_object := json_build_object( |
|||
'endpoint', credentials_value::jsonb #> '{client}' ->> 'endpoint', |
|||
'securityConfigClientMode', credentials_value::jsonb #> '{client}' ->> 'securityConfigClientMode', |
|||
'cert', client_public_key_or_id); |
|||
credentials_value_new := |
|||
credentials_value_new::jsonb || json_build_object('client', client_key_value_object)::jsonb; |
|||
END IF; |
|||
|
|||
IF credentials_value::jsonb #> '{bootstrap,lwm2mServer}' ->> 'securityMode' = 'RPK' OR |
|||
credentials_value::jsonb #> '{bootstrap,lwm2mServer}' ->> 'securityMode' = 'X509' THEN |
|||
IF NULLIF((credentials_value::jsonb #> '{bootstrap,lwm2mServer}' ->> 'clientSecretKey' ~ '^[0-9a-fA-F]+$')::text, |
|||
'false') = 'true' AND |
|||
NULLIF( |
|||
(credentials_value::jsonb #> '{bootstrap,lwm2mServer}' ->> 'clientPublicKeyOrId' ~ '^[0-9a-fA-F]+$')::text, |
|||
'false') = 'true' THEN |
|||
client_secret_key := |
|||
encode(decode(credentials_value::jsonb #> '{bootstrap,lwm2mServer}' ->> 'clientSecretKey', 'hex')::bytea, |
|||
'base64'); |
|||
client_public_key_or_id := encode( |
|||
decode(credentials_value::jsonb #> '{bootstrap,lwm2mServer}' ->> 'clientPublicKeyOrId', 'hex')::bytea, |
|||
'base64'); |
|||
client_bootstrap_server_value_object := jsonb_build_object( |
|||
'securityMode', credentials_value::jsonb #> '{bootstrap,lwm2mServer}' ->> 'securityMode', |
|||
'clientPublicKeyOrId', client_public_key_or_id, |
|||
'clientSecretKey', client_secret_key |
|||
); |
|||
client_bootstrap_server_object := jsonb_build_object('lwm2mServer', client_bootstrap_server_value_object::jsonb); |
|||
client_bootstrap_object := credentials_value_new::jsonb #> '{bootstrap}' || client_bootstrap_server_object::jsonb; |
|||
credentials_value_new := |
|||
jsonb_set(credentials_value_new::jsonb, '{bootstrap}', client_bootstrap_object::jsonb, false)::jsonb; |
|||
END IF; |
|||
END IF; |
|||
|
|||
IF credentials_value::jsonb #> '{bootstrap,bootstrapServer}' ->> 'securityMode' = 'RPK' OR |
|||
credentials_value::jsonb #> '{bootstrap,bootstrapServer}' ->> 'securityMode' = 'X509' THEN |
|||
IF NULLIF( |
|||
(credentials_value::jsonb #> '{bootstrap,bootstrapServer}' ->> 'clientSecretKey' ~ '^[0-9a-fA-F]+$')::text, |
|||
'false') = 'true' AND |
|||
NULLIF( |
|||
(credentials_value::jsonb #> '{bootstrap,bootstrapServer}' ->> 'clientPublicKeyOrId' ~ '^[0-9a-fA-F]+$')::text, |
|||
'false') = 'true' THEN |
|||
client_secret_key := |
|||
encode( |
|||
decode(credentials_value::jsonb #> '{bootstrap,bootstrapServer}' ->> 'clientSecretKey', 'hex')::bytea, |
|||
'base64'); |
|||
client_public_key_or_id := encode( |
|||
decode(credentials_value::jsonb #> '{bootstrap,bootstrapServer}' ->> 'clientPublicKeyOrId', 'hex')::bytea, |
|||
'base64'); |
|||
client_bootstrap_server_value_object := jsonb_build_object( |
|||
'securityMode', credentials_value::jsonb #> '{bootstrap,bootstrapServer}' ->> 'securityMode', |
|||
'clientPublicKeyOrId', client_public_key_or_id, |
|||
'clientSecretKey', client_secret_key |
|||
); |
|||
client_bootstrap_server_object := |
|||
jsonb_build_object('bootstrapServer', client_bootstrap_server_value_object::jsonb); |
|||
client_bootstrap_object := credentials_value_new::jsonb #> '{bootstrap}' || client_bootstrap_server_object::jsonb; |
|||
credentials_value_new := |
|||
jsonb_set(credentials_value_new::jsonb, '{bootstrap}', client_bootstrap_object::jsonb, false)::jsonb; |
|||
END IF; |
|||
END IF; |
|||
|
|||
END; |
|||
$$; |
|||
@ -1,50 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
|
|||
DROP PROCEDURE IF EXISTS public.cleanup_events_by_ttl(bigint, bigint, bigint); |
|||
|
|||
CREATE OR REPLACE PROCEDURE cleanup_events_by_ttl( |
|||
IN regular_events_start_ts bigint, |
|||
IN regular_events_end_ts bigint, |
|||
IN debug_events_start_ts bigint, |
|||
IN debug_events_end_ts bigint, |
|||
INOUT deleted bigint) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
ttl_deleted_count bigint DEFAULT 0; |
|||
debug_ttl_deleted_count bigint DEFAULT 0; |
|||
BEGIN |
|||
IF regular_events_start_ts > 0 AND regular_events_end_ts > 0 THEN |
|||
EXECUTE format( |
|||
'WITH deleted AS (DELETE FROM event WHERE id in (SELECT id from event WHERE ts > %L::bigint AND ts < %L::bigint AND ' || |
|||
'(event_type != %L::varchar AND event_type != %L::varchar)) RETURNING *) ' || |
|||
'SELECT count(*) FROM deleted', regular_events_start_ts, regular_events_end_ts, |
|||
'DEBUG_RULE_NODE', 'DEBUG_RULE_CHAIN') into ttl_deleted_count; |
|||
END IF; |
|||
IF debug_events_start_ts > 0 AND debug_events_end_ts > 0 THEN |
|||
EXECUTE format( |
|||
'WITH deleted AS (DELETE FROM event WHERE id in (SELECT id from event WHERE ts > %L::bigint AND ts < %L::bigint AND ' || |
|||
'(event_type = %L::varchar OR event_type = %L::varchar)) RETURNING *) ' || |
|||
'SELECT count(*) FROM deleted', debug_events_start_ts, debug_events_end_ts, |
|||
'DEBUG_RULE_NODE', 'DEBUG_RULE_CHAIN') into debug_ttl_deleted_count; |
|||
END IF; |
|||
RAISE NOTICE 'Events removed by ttl: %', ttl_deleted_count; |
|||
RAISE NOTICE 'Debug Events removed by ttl: %', debug_ttl_deleted_count; |
|||
deleted := ttl_deleted_count + debug_ttl_deleted_count; |
|||
END |
|||
$$; |
|||
@ -1,29 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
DELETE from ota_package as op WHERE NOT EXISTS(SELECT * FROM device_profile dp where op.device_profile_id = dp.id); |
|||
|
|||
DO |
|||
$$ |
|||
BEGIN |
|||
IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'fk_device_profile_ota_package') THEN |
|||
ALTER TABLE ota_package |
|||
ADD CONSTRAINT fk_device_profile_ota_package |
|||
FOREIGN KEY (device_profile_id) REFERENCES device_profile (id) |
|||
ON DELETE CASCADE; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
@ -1,140 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
ALTER TABLE device |
|||
ADD COLUMN IF NOT EXISTS external_id UUID; |
|||
ALTER TABLE device_profile |
|||
ADD COLUMN IF NOT EXISTS external_id UUID; |
|||
ALTER TABLE asset |
|||
ADD COLUMN IF NOT EXISTS external_id UUID; |
|||
ALTER TABLE rule_chain |
|||
ADD COLUMN IF NOT EXISTS external_id UUID; |
|||
ALTER TABLE rule_node |
|||
ADD COLUMN IF NOT EXISTS external_id UUID; |
|||
ALTER TABLE dashboard |
|||
ADD COLUMN IF NOT EXISTS external_id UUID; |
|||
ALTER TABLE customer |
|||
ADD COLUMN IF NOT EXISTS external_id UUID; |
|||
ALTER TABLE widgets_bundle |
|||
ADD COLUMN IF NOT EXISTS external_id UUID; |
|||
ALTER TABLE entity_view |
|||
ADD COLUMN IF NOT EXISTS external_id UUID; |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_rule_node_external_id ON rule_node(rule_chain_id, external_id); |
|||
CREATE INDEX IF NOT EXISTS idx_rule_node_type ON rule_node(type); |
|||
|
|||
ALTER TABLE admin_settings |
|||
ADD COLUMN IF NOT EXISTS tenant_id uuid NOT NULL DEFAULT '13814000-1dd2-11b2-8080-808080808080'; |
|||
|
|||
CREATE TABLE IF NOT EXISTS queue ( |
|||
id uuid NOT NULL CONSTRAINT queue_pkey PRIMARY KEY, |
|||
created_time bigint NOT NULL, |
|||
tenant_id uuid, |
|||
name varchar(255), |
|||
topic varchar(255), |
|||
poll_interval int, |
|||
partitions int, |
|||
consumer_per_partition boolean, |
|||
pack_processing_timeout bigint, |
|||
submit_strategy varchar(255), |
|||
processing_strategy varchar(255), |
|||
additional_info varchar |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS user_auth_settings ( |
|||
id uuid NOT NULL CONSTRAINT user_auth_settings_pkey PRIMARY KEY, |
|||
created_time bigint NOT NULL, |
|||
user_id uuid UNIQUE NOT NULL CONSTRAINT fk_user_auth_settings_user_id REFERENCES tb_user(id), |
|||
two_fa_settings varchar |
|||
); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_api_usage_state_entity_id ON api_usage_state(entity_id); |
|||
|
|||
ALTER TABLE tenant_profile DROP COLUMN IF EXISTS isolated_tb_core; |
|||
|
|||
DO |
|||
$$ |
|||
BEGIN |
|||
IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'device_external_id_unq_key') THEN |
|||
ALTER TABLE device ADD CONSTRAINT device_external_id_unq_key UNIQUE (tenant_id, external_id); |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
DO |
|||
$$ |
|||
BEGIN |
|||
IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'device_profile_external_id_unq_key') THEN |
|||
ALTER TABLE device_profile ADD CONSTRAINT device_profile_external_id_unq_key UNIQUE (tenant_id, external_id); |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
DO |
|||
$$ |
|||
BEGIN |
|||
IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'asset_external_id_unq_key') THEN |
|||
ALTER TABLE asset ADD CONSTRAINT asset_external_id_unq_key UNIQUE (tenant_id, external_id); |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
DO |
|||
$$ |
|||
BEGIN |
|||
IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'rule_chain_external_id_unq_key') THEN |
|||
ALTER TABLE rule_chain ADD CONSTRAINT rule_chain_external_id_unq_key UNIQUE (tenant_id, external_id); |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
|
|||
DO |
|||
$$ |
|||
BEGIN |
|||
IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'dashboard_external_id_unq_key') THEN |
|||
ALTER TABLE dashboard ADD CONSTRAINT dashboard_external_id_unq_key UNIQUE (tenant_id, external_id); |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
DO |
|||
$$ |
|||
BEGIN |
|||
IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'customer_external_id_unq_key') THEN |
|||
ALTER TABLE customer ADD CONSTRAINT customer_external_id_unq_key UNIQUE (tenant_id, external_id); |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
DO |
|||
$$ |
|||
BEGIN |
|||
IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'widgets_bundle_external_id_unq_key') THEN |
|||
ALTER TABLE widgets_bundle ADD CONSTRAINT widgets_bundle_external_id_unq_key UNIQUE (tenant_id, external_id); |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
DO |
|||
$$ |
|||
BEGIN |
|||
IF NOT EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'entity_view_external_id_unq_key') THEN |
|||
ALTER TABLE entity_view ADD CONSTRAINT entity_view_external_id_unq_key UNIQUE (tenant_id, external_id); |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
@ -1,234 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE TABLE IF NOT EXISTS rule_node_debug_event ( |
|||
id uuid NOT NULL, |
|||
tenant_id uuid NOT NULL , |
|||
ts bigint NOT NULL, |
|||
entity_id uuid NOT NULL, |
|||
service_id varchar, |
|||
e_type varchar, |
|||
e_entity_id uuid, |
|||
e_entity_type varchar, |
|||
e_msg_id uuid, |
|||
e_msg_type varchar, |
|||
e_data_type varchar, |
|||
e_relation_type varchar, |
|||
e_data varchar, |
|||
e_metadata varchar, |
|||
e_error varchar |
|||
) PARTITION BY RANGE (ts); |
|||
|
|||
CREATE TABLE IF NOT EXISTS rule_chain_debug_event ( |
|||
id uuid NOT NULL, |
|||
tenant_id uuid NOT NULL, |
|||
ts bigint NOT NULL, |
|||
entity_id uuid NOT NULL, |
|||
service_id varchar NOT NULL, |
|||
e_message varchar, |
|||
e_error varchar |
|||
) PARTITION BY RANGE (ts); |
|||
|
|||
CREATE TABLE IF NOT EXISTS stats_event ( |
|||
id uuid NOT NULL, |
|||
tenant_id uuid NOT NULL, |
|||
ts bigint NOT NULL, |
|||
entity_id uuid NOT NULL, |
|||
service_id varchar NOT NULL, |
|||
e_messages_processed bigint NOT NULL, |
|||
e_errors_occurred bigint NOT NULL |
|||
) PARTITION BY RANGE (ts); |
|||
|
|||
CREATE TABLE IF NOT EXISTS lc_event ( |
|||
id uuid NOT NULL, |
|||
tenant_id uuid NOT NULL, |
|||
ts bigint NOT NULL, |
|||
entity_id uuid NOT NULL, |
|||
service_id varchar NOT NULL, |
|||
e_type varchar NOT NULL, |
|||
e_success boolean NOT NULL, |
|||
e_error varchar |
|||
) PARTITION BY RANGE (ts); |
|||
|
|||
CREATE TABLE IF NOT EXISTS error_event ( |
|||
id uuid NOT NULL, |
|||
tenant_id uuid NOT NULL, |
|||
ts bigint NOT NULL, |
|||
entity_id uuid NOT NULL, |
|||
service_id varchar NOT NULL, |
|||
e_method varchar NOT NULL, |
|||
e_error varchar |
|||
) PARTITION BY RANGE (ts); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_rule_node_debug_event_main |
|||
ON rule_node_debug_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_rule_chain_debug_event_main |
|||
ON rule_chain_debug_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_stats_event_main |
|||
ON stats_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_lc_event_main |
|||
ON lc_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95); |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_error_event_main |
|||
ON error_event (tenant_id ASC, entity_id ASC, ts DESC NULLS LAST) WITH (FILLFACTOR=95); |
|||
|
|||
CREATE OR REPLACE FUNCTION to_safe_json(p_json text) RETURNS json |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
BEGIN |
|||
return REPLACE(p_json, '\u0000', '' )::json; |
|||
EXCEPTION |
|||
WHEN OTHERS THEN |
|||
return '{}'::json; |
|||
END; |
|||
$$; |
|||
|
|||
-- Useful to migrate old events to the new table structure; |
|||
CREATE OR REPLACE PROCEDURE migrate_regular_events(IN start_ts_in_ms bigint, IN end_ts_in_ms bigint, IN partition_size_in_hours int) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
partition_size_in_ms bigint; |
|||
p record; |
|||
table_name varchar; |
|||
BEGIN |
|||
partition_size_in_ms = partition_size_in_hours * 3600 * 1000; |
|||
|
|||
FOR p IN SELECT DISTINCT event_type as event_type, (created_time - created_time % partition_size_in_ms) as partition_ts FROM event e WHERE e.event_type in ('STATS', 'LC_EVENT', 'ERROR') and ts >= start_ts_in_ms and ts < end_ts_in_ms |
|||
LOOP |
|||
IF p.event_type = 'STATS' THEN |
|||
table_name := 'stats_event'; |
|||
ELSEIF p.event_type = 'LC_EVENT' THEN |
|||
table_name := 'lc_event'; |
|||
ELSEIF p.event_type = 'ERROR' THEN |
|||
table_name := 'error_event'; |
|||
END IF; |
|||
RAISE NOTICE '[%] Partition to create : [%-%]', table_name, p.partition_ts, (p.partition_ts + partition_size_in_ms); |
|||
EXECUTE format('CREATE TABLE IF NOT EXISTS %s_%s PARTITION OF %s FOR VALUES FROM ( %s ) TO ( %s )', table_name, p.partition_ts, table_name, p.partition_ts, (p.partition_ts + partition_size_in_ms)); |
|||
END LOOP; |
|||
|
|||
INSERT INTO stats_event |
|||
SELECT id, |
|||
tenant_id, |
|||
ts, |
|||
entity_id, |
|||
body ->> 'server', |
|||
(body ->> 'messagesProcessed')::bigint, |
|||
(body ->> 'errorsOccurred')::bigint |
|||
FROM |
|||
(select id, tenant_id, ts, entity_id, to_safe_json(body) as body |
|||
FROM event WHERE ts >= start_ts_in_ms and ts < end_ts_in_ms AND event_type = 'STATS' AND to_safe_json(body) ->> 'server' IS NOT NULL |
|||
) safe_event |
|||
ON CONFLICT DO NOTHING; |
|||
|
|||
INSERT INTO lc_event |
|||
SELECT id, |
|||
tenant_id, |
|||
ts, |
|||
entity_id, |
|||
body ->> 'server', |
|||
body ->> 'event', |
|||
(body ->> 'success')::boolean, |
|||
body ->> 'error' |
|||
FROM |
|||
(select id, tenant_id, ts, entity_id, to_safe_json(body) as body |
|||
FROM event WHERE ts >= start_ts_in_ms and ts < end_ts_in_ms AND event_type = 'LC_EVENT' AND to_safe_json(body) ->> 'server' IS NOT NULL |
|||
) safe_event |
|||
ON CONFLICT DO NOTHING; |
|||
|
|||
INSERT INTO error_event |
|||
SELECT id, |
|||
tenant_id, |
|||
ts, |
|||
entity_id, |
|||
body ->> 'server', |
|||
body ->> 'method', |
|||
body ->> 'error' |
|||
FROM |
|||
(select id, tenant_id, ts, entity_id, to_safe_json(body) as body |
|||
FROM event WHERE ts >= start_ts_in_ms and ts < end_ts_in_ms AND event_type = 'ERROR' AND to_safe_json(body) ->> 'server' IS NOT NULL |
|||
) safe_event |
|||
ON CONFLICT DO NOTHING; |
|||
|
|||
END |
|||
$$; |
|||
|
|||
-- Useful to migrate old debug events to the new table structure; |
|||
CREATE OR REPLACE PROCEDURE migrate_debug_events(IN start_ts_in_ms bigint, IN end_ts_in_ms bigint, IN partition_size_in_hours int) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
partition_size_in_ms bigint; |
|||
p record; |
|||
table_name varchar; |
|||
BEGIN |
|||
partition_size_in_ms = partition_size_in_hours * 3600 * 1000; |
|||
|
|||
FOR p IN SELECT DISTINCT event_type as event_type, (created_time - created_time % partition_size_in_ms) as partition_ts FROM event e WHERE e.event_type in ('DEBUG_RULE_NODE', 'DEBUG_RULE_CHAIN') and ts >= start_ts_in_ms and ts < end_ts_in_ms |
|||
LOOP |
|||
IF p.event_type = 'DEBUG_RULE_NODE' THEN |
|||
table_name := 'rule_node_debug_event'; |
|||
ELSEIF p.event_type = 'DEBUG_RULE_CHAIN' THEN |
|||
table_name := 'rule_chain_debug_event'; |
|||
END IF; |
|||
RAISE NOTICE '[%] Partition to create : [%-%]', table_name, p.partition_ts, (p.partition_ts + partition_size_in_ms); |
|||
EXECUTE format('CREATE TABLE IF NOT EXISTS %s_%s PARTITION OF %s FOR VALUES FROM ( %s ) TO ( %s )', table_name, p.partition_ts, table_name, p.partition_ts, (p.partition_ts + partition_size_in_ms)); |
|||
END LOOP; |
|||
|
|||
INSERT INTO rule_node_debug_event |
|||
SELECT id, |
|||
tenant_id, |
|||
ts, |
|||
entity_id, |
|||
body ->> 'server', |
|||
body ->> 'type', |
|||
(body ->> 'entityId')::uuid, |
|||
body ->> 'entityName', |
|||
(body ->> 'msgId')::uuid, |
|||
body ->> 'msgType', |
|||
body ->> 'dataType', |
|||
body ->> 'relationType', |
|||
body ->> 'data', |
|||
body ->> 'metadata', |
|||
body ->> 'error' |
|||
FROM |
|||
(select id, tenant_id, ts, entity_id, to_safe_json(body) as body |
|||
FROM event WHERE ts >= start_ts_in_ms and ts < end_ts_in_ms AND event_type = 'DEBUG_RULE_NODE' AND to_safe_json(body) ->> 'server' IS NOT NULL |
|||
) safe_event |
|||
ON CONFLICT DO NOTHING; |
|||
|
|||
INSERT INTO rule_chain_debug_event |
|||
SELECT id, |
|||
tenant_id, |
|||
ts, |
|||
entity_id, |
|||
body ->> 'server', |
|||
body ->> 'message', |
|||
body ->> 'error' |
|||
FROM |
|||
(select id, tenant_id, ts, entity_id, to_safe_json(body) as body |
|||
FROM event WHERE ts >= start_ts_in_ms and ts < end_ts_in_ms AND event_type = 'DEBUG_RULE_CHAIN' AND to_safe_json(body) ->> 'server' IS NOT NULL |
|||
) safe_event |
|||
ON CONFLICT DO NOTHING; |
|||
END |
|||
$$; |
|||
|
|||
UPDATE tb_user |
|||
SET additional_info = REPLACE(additional_info, '"lang":"ja_JA"', '"lang":"ja_JP"') |
|||
WHERE additional_info LIKE '%"lang":"ja_JA"%'; |
|||
@ -1,142 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
-- AUDIT LOGS MIGRATION START |
|||
DO |
|||
$$ |
|||
DECLARE table_partition RECORD; |
|||
BEGIN |
|||
-- in case of running the upgrade script a second time: |
|||
IF NOT (SELECT exists(SELECT FROM pg_tables WHERE tablename = 'old_audit_log')) THEN |
|||
ALTER TABLE audit_log RENAME TO old_audit_log; |
|||
CREATE INDEX IF NOT EXISTS idx_old_audit_log_created_time ON old_audit_log(created_time); |
|||
|
|||
ALTER INDEX IF EXISTS idx_audit_log_tenant_id_and_created_time RENAME TO idx_old_audit_log_tenant_id_and_created_time; |
|||
|
|||
FOR table_partition IN SELECT tablename AS name, split_part(tablename, '_', 3) AS partition_ts |
|||
FROM pg_tables WHERE tablename LIKE 'audit_log_%' |
|||
LOOP |
|||
EXECUTE format('ALTER TABLE %s RENAME TO old_audit_log_%s', table_partition.name, table_partition.partition_ts); |
|||
END LOOP; |
|||
ELSE |
|||
RAISE NOTICE 'Table old_audit_log already exists, leaving as is'; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
CREATE TABLE IF NOT EXISTS audit_log ( |
|||
id uuid NOT NULL, |
|||
created_time bigint NOT NULL, |
|||
tenant_id uuid, |
|||
customer_id uuid, |
|||
entity_id uuid, |
|||
entity_type varchar(255), |
|||
entity_name varchar(255), |
|||
user_id uuid, |
|||
user_name varchar(255), |
|||
action_type varchar(255), |
|||
action_data varchar(1000000), |
|||
action_status varchar(255), |
|||
action_failure_details varchar(1000000) |
|||
) PARTITION BY RANGE (created_time); |
|||
CREATE INDEX IF NOT EXISTS idx_audit_log_tenant_id_and_created_time ON audit_log(tenant_id, created_time DESC); |
|||
CREATE INDEX IF NOT EXISTS idx_audit_log_id ON audit_log(id); |
|||
|
|||
CREATE OR REPLACE PROCEDURE migrate_audit_logs(IN start_time_ms BIGINT, IN end_time_ms BIGINT, IN partition_size_ms BIGINT) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
p RECORD; |
|||
partition_end_ts BIGINT; |
|||
BEGIN |
|||
FOR p IN SELECT DISTINCT (created_time - created_time % partition_size_ms) AS partition_ts FROM old_audit_log |
|||
WHERE created_time >= start_time_ms AND created_time < end_time_ms |
|||
LOOP |
|||
partition_end_ts = p.partition_ts + partition_size_ms; |
|||
RAISE NOTICE '[audit_log] Partition to create : [%-%]', p.partition_ts, partition_end_ts; |
|||
EXECUTE format('CREATE TABLE IF NOT EXISTS audit_log_%s PARTITION OF audit_log ' || |
|||
'FOR VALUES FROM ( %s ) TO ( %s )', p.partition_ts, p.partition_ts, partition_end_ts); |
|||
END LOOP; |
|||
|
|||
INSERT INTO audit_log |
|||
SELECT id, created_time, tenant_id, customer_id, entity_id, entity_type, entity_name, user_id, user_name, action_type, action_data, action_status, action_failure_details |
|||
FROM old_audit_log |
|||
WHERE created_time >= start_time_ms AND created_time < end_time_ms; |
|||
END; |
|||
$$; |
|||
-- AUDIT LOGS MIGRATION END |
|||
|
|||
|
|||
-- EDGE EVENTS MIGRATION START |
|||
DO |
|||
$$ |
|||
DECLARE table_partition RECORD; |
|||
BEGIN |
|||
-- in case of running the upgrade script a second time: |
|||
IF NOT (SELECT exists(SELECT FROM pg_tables WHERE tablename = 'old_edge_event')) THEN |
|||
ALTER TABLE edge_event RENAME TO old_edge_event; |
|||
CREATE INDEX IF NOT EXISTS idx_old_edge_event_created_time_tmp ON old_edge_event(created_time); |
|||
ALTER INDEX IF EXISTS idx_edge_event_tenant_id_and_created_time RENAME TO idx_old_edge_event_tenant_id_and_created_time; |
|||
|
|||
FOR table_partition IN SELECT tablename AS name, split_part(tablename, '_', 3) AS partition_ts |
|||
FROM pg_tables WHERE tablename LIKE 'edge_event_%' |
|||
LOOP |
|||
EXECUTE format('ALTER TABLE %s RENAME TO old_edge_event_%s', table_partition.name, table_partition.partition_ts); |
|||
END LOOP; |
|||
ELSE |
|||
RAISE NOTICE 'Table old_edge_event already exists, leaving as is'; |
|||
END IF; |
|||
END; |
|||
$$; |
|||
|
|||
CREATE TABLE IF NOT EXISTS edge_event ( |
|||
id uuid NOT NULL, |
|||
created_time bigint NOT NULL, |
|||
edge_id uuid, |
|||
edge_event_type varchar(255), |
|||
edge_event_uid varchar(255), |
|||
entity_id uuid, |
|||
edge_event_action varchar(255), |
|||
body varchar(10000000), |
|||
tenant_id uuid, |
|||
ts bigint NOT NULL |
|||
) PARTITION BY RANGE (created_time); |
|||
CREATE INDEX IF NOT EXISTS idx_edge_event_tenant_id_and_created_time ON edge_event(tenant_id, created_time DESC); |
|||
CREATE INDEX IF NOT EXISTS idx_edge_event_id ON edge_event(id); |
|||
|
|||
CREATE OR REPLACE PROCEDURE migrate_edge_event(IN start_time_ms BIGINT, IN end_time_ms BIGINT, IN partition_size_ms BIGINT) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
p RECORD; |
|||
partition_end_ts BIGINT; |
|||
BEGIN |
|||
FOR p IN SELECT DISTINCT (created_time - created_time % partition_size_ms) AS partition_ts FROM old_edge_event |
|||
WHERE created_time >= start_time_ms AND created_time < end_time_ms |
|||
LOOP |
|||
partition_end_ts = p.partition_ts + partition_size_ms; |
|||
RAISE NOTICE '[edge_event] Partition to create : [%-%]', p.partition_ts, partition_end_ts; |
|||
EXECUTE format('CREATE TABLE IF NOT EXISTS edge_event_%s PARTITION OF edge_event ' || |
|||
'FOR VALUES FROM ( %s ) TO ( %s )', p.partition_ts, p.partition_ts, partition_end_ts); |
|||
END LOOP; |
|||
|
|||
INSERT INTO edge_event |
|||
SELECT id, created_time, edge_id, edge_event_type, edge_event_uid, entity_id, edge_event_action, body, tenant_id, ts |
|||
FROM old_edge_event |
|||
WHERE created_time >= start_time_ms AND created_time < end_time_ms; |
|||
END; |
|||
$$; |
|||
-- EDGE EVENTS MIGRATION END |
|||
@ -1,21 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
DROP PROCEDURE IF EXISTS update_asset_profiles; |
|||
|
|||
ALTER TABLE asset ALTER COLUMN asset_profile_id SET NOT NULL; |
|||
ALTER TABLE asset DROP CONSTRAINT IF EXISTS fk_asset_profile; |
|||
ALTER TABLE asset ADD CONSTRAINT fk_asset_profile FOREIGN KEY (asset_profile_id) REFERENCES asset_profile(id); |
|||
@ -1,46 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
CREATE TABLE IF NOT EXISTS asset_profile ( |
|||
id uuid NOT NULL CONSTRAINT asset_profile_pkey PRIMARY KEY, |
|||
created_time bigint NOT NULL, |
|||
name varchar(255), |
|||
image varchar(1000000), |
|||
description varchar, |
|||
search_text varchar(255), |
|||
is_default boolean, |
|||
tenant_id uuid, |
|||
default_rule_chain_id uuid, |
|||
default_dashboard_id uuid, |
|||
default_queue_name varchar(255), |
|||
external_id uuid, |
|||
CONSTRAINT asset_profile_name_unq_key UNIQUE (tenant_id, name), |
|||
CONSTRAINT asset_profile_external_id_unq_key UNIQUE (tenant_id, external_id), |
|||
CONSTRAINT fk_default_rule_chain_asset_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id), |
|||
CONSTRAINT fk_default_dashboard_asset_profile FOREIGN KEY (default_dashboard_id) REFERENCES dashboard(id) |
|||
); |
|||
|
|||
CREATE OR REPLACE PROCEDURE update_asset_profiles() |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
BEGIN |
|||
UPDATE asset a SET asset_profile_id = COALESCE( |
|||
(SELECT id from asset_profile p WHERE p.tenant_id = a.tenant_id AND a.type = p.name), |
|||
(SELECT id from asset_profile p WHERE p.tenant_id = a.tenant_id AND p.name = 'default') |
|||
) |
|||
WHERE a.asset_profile_id IS NULL; |
|||
END; |
|||
$$; |
|||
@ -1,379 +0,0 @@ |
|||
-- |
|||
-- Copyright © 2016-2024 The Thingsboard Authors |
|||
-- |
|||
-- 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. |
|||
-- |
|||
|
|||
-- USER CREDENTIALS START |
|||
|
|||
ALTER TABLE user_credentials |
|||
ADD COLUMN IF NOT EXISTS additional_info varchar NOT NULL DEFAULT '{}'; |
|||
|
|||
UPDATE user_credentials |
|||
SET additional_info = json_build_object('userPasswordHistory', (u.additional_info::json -> 'userPasswordHistory')) |
|||
FROM tb_user u WHERE user_credentials.user_id = u.id AND u.additional_info::jsonb ? 'userPasswordHistory'; |
|||
|
|||
UPDATE tb_user SET additional_info = tb_user.additional_info::jsonb - 'userPasswordHistory' WHERE additional_info::jsonb ? 'userPasswordHistory'; |
|||
|
|||
-- USER CREDENTIALS END |
|||
|
|||
-- ALARM ASSIGN TO USER START |
|||
|
|||
ALTER TABLE alarm ADD COLUMN IF NOT EXISTS assign_ts BIGINT DEFAULT 0; |
|||
ALTER TABLE alarm ADD COLUMN IF NOT EXISTS assignee_id UUID; |
|||
|
|||
CREATE INDEX IF NOT EXISTS idx_alarm_tenant_assignee_created_time ON alarm(tenant_id, assignee_id, created_time DESC); |
|||
|
|||
-- ALARM ASSIGN TO USER END |
|||
|
|||
-- ALARM STATUS REFACTORING START |
|||
|
|||
ALTER TABLE alarm ADD COLUMN IF NOT EXISTS acknowledged boolean; |
|||
ALTER TABLE alarm ADD COLUMN IF NOT EXISTS cleared boolean; |
|||
|
|||
ALTER TABLE alarm ADD COLUMN IF NOT EXISTS status varchar; -- to avoid failure of the subsequent upgrade. |
|||
UPDATE alarm SET acknowledged = true, cleared = true WHERE status = 'CLEARED_ACK'; |
|||
UPDATE alarm SET acknowledged = true, cleared = false WHERE status = 'ACTIVE_ACK'; |
|||
UPDATE alarm SET acknowledged = false, cleared = true WHERE status = 'CLEARED_UNACK'; |
|||
UPDATE alarm SET acknowledged = false, cleared = false WHERE status = 'ACTIVE_UNACK'; |
|||
|
|||
-- Drop index by 'status' column and replace with new indexes that has only active alarms; |
|||
DROP INDEX IF EXISTS idx_alarm_originator_alarm_type_active; |
|||
CREATE INDEX IF NOT EXISTS idx_alarm_originator_alarm_type_active |
|||
ON alarm USING btree (originator_id, type) WHERE cleared = false; |
|||
|
|||
DROP INDEX IF EXISTS idx_alarm_tenant_alarm_type_active; |
|||
CREATE INDEX IF NOT EXISTS idx_alarm_tenant_alarm_type_active |
|||
ON alarm USING btree (tenant_id, type) WHERE cleared = false; |
|||
|
|||
-- Cover index by alarm type to optimize propagated alarm queries; |
|||
DROP INDEX IF EXISTS idx_entity_alarm_entity_id_alarm_type_created_time_alarm_id; |
|||
CREATE INDEX IF NOT EXISTS idx_entity_alarm_entity_id_alarm_type_created_time_alarm_id ON entity_alarm |
|||
USING btree (tenant_id, entity_id, alarm_type, created_time DESC) INCLUDE(alarm_id); |
|||
|
|||
DROP INDEX IF EXISTS idx_alarm_tenant_status_created_time; |
|||
ALTER TABLE alarm DROP COLUMN IF EXISTS status; |
|||
|
|||
-- Update old alarms and set their state to clear, if there are newer alarms. |
|||
UPDATE alarm a |
|||
SET cleared = TRUE |
|||
WHERE cleared = FALSE |
|||
AND id != (SELECT l.id |
|||
FROM alarm l |
|||
WHERE l.tenant_id = a.tenant_id |
|||
AND l.originator_id = a.originator_id |
|||
AND l.type = a.type |
|||
ORDER BY l.created_time DESC, l.id |
|||
LIMIT 1); |
|||
|
|||
-- ALARM STATUS REFACTORING END |
|||
|
|||
-- ALARM COMMENTS START |
|||
|
|||
CREATE TABLE IF NOT EXISTS alarm_comment ( |
|||
id uuid NOT NULL, |
|||
created_time bigint NOT NULL, |
|||
alarm_id uuid NOT NULL, |
|||
user_id uuid, |
|||
type varchar(255) NOT NULL, |
|||
comment varchar(10000), |
|||
CONSTRAINT fk_alarm_comment_alarm_id FOREIGN KEY (alarm_id) REFERENCES alarm(id) ON DELETE CASCADE |
|||
) PARTITION BY RANGE (created_time); |
|||
CREATE INDEX IF NOT EXISTS idx_alarm_comment_alarm_id ON alarm_comment(alarm_id); |
|||
|
|||
-- ALARM COMMENTS END |
|||
|
|||
-- NOTIFICATIONS START |
|||
|
|||
CREATE TABLE IF NOT EXISTS notification_target ( |
|||
id UUID NOT NULL CONSTRAINT notification_target_pkey PRIMARY KEY, |
|||
created_time BIGINT NOT NULL, |
|||
tenant_id UUID NOT NULL, |
|||
name VARCHAR(255) NOT NULL, |
|||
configuration VARCHAR(10000) NOT NULL, |
|||
CONSTRAINT uq_notification_target_name UNIQUE (tenant_id, name) |
|||
); |
|||
CREATE INDEX IF NOT EXISTS idx_notification_target_tenant_id_created_time ON notification_target(tenant_id, created_time DESC); |
|||
|
|||
CREATE TABLE IF NOT EXISTS notification_template ( |
|||
id UUID NOT NULL CONSTRAINT notification_template_pkey PRIMARY KEY, |
|||
created_time BIGINT NOT NULL, |
|||
tenant_id UUID NOT NULL, |
|||
name VARCHAR(255) NOT NULL, |
|||
notification_type VARCHAR(50) NOT NULL, |
|||
configuration VARCHAR(10000000) NOT NULL, |
|||
CONSTRAINT uq_notification_template_name UNIQUE (tenant_id, name) |
|||
); |
|||
CREATE INDEX IF NOT EXISTS idx_notification_template_tenant_id_created_time ON notification_template(tenant_id, created_time DESC); |
|||
|
|||
CREATE TABLE IF NOT EXISTS notification_rule ( |
|||
id UUID NOT NULL CONSTRAINT notification_rule_pkey PRIMARY KEY, |
|||
created_time BIGINT NOT NULL, |
|||
tenant_id UUID NOT NULL, |
|||
name VARCHAR(255) NOT NULL, |
|||
template_id UUID NOT NULL CONSTRAINT fk_notification_rule_template_id REFERENCES notification_template(id), |
|||
trigger_type VARCHAR(50) NOT NULL, |
|||
trigger_config VARCHAR(1000) NOT NULL, |
|||
recipients_config VARCHAR(10000) NOT NULL, |
|||
additional_config VARCHAR(255), |
|||
CONSTRAINT uq_notification_rule_name UNIQUE (tenant_id, name) |
|||
); |
|||
CREATE INDEX IF NOT EXISTS idx_notification_rule_tenant_id_trigger_type_created_time ON notification_rule(tenant_id, trigger_type, created_time DESC); |
|||
|
|||
CREATE TABLE IF NOT EXISTS notification_request ( |
|||
id UUID NOT NULL CONSTRAINT notification_request_pkey PRIMARY KEY, |
|||
created_time BIGINT NOT NULL, |
|||
tenant_id UUID NOT NULL, |
|||
targets VARCHAR(10000) NOT NULL, |
|||
template_id UUID, |
|||
template VARCHAR(10000000), |
|||
info VARCHAR(1000), |
|||
additional_config VARCHAR(1000), |
|||
originator_entity_id UUID, |
|||
originator_entity_type VARCHAR(32), |
|||
rule_id UUID NULL, |
|||
status VARCHAR(32), |
|||
stats VARCHAR(10000) |
|||
); |
|||
CREATE INDEX IF NOT EXISTS idx_notification_request_tenant_id_user_created_time ON notification_request(tenant_id, created_time DESC) |
|||
WHERE originator_entity_type = 'USER'; |
|||
CREATE INDEX IF NOT EXISTS idx_notification_request_rule_id_originator_entity_id ON notification_request(rule_id, originator_entity_id) |
|||
WHERE originator_entity_type = 'ALARM'; |
|||
CREATE INDEX IF NOT EXISTS idx_notification_request_status ON notification_request(status) |
|||
WHERE status = 'SCHEDULED'; |
|||
|
|||
CREATE TABLE IF NOT EXISTS notification ( |
|||
id UUID NOT NULL, |
|||
created_time BIGINT NOT NULL, |
|||
request_id UUID NULL CONSTRAINT fk_notification_request_id REFERENCES notification_request(id) ON DELETE CASCADE, |
|||
recipient_id UUID NOT NULL CONSTRAINT fk_notification_recipient_id REFERENCES tb_user(id) ON DELETE CASCADE, |
|||
type VARCHAR(50) NOT NULL, |
|||
subject VARCHAR(255), |
|||
body VARCHAR(1000) NOT NULL, |
|||
additional_config VARCHAR(1000), |
|||
status VARCHAR(32) |
|||
) PARTITION BY RANGE (created_time); |
|||
CREATE INDEX IF NOT EXISTS idx_notification_id ON notification(id); |
|||
CREATE INDEX IF NOT EXISTS idx_notification_recipient_id_created_time ON notification(recipient_id, created_time DESC); |
|||
|
|||
-- NOTIFICATIONS END |
|||
|
|||
ALTER TABLE tb_user ADD COLUMN IF NOT EXISTS phone VARCHAR(255); |
|||
|
|||
CREATE TABLE IF NOT EXISTS user_settings ( |
|||
user_id uuid NOT NULL, |
|||
type VARCHAR(50) NOT NULL, |
|||
settings varchar(10000), |
|||
CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES tb_user(id) ON DELETE CASCADE, |
|||
CONSTRAINT user_settings_pkey PRIMARY KEY (user_id, type) |
|||
); |
|||
|
|||
-- TTL DROP PARTITIONS FUNCTIONS UPDATE START |
|||
|
|||
DROP PROCEDURE IF EXISTS drop_partitions_by_max_ttl(character varying, bigint, bigint); |
|||
DROP FUNCTION IF EXISTS get_partition_by_max_ttl_date; |
|||
|
|||
CREATE OR REPLACE FUNCTION get_partition_by_system_ttl_date(IN partition_type varchar, IN date timestamp, OUT partition varchar) AS |
|||
$$ |
|||
BEGIN |
|||
CASE |
|||
WHEN partition_type = 'DAYS' THEN |
|||
partition := 'ts_kv_' || to_char(date, 'yyyy') || '_' || to_char(date, 'MM') || '_' || to_char(date, 'dd'); |
|||
WHEN partition_type = 'MONTHS' THEN |
|||
partition := 'ts_kv_' || to_char(date, 'yyyy') || '_' || to_char(date, 'MM'); |
|||
WHEN partition_type = 'YEARS' THEN |
|||
partition := 'ts_kv_' || to_char(date, 'yyyy'); |
|||
ELSE |
|||
partition := NULL; |
|||
END CASE; |
|||
IF partition IS NOT NULL THEN |
|||
IF NOT EXISTS(SELECT |
|||
FROM pg_tables |
|||
WHERE schemaname = 'public' |
|||
AND tablename = partition) THEN |
|||
partition := NULL; |
|||
RAISE NOTICE 'Failed to found partition by ttl'; |
|||
END IF; |
|||
END IF; |
|||
END; |
|||
$$ LANGUAGE plpgsql; |
|||
|
|||
CREATE OR REPLACE PROCEDURE drop_partitions_by_system_ttl(IN partition_type varchar, IN system_ttl bigint, INOUT deleted bigint) |
|||
LANGUAGE plpgsql AS |
|||
$$ |
|||
DECLARE |
|||
date timestamp; |
|||
partition_by_max_ttl_date varchar; |
|||
partition_by_max_ttl_month varchar; |
|||
partition_by_max_ttl_day varchar; |
|||
partition_by_max_ttl_year varchar; |
|||
partition varchar; |
|||
partition_year integer; |
|||
partition_month integer; |
|||
partition_day integer; |
|||
|
|||
BEGIN |
|||
if system_ttl IS NOT NULL AND system_ttl > 0 THEN |
|||
date := to_timestamp(EXTRACT(EPOCH FROM current_timestamp) - system_ttl); |
|||
partition_by_max_ttl_date := get_partition_by_system_ttl_date(partition_type, date); |
|||
RAISE NOTICE 'Date by max ttl: %', date; |
|||
RAISE NOTICE 'Partition by max ttl: %', partition_by_max_ttl_date; |
|||
IF partition_by_max_ttl_date IS NOT NULL THEN |
|||
CASE |
|||
WHEN partition_type = 'DAYS' THEN |
|||
partition_by_max_ttl_year := SPLIT_PART(partition_by_max_ttl_date, '_', 3); |
|||
partition_by_max_ttl_month := SPLIT_PART(partition_by_max_ttl_date, '_', 4); |
|||
partition_by_max_ttl_day := SPLIT_PART(partition_by_max_ttl_date, '_', 5); |
|||
WHEN partition_type = 'MONTHS' THEN |
|||
partition_by_max_ttl_year := SPLIT_PART(partition_by_max_ttl_date, '_', 3); |
|||
partition_by_max_ttl_month := SPLIT_PART(partition_by_max_ttl_date, '_', 4); |
|||
ELSE |
|||
partition_by_max_ttl_year := SPLIT_PART(partition_by_max_ttl_date, '_', 3); |
|||
END CASE; |
|||
IF partition_by_max_ttl_year IS NULL THEN |
|||
RAISE NOTICE 'Failed to remove partitions by max ttl date due to partition_by_max_ttl_year is null!'; |
|||
ELSE |
|||
IF partition_type = 'YEARS' THEN |
|||
FOR partition IN SELECT tablename |
|||
FROM pg_tables |
|||
WHERE schemaname = 'public' |
|||
AND tablename like 'ts_kv_' || '%' |
|||
AND tablename != 'ts_kv_latest' |
|||
AND tablename != 'ts_kv_dictionary' |
|||
AND tablename != 'ts_kv_indefinite' |
|||
AND tablename != partition_by_max_ttl_date |
|||
LOOP |
|||
partition_year := SPLIT_PART(partition, '_', 3)::integer; |
|||
IF partition_year < partition_by_max_ttl_year::integer THEN |
|||
RAISE NOTICE 'Partition to delete by max ttl: %', partition; |
|||
EXECUTE format('DROP TABLE IF EXISTS %I', partition); |
|||
deleted := deleted + 1; |
|||
END IF; |
|||
END LOOP; |
|||
ELSE |
|||
IF partition_type = 'MONTHS' THEN |
|||
IF partition_by_max_ttl_month IS NULL THEN |
|||
RAISE NOTICE 'Failed to remove months partitions by max ttl date due to partition_by_max_ttl_month is null!'; |
|||
ELSE |
|||
FOR partition IN SELECT tablename |
|||
FROM pg_tables |
|||
WHERE schemaname = 'public' |
|||
AND tablename like 'ts_kv_' || '%' |
|||
AND tablename != 'ts_kv_latest' |
|||
AND tablename != 'ts_kv_dictionary' |
|||
AND tablename != 'ts_kv_indefinite' |
|||
AND tablename != partition_by_max_ttl_date |
|||
LOOP |
|||
partition_year := SPLIT_PART(partition, '_', 3)::integer; |
|||
IF partition_year > partition_by_max_ttl_year::integer THEN |
|||
RAISE NOTICE 'Skip iteration! Partition: % is valid!', partition; |
|||
CONTINUE; |
|||
ELSE |
|||
IF partition_year < partition_by_max_ttl_year::integer THEN |
|||
RAISE NOTICE 'Partition to delete by max ttl: %', partition; |
|||
EXECUTE format('DROP TABLE IF EXISTS %I', partition); |
|||
deleted := deleted + 1; |
|||
ELSE |
|||
partition_month := SPLIT_PART(partition, '_', 4)::integer; |
|||
IF partition_year = partition_by_max_ttl_year::integer THEN |
|||
IF partition_month >= partition_by_max_ttl_month::integer THEN |
|||
RAISE NOTICE 'Skip iteration! Partition: % is valid!', partition; |
|||
CONTINUE; |
|||
ELSE |
|||
RAISE NOTICE 'Partition to delete by max ttl: %', partition; |
|||
EXECUTE format('DROP TABLE IF EXISTS %I', partition); |
|||
deleted := deleted + 1; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END LOOP; |
|||
END IF; |
|||
ELSE |
|||
IF partition_type = 'DAYS' THEN |
|||
IF partition_by_max_ttl_month IS NULL THEN |
|||
RAISE NOTICE 'Failed to remove days partitions by max ttl date due to partition_by_max_ttl_month is null!'; |
|||
ELSE |
|||
IF partition_by_max_ttl_day IS NULL THEN |
|||
RAISE NOTICE 'Failed to remove days partitions by max ttl date due to partition_by_max_ttl_day is null!'; |
|||
ELSE |
|||
FOR partition IN SELECT tablename |
|||
FROM pg_tables |
|||
WHERE schemaname = 'public' |
|||
AND tablename like 'ts_kv_' || '%' |
|||
AND tablename != 'ts_kv_latest' |
|||
AND tablename != 'ts_kv_dictionary' |
|||
AND tablename != 'ts_kv_indefinite' |
|||
AND tablename != partition_by_max_ttl_date |
|||
LOOP |
|||
partition_year := SPLIT_PART(partition, '_', 3)::integer; |
|||
IF partition_year > partition_by_max_ttl_year::integer THEN |
|||
RAISE NOTICE 'Skip iteration! Partition: % is valid!', partition; |
|||
CONTINUE; |
|||
ELSE |
|||
IF partition_year < partition_by_max_ttl_year::integer THEN |
|||
RAISE NOTICE 'Partition to delete by max ttl: %', partition; |
|||
EXECUTE format('DROP TABLE IF EXISTS %I', partition); |
|||
deleted := deleted + 1; |
|||
ELSE |
|||
partition_month := SPLIT_PART(partition, '_', 4)::integer; |
|||
IF partition_month > partition_by_max_ttl_month::integer THEN |
|||
RAISE NOTICE 'Skip iteration! Partition: % is valid!', partition; |
|||
CONTINUE; |
|||
ELSE |
|||
IF partition_month < partition_by_max_ttl_month::integer THEN |
|||
RAISE NOTICE 'Partition to delete by max ttl: %', partition; |
|||
EXECUTE format('DROP TABLE IF EXISTS %I', partition); |
|||
deleted := deleted + 1; |
|||
ELSE |
|||
partition_day := SPLIT_PART(partition, '_', 5)::integer; |
|||
IF partition_day >= partition_by_max_ttl_day::integer THEN |
|||
RAISE NOTICE 'Skip iteration! Partition: % is valid!', partition; |
|||
CONTINUE; |
|||
ELSE |
|||
IF partition_day < partition_by_max_ttl_day::integer THEN |
|||
RAISE NOTICE 'Partition to delete by max ttl: %', partition; |
|||
EXECUTE format('DROP TABLE IF EXISTS %I', partition); |
|||
deleted := deleted + 1; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END LOOP; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END IF; |
|||
END |
|||
$$; |
|||
|
|||
-- TTL DROP PARTITIONS FUNCTIONS UPDATE END |
|||
|
|||
-- RULE NODE SINGLETON MODE SUPPORT |
|||
|
|||
ALTER TABLE rule_node ADD COLUMN IF NOT EXISTS singleton_mode bool DEFAULT false; |
|||
|
|||
UPDATE rule_node SET singleton_mode = true WHERE type IN ('org.thingsboard.rule.engine.mqtt.azure.TbAzureIotHubNode', 'org.thingsboard.rule.engine.mqtt.TbMqttNode'); |
|||
|
|||
ALTER TABLE component_descriptor ADD COLUMN IF NOT EXISTS clustering_mode varchar(255) DEFAULT 'ENABLED'; |
|||
|
|||
UPDATE component_descriptor SET clustering_mode = 'USER_PREFERENCE' WHERE clazz = 'org.thingsboard.rule.engine.mqtt.TbMqttNode'; |
|||
|
|||
UPDATE component_descriptor SET clustering_mode = 'SINGLETON' WHERE clazz = 'org.thingsboard.rule.engine.mqtt.azure.TbAzureIotHubNode'; |
|||
|
|||
@ -1,114 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* 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. |
|||
*/ |
|||
package org.thingsboard.server.service.install; |
|||
|
|||
import com.fasterxml.jackson.databind.JavaType; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.apache.commons.csv.CSVFormat; |
|||
import org.apache.commons.csv.CSVParser; |
|||
import org.thingsboard.common.util.JacksonUtil; |
|||
import org.thingsboard.server.common.data.ShortCustomerInfo; |
|||
import org.thingsboard.server.common.data.StringUtils; |
|||
import org.thingsboard.server.common.data.UUIDConverter; |
|||
import org.thingsboard.server.common.data.id.CustomerId; |
|||
import org.thingsboard.server.common.data.id.DashboardId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.dao.dashboard.DashboardService; |
|||
|
|||
import java.io.IOException; |
|||
import java.nio.file.Files; |
|||
import java.nio.file.Path; |
|||
import java.util.ArrayList; |
|||
import java.util.HashSet; |
|||
import java.util.List; |
|||
import java.util.Set; |
|||
import java.util.UUID; |
|||
|
|||
/** |
|||
* Created by igor on 2/27/18. |
|||
*/ |
|||
@Slf4j |
|||
public class DatabaseHelper { |
|||
|
|||
public static final CSVFormat CSV_DUMP_FORMAT = CSVFormat.DEFAULT.withNullString("\\N"); |
|||
|
|||
public static final String DEVICE = "device"; |
|||
public static final String ENTITY_ID = "entity_id"; |
|||
public static final String TENANT_ID = "tenant_id"; |
|||
public static final String ENTITY_TYPE = "entity_type"; |
|||
public static final String CUSTOMER_ID = "customer_id"; |
|||
public static final String SEARCH_TEXT = "search_text"; |
|||
public static final String ADDITIONAL_INFO = "additional_info"; |
|||
public static final String ASSET = "asset"; |
|||
public static final String DASHBOARD = "dashboard"; |
|||
public static final String ENTITY_VIEWS = "entity_views"; |
|||
public static final String ENTITY_VIEW = "entity_view"; |
|||
public static final String RULE_CHAIN = "rule_chain"; |
|||
public static final String ID = "id"; |
|||
public static final String TITLE = "title"; |
|||
public static final String TYPE = "type"; |
|||
public static final String NAME = "name"; |
|||
public static final String KEYS = "keys"; |
|||
public static final String START_TS = "start_ts"; |
|||
public static final String END_TS = "end_ts"; |
|||
public static final String ASSIGNED_CUSTOMERS = "assigned_customers"; |
|||
public static final String CONFIGURATION = "configuration"; |
|||
|
|||
|
|||
public static void upgradeTo40_assignDashboards(Path dashboardsDump, DashboardService dashboardService, boolean sql) throws Exception { |
|||
JavaType assignedCustomersType = |
|||
JacksonUtil.constructCollectionType(HashSet.class, ShortCustomerInfo.class); |
|||
try (CSVParser csvParser = new CSVParser(Files.newBufferedReader(dashboardsDump), CSV_DUMP_FORMAT.withFirstRecordAsHeader())) { |
|||
csvParser.forEach(record -> { |
|||
String customerIdString = record.get(CUSTOMER_ID); |
|||
String assignedCustomersString = record.get(ASSIGNED_CUSTOMERS); |
|||
DashboardId dashboardId = new DashboardId(toUUID(record.get(ID), sql)); |
|||
List<CustomerId> customerIds = new ArrayList<>(); |
|||
if (!StringUtils.isEmpty(assignedCustomersString)) { |
|||
try { |
|||
Set<ShortCustomerInfo> assignedCustomers = JacksonUtil.fromString(assignedCustomersString, assignedCustomersType); |
|||
assignedCustomers.forEach((customerInfo) -> { |
|||
CustomerId customerId = customerInfo.getCustomerId(); |
|||
if (!customerId.isNullUid()) { |
|||
customerIds.add(customerId); |
|||
} |
|||
}); |
|||
} catch (IllegalArgumentException e) { |
|||
log.error("Unable to parse assigned customers field", e); |
|||
} |
|||
} |
|||
if (!StringUtils.isEmpty(customerIdString)) { |
|||
CustomerId customerId = new CustomerId(toUUID(customerIdString, sql)); |
|||
if (!customerId.isNullUid()) { |
|||
customerIds.add(customerId); |
|||
} |
|||
} |
|||
for (CustomerId customerId : customerIds) { |
|||
dashboardService.assignDashboardToCustomer(TenantId.SYS_TENANT_ID, dashboardId, customerId); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
|
|||
private static UUID toUUID(String src, boolean sql) { |
|||
if (sql) { |
|||
return UUIDConverter.fromString(src); |
|||
} else { |
|||
return UUID.fromString(src); |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -1,49 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* 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. |
|||
*/ |
|||
package org.thingsboard.server.service.install; |
|||
|
|||
import lombok.Data; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; |
|||
import org.springframework.boot.context.properties.ConfigurationProperties; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.context.annotation.Profile; |
|||
import org.thingsboard.server.common.data.DataConstants; |
|||
import org.thingsboard.server.queue.settings.TbRuleEngineQueueConfiguration; |
|||
|
|||
import javax.annotation.PostConstruct; |
|||
import java.util.List; |
|||
|
|||
@Slf4j |
|||
@Data |
|||
@EnableAutoConfiguration |
|||
@Configuration |
|||
@ConfigurationProperties(prefix = "queue.rule-engine") |
|||
@Profile("install") |
|||
public class TbRuleEngineQueueConfigService { |
|||
|
|||
private String topic; |
|||
private List<TbRuleEngineQueueConfiguration> queues; |
|||
|
|||
@PostConstruct |
|||
public void validate() { |
|||
queues.stream().filter(queue -> queue.getName().equals(DataConstants.MAIN_QUEUE_NAME)).findFirst().orElseThrow(() -> { |
|||
log.error("Main queue is not configured in thingsboard.yml"); |
|||
return new RuntimeException("No \"Main\" queue configured!"); |
|||
}); |
|||
} |
|||
|
|||
} |
|||
@ -1,218 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* 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. |
|||
*/ |
|||
package org.thingsboard.server.service.install.cql; |
|||
|
|||
import com.datastax.oss.driver.api.core.cql.BoundStatementBuilder; |
|||
import com.datastax.oss.driver.api.core.cql.PreparedStatement; |
|||
import com.datastax.oss.driver.api.core.cql.ResultSet; |
|||
import com.datastax.oss.driver.api.core.cql.Row; |
|||
import com.datastax.oss.driver.api.core.cql.SimpleStatement; |
|||
import com.datastax.oss.driver.api.core.cql.Statement; |
|||
import com.datastax.oss.driver.api.core.metadata.schema.KeyspaceMetadata; |
|||
import com.datastax.oss.driver.api.core.metadata.schema.TableMetadata; |
|||
import com.datastax.oss.driver.api.core.type.DataType; |
|||
import com.datastax.oss.protocol.internal.ProtocolConstants; |
|||
import org.apache.commons.csv.CSVFormat; |
|||
import org.apache.commons.csv.CSVParser; |
|||
import org.apache.commons.csv.CSVPrinter; |
|||
import org.apache.commons.csv.CSVRecord; |
|||
import org.thingsboard.server.dao.cassandra.guava.GuavaSession; |
|||
|
|||
import java.io.IOException; |
|||
import java.nio.file.Files; |
|||
import java.nio.file.Path; |
|||
import java.nio.file.StandardCopyOption; |
|||
import java.time.Instant; |
|||
import java.util.ArrayList; |
|||
import java.util.Iterator; |
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
import static org.thingsboard.server.service.install.DatabaseHelper.CSV_DUMP_FORMAT; |
|||
|
|||
public class CassandraDbHelper { |
|||
|
|||
public static Path dumpCfIfExists(KeyspaceMetadata ks, GuavaSession session, String cfName, |
|||
String[] columns, String[] defaultValues, String dumpPrefix) throws Exception { |
|||
return dumpCfIfExists(ks, session, cfName, columns, defaultValues, dumpPrefix, false); |
|||
} |
|||
|
|||
public static Path dumpCfIfExists(KeyspaceMetadata ks, GuavaSession session, String cfName, |
|||
String[] columns, String[] defaultValues, String dumpPrefix, boolean printHeader) throws Exception { |
|||
if (ks.getTable(cfName) != null) { |
|||
Path dumpFile = Files.createTempFile(dumpPrefix, null); |
|||
Files.deleteIfExists(dumpFile); |
|||
CSVFormat csvFormat = CSV_DUMP_FORMAT; |
|||
if (printHeader) { |
|||
csvFormat = csvFormat.withHeader(columns); |
|||
} |
|||
try (CSVPrinter csvPrinter = new CSVPrinter(Files.newBufferedWriter(dumpFile), csvFormat)) { |
|||
Statement stmt = SimpleStatement.newInstance("SELECT * FROM " + cfName); |
|||
stmt.setPageSize(1000); |
|||
ResultSet rs = session.execute(stmt); |
|||
Iterator<Row> iter = rs.iterator(); |
|||
while (iter.hasNext()) { |
|||
Row row = iter.next(); |
|||
if (row != null) { |
|||
dumpRow(row, columns, defaultValues, csvPrinter); |
|||
} |
|||
} |
|||
} |
|||
return dumpFile; |
|||
} else { |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
public static void appendToEndOfLine(Path targetDumpFile, String toAppend) throws Exception { |
|||
Path tmp = Files.createTempFile(null, null); |
|||
try (CSVParser csvParser = new CSVParser(Files.newBufferedReader(targetDumpFile), CSV_DUMP_FORMAT)) { |
|||
try (CSVPrinter csvPrinter = new CSVPrinter(Files.newBufferedWriter(tmp), CSV_DUMP_FORMAT)) { |
|||
csvParser.forEach(record -> { |
|||
List<String> newRecord = new ArrayList<>(); |
|||
record.forEach(val -> newRecord.add(val)); |
|||
newRecord.add(toAppend); |
|||
try { |
|||
csvPrinter.printRecord(newRecord); |
|||
} catch (IOException e) { |
|||
throw new RuntimeException("Error appending to EOL", e); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
Files.move(tmp, targetDumpFile, StandardCopyOption.REPLACE_EXISTING); |
|||
} |
|||
|
|||
public static void loadCf(KeyspaceMetadata ks, GuavaSession session, String cfName, String[] columns, Path sourceFile) throws Exception { |
|||
loadCf(ks, session, cfName, columns, sourceFile, false); |
|||
} |
|||
|
|||
public static void loadCf(KeyspaceMetadata ks, GuavaSession session, String cfName, String[] columns, Path sourceFile, boolean parseHeader) throws Exception { |
|||
TableMetadata tableMetadata = ks.getTable(cfName).get(); |
|||
PreparedStatement prepared = session.prepare(createInsertStatement(cfName, columns)); |
|||
CSVFormat csvFormat = CSV_DUMP_FORMAT; |
|||
if (parseHeader) { |
|||
csvFormat = csvFormat.withFirstRecordAsHeader(); |
|||
} else { |
|||
csvFormat = CSV_DUMP_FORMAT.withHeader(columns); |
|||
} |
|||
try (CSVParser csvParser = new CSVParser(Files.newBufferedReader(sourceFile), csvFormat)) { |
|||
csvParser.forEach(record -> { |
|||
BoundStatementBuilder boundStatementBuilder = new BoundStatementBuilder(prepared.bind()); |
|||
for (String column : columns) { |
|||
setColumnValue(tableMetadata, column, record, boundStatementBuilder); |
|||
} |
|||
session.execute(boundStatementBuilder.build()); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
|
|||
private static void dumpRow(Row row, String[] columns, String[] defaultValues, CSVPrinter csvPrinter) throws Exception { |
|||
List<String> record = new ArrayList<>(); |
|||
for (int i=0;i<columns.length;i++) { |
|||
String column = columns[i]; |
|||
String defaultValue; |
|||
if (defaultValues != null && i < defaultValues.length) { |
|||
defaultValue = defaultValues[i]; |
|||
} else { |
|||
defaultValue = ""; |
|||
} |
|||
record.add(getColumnValue(column, defaultValue, row)); |
|||
} |
|||
csvPrinter.printRecord(record); |
|||
} |
|||
|
|||
private static String getColumnValue(String column, String defaultValue, Row row) { |
|||
int index = row.getColumnDefinitions().firstIndexOf(column); |
|||
if (index > -1) { |
|||
String str; |
|||
DataType type = row.getColumnDefinitions().get(index).getType(); |
|||
try { |
|||
if (row.isNull(index)) { |
|||
return null; |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.DOUBLE) { |
|||
str = Double.valueOf(row.getDouble(index)).toString(); |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.INT) { |
|||
str = Integer.valueOf(row.getInt(index)).toString(); |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.BIGINT) { |
|||
str = Long.valueOf(row.getLong(index)).toString(); |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.UUID) { |
|||
str = row.getUuid(index).toString(); |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.TIMEUUID) { |
|||
str = row.getUuid(index).toString(); |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.FLOAT) { |
|||
str = Float.valueOf(row.getFloat(index)).toString(); |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.TIMESTAMP) { |
|||
str = ""+row.getInstant(index).toEpochMilli(); |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.BOOLEAN) { |
|||
str = Boolean.valueOf(row.getBoolean(index)).toString(); |
|||
} else { |
|||
str = row.getString(index); |
|||
} |
|||
} catch (Exception e) { |
|||
str = ""; |
|||
} |
|||
return str; |
|||
} else { |
|||
return defaultValue; |
|||
} |
|||
} |
|||
|
|||
private static String createInsertStatement(String cfName, String[] columns) { |
|||
StringBuilder insertStatementBuilder = new StringBuilder(); |
|||
insertStatementBuilder.append("INSERT INTO ").append(cfName).append(" ("); |
|||
for (String column : columns) { |
|||
insertStatementBuilder.append(column).append(","); |
|||
} |
|||
insertStatementBuilder.deleteCharAt(insertStatementBuilder.length() - 1); |
|||
insertStatementBuilder.append(") VALUES ("); |
|||
for (String column : columns) { |
|||
insertStatementBuilder.append("?").append(","); |
|||
} |
|||
insertStatementBuilder.deleteCharAt(insertStatementBuilder.length() - 1); |
|||
insertStatementBuilder.append(")"); |
|||
return insertStatementBuilder.toString(); |
|||
} |
|||
|
|||
private static void setColumnValue(TableMetadata tableMetadata, String column, |
|||
CSVRecord record, BoundStatementBuilder boundStatementBuilder) { |
|||
String value = record.get(column); |
|||
DataType type = tableMetadata.getColumn(column).get().getType(); |
|||
if (value == null) { |
|||
boundStatementBuilder.setToNull(column); |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.DOUBLE) { |
|||
boundStatementBuilder.setDouble(column, Double.valueOf(value)); |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.INT) { |
|||
boundStatementBuilder.setInt(column, Integer.valueOf(value)); |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.BIGINT) { |
|||
boundStatementBuilder.setLong(column, Long.valueOf(value)); |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.UUID) { |
|||
boundStatementBuilder.setUuid(column, UUID.fromString(value)); |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.TIMEUUID) { |
|||
boundStatementBuilder.setUuid(column, UUID.fromString(value)); |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.FLOAT) { |
|||
boundStatementBuilder.setFloat(column, Float.valueOf(value)); |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.TIMESTAMP) { |
|||
boundStatementBuilder.setInstant(column, Instant.ofEpochMilli(Long.valueOf(value))); |
|||
} else if (type.getProtocolCode() == ProtocolConstants.DataType.BOOLEAN) { |
|||
boundStatementBuilder.setBoolean(column, Boolean.valueOf(value)); |
|||
} else { |
|||
boundStatementBuilder.setString(column, value); |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -1,327 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* 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. |
|||
*/ |
|||
package org.thingsboard.server.service.install.migrate; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.context.annotation.Profile; |
|||
import org.springframework.stereotype.Service; |
|||
import org.thingsboard.server.common.data.EntityType; |
|||
import org.thingsboard.server.common.data.UUIDConverter; |
|||
import org.thingsboard.server.dao.cassandra.CassandraCluster; |
|||
import org.thingsboard.server.dao.util.NoSqlAnyDao; |
|||
import org.thingsboard.server.service.install.EntityDatabaseSchemaService; |
|||
|
|||
import java.sql.Connection; |
|||
import java.sql.DriverManager; |
|||
import java.util.Arrays; |
|||
import java.util.List; |
|||
|
|||
import static org.thingsboard.server.service.install.migrate.CassandraToSqlColumn.bigintColumn; |
|||
import static org.thingsboard.server.service.install.migrate.CassandraToSqlColumn.booleanColumn; |
|||
import static org.thingsboard.server.service.install.migrate.CassandraToSqlColumn.doubleColumn; |
|||
import static org.thingsboard.server.service.install.migrate.CassandraToSqlColumn.enumToIntColumn; |
|||
import static org.thingsboard.server.service.install.migrate.CassandraToSqlColumn.idColumn; |
|||
import static org.thingsboard.server.service.install.migrate.CassandraToSqlColumn.jsonColumn; |
|||
import static org.thingsboard.server.service.install.migrate.CassandraToSqlColumn.stringColumn; |
|||
|
|||
@Service |
|||
@Profile("install") |
|||
@NoSqlAnyDao |
|||
@Slf4j |
|||
public class CassandraEntitiesToSqlMigrateService implements EntitiesMigrateService { |
|||
|
|||
@Autowired |
|||
private EntityDatabaseSchemaService entityDatabaseSchemaService; |
|||
|
|||
@Autowired |
|||
protected CassandraCluster cluster; |
|||
|
|||
@Value("${spring.datasource.url}") |
|||
protected String dbUrl; |
|||
|
|||
@Value("${spring.datasource.username}") |
|||
protected String dbUserName; |
|||
|
|||
@Value("${spring.datasource.password}") |
|||
protected String dbPassword; |
|||
|
|||
@Override |
|||
public void migrate() throws Exception { |
|||
log.info("Performing migration of entities data from cassandra to SQL database ..."); |
|||
entityDatabaseSchemaService.createDatabaseSchema(false); |
|||
try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { |
|||
conn.setAutoCommit(false); |
|||
for (CassandraToSqlTable table: tables) { |
|||
table.migrateToSql(cluster.getSession(), conn); |
|||
} |
|||
} catch (Exception e) { |
|||
log.error("Unexpected error during ThingsBoard entities data migration!", e); |
|||
throw e; |
|||
} |
|||
entityDatabaseSchemaService.createDatabaseIndexes(); |
|||
} |
|||
|
|||
private static List<CassandraToSqlTable> tables = Arrays.asList( |
|||
new CassandraToSqlTable("admin_settings", |
|||
idColumn("id"), |
|||
stringColumn("key"), |
|||
stringColumn("json_value")), |
|||
new CassandraToSqlTable("alarm", |
|||
idColumn("id"), |
|||
idColumn("tenant_id"), |
|||
stringColumn("type"), |
|||
idColumn("originator_id"), |
|||
enumToIntColumn("originator_type", EntityType.class), |
|||
stringColumn("severity"), |
|||
stringColumn("status"), |
|||
bigintColumn("start_ts"), |
|||
bigintColumn("end_ts"), |
|||
bigintColumn("ack_ts"), |
|||
bigintColumn("clear_ts"), |
|||
stringColumn("details", "additional_info"), |
|||
booleanColumn("propagate"), |
|||
stringColumn("propagate_relation_types")), |
|||
new CassandraToSqlTable("asset", |
|||
idColumn("id"), |
|||
idColumn("tenant_id"), |
|||
idColumn("customer_id"), |
|||
stringColumn("name"), |
|||
stringColumn("type"), |
|||
stringColumn("label"), |
|||
stringColumn("search_text"), |
|||
stringColumn("additional_info")) { |
|||
@Override |
|||
protected boolean onConstraintViolation(List<CassandraToSqlColumnData[]> batchData, |
|||
CassandraToSqlColumnData[] data, String constraint) { |
|||
if (constraint.equalsIgnoreCase("asset_name_unq_key")) { |
|||
this.handleUniqueNameViolation(data, "asset"); |
|||
return true; |
|||
} |
|||
return super.onConstraintViolation(batchData, data, constraint); |
|||
} |
|||
}, |
|||
new CassandraToSqlTable("audit_log_by_tenant_id", "audit_log", |
|||
idColumn("id"), |
|||
idColumn("tenant_id"), |
|||
idColumn("customer_id"), |
|||
idColumn("entity_id"), |
|||
stringColumn("entity_type"), |
|||
stringColumn("entity_name"), |
|||
idColumn("user_id"), |
|||
stringColumn("user_name"), |
|||
stringColumn("action_type"), |
|||
stringColumn("action_data"), |
|||
stringColumn("action_status"), |
|||
stringColumn("action_failure_details")), |
|||
new CassandraToSqlTable("attributes_kv_cf", "attribute_kv", |
|||
idColumn("entity_id"), |
|||
stringColumn("entity_type"), |
|||
stringColumn("attribute_type"), |
|||
stringColumn("attribute_key"), |
|||
booleanColumn("bool_v", true), |
|||
stringColumn("str_v"), |
|||
bigintColumn("long_v"), |
|||
doubleColumn("dbl_v"), |
|||
jsonColumn("json_v"), |
|||
bigintColumn("last_update_ts")), |
|||
new CassandraToSqlTable("component_descriptor", |
|||
idColumn("id"), |
|||
stringColumn("type"), |
|||
stringColumn("scope"), |
|||
stringColumn("name"), |
|||
stringColumn("search_text"), |
|||
stringColumn("clazz"), |
|||
stringColumn("configuration_descriptor"), |
|||
stringColumn("actions")) { |
|||
@Override |
|||
protected boolean onConstraintViolation(List<CassandraToSqlColumnData[]> batchData, |
|||
CassandraToSqlColumnData[] data, String constraint) { |
|||
if (constraint.equalsIgnoreCase("component_descriptor_clazz_key")) { |
|||
String clazz = this.getColumnData(data, "clazz").getValue(); |
|||
log.warn("Found component_descriptor record with duplicate clazz [{}]. Record will be ignored!", clazz); |
|||
this.ignoreRecord(batchData, data); |
|||
return true; |
|||
} |
|||
return super.onConstraintViolation(batchData, data, constraint); |
|||
} |
|||
}, |
|||
new CassandraToSqlTable("customer", |
|||
idColumn("id"), |
|||
idColumn("tenant_id"), |
|||
stringColumn("title"), |
|||
stringColumn("search_text"), |
|||
stringColumn("country"), |
|||
stringColumn("state"), |
|||
stringColumn("city"), |
|||
stringColumn("address"), |
|||
stringColumn("address2"), |
|||
stringColumn("zip"), |
|||
stringColumn("phone"), |
|||
stringColumn("email"), |
|||
stringColumn("additional_info")), |
|||
new CassandraToSqlTable("dashboard", |
|||
idColumn("id"), |
|||
idColumn("tenant_id"), |
|||
stringColumn("title"), |
|||
stringColumn("search_text"), |
|||
stringColumn("assigned_customers"), |
|||
stringColumn("configuration")), |
|||
new CassandraToSqlTable("device", |
|||
idColumn("id"), |
|||
idColumn("tenant_id"), |
|||
idColumn("customer_id"), |
|||
stringColumn("name"), |
|||
stringColumn("type"), |
|||
stringColumn("label"), |
|||
stringColumn("search_text"), |
|||
stringColumn("additional_info")) { |
|||
@Override |
|||
protected boolean onConstraintViolation(List<CassandraToSqlColumnData[]> batchData, |
|||
CassandraToSqlColumnData[] data, String constraint) { |
|||
if (constraint.equalsIgnoreCase("device_name_unq_key")) { |
|||
this.handleUniqueNameViolation(data, "device"); |
|||
return true; |
|||
} |
|||
return super.onConstraintViolation(batchData, data, constraint); |
|||
} |
|||
}, |
|||
new CassandraToSqlTable("device_credentials", |
|||
idColumn("id"), |
|||
idColumn("device_id"), |
|||
stringColumn("credentials_type"), |
|||
stringColumn("credentials_id"), |
|||
stringColumn("credentials_value")), |
|||
new CassandraToSqlTable("event", |
|||
idColumn("id"), |
|||
idColumn("tenant_id"), |
|||
idColumn("entity_id"), |
|||
stringColumn("entity_type"), |
|||
stringColumn("event_type"), |
|||
stringColumn("event_uid"), |
|||
stringColumn("body"), |
|||
new CassandraToSqlEventTsColumn()), |
|||
new CassandraToSqlTable("relation", |
|||
idColumn("from_id"), |
|||
stringColumn("from_type"), |
|||
idColumn("to_id"), |
|||
stringColumn("to_type"), |
|||
stringColumn("relation_type_group"), |
|||
stringColumn("relation_type"), |
|||
stringColumn("additional_info")), |
|||
new CassandraToSqlTable("user", "tb_user", |
|||
idColumn("id"), |
|||
idColumn("tenant_id"), |
|||
idColumn("customer_id"), |
|||
stringColumn("email"), |
|||
stringColumn("search_text"), |
|||
stringColumn("authority"), |
|||
stringColumn("first_name"), |
|||
stringColumn("last_name"), |
|||
stringColumn("additional_info")) { |
|||
@Override |
|||
protected boolean onConstraintViolation(List<CassandraToSqlColumnData[]> batchData, |
|||
CassandraToSqlColumnData[] data, String constraint) { |
|||
if (constraint.equalsIgnoreCase("tb_user_email_key")) { |
|||
this.handleUniqueEmailViolation(data); |
|||
return true; |
|||
} |
|||
return super.onConstraintViolation(batchData, data, constraint); |
|||
} |
|||
}, |
|||
new CassandraToSqlTable("tenant", |
|||
idColumn("id"), |
|||
stringColumn("title"), |
|||
stringColumn("search_text"), |
|||
stringColumn("region"), |
|||
stringColumn("country"), |
|||
stringColumn("state"), |
|||
stringColumn("city"), |
|||
stringColumn("address"), |
|||
stringColumn("address2"), |
|||
stringColumn("zip"), |
|||
stringColumn("phone"), |
|||
stringColumn("email"), |
|||
stringColumn("additional_info"), |
|||
booleanColumn("isolated_tb_core"), |
|||
booleanColumn("isolated_tb_rule_engine")), |
|||
new CassandraToSqlTable("user_credentials", |
|||
idColumn("id"), |
|||
idColumn("user_id"), |
|||
booleanColumn("enabled"), |
|||
stringColumn("password"), |
|||
stringColumn("activate_token"), |
|||
stringColumn("reset_token")) { |
|||
@Override |
|||
protected boolean onConstraintViolation(List<CassandraToSqlColumnData[]> batchData, |
|||
CassandraToSqlColumnData[] data, String constraint) { |
|||
if (constraint.equalsIgnoreCase("user_credentials_user_id_key")) { |
|||
String id = UUIDConverter.fromString(this.getColumnData(data, "id").getValue()).toString(); |
|||
log.warn("Found user credentials record with duplicate user_id [id:[{}]]. Record will be ignored!", id); |
|||
this.ignoreRecord(batchData, data); |
|||
return true; |
|||
} |
|||
return super.onConstraintViolation(batchData, data, constraint); |
|||
} |
|||
}, |
|||
new CassandraToSqlTable("widget_type", |
|||
idColumn("id"), |
|||
idColumn("tenant_id"), |
|||
stringColumn("bundle_alias"), |
|||
stringColumn("alias"), |
|||
stringColumn("name"), |
|||
stringColumn("descriptor")), |
|||
new CassandraToSqlTable("widgets_bundle", |
|||
idColumn("id"), |
|||
idColumn("tenant_id"), |
|||
stringColumn("alias"), |
|||
stringColumn("title"), |
|||
stringColumn("search_text")), |
|||
new CassandraToSqlTable("rule_chain", |
|||
idColumn("id"), |
|||
idColumn("tenant_id"), |
|||
stringColumn("name"), |
|||
stringColumn("search_text"), |
|||
idColumn("first_rule_node_id"), |
|||
booleanColumn("root"), |
|||
booleanColumn("debug_mode"), |
|||
stringColumn("configuration"), |
|||
stringColumn("additional_info")), |
|||
new CassandraToSqlTable("rule_node", |
|||
idColumn("id"), |
|||
idColumn("rule_chain_id"), |
|||
stringColumn("type"), |
|||
stringColumn("name"), |
|||
booleanColumn("debug_mode"), |
|||
stringColumn("search_text"), |
|||
stringColumn("configuration"), |
|||
stringColumn("additional_info")), |
|||
new CassandraToSqlTable("entity_view", |
|||
idColumn("id"), |
|||
idColumn("tenant_id"), |
|||
idColumn("customer_id"), |
|||
idColumn("entity_id"), |
|||
stringColumn("entity_type"), |
|||
stringColumn("name"), |
|||
stringColumn("type"), |
|||
stringColumn("keys"), |
|||
bigintColumn("start_ts"), |
|||
bigintColumn("end_ts"), |
|||
stringColumn("search_text"), |
|||
stringColumn("additional_info")) |
|||
); |
|||
} |
|||
@ -1,40 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* 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. |
|||
*/ |
|||
package org.thingsboard.server.service.install.migrate; |
|||
|
|||
import com.datastax.oss.driver.api.core.cql.Row; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
import static org.thingsboard.server.dao.model.ModelConstants.EPOCH_DIFF; |
|||
|
|||
public class CassandraToSqlEventTsColumn extends CassandraToSqlColumn { |
|||
|
|||
CassandraToSqlEventTsColumn() { |
|||
super("id", "ts", CassandraToSqlColumnType.BIGINT, null, false); |
|||
} |
|||
|
|||
@Override |
|||
public String getColumnValue(Row row) { |
|||
UUID id = row.getUuid(getIndex()); |
|||
long ts = getTs(id); |
|||
return ts + ""; |
|||
} |
|||
|
|||
private long getTs(UUID uuid) { |
|||
return (uuid.timestamp() - EPOCH_DIFF) / 10000; |
|||
} |
|||
} |
|||
@ -1,22 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* 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. |
|||
*/ |
|||
package org.thingsboard.server.service.install.migrate; |
|||
|
|||
public interface EntitiesMigrateService { |
|||
|
|||
void migrate() throws Exception; |
|||
|
|||
} |
|||
@ -1,176 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* 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. |
|||
*/ |
|||
package org.thingsboard.server.service.install.sql; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.apache.commons.csv.CSVFormat; |
|||
import org.apache.commons.csv.CSVParser; |
|||
import org.apache.commons.csv.CSVPrinter; |
|||
import org.apache.commons.csv.CSVRecord; |
|||
|
|||
import java.nio.file.Files; |
|||
import java.nio.file.Path; |
|||
import java.sql.Connection; |
|||
import java.sql.PreparedStatement; |
|||
import java.sql.ResultSet; |
|||
import java.sql.ResultSetMetaData; |
|||
import java.sql.SQLException; |
|||
import java.sql.Statement; |
|||
import java.util.ArrayList; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
import static org.thingsboard.server.service.install.DatabaseHelper.CSV_DUMP_FORMAT; |
|||
|
|||
/** |
|||
* Created by igor on 2/27/18. |
|||
*/ |
|||
@Slf4j |
|||
public class SqlDbHelper { |
|||
|
|||
public static Path dumpTableIfExists(Connection conn, String tableName, |
|||
String[] columns, String[] defaultValues, String dumpPrefix) throws Exception { |
|||
return dumpTableIfExists(conn, tableName, columns, defaultValues, dumpPrefix, false); |
|||
} |
|||
|
|||
public static Path dumpTableIfExists(Connection conn, String tableName, |
|||
String[] columns, String[] defaultValues, String dumpPrefix, boolean printHeader) throws Exception { |
|||
|
|||
if (tableExists(conn, tableName)) { |
|||
Path dumpFile = Files.createTempFile(dumpPrefix, null); |
|||
Files.deleteIfExists(dumpFile); |
|||
CSVFormat csvFormat = CSV_DUMP_FORMAT; |
|||
if (printHeader) { |
|||
csvFormat = csvFormat.withHeader(columns); |
|||
} |
|||
try (CSVPrinter csvPrinter = new CSVPrinter(Files.newBufferedWriter(dumpFile), csvFormat)) { |
|||
try (PreparedStatement stmt = conn.prepareStatement("SELECT * FROM " + tableName)) { |
|||
try (ResultSet tableRes = stmt.executeQuery()) { |
|||
ResultSetMetaData resMetaData = tableRes.getMetaData(); |
|||
Map<String, Integer> columnIndexMap = new HashMap<>(); |
|||
for (int i = 1; i <= resMetaData.getColumnCount(); i++) { |
|||
String columnName = resMetaData.getColumnName(i); |
|||
columnIndexMap.put(columnName.toUpperCase(), i); |
|||
} |
|||
while(tableRes.next()) { |
|||
dumpRow(tableRes, columnIndexMap, columns, defaultValues, csvPrinter); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return dumpFile; |
|||
} else { |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
private static boolean tableExists(Connection conn, String tableName) { |
|||
try (Statement stmt = conn.createStatement()) { |
|||
stmt.executeQuery("select * from " + tableName + " where 1=0"); |
|||
return true; |
|||
} catch (Exception e) { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
public static void loadTable(Connection conn, String tableName, String[] columns, Path sourceFile) throws Exception { |
|||
loadTable(conn, tableName, columns, sourceFile, false); |
|||
} |
|||
|
|||
public static void loadTable(Connection conn, String tableName, String[] columns, Path sourceFile, boolean parseHeader) throws Exception { |
|||
CSVFormat csvFormat = CSV_DUMP_FORMAT; |
|||
if (parseHeader) { |
|||
csvFormat = csvFormat.withFirstRecordAsHeader(); |
|||
} else { |
|||
csvFormat = CSV_DUMP_FORMAT.withHeader(columns); |
|||
} |
|||
try (PreparedStatement prepared = conn.prepareStatement(createInsertStatement(tableName, columns))) { |
|||
try (CSVParser csvParser = new CSVParser(Files.newBufferedReader(sourceFile), csvFormat)) { |
|||
csvParser.forEach(record -> { |
|||
try { |
|||
for (int i = 0; i < columns.length; i++) { |
|||
setColumnValue(i, columns[i], record, prepared); |
|||
} |
|||
prepared.execute(); |
|||
} catch (SQLException e) { |
|||
log.error("Unable to load table record!", e); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private static void dumpRow(ResultSet res, Map<String, Integer> columnIndexMap, String[] columns, |
|||
String[] defaultValues, CSVPrinter csvPrinter) throws Exception { |
|||
List<String> record = new ArrayList<>(); |
|||
for (int i=0;i<columns.length;i++) { |
|||
String column = columns[i]; |
|||
String defaultValue; |
|||
if (defaultValues != null && i < defaultValues.length) { |
|||
defaultValue = defaultValues[i]; |
|||
} else { |
|||
defaultValue = ""; |
|||
} |
|||
record.add(getColumnValue(column, defaultValue, columnIndexMap, res)); |
|||
} |
|||
csvPrinter.printRecord(record); |
|||
} |
|||
|
|||
private static String getColumnValue(String column, String defaultValue, Map<String, Integer> columnIndexMap, ResultSet res) { |
|||
int index = columnIndexMap.containsKey(column.toUpperCase()) ? columnIndexMap.get(column.toUpperCase()) : -1; |
|||
if (index > -1) { |
|||
String str; |
|||
try { |
|||
Object obj = res.getObject(index); |
|||
if (obj == null) { |
|||
return null; |
|||
} else { |
|||
str = obj.toString(); |
|||
} |
|||
} catch (Exception e) { |
|||
str = ""; |
|||
} |
|||
return str; |
|||
} else { |
|||
return defaultValue; |
|||
} |
|||
} |
|||
|
|||
private static void setColumnValue(int index, String column, |
|||
CSVRecord record, PreparedStatement preparedStatement) throws SQLException { |
|||
String value = record.get(column); |
|||
int type = preparedStatement.getParameterMetaData().getParameterType(index + 1); |
|||
preparedStatement.setObject(index + 1, value, type); |
|||
} |
|||
|
|||
private static String createInsertStatement(String tableName, String[] columns) { |
|||
StringBuilder insertStatementBuilder = new StringBuilder(); |
|||
insertStatementBuilder.append("INSERT INTO ").append(tableName).append(" ("); |
|||
for (String column : columns) { |
|||
insertStatementBuilder.append(column).append(","); |
|||
} |
|||
insertStatementBuilder.deleteCharAt(insertStatementBuilder.length() - 1); |
|||
insertStatementBuilder.append(") VALUES ("); |
|||
for (String column : columns) { |
|||
insertStatementBuilder.append("?").append(","); |
|||
} |
|||
insertStatementBuilder.deleteCharAt(insertStatementBuilder.length() - 1); |
|||
insertStatementBuilder.append(")"); |
|||
return insertStatementBuilder.toString(); |
|||
} |
|||
|
|||
} |
|||
@ -1,115 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* 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. |
|||
*/ |
|||
package org.thingsboard.server.service.install.update; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.server.common.data.StringUtils; |
|||
import org.thingsboard.server.common.data.TenantProfile; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.page.PageData; |
|||
import org.thingsboard.server.common.data.page.PageLink; |
|||
import org.thingsboard.server.dao.tenant.TenantProfileService; |
|||
|
|||
@Component |
|||
class RateLimitsUpdater extends PaginatedUpdater<String, TenantProfile> { |
|||
|
|||
@Value("#{ environment.getProperty('TB_SERVER_REST_LIMITS_TENANT_ENABLED') ?: environment.getProperty('server.rest.limits.tenant.enabled') ?: 'false' }") |
|||
boolean tenantServerRestLimitsEnabled; |
|||
@Value("#{ environment.getProperty('TB_SERVER_REST_LIMITS_TENANT_CONFIGURATION') ?: environment.getProperty('server.rest.limits.tenant.configuration') ?: '100:1,2000:60' }") |
|||
String tenantServerRestLimitsConfiguration; |
|||
@Value("#{ environment.getProperty('TB_SERVER_REST_LIMITS_CUSTOMER_ENABLED') ?: environment.getProperty('server.rest.limits.customer.enabled') ?: 'false' }") |
|||
boolean customerServerRestLimitsEnabled; |
|||
@Value("#{ environment.getProperty('TB_SERVER_REST_LIMITS_CUSTOMER_CONFIGURATION') ?: environment.getProperty('server.rest.limits.customer.configuration') ?: '50:1,1000:60' }") |
|||
String customerServerRestLimitsConfiguration; |
|||
|
|||
@Value("#{ environment.getProperty('TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SESSIONS_PER_TENANT') ?: environment.getProperty('server.ws.limits.max_sessions_per_tenant') ?: '0' }") |
|||
private int maxWsSessionsPerTenant; |
|||
@Value("#{ environment.getProperty('TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SESSIONS_PER_CUSTOMER') ?: environment.getProperty('server.ws.limits.max_sessions_per_customer') ?: '0' }") |
|||
private int maxWsSessionsPerCustomer; |
|||
@Value("#{ environment.getProperty('TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SESSIONS_PER_REGULAR_USER') ?: environment.getProperty('server.ws.limits.max_sessions_per_regular_user') ?: '0' }") |
|||
private int maxWsSessionsPerRegularUser; |
|||
@Value("#{ environment.getProperty('TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SESSIONS_PER_PUBLIC_USER') ?: environment.getProperty('server.ws.limits.max_sessions_per_public_user') ?: '0' }") |
|||
private int maxWsSessionsPerPublicUser; |
|||
@Value("#{ environment.getProperty('TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_QUEUE_PER_WS_SESSION') ?: environment.getProperty('server.ws.limits.max_queue_per_ws_session') ?: '500' }") |
|||
private int wsMsgQueueLimitPerSession; |
|||
@Value("#{ environment.getProperty('TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SUBSCRIPTIONS_PER_TENANT') ?: environment.getProperty('server.ws.limits.max_subscriptions_per_tenant') ?: '0' }") |
|||
private long maxWsSubscriptionsPerTenant; |
|||
@Value("#{ environment.getProperty('TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SUBSCRIPTIONS_PER_CUSTOMER') ?: environment.getProperty('server.ws.limits.max_subscriptions_per_customer') ?: '0' }") |
|||
private long maxWsSubscriptionsPerCustomer; |
|||
@Value("#{ environment.getProperty('TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SUBSCRIPTIONS_PER_REGULAR_USER') ?: environment.getProperty('server.ws.limits.max_subscriptions_per_regular_user') ?: '0' }") |
|||
private long maxWsSubscriptionsPerRegularUser; |
|||
@Value("#{ environment.getProperty('TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_SUBSCRIPTIONS_PER_PUBLIC_USER') ?: environment.getProperty('server.ws.limits.max_subscriptions_per_public_user') ?: '0' }") |
|||
private long maxWsSubscriptionsPerPublicUser; |
|||
@Value("#{ environment.getProperty('TB_SERVER_WS_TENANT_RATE_LIMITS_MAX_UPDATES_PER_SESSION') ?: environment.getProperty('server.ws.limits.max_updates_per_session') ?: '300:1,3000:60' }") |
|||
private String wsUpdatesPerSessionRateLimit; |
|||
|
|||
@Value("#{ environment.getProperty('CASSANDRA_QUERY_TENANT_RATE_LIMITS_ENABLED') ?: environment.getProperty('cassandra.query.tenant_rate_limits.enabled') ?: 'false' }") |
|||
private boolean cassandraQueryTenantRateLimitsEnabled; |
|||
@Value("#{ environment.getProperty('CASSANDRA_QUERY_TENANT_RATE_LIMITS_CONFIGURATION') ?: environment.getProperty('cassandra.query.tenant_rate_limits.configuration') ?: '1000:1,30000:60' }") |
|||
private String cassandraQueryTenantRateLimitsConfiguration; |
|||
|
|||
@Autowired |
|||
private TenantProfileService tenantProfileService; |
|||
|
|||
@Override |
|||
protected boolean forceReportTotal() { |
|||
return true; |
|||
} |
|||
|
|||
@Override |
|||
protected String getName() { |
|||
return "Rate limits updater"; |
|||
} |
|||
|
|||
@Override |
|||
protected PageData<TenantProfile> findEntities(String id, PageLink pageLink) { |
|||
return tenantProfileService.findTenantProfiles(TenantId.SYS_TENANT_ID, pageLink); |
|||
} |
|||
|
|||
@Override |
|||
protected void updateEntity(TenantProfile tenantProfile) { |
|||
var profileConfiguration = tenantProfile.getDefaultProfileConfiguration(); |
|||
|
|||
if (tenantServerRestLimitsEnabled && StringUtils.isNotEmpty(tenantServerRestLimitsConfiguration)) { |
|||
profileConfiguration.setTenantServerRestLimitsConfiguration(tenantServerRestLimitsConfiguration); |
|||
} |
|||
if (customerServerRestLimitsEnabled && StringUtils.isNotEmpty(customerServerRestLimitsConfiguration)) { |
|||
profileConfiguration.setCustomerServerRestLimitsConfiguration(customerServerRestLimitsConfiguration); |
|||
} |
|||
|
|||
profileConfiguration.setMaxWsSessionsPerTenant(maxWsSessionsPerTenant); |
|||
profileConfiguration.setMaxWsSessionsPerCustomer(maxWsSessionsPerCustomer); |
|||
profileConfiguration.setMaxWsSessionsPerPublicUser(maxWsSessionsPerPublicUser); |
|||
profileConfiguration.setMaxWsSessionsPerRegularUser(maxWsSessionsPerRegularUser); |
|||
profileConfiguration.setMaxWsSubscriptionsPerTenant(maxWsSubscriptionsPerTenant); |
|||
profileConfiguration.setMaxWsSubscriptionsPerCustomer(maxWsSubscriptionsPerCustomer); |
|||
profileConfiguration.setMaxWsSubscriptionsPerPublicUser(maxWsSubscriptionsPerPublicUser); |
|||
profileConfiguration.setMaxWsSubscriptionsPerRegularUser(maxWsSubscriptionsPerRegularUser); |
|||
profileConfiguration.setWsMsgQueueLimitPerSession(wsMsgQueueLimitPerSession); |
|||
if (StringUtils.isNotEmpty(wsUpdatesPerSessionRateLimit)) { |
|||
profileConfiguration.setWsUpdatesPerSessionRateLimit(wsUpdatesPerSessionRateLimit); |
|||
} |
|||
|
|||
if (cassandraQueryTenantRateLimitsEnabled && StringUtils.isNotEmpty(cassandraQueryTenantRateLimitsConfiguration)) { |
|||
profileConfiguration.setCassandraQueryTenantRateLimitsConfiguration(cassandraQueryTenantRateLimitsConfiguration); |
|||
} |
|||
|
|||
tenantProfileService.saveTenantProfile(TenantId.SYS_TENANT_ID, tenantProfile); |
|||
} |
|||
|
|||
} |
|||
@ -1,30 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* 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. |
|||
*/ |
|||
package org.thingsboard.server.queue.settings; |
|||
|
|||
import lombok.Data; |
|||
|
|||
@Data |
|||
@Deprecated |
|||
public class TbRuleEngineQueueAckStrategyConfiguration { |
|||
|
|||
private String type; |
|||
private int retries; |
|||
private double failurePercentage; |
|||
private long pauseBetweenRetries; |
|||
private long maxPauseBetweenRetries; |
|||
|
|||
} |
|||
@ -1,33 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* 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. |
|||
*/ |
|||
package org.thingsboard.server.queue.settings; |
|||
|
|||
import lombok.Data; |
|||
|
|||
@Data |
|||
@Deprecated |
|||
public class TbRuleEngineQueueConfiguration { |
|||
|
|||
private String name; |
|||
private String topic; |
|||
private int pollInterval; |
|||
private int partitions; |
|||
private boolean consumerPerPartition; |
|||
private long packProcessingTimeout; |
|||
private TbRuleEngineQueueSubmitStrategyConfiguration submitStrategy; |
|||
private TbRuleEngineQueueAckStrategyConfiguration processingStrategy; |
|||
|
|||
} |
|||
@ -1,27 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* 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. |
|||
*/ |
|||
package org.thingsboard.server.queue.settings; |
|||
|
|||
import lombok.Data; |
|||
|
|||
@Data |
|||
@Deprecated |
|||
public class TbRuleEngineQueueSubmitStrategyConfiguration { |
|||
|
|||
private String type; |
|||
private int batchSize; |
|||
|
|||
} |
|||
Loading…
Reference in new issue