diff --git a/server/app/build.gradle.kts b/server/app/build.gradle.kts index fce88e2d9..4c0a30863 100644 --- a/server/app/build.gradle.kts +++ b/server/app/build.gradle.kts @@ -16,6 +16,7 @@ dependencies { // INTERNAL implementation(project(":server:core")) implementation(project(":server:persistence:memory")) + implementation(project(":server:persistence:jdbc")) // QUARKUS implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")) diff --git a/server/core/build.gradle.kts b/server/core/build.gradle.kts index 5eb68dbe3..fbcde1cd2 100644 --- a/server/core/build.gradle.kts +++ b/server/core/build.gradle.kts @@ -48,6 +48,7 @@ dependencies { testImplementation("io.quarkus:quarkus-arc") testImplementation(String.format("org.hamcrest:hamcrest:%s", hamcrestVersion)) testImplementation(project(":server:persistence:memory")) + testImplementation(project(":server:persistence:jdbc")) } // endregion diff --git a/server/core/src/main/java/io/whitefox/core/services/ShareService.java b/server/core/src/main/java/io/whitefox/core/services/ShareService.java index a535dfbd4..5bad6c8d2 100644 --- a/server/core/src/main/java/io/whitefox/core/services/ShareService.java +++ b/server/core/src/main/java/io/whitefox/core/services/ShareService.java @@ -5,6 +5,7 @@ import io.whitefox.core.services.exceptions.*; import io.whitefox.persistence.StorageManager; import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; import java.time.Clock; import java.util.Collections; import java.util.List; @@ -22,6 +23,7 @@ public class ShareService { private final Clock clock; + @Inject public ShareService(StorageManager storageManager, ProviderService providerService, Clock clock) { this.storageManager = storageManager; this.providerService = providerService; diff --git a/server/persistence/jdbc/build.gradle.kts b/server/persistence/jdbc/build.gradle.kts new file mode 100644 index 000000000..59a176f5a --- /dev/null +++ b/server/persistence/jdbc/build.gradle.kts @@ -0,0 +1,41 @@ +plugins { + `java-library` + id("whitefox.java-conventions") +} + +val quarkusPlatformGroupId: String by project +val quarkusPlatformArtifactId: String by project +val quarkusPlatformVersion: String by project + +repositories { + mavenCentral() +} + +dependencies { + implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")) + + implementation("io.quarkus:quarkus-jdbc-postgresql") + implementation("io.quarkus:quarkus-hibernate-orm-panache") + + + // QUARKUS + compileOnly("jakarta.enterprise:jakarta.enterprise.cdi-api") + compileOnly("jakarta.ws.rs:jakarta.ws.rs-api") + compileOnly("org.eclipse.microprofile.config:microprofile-config-api") + + compileOnly(project(":server:core")) + + // TEST + testImplementation("io.quarkus:quarkus-junit5") + testImplementation("io.quarkus:quarkus-arc") +} + + +tasks.withType { + options.encoding = "UTF-8" + options.compilerArgs.add("-parameters") +} + +tasks.test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/server/persistence/jdbc/src/main/java/JdbcStorageManager.java b/server/persistence/jdbc/src/main/java/JdbcStorageManager.java new file mode 100644 index 000000000..f2ca23963 --- /dev/null +++ b/server/persistence/jdbc/src/main/java/JdbcStorageManager.java @@ -0,0 +1,118 @@ +import io.whitefox.core.*; +import io.whitefox.persistence.StorageManager; +import io.whitefox.persistence.exceptions.InvalidPageTokenException; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.transaction.Transactional; +import mapper.ShareMapper; +import repository.ShareRepository; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@Transactional +@ApplicationScoped +public class JdbcStorageManager implements StorageManager { + + @Inject + ShareRepository shareRepository; + + @Inject + public JdbcStorageManager(){ + this.shareRepository = new ShareRepository(); + } + + @Override + public Optional getShare(String share) { + return Optional.empty(); + } + + @Override + public ResultAndTotalSize> getShares(int offset, int maxResultSize) { + + List shares = shareRepository.listAll().stream() + .map(ShareMapper::shareDaoToShare) + .collect(Collectors.toList()); + var totalSize = shares.size(); + if (offset > totalSize) { + throw new InvalidPageTokenException( + String.format("Invalid Next Page Token: token %s is larger than totalSize", offset)); + } else { + return new ResultAndTotalSize<>( + shares.stream().skip(offset).limit(maxResultSize).collect(Collectors.toList()), + totalSize); + } + } + + @Override + public Optional getSharedTable(String share, String schema, String table) { + return Optional.empty(); + } + + @Override + public Optional>> listSchemas(String share, int offset, int maxResultSize) { + return Optional.empty(); + } + + @Override + public Optional>> listTables(String share, String schema, int offset, int maxResultSize) { + return Optional.empty(); + } + + @Override + public Optional>> listTablesOfShare(String share, int offset, int finalMaxResults) { + return Optional.empty(); + } + + @Override + public Metastore createMetastore(Metastore metastore) { + return null; + } + + @Override + public Optional getMetastore(String name) { + return Optional.empty(); + } + + @Override + public Storage createStorage(Storage storage) { + return null; + } + + @Override + public Optional getStorage(String name) { + return Optional.empty(); + } + + @Override + public Provider createProvider(Provider provider) { + return null; + } + + @Override + public Optional getProvider(String name) { + return Optional.empty(); + } + + @Override + public InternalTable createInternalTable(InternalTable internalTable) { + return null; + } + + @Override + public Share createShare(Share share) { + shareRepository.persist(ShareMapper.shareToShareDao(share)); + return share; + } + + @Override + public Share updateShare(Share newShare) { + return null; + } + + @Override + public Share addTableToSchema(Share shareObj, Schema schemaObj, Provider providerObj, InternalTable table, SharedTableName sharedTableName, Principal currentUser, long millis) { + return null; + } +} diff --git a/server/persistence/jdbc/src/main/java/mapper/ShareMapper.java b/server/persistence/jdbc/src/main/java/mapper/ShareMapper.java new file mode 100644 index 000000000..b703d4400 --- /dev/null +++ b/server/persistence/jdbc/src/main/java/mapper/ShareMapper.java @@ -0,0 +1,39 @@ +package mapper; + +import io.whitefox.core.Principal; +import io.whitefox.core.Schema; +import io.whitefox.core.Share; +import jakarta.inject.Singleton; +import model.ShareDao; + +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +@Singleton +public class ShareMapper { + + public static Share shareDaoToShare(ShareDao shareDao){ + String id = shareDao.getId(); + String name = shareDao.getName(); + Optional comment = shareDao.getComment(); + Map schemas = Map.of(); + Set recipients = Set.of(); + Long createdAt = shareDao.getCreatedAt(); + Principal principal = new Principal(shareDao.getCreatedBy()); + Long updatedAt = shareDao.getUpdatedAt(); + return new Share(name, id, schemas, comment, recipients, createdAt, principal, updatedAt, principal, principal ); + } + + public static ShareDao shareToShareDao(Share share){ + String id = share.id(); + String name = share.name(); + String comment = share.comment().orElse(""); + Long createdAt = share.createdAt(); + String createdBy = share.createdBy().name(); + Long updatedAt = share.updatedAt(); + String updatedBy = share.updatedBy().name(); + String owner = share.owner().name(); + return new ShareDao(id, name, comment, createdAt, createdBy, updatedAt, updatedBy, owner); + } +} diff --git a/server/persistence/jdbc/src/main/java/model/ShareDao.java b/server/persistence/jdbc/src/main/java/model/ShareDao.java new file mode 100644 index 000000000..7f6a4392b --- /dev/null +++ b/server/persistence/jdbc/src/main/java/model/ShareDao.java @@ -0,0 +1,103 @@ +package model; + +import jakarta.persistence.*; + +import java.util.Optional; +@Entity +@Table(name = "share") +public class ShareDao { + + @Id + private String id; + private String name; + + private String comment; + //todo make these fields +// private Map schema; +// private Set recipients; + private Long createdAt; + + private String createdBy; + private Long updatedAt; + + private String updatedBy; + + private String owner; + + public ShareDao() { + } + + public ShareDao(String id, String name, String comment, Long createdAt, String createdBy, Long updatedAt, String updatedBy, String owner) { + this.id = id; + this.name = name; + this.comment = comment; + this.createdAt = createdAt; + this.createdBy = createdBy; + this.updatedAt = updatedAt; + this.updatedBy = updatedBy; + this.owner = owner; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public Optional getComment(){ + return Optional.ofNullable(this.comment); + } + public void setComment(String comment){ + this.comment = comment; + } + + public void setName(String name) { + this.name = name; + } + + public Long getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Long createdAt) { + this.createdAt = createdAt; + } + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + public Long getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Long updatedAt) { + this.updatedAt = updatedAt; + } + + public String getUpdatedBy() { + return updatedBy; + } + + public void setUpdatedBy(String updatedBy) { + this.updatedBy = updatedBy; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } +} diff --git a/server/persistence/jdbc/src/main/java/repository/ShareRepository.java b/server/persistence/jdbc/src/main/java/repository/ShareRepository.java new file mode 100644 index 000000000..81a40b181 --- /dev/null +++ b/server/persistence/jdbc/src/main/java/repository/ShareRepository.java @@ -0,0 +1,14 @@ +package repository; + +import io.quarkus.hibernate.orm.panache.PanacheRepositoryBase; +import jakarta.enterprise.context.ApplicationScoped; +import model.ShareDao; + +@ApplicationScoped +public class ShareRepository implements PanacheRepositoryBase { + + @Override + public void persist(ShareDao shareDao) { + PanacheRepositoryBase.super.persist(shareDao); + } +} diff --git a/server/persistence/jdbc/src/main/resources/META-INF/beans.xml b/server/persistence/jdbc/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..e69de29bb diff --git a/server/persistence/jdbc/src/main/resources/application.properties b/server/persistence/jdbc/src/main/resources/application.properties new file mode 100644 index 000000000..eafe62645 --- /dev/null +++ b/server/persistence/jdbc/src/main/resources/application.properties @@ -0,0 +1,6 @@ +quarkus.datasource.db-kind=postgresql +quarkus.datasource.username=postgres +quarkus.datasource.password=postgres +quarkus.datasource.reactive.url=jdbc:postgresql://localhost:5432/postgres +quarkus.hibernate-orm.database.generation=drop-and-create +quarkus.hibernate-orm.active=true \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 1493a22eb..733a48e9b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,6 +5,7 @@ include("server:persistence:memory") include("server:app") include("docsite") include("client-spark") +include("server:persistence:jdbc") pluginManagement { val quarkusPluginVersion: String by settings