Skip to content

Commit

Permalink
[#12048] Migrate accounts db layer (#12114)
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelfangjw committed Feb 26, 2023
1 parent f077dac commit 256e3cf
Show file tree
Hide file tree
Showing 9 changed files with 340 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public void testCreateReadDeleteAccountRequest() throws Exception {

AccountRequest actualAccountRequest =
accountRequestDb.getAccountRequest(accountRequest.getEmail(), accountRequest.getInstitute());
verifyEquals(null, actualAccountRequest);
assertNull(actualAccountRequest);
}

@Test
Expand Down
61 changes: 61 additions & 0 deletions src/it/java/teammates/it/storage/sqlapi/AccountsDbIT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package teammates.it.storage.sqlapi;

import org.testng.annotations.Test;

import teammates.common.exception.EntityAlreadyExistsException;
import teammates.common.exception.InvalidParametersException;
import teammates.common.util.HibernateUtil;
import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;
import teammates.storage.sqlapi.AccountsDb;
import teammates.storage.sqlentity.Account;

/**
* SUT: {@link AccountsDb}.
*/
public class AccountsDbIT extends BaseTestCaseWithSqlDatabaseAccess {

private final AccountsDb accountsDb = AccountsDb.inst();

@Test
public void testCreateAccount() throws Exception {
______TS("Create account, does not exists, succeeds");

Account account = new Account("google-id", "name", "[email protected]");

accountsDb.createAccount(account);
HibernateUtil.flushSession();

Account actualAccount = accountsDb.getAccount(account.getId());
verifyEquals(account, actualAccount);
}

@Test
public void testUpdateAccount() throws Exception {
Account account = new Account("google-id", "name", "[email protected]");
accountsDb.createAccount(account);
HibernateUtil.flushSession();

______TS("Update existing account, success");

account.setName("new account name");
accountsDb.updateAccount(account);

Account actual = accountsDb.getAccount(account.getId());
verifyEquals(account, actual);
}

@Test
public void testDeleteAccount() throws InvalidParametersException, EntityAlreadyExistsException {
Account account = new Account("google-id", "name", "[email protected]");
accountsDb.createAccount(account);
HibernateUtil.flushSession();

______TS("Delete existing account, success");

accountsDb.deleteAccount(account);

Account actual = accountsDb.getAccount(account.getId());
assertNull(actual);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@
import teammates.common.util.JsonUtils;
import teammates.sqllogic.api.Logic;
import teammates.sqllogic.core.LogicStarter;
import teammates.storage.sqlentity.Account;
import teammates.storage.sqlentity.AccountRequest;
import teammates.storage.sqlentity.BaseEntity;
import teammates.storage.sqlentity.Course;
import teammates.storage.sqlentity.Notification;
import teammates.storage.sqlentity.UsageStatistics;
import teammates.test.BaseTestCase;

/**
Expand All @@ -34,7 +37,8 @@ public class BaseTestCaseWithSqlDatabaseAccess extends BaseTestCase {
public static void setUpClass() throws Exception {
PGSQL.start();
// Temporarily disable migration utility
// DbMigrationUtil.resetDb(PGSQL.getJdbcUrl(), PGSQL.getUsername(), PGSQL.getPassword());
// DbMigrationUtil.resetDb(PGSQL.getJdbcUrl(), PGSQL.getUsername(),
// PGSQL.getPassword());
HibernateUtil.buildSessionFactory(PGSQL.getJdbcUrl(), PGSQL.getUsername(), PGSQL.getPassword());

LogicStarter.initializeDependencies();
Expand Down Expand Up @@ -69,6 +73,23 @@ protected void verifyEquals(BaseEntity expected, BaseEntity actual) {
Notification actualNotification = (Notification) actual;
equalizeIrrelevantData(expectedNotification, actualNotification);
assertEquals(JsonUtils.toJson(expectedNotification), JsonUtils.toJson(actualNotification));
} else if (expected instanceof Account) {
Account expectedAccount = (Account) expected;
Account actualAccount = (Account) actual;
equalizeIrrelevantData(expectedAccount, actualAccount);
assertEquals(JsonUtils.toJson(expectedAccount), JsonUtils.toJson(actualAccount));
} else if (expected instanceof AccountRequest) {
AccountRequest expectedAccountRequest = (AccountRequest) expected;
AccountRequest actualAccountRequest = (AccountRequest) actual;
equalizeIrrelevantData(expectedAccountRequest, actualAccountRequest);
assertEquals(JsonUtils.toJson(expectedAccountRequest), JsonUtils.toJson(actualAccountRequest));
} else if (expected instanceof UsageStatistics) {
UsageStatistics expectedUsageStatistics = (UsageStatistics) expected;
UsageStatistics actualUsageStatistics = (UsageStatistics) actual;
equalizeIrrelevantData(expectedUsageStatistics, actualUsageStatistics);
assertEquals(JsonUtils.toJson(expectedUsageStatistics), JsonUtils.toJson(actualUsageStatistics));
} else {
fail("Unknown entity");
}
}

Expand Down Expand Up @@ -100,6 +121,23 @@ private void equalizeIrrelevantData(Notification expected, Notification actual)
expected.setUpdatedAt(actual.getUpdatedAt());
}

private void equalizeIrrelevantData(Account expected, Account actual) {
// Ignore time field as it is stamped at the time of creation in testing
expected.setCreatedAt(actual.getCreatedAt());
expected.setUpdatedAt(actual.getUpdatedAt());
}

private void equalizeIrrelevantData(AccountRequest expected, AccountRequest actual) {
// Ignore time field as it is stamped at the time of creation in testing
expected.setCreatedAt(actual.getCreatedAt());
expected.setUpdatedAt(actual.getUpdatedAt());
}

private void equalizeIrrelevantData(UsageStatistics expected, UsageStatistics actual) {
// Ignore time field as it is stamped at the time of creation in testing
expected.setCreatedAt(actual.getCreatedAt());
}

/**
* Generates a UUID that is different from the given {@code uuid}.
*/
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/teammates/common/util/HibernateUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,15 @@ public static <T extends BaseEntity> T get(Class<T> entityType, Object id) {
return HibernateUtil.getCurrentSession().get(entityType, id);
}

/**
* Return the persistent instance of the given entity class with the given natural id,
* or null if there is no such persistent instance.
* @see Session#get(Class, Object)
*/
public static <T extends BaseEntity> T getBySimpleNaturalId(Class<T> entityType, Object id) {
return HibernateUtil.getCurrentSession().bySimpleNaturalId(entityType).load(id);
}

/**
* Copy the state of the given object onto the persistent object with the same identifier.
* @see Session#merge(E)
Expand Down
88 changes: 88 additions & 0 deletions src/main/java/teammates/storage/sqlapi/AccountsDb.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package teammates.storage.sqlapi;

import teammates.common.exception.EntityAlreadyExistsException;
import teammates.common.exception.EntityDoesNotExistException;
import teammates.common.exception.InvalidParametersException;
import teammates.common.util.HibernateUtil;
import teammates.storage.sqlentity.Account;

/**
* Handles CRUD operations for accounts.
*
* @see Account
*/
public final class AccountsDb extends EntitiesDb<Account> {

private static final AccountsDb instance = new AccountsDb();

private AccountsDb() {
// prevent initialization
}

public static AccountsDb inst() {
return instance;
}

/**
* Returns an Account with the {@code id} or null if it does not exist.
*/
public Account getAccount(Integer id) {
assert id != null;

return HibernateUtil.get(Account.class, id);
}

/**
* Returns an Account with the {@code googleId} or null if it does not exist.
*/
public Account getAccountByGoogleId(String googleId) {
assert googleId != null;

return HibernateUtil.getBySimpleNaturalId(Account.class, googleId);
}

/**
* Creates an Account.
*/
public Account createAccount(Account account) throws InvalidParametersException, EntityAlreadyExistsException {
assert account != null;

if (!account.isValid()) {
throw new InvalidParametersException(account.getInvalidityInfo());
}

if (getAccountByGoogleId(account.getGoogleId()) != null) {
throw new EntityAlreadyExistsException(String.format(ERROR_CREATE_ENTITY_ALREADY_EXISTS, account.toString()));
}

persist(account);
return account;
}

/**
* Saves an updated {@code Account} to the db.
*/
public Account updateAccount(Account account) throws InvalidParametersException, EntityDoesNotExistException {
assert account != null;

if (!account.isValid()) {
throw new InvalidParametersException(account.getInvalidityInfo());
}

if (getAccount(account.getId()) == null) {
throw new EntityDoesNotExistException(ERROR_UPDATE_NON_EXISTENT + account.toString());
}

return merge(account);
}

/**
* Deletes an Account.
*/
public void deleteAccount(Account account) {
if (account != null) {
delete(account);
}
}

}
8 changes: 4 additions & 4 deletions src/main/java/teammates/storage/sqlapi/EntitiesDb.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,18 @@ class EntitiesDb<E extends BaseEntity> {
* Copy the state of the given object onto the persistent object with the same identifier.
* If there is no persistent instance currently associated with the session, it will be loaded.
*/
E merge(E entity) {
protected E merge(E entity) {
assert entity != null;

E newEntity = HibernateUtil.merge(entity);
log.info("Entity saves: " + JsonUtils.toJson(entity));
log.info("Entity updated: " + JsonUtils.toJson(entity));
return newEntity;
}

/**
* Associate {@code entity} with the persistence context.
*/
void persist(E entity) {
protected void persist(E entity) {
assert entity != null;

HibernateUtil.persist(entity);
Expand All @@ -43,7 +43,7 @@ void persist(E entity) {
/**
* Deletes {@code entity} from persistence context.
*/
void delete(E entity) {
protected void delete(E entity) {
assert entity != null;

HibernateUtil.remove(entity);
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/teammates/storage/sqlentity/Account.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.List;
import java.util.Objects;

import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.UpdateTimestamp;

import teammates.common.util.FieldValidator;
Expand All @@ -27,7 +28,7 @@ public class Account extends BaseEntity {
@GeneratedValue
private Integer id;

@Column(nullable = false)
@NaturalId
private String googleId;

@Column(nullable = false)
Expand Down
Loading

0 comments on commit 256e3cf

Please sign in to comment.