From ad4e212edf66d68add5e4f4f6dd47043e181e83e Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Thu, 28 Dec 2023 13:03:19 +0200 Subject: [PATCH] Migrate user settings to jsonb --- .../main/data/upgrade/3.6.2/schema_update.sql | 29 +++++++++++++++++++ .../install/ThingsboardInstallService.java | 3 ++ .../install/SqlDatabaseUpgradeService.java | 3 ++ .../MobileAppNotificationChannel.java | 3 +- .../dao/model/sql/UserSettingsEntity.java | 8 ++--- .../server/dao/sql/user/UserRepository.java | 3 +- .../resources/sql/schema-entities-idx.sql | 2 ++ .../main/resources/sql/schema-entities.sql | 2 +- 8 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 application/src/main/data/upgrade/3.6.2/schema_update.sql diff --git a/application/src/main/data/upgrade/3.6.2/schema_update.sql b/application/src/main/data/upgrade/3.6.2/schema_update.sql new file mode 100644 index 0000000000..6ee752eb10 --- /dev/null +++ b/application/src/main/data/upgrade/3.6.2/schema_update.sql @@ -0,0 +1,29 @@ +-- +-- Copyright © 2016-2023 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. +-- + +DO +$$ + BEGIN + IF NOT EXISTS(SELECT 1 FROM information_schema.columns WHERE table_name = 'user_settings' AND column_name = 'settings' AND data_type = 'jsonb') THEN + ALTER TABLE user_settings RENAME COLUMN settings to old_settings; + ALTER TABLE user_settings ADD COLUMN settings jsonb; + UPDATE user_settings SET settings = old_settings::jsonb WHERE old_settings IS NOT NULL; + ALTER TABLE user_settings DROP COLUMN old_settings; + END IF; + END; +$$; + +CREATE INDEX IF NOT EXISTS idx_user_settings_mobile_fcm_token ON user_settings ((settings ->> 'fcmToken')) WHERE type = 'MOBILE'; diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 5ab3b7b28e..bd557b5476 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -277,6 +277,9 @@ public class ThingsboardInstallService { log.info("Skipping images migration. Run the upgrade with fromVersion as '3.6.2-images' to migrate"); } //TODO DON'T FORGET to update switch statement in the CacheCleanupService if you need to clear the cache + case "3.6.2": + log.info("Upgrading ThingsBoard from version 3.6.2 to 3.6.3 ..."); + databaseEntitiesUpgradeService.upgradeDatabase("3.6.2"); break; default: throw new RuntimeException("Unable to upgrade ThingsBoard, unsupported fromVersion: " + upgradeFromVersion); diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index c2444390f6..4a96d0d2c3 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -772,6 +772,9 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService } }); break; + case "3.6.2": + updateSchema("3.6.2", 3006002, "3.6.3", 3006003, null); + break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/channels/MobileAppNotificationChannel.java b/application/src/main/java/org/thingsboard/server/service/notification/channels/MobileAppNotificationChannel.java index 839368c2d7..b6a63fdeb2 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/channels/MobileAppNotificationChannel.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/channels/MobileAppNotificationChannel.java @@ -53,7 +53,8 @@ public class MobileAppNotificationChannel implements NotificationChannel { @Id @Column(name = ModelConstants.USER_SETTINGS_TYPE_PROPERTY) private String type; - @Type(type = "json") - @Column(name = ModelConstants.USER_SETTINGS_SETTINGS) + @Type(type = "jsonb") + @Column(name = ModelConstants.USER_SETTINGS_SETTINGS, columnDefinition = "jsonb") private JsonNode settings; public UserSettingsEntity(UserSettings userSettings) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/user/UserRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/user/UserRepository.java index d07ddc739b..4db366193c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/user/UserRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/user/UserRepository.java @@ -73,7 +73,8 @@ public interface UserRepository extends JpaRepository { Long countByTenantId(UUID tenantId); - @Query(value = "UPDATE user_settings SET settings = (settings::jsonb - 'fcmToken')::text WHERE type = 'MOBILE'", nativeQuery = true) + @Query(value = "UPDATE user_settings SET settings = settings - 'fcmToken' " + + "WHERE type = 'MOBILE' AND (settings ->> 'fcmToken') = :fcmToken", nativeQuery = true) @Modifying @Transactional void unassignFcmToken(@Param("fcmToken") String fcmToken); diff --git a/dao/src/main/resources/sql/schema-entities-idx.sql b/dao/src/main/resources/sql/schema-entities-idx.sql index df95a50d47..4766809d34 100644 --- a/dao/src/main/resources/sql/schema-entities-idx.sql +++ b/dao/src/main/resources/sql/schema-entities-idx.sql @@ -129,3 +129,5 @@ CREATE INDEX IF NOT EXISTS idx_resource_etag ON resource(tenant_id, etag); CREATE INDEX IF NOT EXISTS idx_resource_etag ON resource(tenant_id, etag); CREATE INDEX IF NOT EXISTS idx_resource_type_public_resource_key ON resource(resource_type, public_resource_key); + +CREATE INDEX IF NOT EXISTS idx_user_settings_mobile_fcm_token ON user_settings ((settings ->> 'fcmToken')) WHERE type = 'MOBILE'; diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index d216380eaa..280ec534c8 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -871,7 +871,7 @@ CREATE TABLE IF NOT EXISTS notification ( CREATE TABLE IF NOT EXISTS user_settings ( user_id uuid NOT NULL, type VARCHAR(50) NOT NULL, - settings varchar(10000), + settings jsonb, CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES tb_user(id) ON DELETE CASCADE, CONSTRAINT user_settings_pkey PRIMARY KEY (user_id, type) );