diff options
author | Pierre <pierre.guillot@sonarsource.com> | 2022-07-15 11:50:31 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-07-21 20:03:05 +0000 |
commit | 4d4fa01b933038ba8e9639679fab4a36b6eff91a (patch) | |
tree | 7d5b99d4ffe2beab24dcb49a101d7e60127e1e0e /server/sonar-db-migration | |
parent | 5f4e6f7f86a2d780f92125a4fac844d1c2ca5a07 (diff) | |
download | sonarqube-4d4fa01b933038ba8e9639679fab4a36b6eff91a.tar.gz sonarqube-4d4fa01b933038ba8e9639679fab4a36b6eff91a.zip |
SONAR-16613 Migrate users field 'sonarlint_ad_seen' to use the new notice mechanism
Diffstat (limited to 'server/sonar-db-migration')
10 files changed, 359 insertions, 29 deletions
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/step/DropColumnChange.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/step/DropColumnChange.java index 5bf051020f2..ba761526777 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/step/DropColumnChange.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/step/DropColumnChange.java @@ -44,7 +44,7 @@ public abstract class DropColumnChange extends DdlChange { context.execute(new DropColumnsBuilder(getDatabase().getDialect(), tableName, columnName).build()); } - private boolean checkIfUseManagedColumnExists() throws SQLException { + public boolean checkIfUseManagedColumnExists() throws SQLException { try (var connection = getDatabase().getDataSource().getConnection()) { if (DatabaseUtils.tableColumnExists(connection, tableName, columnName)) { return true; diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/step/DropColumnWithConstraint.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/step/DropColumnWithConstraint.java new file mode 100644 index 00000000000..34d9dc1fe3b --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/step/DropColumnWithConstraint.java @@ -0,0 +1,51 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.platform.db.migration.step; + +import java.sql.SQLException; +import org.sonar.db.Database; +import org.sonar.db.dialect.MsSql; +import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder; +import org.sonar.server.platform.db.migration.sql.DropMsSQLDefaultConstraintsBuilder; + +public class DropColumnWithConstraint extends DropColumnChange { + + private final String tableName; + private final String column; + + public DropColumnWithConstraint(Database db, String tableName, String column) { + super(db, tableName, column); + this.tableName = tableName; + this.column = column; + } + + @Override + public void execute(Context context) throws SQLException { + if (!checkIfUseManagedColumnExists()) { + return; + } + + if (MsSql.ID.equals(getDatabase().getDialect().getId())) { + context.execute(new DropMsSQLDefaultConstraintsBuilder(getDatabase()).setTable(tableName).setColumns(column).build()); + } + context.execute(new DropColumnsBuilder(getDatabase().getDialect(), tableName, column).build()); + } + +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedColumnFromMetricsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedColumnFromMetricsTable.java index 05628583383..3cfcce03f27 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedColumnFromMetricsTable.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v91/DropUserManagedColumnFromMetricsTable.java @@ -19,41 +19,16 @@ */ package org.sonar.server.platform.db.migration.version.v91; -import java.sql.SQLException; import org.sonar.db.Database; -import org.sonar.db.DatabaseUtils; -import org.sonar.db.dialect.MsSql; -import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder; -import org.sonar.server.platform.db.migration.sql.DropMsSQLDefaultConstraintsBuilder; -import org.sonar.server.platform.db.migration.step.DdlChange; +import org.sonar.server.platform.db.migration.step.DropColumnWithConstraint; -public class DropUserManagedColumnFromMetricsTable extends DdlChange { +public class DropUserManagedColumnFromMetricsTable extends DropColumnWithConstraint { private static final String TABLE_NAME = "metrics"; private static final String COLUMN = "user_managed"; public DropUserManagedColumnFromMetricsTable(Database db) { - super(db); + super(db, TABLE_NAME, COLUMN); } - @Override - public void execute(Context context) throws SQLException { - if (!checkIfUseManagedColumnExists()) { - return; - } - - if (MsSql.ID.equals(getDatabase().getDialect().getId())) { - context.execute(new DropMsSQLDefaultConstraintsBuilder(getDatabase()).setTable(TABLE_NAME).setColumns(COLUMN).build()); - } - context.execute(new DropColumnsBuilder(getDatabase().getDialect(), TABLE_NAME, COLUMN).build()); - } - - private boolean checkIfUseManagedColumnExists() throws SQLException { - try (var connection = getDatabase().getDataSource().getConnection()) { - if (DatabaseUtils.tableColumnExists(connection, TABLE_NAME, COLUMN)) { - return true; - } - } - return false; - } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v96/DbVersion96.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v96/DbVersion96.java index 4c3ad0be119..71692004e58 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v96/DbVersion96.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v96/DbVersion96.java @@ -36,6 +36,8 @@ public class DbVersion96 implements DbVersion { .add(6505, "Add column 'rule_description_context_key' to 'issues'", AddRuleDescriptionContextKeyInIssuesTable.class) .add(6506, "Add column 'education_principles' to 'rules'", AddEducationPrinciplesColumnToRuleTable.class) .add(6507, "Overwrite plugin file hash to force reloading rules", ForceReloadingOfAllPlugins.class) + .add(6508, "Migrate 'sonarlint_ad_seen' from users to properties", MigrateSonarlintAdSeenFromUsersToProperties.class) + .add(6509, "Drop column sonarlint_ad_seen in 'users'", DropSonarlintAdSeenColumnInUsersTable.class) ; } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v96/DropSonarlintAdSeenColumnInUsersTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v96/DropSonarlintAdSeenColumnInUsersTable.java new file mode 100644 index 00000000000..fa8bc33dfd7 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v96/DropSonarlintAdSeenColumnInUsersTable.java @@ -0,0 +1,34 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.platform.db.migration.version.v96; + +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.step.DropColumnWithConstraint; + +public class DropSonarlintAdSeenColumnInUsersTable extends DropColumnWithConstraint { + + private static final String TABLE_NAME = "users"; + private static final String COLUMN = "sonarlint_ad_seen"; + + public DropSonarlintAdSeenColumnInUsersTable(Database db) { + super(db, TABLE_NAME, COLUMN); + } + +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v96/MigrateSonarlintAdSeenFromUsersToProperties.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v96/MigrateSonarlintAdSeenFromUsersToProperties.java new file mode 100644 index 00000000000..99c52dfd358 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v96/MigrateSonarlintAdSeenFromUsersToProperties.java @@ -0,0 +1,66 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.platform.db.migration.version.v96; + +import java.sql.SQLException; +import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactory; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.step.DataChange; +import org.sonar.server.platform.db.migration.step.MassUpdate; + +public class MigrateSonarlintAdSeenFromUsersToProperties extends DataChange { + + public static final String USER_DISMISSED_NOTICES_SONARLINT_AD = "user.dismissedNotices.sonarlintAd"; + + private final UuidFactory uuidFactory; + private final System2 system2; + + public MigrateSonarlintAdSeenFromUsersToProperties(Database db, UuidFactory uuidFactory, System2 system2) { + super(db); + this.uuidFactory = uuidFactory; + this.system2 = system2; + } + + @Override + protected void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + + massUpdate.select("select u.uuid, u.sonarlint_ad_seen, p.uuid from users u" + + " left join properties p on u.uuid = p.user_uuid and p.prop_key = ?" + + " where u.sonarlint_ad_seen = ?" + + " and p.uuid is null") + .setString(1, USER_DISMISSED_NOTICES_SONARLINT_AD) + .setBoolean(2, true); + + massUpdate.update("insert into properties (uuid,prop_key,user_uuid,is_empty,created_at) values (?, ?, ?, ?, ?)"); + + massUpdate.execute((row, update) -> { + update.setString(1, uuidFactory.create()); + update.setString(2, USER_DISMISSED_NOTICES_SONARLINT_AD); + update.setString(3, row.getString(1)); + update.setBoolean(4, true); + update.setLong(5, system2.now()); + + return true; + }); + + } +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v96/DropSonarlintAdSeenColumnInUsersTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v96/DropSonarlintAdSeenColumnInUsersTableTest.java new file mode 100644 index 00000000000..1dca64023a9 --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v96/DropSonarlintAdSeenColumnInUsersTableTest.java @@ -0,0 +1,54 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.platform.db.migration.version.v96; + +import java.sql.SQLException; +import java.sql.Types; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.db.CoreDbTester; +import org.sonar.server.platform.db.migration.step.DdlChange; + +public class DropSonarlintAdSeenColumnInUsersTableTest { + + private static final String COLUMN_NAME = "sonarlint_ad_seen"; + private static final String TABLE_NAME = "users"; + + @Rule + public final CoreDbTester db = CoreDbTester.createForSchema(DropSonarlintAdSeenColumnInUsersTableTest.class, "schema.sql"); + + private final DdlChange underTest = new DropSonarlintAdSeenColumnInUsersTable(db.database()); + + @Test + public void migration_should_drop_column() throws SQLException { + db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.BOOLEAN, null, true); + underTest.execute(); + db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); + } + + @Test + public void migration_should_be_reentrant() throws SQLException { + db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.BOOLEAN, null, true); + underTest.execute(); + // re-entrant + underTest.execute(); + db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME); + } +}
\ No newline at end of file diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v96/MigrateSonarlintAdSeenFromUsersToPropertiesTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v96/MigrateSonarlintAdSeenFromUsersToPropertiesTest.java new file mode 100644 index 00000000000..02d0c929ba1 --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v96/MigrateSonarlintAdSeenFromUsersToPropertiesTest.java @@ -0,0 +1,78 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.platform.db.migration.version.v96; + +import java.sql.SQLException; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactory; +import org.sonar.core.util.UuidFactoryFast; +import org.sonar.db.CoreDbTester; +import org.sonar.server.platform.db.migration.step.DataChange; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.server.platform.db.migration.version.v96.MigrateSonarlintAdSeenFromUsersToProperties.USER_DISMISSED_NOTICES_SONARLINT_AD; + +public class MigrateSonarlintAdSeenFromUsersToPropertiesTest { + + @Rule + public final CoreDbTester db = CoreDbTester.createForSchema(MigrateSonarlintAdSeenFromUsersToPropertiesTest.class, "schema.sql"); + + private final UuidFactory uuidFactory = UuidFactoryFast.getInstance(); + + private final System2 system2 = new System2(); + + private final DataChange underTest = new MigrateSonarlintAdSeenFromUsersToProperties(db.database(), uuidFactory, system2); + + @Test + public void migrate_sonarlintAd_to_properties() throws SQLException { + insertUser(db, "uuid-user-1", "user1", "externalId1", "externalLogin1", true); + insertUser(db, "uuid-user-2", "user2", "externalId2", "externalLogin2", false); + + underTest.execute(); + + assertThat(db.countSql("select count(*) from properties where prop_key='" + USER_DISMISSED_NOTICES_SONARLINT_AD + "' and user_uuid='uuid-user-1'")).isEqualTo(1); + assertThat(db.countSql("select count(*) from properties where prop_key='" + USER_DISMISSED_NOTICES_SONARLINT_AD + "' and user_uuid='uuid-user-2'")).isZero(); + } + + @Test + public void migration_is_reentrant() throws SQLException { + insertUser(db, "uuid-user-1", "user1", "externalId1", "externalLogin1", true); + + underTest.execute(); + underTest.execute(); + + assertThat(db.countSql("select count(*) from properties where prop_key='" + USER_DISMISSED_NOTICES_SONARLINT_AD + "' and user_uuid='uuid-user-1'")).isEqualTo(1); + } + + private void insertUser(CoreDbTester db, String userUuid, String login, String externalId, String externalLogin, boolean seen) { + db.executeInsert("users", "UUID", userUuid, + "login", login, + "external_identity_provider", "none", + "external_id", externalId, + "external_login", externalLogin, + "reset_password", false, + "sonarlint_ad_seen", seen + ); + } + + +}
\ No newline at end of file diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v96/DropSonarlintAdSeenColumnInUsersTableTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v96/DropSonarlintAdSeenColumnInUsersTableTest/schema.sql new file mode 100644 index 00000000000..82da2b04f35 --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v96/DropSonarlintAdSeenColumnInUsersTableTest/schema.sql @@ -0,0 +1,28 @@ +CREATE TABLE "USERS"( + "UUID" CHARACTER VARYING(255) NOT NULL, + "LOGIN" CHARACTER VARYING(255) NOT NULL, + "NAME" CHARACTER VARYING(200), + "EMAIL" CHARACTER VARYING(100), + "CRYPTED_PASSWORD" CHARACTER VARYING(100), + "SALT" CHARACTER VARYING(40), + "HASH_METHOD" CHARACTER VARYING(10), + "ACTIVE" BOOLEAN DEFAULT TRUE, + "SCM_ACCOUNTS" CHARACTER VARYING(4000), + "EXTERNAL_LOGIN" CHARACTER VARYING(255) NOT NULL, + "EXTERNAL_IDENTITY_PROVIDER" CHARACTER VARYING(100) NOT NULL, + "EXTERNAL_ID" CHARACTER VARYING(255) NOT NULL, + "USER_LOCAL" BOOLEAN, + "HOMEPAGE_TYPE" CHARACTER VARYING(40), + "HOMEPAGE_PARAMETER" CHARACTER VARYING(40), + "LAST_CONNECTION_DATE" BIGINT, + "CREATED_AT" BIGINT, + "UPDATED_AT" BIGINT, + "RESET_PASSWORD" BOOLEAN NOT NULL, + "LAST_SONARLINT_CONNECTION" BIGINT, + "SONARLINT_AD_SEEN" BOOLEAN DEFAULT FALSE +); +ALTER TABLE "USERS" ADD CONSTRAINT "PK_USERS" PRIMARY KEY("UUID"); +CREATE UNIQUE INDEX "USERS_LOGIN" ON "USERS"("LOGIN" NULLS FIRST); +CREATE INDEX "USERS_UPDATED_AT" ON "USERS"("UPDATED_AT" NULLS FIRST); +CREATE UNIQUE INDEX "UNIQ_EXTERNAL_ID" ON "USERS"("EXTERNAL_IDENTITY_PROVIDER" NULLS FIRST, "EXTERNAL_ID" NULLS FIRST); +CREATE UNIQUE INDEX "UNIQ_EXTERNAL_LOGIN" ON "USERS"("EXTERNAL_IDENTITY_PROVIDER" NULLS FIRST, "EXTERNAL_LOGIN" NULLS FIRST); diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v96/MigrateSonarlintAdSeenFromUsersToPropertiesTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v96/MigrateSonarlintAdSeenFromUsersToPropertiesTest/schema.sql new file mode 100644 index 00000000000..f5eda0e9df8 --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v96/MigrateSonarlintAdSeenFromUsersToPropertiesTest/schema.sql @@ -0,0 +1,42 @@ +CREATE TABLE "USERS"( + "UUID" CHARACTER VARYING(255) NOT NULL, + "LOGIN" CHARACTER VARYING(255) NOT NULL, + "NAME" CHARACTER VARYING(200), + "EMAIL" CHARACTER VARYING(100), + "CRYPTED_PASSWORD" CHARACTER VARYING(100), + "SALT" CHARACTER VARYING(40), + "HASH_METHOD" CHARACTER VARYING(10), + "ACTIVE" BOOLEAN DEFAULT TRUE, + "SCM_ACCOUNTS" CHARACTER VARYING(4000), + "EXTERNAL_LOGIN" CHARACTER VARYING(255) NOT NULL, + "EXTERNAL_IDENTITY_PROVIDER" CHARACTER VARYING(100) NOT NULL, + "EXTERNAL_ID" CHARACTER VARYING(255) NOT NULL, + "USER_LOCAL" BOOLEAN, + "HOMEPAGE_TYPE" CHARACTER VARYING(40), + "HOMEPAGE_PARAMETER" CHARACTER VARYING(40), + "LAST_CONNECTION_DATE" BIGINT, + "CREATED_AT" BIGINT, + "UPDATED_AT" BIGINT, + "RESET_PASSWORD" BOOLEAN NOT NULL, + "LAST_SONARLINT_CONNECTION" BIGINT, + "SONARLINT_AD_SEEN" BOOLEAN DEFAULT FALSE +); +ALTER TABLE "USERS" ADD CONSTRAINT "PK_USERS" PRIMARY KEY("UUID"); +CREATE UNIQUE INDEX "USERS_LOGIN" ON "USERS"("LOGIN" NULLS FIRST); +CREATE INDEX "USERS_UPDATED_AT" ON "USERS"("UPDATED_AT" NULLS FIRST); +CREATE UNIQUE INDEX "UNIQ_EXTERNAL_ID" ON "USERS"("EXTERNAL_IDENTITY_PROVIDER" NULLS FIRST, "EXTERNAL_ID" NULLS FIRST); +CREATE UNIQUE INDEX "UNIQ_EXTERNAL_LOGIN" ON "USERS"("EXTERNAL_IDENTITY_PROVIDER" NULLS FIRST, "EXTERNAL_LOGIN" NULLS FIRST); + + +CREATE TABLE "PROPERTIES"( + "UUID" CHARACTER VARYING(40) NOT NULL, + "PROP_KEY" CHARACTER VARYING(512) NOT NULL, + "IS_EMPTY" BOOLEAN NOT NULL, + "TEXT_VALUE" CHARACTER VARYING(4000), + "CLOB_VALUE" CHARACTER LARGE OBJECT, + "CREATED_AT" BIGINT NOT NULL, + "COMPONENT_UUID" CHARACTER VARYING(40), + "USER_UUID" CHARACTER VARYING(255) +); +ALTER TABLE "PROPERTIES" ADD CONSTRAINT "PK_PROPERTIES" PRIMARY KEY("UUID"); +CREATE INDEX "PROPERTIES_KEY" ON "PROPERTIES"("PROP_KEY" NULLS FIRST); |