Skip to content

Commit

Permalink
Storing Parent Entity Id's in All Child Entities (unitycatalog#38)
Browse files Browse the repository at this point in the history
* Storing Parent Id's instead of names in all child entities.
* This keeps parent child relationships consistent on parent entity name
updates.
* Added test cases to test out similar scenarios.
* Move all validation (entity not found, entity already existing) under
a single transaction.

### Testing
Ran All Tests by running `build/sbt clean test` and they succeed.
  • Loading branch information
ravivj-db authored Jun 15, 2024
1 parent 35daabc commit af5c342
Show file tree
Hide file tree
Showing 25 changed files with 937 additions and 743 deletions.
Binary file modified etc/db/h2db.mv.db
Binary file not shown.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package io.unitycatalog.server.persist;

import io.unitycatalog.server.exception.BaseException;
import io.unitycatalog.server.exception.ErrorCode;
import io.unitycatalog.server.model.CatalogInfo;
import io.unitycatalog.server.model.ListCatalogsResponse;
import io.unitycatalog.server.persist.dao.CatalogInfoDAO;
import io.unitycatalog.server.utils.ValidationUtils;
import lombok.Getter;
import org.hibernate.query.Query;
import io.unitycatalog.server.model.CreateCatalog;
import io.unitycatalog.server.model.UpdateCatalog;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.stream.Collectors;

public class CatalogRepository {
@Getter
private static final CatalogRepository instance = new CatalogRepository();
private static final Logger LOGGER = LoggerFactory.getLogger(CatalogRepository.class);
private static final SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
private CatalogRepository() {}

public CatalogInfo addCatalog(CreateCatalog createCatalog) {
ValidationUtils.validateSqlObjectName(createCatalog.getName());
CatalogInfoDAO catalogInfo = new CatalogInfoDAO();
catalogInfo.setId(java.util.UUID.randomUUID());
catalogInfo.setName(createCatalog.getName());
catalogInfo.setComment(createCatalog.getComment());
catalogInfo.setCreatedAt(new Date());

try (Session session = sessionFactory.openSession()) {
Transaction tx = session.beginTransaction();
try {
if (getCatalogDAO(session, createCatalog.getName()) != null) {
throw new BaseException(ErrorCode.ALREADY_EXISTS,
"Catalog already exists: " + createCatalog.getName());
}
session.persist(catalogInfo);
tx.commit();
System.out.println("Added catalog: " + catalogInfo.getName());
return CatalogInfoDAO.toCatalogInfo(catalogInfo);
} catch (Exception e) {
tx.rollback();
throw e;
}
}
}

public ListCatalogsResponse listCatalogs() {
ListCatalogsResponse response = new ListCatalogsResponse();
try (Session session = sessionFactory.openSession()) {
session.setDefaultReadOnly(true);
Transaction tx = session.beginTransaction();
try {
response.setCatalogs(session
.createQuery("from CatalogInfoDAO ", CatalogInfoDAO.class).list()
.stream().map(CatalogInfoDAO::toCatalogInfo).collect(Collectors.toList()));
tx.commit();
} catch (Exception e) {
tx.rollback();
throw e;
}
return response;
}
}

public CatalogInfo getCatalog(String name) {
try (Session session = sessionFactory.openSession()) {
session.setDefaultReadOnly(true);
Transaction tx = session.beginTransaction();
CatalogInfoDAO catalogInfo = null;
try {
catalogInfo = getCatalogDAO(session, name);
tx.commit();
} catch (Exception e) {
tx.rollback();
throw e;
}
if (catalogInfo == null) {
throw new BaseException(ErrorCode.NOT_FOUND, "Catalog not found: " + name);
}
return CatalogInfoDAO.
toCatalogInfo(getCatalogDAO(session, name));
}
}

public CatalogInfoDAO getCatalogDAO(Session session, String name) {
Query<CatalogInfoDAO> query = session
.createQuery("FROM CatalogInfoDAO WHERE name = :value", CatalogInfoDAO.class);
query.setParameter("value", name);
query.setMaxResults(1);
return query.uniqueResult();
}

public CatalogInfo updateCatalog(String name, UpdateCatalog updateCatalog) {
ValidationUtils.validateSqlObjectName(updateCatalog.getNewName());
// cna make this just update once we have an identifier that is not the name
try (Session session = sessionFactory.openSession()) {
Transaction tx = session.beginTransaction();
try {
CatalogInfoDAO catalogInfo = getCatalogDAO(session, name);
if (catalogInfo == null) {
throw new BaseException(ErrorCode.NOT_FOUND, "Catalog not found: " + name);
}
if (getCatalogDAO(session, updateCatalog.getNewName()) != null) {
throw new BaseException(ErrorCode.ALREADY_EXISTS,
"Catalog already exists: " + updateCatalog.getNewName());
}
catalogInfo.setName(updateCatalog.getNewName());
catalogInfo.setComment(updateCatalog.getComment());
catalogInfo.setUpdatedAt(new Date());
session.merge(catalogInfo);
tx.commit();
return CatalogInfoDAO.toCatalogInfo(catalogInfo);
} catch (Exception e) {
tx.rollback();
throw e;
}
}
}

public void deleteCatalog(String name) {
try (Session session = sessionFactory.openSession()) {
Transaction tx = session.beginTransaction();
try {
CatalogInfoDAO catalogInfo = getCatalogDAO(session, name);
if (catalogInfo != null) {
session.remove(catalogInfo);
tx.commit();
LOGGER.info("Deleted catalog: {}", catalogInfo.getName());
} else {
throw new BaseException(ErrorCode.NOT_FOUND, "Catalog not found: " + name);
}
} catch (Exception e) {
tx.rollback();
throw e;
}
}
}
}
Loading

0 comments on commit af5c342

Please sign in to comment.