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