Skip to content

Commit

Permalink
feat(user): added email addresses and phone numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
zZHorizonZz committed Aug 23, 2024
1 parent 6b7a63d commit 51887f2
Show file tree
Hide file tree
Showing 18 changed files with 548 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import dev.cloudeko.zenei.user.QueryRegistry;

public enum DefaultQuery {
/**
* User Account Queries
*/
USER_ACCOUNT_FIND_BY_IDENTIFIER(QueryMetadata.of(
"SELECT id, username, created_at, updated_at FROM zenei_user_account WHERE id = %s",
1,
Expand All @@ -13,6 +16,16 @@ public enum DefaultQuery {
1,
QueryRegistry.USER_ACCOUNT_FIND_BY_USERNAME
)),
USER_ACCOUNT_FIND_BY_PRIMARY_EMAIL(QueryMetadata.of(
"SELECT id, username, created_at, updated_at FROM zenei_user_account WHERE id = (SELECT user_id FROM zenei_user_email_addresses WHERE email = %s AND primary_email = true)",
1,
QueryRegistry.USER_ACCOUNT_FIND_BY_PRIMARY_EMAIL_ADDRESS
)),
USER_ACCOUNT_FIND_BY_PRIMARY_PHONE_NUMBER(QueryMetadata.of(
"SELECT id, username, created_at, updated_at FROM zenei_user_account WHERE id = (SELECT user_id FROM zenei_user_phone_numbers WHERE phone_number = %s AND primary_phone_number = true)",
1,
QueryRegistry.USER_ACCOUNT_FIND_BY_PRIMARY_PHONE_NUMBER
)),
USER_ACCOUNT_LIST(QueryMetadata.of(
"SELECT id, username, created_at, updated_at FROM zenei_user_account",
0,
Expand All @@ -37,6 +50,35 @@ public enum DefaultQuery {
"DELETE FROM zenei_user_account WHERE id = %s RETURNING id, username, image, created_at, updated_at",
1,
QueryRegistry.USER_ACCOUNT_DELETE
)),

/**
* User Account Email Addresses Queries
*/
USER_ACCOUNT_LIST_EMAIL_ADDRESSES(QueryMetadata.of(
"SELECT id, user_id, email, email_verified, primary_email, created_at, updated_at FROM zenei_user_email_addresses WHERE user_id = %s",
1,
QueryRegistry.USER_ACCOUNT_EMAIL_ADDRESSES_LIST_BY_USER_ID
)),
USER_ACCOUNT_EMAIL_ADDRESSES_CREATE(QueryMetadata.of(
"INSERT INTO zenei_user_email_addresses (user_id, email, email_verified, primary_email, created_at, updated_at) VALUES (%s, %s, %s, %s, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) RETURNING id, user_id, email, email_verified, primary_email, created_at, updated_at",
4,
QueryRegistry.USER_ACCOUNT_EMAIL_ADDRESSES_CREATE
)),
USER_ACCOUNT_EMAIL_ADDRESSES_UPDATE(QueryMetadata.of(
"UPDATE zenei_user_email_addresses SET email = %s, email_verified = %s, primary_email = %s, updated_at = CURRENT_TIMESTAMP WHERE id = %s RETURNING id, user_id, email, email_verified, primary_email, created_at, updated_at",
4,
QueryRegistry.USER_ACCOUNT_EMAIL_ADDRESSES_UPDATE
)),
USER_ACCOUNT_EMAIL_ADDRESSES_DELETE(QueryMetadata.of(
"DELETE FROM zenei_user_email_addresses WHERE user_id = %s AND email = %s",
2,
QueryRegistry.USER_ACCOUNT_EMAIL_ADDRESSES_DELETE
)),
USER_ACCOUNT_EMAIL_ADDRESSES_DELETE_BY_USER_ID(QueryMetadata.of(
"DELETE FROM zenei_user_email_addresses WHERE user_id = %s",
1,
QueryRegistry.USER_ACCOUNT_EMAIL_ADDRESSES_DELETE_BY_USER_ID
));

private final QueryMetadata metadata;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import java.util.function.Function;

public enum DefaultTableSchema {
USER_ACCOUNT("zenei_user_account", UserAccountTableSchema::fromClient);
USER_ACCOUNT("zenei_user_account", UserAccountTableSchema::fromClient),
USER_ACCOUNT_EMAIL_ADDRESSES("zenei_user_email_addresses", UserAccountEmailAddressesTableSchema::fromClient);

private final String tableName;
private final Function<Capabilities, TableSchema> schemaFunction;
Expand Down Expand Up @@ -105,4 +106,89 @@ public boolean isSupportsIfNotExists() {
return supportsIfNotExists;
}
}

public enum UserAccountEmailAddressesTableSchema implements TableSchema {
REACTIVE_PG_CLIENT(Capability.REACTIVE_PG_CLIENT,
"CREATE TABLE IF NOT EXISTS zenei_user_email_addresses ("
+ "id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, "
+ "user_id BIGINT NOT NULL, "
+ "email_address VARCHAR(100) NOT NULL, "
+ "primary_email BOOLEAN NOT NULL, "
+ "email_verified BOOLEAN NOT NULL, "
+ "created_at TIMESTAMP NOT NULL, "
+ "updated_at TIMESTAMP NOT NULL)",
true),
REACTIVE_MYSQL_CLIENT(Capability.REACTIVE_MYSQL_CLIENT,
"CREATE TABLE IF NOT EXISTS zenei_user_email_addresses ("
+ "id BIGINT AUTO_INCREMENT PRIMARY KEY, "
+ "user_id BIGINT NOT NULL, "
+ "email_address VARCHAR(100) NOT NULL, "
+ "primary_email BOOLEAN NOT NULL, "
+ "email_verified BOOLEAN NOT NULL, "
+ "created_at TIMESTAMP NOT NULL, "
+ "updated_at TIMESTAMP NOT NULL)",
true),
REACTIVE_MSSQL_CLIENT(Capability.REACTIVE_MSSQL_CLIENT,
"CREATE TABLE zenei_user_email_addresses ("
+ "id BIGINT IDENTITY(1,1) PRIMARY KEY, "
+ "user_id BIGINT NOT NULL, "
+ "email_address NVARCHAR(100) NOT NULL, "
+ "primary_email BIT NOT NULL, "
+ "email_verified BIT NOT NULL, "
+ "created_at DATETIME2 NOT NULL, "
+ "updated_at DATETIME2 NOT NULL)",
false),
REACTIVE_DB2_CLIENT(Capability.REACTIVE_DB2_CLIENT,
"CREATE TABLE zenei_user_email_addresses ("
+ "id BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), "
+ "user_id BIGINT NOT NULL, "
+ "email_address VARCHAR(100) NOT NULL, "
+ "primary_email SMALLINT NOT NULL, "
+ "email_verified SMALLINT NOT NULL, "
+ "created_at TIMESTAMP NOT NULL, "
+ "updated_at TIMESTAMP NOT NULL, "
+ "PRIMARY KEY (id))",
false),
REACTIVE_ORACLE_CLIENT(Capability.REACTIVE_ORACLE_CLIENT,
"CREATE TABLE zenei_user_email_addresses ("
+ "id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, "
+ "user_id NUMBER NOT NULL, "
+ "email_address VARCHAR2(100) NOT NULL, "
+ "primary_email NUMBER NOT NULL, "
+ "email_verified NUMBER NOT NULL, "
+ "created_at TIMESTAMP NOT NULL, "
+ "updated_at TIMESTAMP NOT NULL)",
true);

private final String client;
private final String ddl;
private final boolean supportsIfNotExists;

UserAccountEmailAddressesTableSchema(String client, String ddl, boolean supportsIfNotExists) {
this.client = client;
this.ddl = ddl;
this.supportsIfNotExists = supportsIfNotExists;
}

public static UserAccountEmailAddressesTableSchema fromClient(Capabilities capabilities) {
for (UserAccountEmailAddressesTableSchema schema : values()) {
if (capabilities.isPresent(schema.client)) {
return schema;
}
}
throw new IllegalArgumentException("No table schema found for the given capabilities");
}

public String getClient() {
return client;
}

public String getDdl() {
return ddl;
}

public boolean isSupportsIfNotExists() {
return supportsIfNotExists;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
import java.time.LocalDateTime;
import java.util.List;

public abstract class BasicUserAccount<ID> extends UserAccount<ID> {
public abstract class BasicUserAccount<ID, EMAIL extends EmailAddress, PHONE extends PhoneNumber> extends UserAccount<ID> {

protected String username;

private List<EmailAddress> emailAddresses;
private List<PhoneNumber> phoneNumbers;
private List<EMAIL> emailAddresses;
private List<PHONE> phoneNumbers;

public BasicUserAccount() {

Expand All @@ -32,33 +32,27 @@ public void setUsername(String username) {
this.username = username;
}

public EmailAddress getPrimaryEmailAddress() {
return emailAddresses.stream().filter(EmailAddress::primary).findFirst().orElse(null);
public EMAIL getPrimaryEmailAddress() {
return emailAddresses.stream().filter(EmailAddress::isPrimaryEmail).findFirst().orElse(null);
}

public List<EmailAddress> getEmailAddresses() {
public List<EMAIL> getEmailAddresses() {
return emailAddresses;
}

public void setEmailAddresses(List<EmailAddress> emailAddresses) {
public void setEmailAddresses(List<EMAIL> emailAddresses) {
this.emailAddresses = emailAddresses;
}

public PhoneNumber getPrimaryPhoneNumber() {
return phoneNumbers.stream().filter(PhoneNumber::primary).findFirst().orElse(null);
public PHONE getPrimaryPhoneNumber() {
return phoneNumbers.stream().filter(PhoneNumber::isPrimaryPhoneNumber).findFirst().orElse(null);
}

public List<PhoneNumber> getPhoneNumbers() {
public List<PHONE> getPhoneNumbers() {
return phoneNumbers;
}

public void setPhoneNumbers(List<PhoneNumber> phoneNumbers) {
public void setPhoneNumbers(List<PHONE> phoneNumbers) {
this.phoneNumbers = phoneNumbers;
}

public record EmailAddress(String email, boolean verified, boolean primary) {
}

public record PhoneNumber(String number, boolean verified, boolean primary) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package dev.cloudeko.zenei.user;

import io.smallrye.mutiny.Uni;
import io.vertx.sqlclient.Row;
import io.vertx.sqlclient.RowIterator;
import io.vertx.sqlclient.RowSet;

public class DatabaseUtil {
public static Uni<Row> processNullableRow(RowSet<Row> rows) {
if (rows.size() == 0) {
return Uni.createFrom().nullItem();
}

final RowIterator<Row> iterator = rows.iterator();
if (iterator.hasNext()) {
return Uni.createFrom().item(iterator.next());
}

return Uni.createFrom().nullItem();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package dev.cloudeko.zenei.user;

import java.time.LocalDateTime;

public class EmailAddress {

private String email;
private boolean primaryEmail;
private boolean emailVerified;

private LocalDateTime createdAt;
private LocalDateTime updatedAt;

public EmailAddress() {
}

public EmailAddress(String email, boolean verified, boolean primary) {
this.email = email;
this.emailVerified = verified;
this.primaryEmail = primary;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public boolean isPrimaryEmail() {
return primaryEmail;
}

public void setPrimaryEmail(boolean primaryEmail) {
this.primaryEmail = primaryEmail;
}

public boolean isEmailVerified() {
return emailVerified;
}

public void setEmailVerified(boolean emailVerified) {
this.emailVerified = emailVerified;
}

public LocalDateTime getCreatedAt() {
return createdAt;
}

public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}

public LocalDateTime getUpdatedAt() {
return updatedAt;
}

public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package dev.cloudeko.zenei.user;

public interface EmailAddressManager {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package dev.cloudeko.zenei.user;

import java.time.LocalDateTime;

public class PhoneNumber {

private String phoneNumber;
private boolean primaryPhoneNumber;
private boolean phoneNumberVerified;

private LocalDateTime createdAt;
private LocalDateTime updatedAt;

public PhoneNumber() {
}

public PhoneNumber(String phoneNumber, boolean verified, boolean primary) {
this.phoneNumber = phoneNumber;
this.phoneNumberVerified = verified;
this.primaryPhoneNumber = primary;
}

public String getPhoneNumber() {
return phoneNumber;
}

public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}

public boolean isPrimaryPhoneNumber() {
return primaryPhoneNumber;
}

public void setPrimaryPhoneNumber(boolean primaryPhoneNumber) {
this.primaryPhoneNumber = primaryPhoneNumber;
}

public boolean isPhoneNumberVerified() {
return phoneNumberVerified;
}

public void setPhoneNumberVerified(boolean phoneNumberVerified) {
this.phoneNumberVerified = phoneNumberVerified;
}

public LocalDateTime getCreatedAt() {
return createdAt;
}

public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}

public LocalDateTime getUpdatedAt() {
return updatedAt;
}

public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package dev.cloudeko.zenei.user;

public interface PhoneNumberManager {
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,19 @@
public class QueryRegistry {
public static final String USER_ACCOUNT_FIND_BY_IDENTIFIER = "user-account-find-by-identifier";
public static final String USER_ACCOUNT_FIND_BY_USERNAME = "user-account-find-by-username";
public static final String USER_ACCOUNT_FIND_BY_PRIMARY_EMAIL_ADDRESS = "user-account-find-by-primary-email";
public static final String USER_ACCOUNT_FIND_BY_PRIMARY_PHONE_NUMBER = "user-account-find-by-primary-phone-number";
public static final String USER_ACCOUNT_LIST = "user-account-list";
public static final String USER_ACCOUNT_LIST_PAGINATED = "user-account-list-paginated";
public static final String USER_ACCOUNT_CREATE = "user-account-create";
public static final String USER_ACCOUNT_UPDATE = "user-account-update";
public static final String USER_ACCOUNT_DELETE = "user-account-delete";

public static final String USER_ACCOUNT_EMAIL_ADDRESSES_LIST_BY_USER_ID = "user-account-email-addresses-find-by-user-id";
public static final String USER_ACCOUNT_EMAIL_ADDRESSES_CREATE = "user-account-email-addresses-create";
public static final String USER_ACCOUNT_EMAIL_ADDRESSES_UPDATE = "user-account-email-addresses-update";
public static final String USER_ACCOUNT_EMAIL_ADDRESSES_DELETE = "user-account-email-addresses-delete";
public static final String USER_ACCOUNT_EMAIL_ADDRESSES_DELETE_BY_USER_ID = "user-account-email-addresses-delete-by-user-id";
public static final String USER_ACCOUNT_EMAIL_ADDRESSES_SET_PRIMARY = "user-account-email-addresses-set-primary";
public static final String USER_ACCOUNT_EMAIL_ADDRESSES_SET_VERIFIED = "user-account-email-addresses-set-verified";
}
Loading

0 comments on commit 51887f2

Please sign in to comment.