This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch postgresql
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit f45cc5c1afd54b740fdb3a216c469c47679c497c
Author: Tung Tran <[email protected]>
AuthorDate: Tue Mar 19 16:14:09 2024 +0700

    JAMES-2586 Refactor the handle way duplicate value on constraint index to 
avoid noise log (Mailbox and User table)
---
 .../james/mailbox/postgres/mail/PostgresMailboxModule.java |  5 ++++-
 .../mailbox/postgres/mail/dao/PostgresMailboxDAO.java      | 14 ++++++++------
 .../org/apache/james/user/postgres/PostgresUserModule.java |  5 ++++-
 .../org/apache/james/user/postgres/PostgresUsersDAO.java   | 12 +++++++-----
 4 files changed, 23 insertions(+), 13 deletions(-)

diff --git 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/PostgresMailboxModule.java
 
b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/PostgresMailboxModule.java
index 1b56199ad7..68a0253413 100644
--- 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/PostgresMailboxModule.java
+++ 
b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/PostgresMailboxModule.java
@@ -27,6 +27,7 @@ import org.apache.james.backends.postgres.PostgresIndex;
 import org.apache.james.backends.postgres.PostgresModule;
 import org.apache.james.backends.postgres.PostgresTable;
 import org.jooq.Field;
+import org.jooq.Name;
 import org.jooq.Record;
 import org.jooq.Table;
 import org.jooq.impl.DSL;
@@ -47,6 +48,8 @@ public interface PostgresMailboxModule {
         Field<Long> MAILBOX_HIGHEST_MODSEQ = 
DSL.field("mailbox_highest_modseq", BIGINT);
         Field<Hstore> MAILBOX_ACL = DSL.field("mailbox_acl", 
org.jooq.impl.DefaultDataType.getDefaultDataType("hstore").asConvertedDataType(new
 HstoreBinding()));
 
+        Name MAILBOX_NAME_USER_NAME_NAMESPACE_UNIQUE_CONSTRAINT = 
DSL.name("mailbox_mailbox_name_user_name_mailbox_namespace_key");
+
         PostgresTable TABLE = PostgresTable.name(TABLE_NAME.getName())
             .createTableStep(((dsl, tableName) -> 
dsl.createTableIfNotExists(tableName)
                 .column(MAILBOX_ID, SQLDataType.UUID)
@@ -58,7 +61,7 @@ public interface PostgresMailboxModule {
                 .column(MAILBOX_HIGHEST_MODSEQ)
                 .column(MAILBOX_ACL)
                 .constraint(DSL.primaryKey(MAILBOX_ID))
-                .constraint(DSL.unique(MAILBOX_NAME, USER_NAME, 
MAILBOX_NAMESPACE))))
+                
.constraint(DSL.constraint(MAILBOX_NAME_USER_NAME_NAMESPACE_UNIQUE_CONSTRAINT).unique(MAILBOX_NAME,
 USER_NAME, MAILBOX_NAMESPACE))))
             .supportsRowLevelSecurity()
             .build();
         PostgresIndex MAILBOX_USERNAME_NAMESPACE_INDEX = 
PostgresIndex.name("mailbox_username_namespace_index")
diff --git 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxDAO.java
 
b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxDAO.java
index e4f1a6f71d..89fbc929c3 100644
--- 
a/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxDAO.java
+++ 
b/mailbox/postgres/src/main/java/org/apache/james/mailbox/postgres/mail/dao/PostgresMailboxDAO.java
@@ -19,13 +19,13 @@
 
 package org.apache.james.mailbox.postgres.mail.dao;
 
-import static 
org.apache.james.backends.postgres.utils.PostgresUtils.UNIQUE_CONSTRAINT_VIOLATION_PREDICATE;
 import static 
org.apache.james.mailbox.postgres.mail.PostgresMailboxModule.PostgresMailboxTable.MAILBOX_ACL;
 import static 
org.apache.james.mailbox.postgres.mail.PostgresMailboxModule.PostgresMailboxTable.MAILBOX_HIGHEST_MODSEQ;
 import static 
org.apache.james.mailbox.postgres.mail.PostgresMailboxModule.PostgresMailboxTable.MAILBOX_ID;
 import static 
org.apache.james.mailbox.postgres.mail.PostgresMailboxModule.PostgresMailboxTable.MAILBOX_LAST_UID;
 import static 
org.apache.james.mailbox.postgres.mail.PostgresMailboxModule.PostgresMailboxTable.MAILBOX_NAME;
 import static 
org.apache.james.mailbox.postgres.mail.PostgresMailboxModule.PostgresMailboxTable.MAILBOX_NAMESPACE;
+import static 
org.apache.james.mailbox.postgres.mail.PostgresMailboxModule.PostgresMailboxTable.MAILBOX_NAME_USER_NAME_NAMESPACE_UNIQUE_CONSTRAINT;
 import static 
org.apache.james.mailbox.postgres.mail.PostgresMailboxModule.PostgresMailboxTable.MAILBOX_UID_VALIDITY;
 import static 
org.apache.james.mailbox.postgres.mail.PostgresMailboxModule.PostgresMailboxTable.TABLE_NAME;
 import static 
org.apache.james.mailbox.postgres.mail.PostgresMailboxModule.PostgresMailboxTable.USER_NAME;
@@ -117,12 +117,14 @@ public class PostgresMailboxDAO {
     public Mono<Mailbox> create(MailboxPath mailboxPath, UidValidity 
uidValidity) {
         PostgresMailboxId mailboxId = PostgresMailboxId.generate();
 
-        return postgresExecutor.executeVoid(dslContext ->
+        return postgresExecutor.executeRow(dslContext ->
                 Mono.from(dslContext.insertInto(TABLE_NAME, MAILBOX_ID, 
MAILBOX_NAME, USER_NAME, MAILBOX_NAMESPACE, MAILBOX_UID_VALIDITY)
-                    .values(mailboxId.asUuid(), mailboxPath.getName(), 
mailboxPath.getUser().asString(), mailboxPath.getNamespace(), 
uidValidity.asLong())))
-            .thenReturn(new Mailbox(mailboxPath, uidValidity, mailboxId))
-            .onErrorMap(UNIQUE_CONSTRAINT_VIOLATION_PREDICATE,
-                e -> new MailboxExistsException(mailboxPath.getName()));
+                    .values(mailboxId.asUuid(), mailboxPath.getName(), 
mailboxPath.getUser().asString(), mailboxPath.getNamespace(), 
uidValidity.asLong())
+                    
.onConflictOnConstraint(MAILBOX_NAME_USER_NAME_NAMESPACE_UNIQUE_CONSTRAINT)
+                    .doNothing()
+                    .returning(MAILBOX_ID)))
+            .map(record -> new Mailbox(mailboxPath, uidValidity, 
PostgresMailboxId.of(record.get(MAILBOX_ID))))
+            .switchIfEmpty(Mono.error(new 
MailboxExistsException(mailboxPath.getName())));
     }
 
     public Mono<MailboxId> rename(Mailbox mailbox) {
diff --git 
a/server/data/data-postgres/src/main/java/org/apache/james/user/postgres/PostgresUserModule.java
 
b/server/data/data-postgres/src/main/java/org/apache/james/user/postgres/PostgresUserModule.java
index 8840ca22fe..f0b67a25fd 100644
--- 
a/server/data/data-postgres/src/main/java/org/apache/james/user/postgres/PostgresUserModule.java
+++ 
b/server/data/data-postgres/src/main/java/org/apache/james/user/postgres/PostgresUserModule.java
@@ -22,6 +22,7 @@ package org.apache.james.user.postgres;
 import org.apache.james.backends.postgres.PostgresModule;
 import org.apache.james.backends.postgres.PostgresTable;
 import org.jooq.Field;
+import org.jooq.Name;
 import org.jooq.Record;
 import org.jooq.Table;
 import org.jooq.impl.DSL;
@@ -37,6 +38,8 @@ public interface PostgresUserModule {
         Field<String[]> AUTHORIZED_USERS = DSL.field("authorized_users", 
SQLDataType.VARCHAR.getArrayDataType());
         Field<String[]> DELEGATED_USERS = DSL.field("delegated_users", 
SQLDataType.VARCHAR.getArrayDataType());
 
+        Name USERNAME_PRIMARY_KEY = DSL.name("users_username_pk");
+
         PostgresTable TABLE = PostgresTable.name(TABLE_NAME.getName())
             .createTableStep(((dsl, tableName) -> 
dsl.createTableIfNotExists(tableName)
                 .column(USERNAME)
@@ -44,7 +47,7 @@ public interface PostgresUserModule {
                 .column(ALGORITHM)
                 .column(AUTHORIZED_USERS)
                 .column(DELEGATED_USERS)
-                .constraint(DSL.primaryKey(USERNAME))))
+                
.constraint(DSL.constraint(USERNAME_PRIMARY_KEY).primaryKey(USERNAME))))
             .disableRowLevelSecurity()
             .build();
     }
diff --git 
a/server/data/data-postgres/src/main/java/org/apache/james/user/postgres/PostgresUsersDAO.java
 
b/server/data/data-postgres/src/main/java/org/apache/james/user/postgres/PostgresUsersDAO.java
index 0b58bf0b9b..fcd0ac80b1 100644
--- 
a/server/data/data-postgres/src/main/java/org/apache/james/user/postgres/PostgresUsersDAO.java
+++ 
b/server/data/data-postgres/src/main/java/org/apache/james/user/postgres/PostgresUsersDAO.java
@@ -20,7 +20,6 @@
 package org.apache.james.user.postgres;
 
 import static 
org.apache.james.backends.postgres.utils.PostgresExecutor.DEFAULT_INJECT;
-import static 
org.apache.james.backends.postgres.utils.PostgresUtils.UNIQUE_CONSTRAINT_VIOLATION_PREDICATE;
 import static 
org.apache.james.user.postgres.PostgresUserModule.PostgresUserTable.ALGORITHM;
 import static 
org.apache.james.user.postgres.PostgresUserModule.PostgresUserTable.AUTHORIZED_USERS;
 import static 
org.apache.james.user.postgres.PostgresUserModule.PostgresUserTable.DELEGATED_USERS;
@@ -28,6 +27,7 @@ import static 
org.apache.james.user.postgres.PostgresUserModule.PostgresUserTabl
 import static 
org.apache.james.user.postgres.PostgresUserModule.PostgresUserTable.TABLE;
 import static 
org.apache.james.user.postgres.PostgresUserModule.PostgresUserTable.TABLE_NAME;
 import static 
org.apache.james.user.postgres.PostgresUserModule.PostgresUserTable.USERNAME;
+import static 
org.apache.james.user.postgres.PostgresUserModule.PostgresUserTable.USERNAME_PRIMARY_KEY;
 import static org.jooq.impl.DSL.count;
 
 import java.util.Iterator;
@@ -149,10 +149,12 @@ public class PostgresUsersDAO implements UsersDAO {
         DefaultUser user = new DefaultUser(username, algorithm, algorithm);
         user.setPassword(password);
 
-        postgresExecutor.executeVoid(dslContext -> 
Mono.from(dslContext.insertInto(TABLE_NAME, USERNAME, HASHED_PASSWORD, 
ALGORITHM)
-                .values(user.getUserName().asString(), 
user.getHashedPassword(), user.getHashAlgorithm().asString())))
-            .onErrorMap(UNIQUE_CONSTRAINT_VIOLATION_PREDICATE,
-                e -> new AlreadyExistInUsersRepositoryException("User with 
username " + username + " already exist!"))
+        postgresExecutor.executeRow(dslContext -> 
Mono.from(dslContext.insertInto(TABLE_NAME, USERNAME, HASHED_PASSWORD, 
ALGORITHM)
+                .values(user.getUserName().asString(), 
user.getHashedPassword(), user.getHashAlgorithm().asString())
+                .onConflictOnConstraint(USERNAME_PRIMARY_KEY)
+                .doNothing()
+                .returning(USERNAME)))
+            .switchIfEmpty(Mono.error(new 
AlreadyExistInUsersRepositoryException("User with username " + username + " 
already exist!")))
             .block();
     }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to