diff --git a/persistence-modules/java-harperdb/pom.xml b/persistence-modules/java-harperdb/pom.xml
new file mode 100644
index 0000000000..896a58f858
--- /dev/null
+++ b/persistence-modules/java-harperdb/pom.xml
@@ -0,0 +1,61 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ java-harperdb
+ 1.0-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 9
+
+
+
+
+
+
+ com.baeldung
+ persistence-modules
+ 1.0.0-SNAPSHOT
+
+
+
+ com.baeldung
+ java-harperdb
+ 4.2
+ system
+ ${project.basedir}/lib/cdata.jdbc.harperdb.jar
+
+
+ org.testcontainers
+ testcontainers
+ test
+
+
+
+
+
+
+ org.testcontainers
+ testcontainers-bom
+ 1.19.3
+ pom
+ import
+
+
+
+
+
+ 19
+ 19
+ UTF-8
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/java-harperdb/src/main/resources/data-model.puml b/persistence-modules/java-harperdb/src/main/resources/data-model.puml
new file mode 100644
index 0000000000..8e3681c749
--- /dev/null
+++ b/persistence-modules/java-harperdb/src/main/resources/data-model.puml
@@ -0,0 +1,41 @@
+@startuml
+'https://gist.github.com/QuantumGhost/0955a45383a0b6c0bc24f9654b3cb561
+' uncomment the line below if you're using computer with a retina display
+' skinparam dpi 300
+!theme sketchy-outline
+!define Table(name,desc) class name as "desc" << (T, #63b175) >>
+' we use bold for primary key
+' green color for unique
+' and underscore for not_null
+!define primary_key(x) x
+!define unique(x) x
+!define not_null(x) x
+' other tags available:
+'
+' , where color is a color name or html color code
+' (#FFAACC)
+' see: http://plantuml.com/classes.html#More
+hide methods
+hide stereotypes
+
+' entities
+
+
+Table(Teacher, "Teacher") {
+ primary_key(Id) Number
+ Name Varchar
+ joining_date Date
+}
+Table(Subject, "Subject") {
+ primary_key(Id) Number
+ Name Varchar
+}
+Table(Teacher_Details, "Teacher_Details") {
+ primary_key(Id) Number
+ teacher_id Number
+ subject_id Number
+}
+
+Teacher_Details "*" -left-> "1" Subject: " "
+Teacher "1" -left-> "*" Teacher_Details: " "
+@enduml
\ No newline at end of file
diff --git a/persistence-modules/java-harperdb/src/test/java/com/baledung/harperdb/HarperDBApiService.java b/persistence-modules/java-harperdb/src/test/java/com/baledung/harperdb/HarperDBApiService.java
new file mode 100644
index 0000000000..1eedd8648f
--- /dev/null
+++ b/persistence-modules/java-harperdb/src/test/java/com/baledung/harperdb/HarperDBApiService.java
@@ -0,0 +1,74 @@
+package com.baledung.harperdb;
+
+import com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.classic.methods.HttpPost;
+import com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+import com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.ClassicHttpRequest;
+import com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.HttpEntity;
+import com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io.entity.StringEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Base64;
+
+public class HarperDBApiService {
+ private String url;
+ private String base64auth;
+
+ public HarperDBApiService(String url, String user, String password) {
+ this.url = url;
+ this.base64auth = Base64.getEncoder()
+ .encodeToString(new StringBuilder().append(user).append(":").append(password).toString().getBytes());
+ }
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(HarperDBApiService.class);
+
+ public void createSchema(String schema) throws IOException {
+ String requestBody = "{\"operation\":\"create_schema\", \"" + "schema\":\"" + schema + "\"" + "}";
+ executeHttpPostRequest(requestBody);
+ }
+
+ public void createTable(String schema, String table, String ... attributes) throws IOException {
+ String createTableReq = "{\"operation\":\"create_table\","
+ + "\"schema\":\"" + schema
+ + "\",\"table\":\"" + table
+ + "\",\"hash_attribute\":\"id\""
+ + "}";
+ executeHttpPostRequest(createTableReq);
+ LOGGER.info("created table:" + table);
+ for (String attribute : attributes) {
+ String createAttrReq = "{\"operation\":\"create_attribute\",\"schema\":\""
+ + schema + "\",\"table\":\""
+ + table + "\",\"attribute\":\""
+ + attribute + "\""
+ + "}";
+ executeHttpPostRequest(createAttrReq);
+ LOGGER.info("created attribute:" + attribute + " in table:" + table);
+ }
+ }
+
+ public void insertRecords(String schema, String table, String records) throws IOException {
+ String requestBody = "{\"table\":" + "\"" + table + "\","
+ + "\"schema\":" + "\"" + schema + "\"" + ","
+ + "\"operation\":" + "\"" + "insert" + "\"" + ","
+ + "\"records\":" + records
+ + "}";
+ executeHttpPostRequest(requestBody);
+ }
+
+ private void executeHttpPostRequest(String httpRequest) throws IOException {
+ LOGGER.info("Post request body:" + httpRequest);
+
+ try (CloseableHttpClient closeableHttpClient = HttpClientBuilder.create().build()) {
+ HttpPost request = new HttpPost(this.url);
+ request.addHeader("Authorization", "Basic " + this.base64auth);
+ request.addHeader("Content-Type", "application/json");
+ request.setEntity((HttpEntity) new StringEntity(httpRequest));
+ CloseableHttpResponse response = closeableHttpClient.execute((ClassicHttpRequest) request);
+ LOGGER.info("REST API response:" + response.toString());
+ assert(200 == response.getCode());
+ }
+ }
+}
diff --git a/persistence-modules/java-harperdb/src/test/java/com/baledung/harperdb/HarperDBContainer.java b/persistence-modules/java-harperdb/src/test/java/com/baledung/harperdb/HarperDBContainer.java
new file mode 100644
index 0000000000..79656b1b73
--- /dev/null
+++ b/persistence-modules/java-harperdb/src/test/java/com/baledung/harperdb/HarperDBContainer.java
@@ -0,0 +1,42 @@
+package com.baledung.harperdb;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.GenericContainer;
+
+import java.util.Map;
+
+public class HarperDBContainer {
+ private final static Logger LOGGER = LoggerFactory.getLogger(HarperDBContainer.class);
+
+
+
+ private static final Map DEFAULT_ENV_MAP = Map.of(
+ "HDB_ADMIN_USERNAME", "admin",
+ "HDB_ADMIN_PASSWORD", "password",
+ "OPERATIONSAPI_NETWORK_PORT", "9925",
+ "ROOTPATH", "/home/harperdb/hdb",
+ "LOGGING_STDSTREAMS", "true"
+ );
+
+ private static final Integer[] DEFAULT_EXPOSED_PORTS = {9925, 9926};
+
+ private static final String HARPER_DOCKER_IMAGE = "harperdb/harperdb:latest";
+
+ public void stop() {
+ harperDBContainer.stop();
+ }
+ GenericContainer harperDBContainer;
+ public GenericContainer installHarperDB() {
+ harperDBContainer = new GenericContainer(HARPER_DOCKER_IMAGE)
+ .withEnv(DEFAULT_ENV_MAP)
+ .withExposedPorts(DEFAULT_EXPOSED_PORTS);
+ return harperDBContainer;
+ }
+
+ public GenericContainer installHarperDB(String dockerImgage, final Map envMap, final Integer ... exposedPorts) {
+ return new GenericContainer(dockerImgage)
+ .withEnv(envMap)
+ .withExposedPorts(exposedPorts);
+ }
+}
diff --git a/persistence-modules/java-harperdb/src/test/java/com/baledung/harperdb/HarperDBLiveTest.java b/persistence-modules/java-harperdb/src/test/java/com/baledung/harperdb/HarperDBLiveTest.java
new file mode 100644
index 0000000000..767d9d971b
--- /dev/null
+++ b/persistence-modules/java-harperdb/src/test/java/com/baledung/harperdb/HarperDBLiveTest.java
@@ -0,0 +1,336 @@
+package com.baledung.harperdb;
+
+import cdata.jdbc.harperdb.HarperDBConnectionPoolDataSource;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.GenericContainer;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.sql.*;
+import java.util.Properties;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class HarperDBLiveTest {
+ private static final Logger logger = LoggerFactory.getLogger(HarperDBLiveTest.class);
+
+ private static String host;
+
+ private static Integer port;
+
+ private static HarperDBContainer harperDBContainer;
+ private static HarperDBApiService harperDbApiService;
+
+ @BeforeAll
+ static void setupHarperDB() throws IOException, InterruptedException, URISyntaxException {
+ installHarperDB();
+ initHarperDBApiService();
+ setupDB();
+ }
+
+ private static void installHarperDB() {
+ harperDBContainer = new HarperDBContainer();
+
+ GenericContainer genericContainer = harperDBContainer.installHarperDB();
+
+ host = genericContainer.getHost();
+ genericContainer.start();
+
+ port = genericContainer.getFirstMappedPort();
+ }
+
+ private static void initHarperDBApiService() {
+ String url = "http://localhost:" + port + "/";
+ harperDbApiService = new HarperDBApiService(url, "admin", "password");
+ }
+
+ private static void setupDB() throws URISyntaxException, IOException {
+ harperDbApiService.createSchema("Demo");
+
+ harperDbApiService.createTable("Demo", "Subject", "name");
+ harperDbApiService.createTable("Demo", "Teacher", "name", "joining_date", "subject_id");
+ harperDbApiService.createTable("Demo", "Teacher_Details", "teacher_id", "subject_id");
+
+ insertSubjectRecords();
+ insertTeacherRecords();
+ insertTeacherDetailsRecords();
+ }
+
+ private static void insertSubjectRecords() throws IOException {
+ String records = "["
+ + "{\"id\":1, \"name\":\"English\"},"
+ + "{\"id\":2, \"name\":\"Maths\"},"
+ + "{\"id\":3, \"name\":\"Science\"}"
+ + "]";
+
+ harperDbApiService.insertRecords("Demo", "Subject", records);
+ }
+
+ private static void insertTeacherRecords() throws IOException {
+ String records = "[" +
+ "{\"id\":1, \"name\":\"Parthiv Pradhan\", \"joining_date\":\"04-05-2000\"},"
+ + "{\"id\":2, \"name\":\"David Martinez\", \"joining_date\":\"20-10-2005\"},"
+ + "{\"id\":3, \"name\":\"Liam Williams\", \"joining_date\":\"04-06-1997\"},"
+ + "{\"id\":4, \"name\":\"Robin Williams\", \"joining_date\":\"01-01-2020\"},"
+ + "{\"id\":5, \"name\":\"Eric Martin\", \"joining_date\":\"04-05-2022\"},"
+ + "{\"id\":6, \"name\":\"Sajjan Nagendra\", \"joining_date\":\"02-02-1999\"}"
+ + "]";
+ harperDbApiService.insertRecords("Demo", "Teacher", records);
+ }
+
+ private static void insertTeacherDetailsRecords() throws IOException {
+ String records = "["
+ + "{\"id\":1, \"teacher_id\":1, \"subject_id\":1},"
+ + "{\"id\":2, \"teacher_id\":1, \"subject_id\":2},"
+ + "{\"id\":3, \"teacher_id\":2, \"subject_id\":3 },"
+ + "{\"id\":4, \"teacher_id\":3, \"subject_id\":1},"
+ + "{\"id\":5, \"teacher_id\":3, \"subject_id\":3},"
+ + "{\"id\":6, \"teacher_id\":4, \"subject_id\":2},"
+ + "{\"id\":7, \"teacher_id\":5, \"subject_id\":3},"
+ + "{\"id\":8, \"teacher_id\":6, \"subject_id\":1},"
+ + "{\"id\":9, \"teacher_id\":6, \"subject_id\":2},"
+ + "{\"id\":15, \"teacher_id\":6, \"subject_id\":3}"
+ + "]";
+
+ harperDbApiService.insertRecords("Demo", "Teacher_Details", records);
+ }
+
+ @AfterAll
+ static void stopHarperDB() {
+ harperDBContainer.stop();
+ }
+
+ @Test
+ void whenConnectionInfoInURL_thenConnectSuccess() throws SQLException {
+ assertDoesNotThrow(() -> {
+ final String JDBC_URL = "jdbc:harperdb:Server=127.0.0.1:" + port + ";User=admin;Password=password;";
+
+ try (Connection connection = DriverManager.getConnection(JDBC_URL)) {
+ connection.createStatement().executeQuery("select 1");
+ logger.info("Connection Successful");
+ }
+ });
+ }
+
+ @Test
+ void whenConnectionInfoInProperties_thenConnectSuccess() throws SQLException {
+ assertDoesNotThrow(() -> {
+ Properties prop = new Properties();
+ prop.setProperty("Server", "127.0.0.1:" + port);
+ prop.setProperty("User", "admin");
+ prop.setProperty("Password", "password");
+
+ try (Connection connection = DriverManager.getConnection("jdbc:harperdb:", prop)) {
+ connection.createStatement().executeQuery("select 1");
+ logger.info("Connection Successful");
+ }
+ });
+ }
+
+ @Test
+ void whenConnectionPooling_thenConnectSuccess() throws SQLException {
+ assertDoesNotThrow(() -> {
+ HarperDBConnectionPoolDataSource harperdbPoolDataSource = new HarperDBConnectionPoolDataSource();
+ final String JDBC_URL = "jdbc:harperdb:UseConnectionPooling=true;PoolMaxSize=2;Server=127.0.0.1:" + port
+ + ";User=admin;Password=password;";
+ harperdbPoolDataSource.setURL(JDBC_URL);
+
+ try(Connection connection = harperdbPoolDataSource.getPooledConnection().getConnection()) {
+ connection.createStatement().executeQuery("select 1");
+ logger.info("Connection Pool Successful");
+ }
+ });
+ }
+
+ private static Connection getConnection() throws SQLException {
+ String URL = "jdbc:harperdb:Server=127.0.0.1:" + port + ";User=admin;Password=password;";
+ return DriverManager.getConnection(URL);
+ }
+
+ @Test
+ void givenStatement_whenFetchRecord_thenSuccess() throws SQLException {
+ final String SQL_QUERY = "select id, name, grade from Demo.student";
+
+ try(Connection connection = getConnection()) {
+ Statement statement = connection.createStatement();
+ ResultSet resultSet = statement.executeQuery(SQL_QUERY);
+ while (resultSet.next()) {
+ int id = resultSet.getInt("id");
+ String name = resultSet.getString("name");
+ int grade = resultSet.getInt("grade");
+ assertNotNull(Integer.valueOf(id));
+ logger.info("Student id:" + id + " Student Name:" + name + " grade:" + grade);
+ }
+ }
+ }
+
+ @Test
+ void givenStatement_whenInsertRecord_thenSuccess() throws SQLException {
+ final String INSERT_SQL = "insert into Demo.student(id, name, grade) values (10, 'Barak', 3)";
+
+ try(Connection connection = getConnection()) {
+ Statement statement = connection.createStatement();
+ assertDoesNotThrow(() -> statement.execute(INSERT_SQL));
+ }
+ }
+
+ @Test
+ void givenStatement_whenInsertRecordInTableWithoutAttributes_thenSuccess() throws SQLException {
+ final String INSERT_SQL = "insert into Demo.teacher(id, name, joining_date) "
+ + "values (7, 'David Sirocco', '04-05-2004'), (8, 'Ali Azmat', '04-10-2000')";
+ final String QUERY_SQL = "select name, joining_date from Demo.teacher where name = ?";
+
+ try(Connection connection = getConnection()) {
+ Statement statement = connection.createStatement();
+ assertDoesNotThrow(() -> statement.execute(INSERT_SQL));
+ PreparedStatement preparedStatement = connection.prepareStatement(QUERY_SQL);
+ preparedStatement.setString(1, "David Sirocco");
+ ResultSet resultSet = preparedStatement.executeQuery();
+ while (resultSet.next()) {
+ String teacherName = resultSet.getString("name");
+ String joinDate = resultSet.getString("joining_date");
+ assertEquals("David Sirocco", teacherName);
+ assertEquals("04-05-2004", joinDate);
+ logger.info("name:" + teacherName + " joining date:" + joinDate);
+ }
+ }
+ }
+
+ @Test
+ void givenStatement_whenUpdateRecord_thenSuccess() throws SQLException {
+ final String UPDATE_SQL = "update Demo.student set grade = 4 where id = 5";
+
+ try(Connection connection = getConnection()) {
+ Statement statement = connection.createStatement();
+ assertDoesNotThrow(() -> statement.execute(UPDATE_SQL));
+ assertEquals(1, statement.getUpdateCount());
+ }
+ }
+
+ @Test
+ void givenStatement_whenDeleteRecord_thenSuccess() throws SQLException {
+ final String DELETE_SQL = "delete from Demo.student where id = 3";
+
+ try(Connection connection = getConnection()) {
+ Statement statement = connection.createStatement();
+ assertDoesNotThrow(() -> statement.execute(DELETE_SQL));
+ assertEquals(1, statement.getUpdateCount());
+ }
+ }
+
+ @Test
+ void givenPreparedStatement_whenFetchRecord_thenSuccess() throws SQLException {
+ final String SQL_QUERY = "select id, name, grade from Demo.student where name = ? and grade = ?";
+
+ try(Connection connection = getConnection()) {
+ PreparedStatement preparedStatement = connection.prepareStatement(SQL_QUERY);
+ preparedStatement.setString(1, "Robin");
+ preparedStatement.setInt(2, 4);
+ ResultSet resultSet = preparedStatement.executeQuery();
+ while (resultSet.next()) {
+ int id = resultSet.getInt("id");
+ String name = resultSet.getString("name");
+ int grade = resultSet.getInt("grade");
+ assertNotNull(Integer.valueOf(id));
+ assertEquals("Robin", name);
+ logger.info("Student id:" + id + " Student Name:" + name + " grade:" + grade);
+ }
+ }
+ }
+
+ @Test
+ void givenPreparedStatement_whenDeleteRecord_thenSuccess() throws SQLException {
+ final String DELETE_SQL = "delete from Demo.student where name = ?";
+
+ try(Connection connection = getConnection()) {
+ PreparedStatement preparedStatement = connection.prepareStatement(DELETE_SQL);
+ preparedStatement.setString(1, "James");
+ assertDoesNotThrow(() -> preparedStatement.execute());
+ assertEquals(1, preparedStatement.getUpdateCount());
+ }
+ }
+
+ @Test
+ void givenPreparedStatement_whenUpdateRecord_thenSuccess() throws SQLException {
+ final String UPDATE_SQL = "update Demo.student set grade = ? where id = ? and name = ?";
+
+ try(Connection connection = getConnection()) {
+ PreparedStatement preparedStatement = connection.prepareStatement(UPDATE_SQL);
+ preparedStatement.setInt(1, 5);
+ preparedStatement.setInt(2, 1);
+ preparedStatement.setString(3, "John");
+ assertDoesNotThrow(() -> preparedStatement.execute());
+ assertEquals(1, preparedStatement.getUpdateCount());
+ }
+ }
+
+ //@Test
+ void whenAddtoBatch_thenExecuteBatchIsSuccess() throws SQLException {
+ final String INSERT_SQL = "insert into Demo.teacher(id, name, joining_date, subject_id)"
+ + "values(?, ?, ?, ?)";
+
+ try(Connection connection = getConnection()) {
+ PreparedStatement preparedStatement = connection.prepareStatement(INSERT_SQL);
+ preparedStatement.setInt(1, 9);
+ preparedStatement.setString(2, "Bret Lee");
+ preparedStatement.setString(3, "07-08-2002");
+ preparedStatement.setString(4, "[1, 3]");
+ preparedStatement.addBatch();
+
+ preparedStatement.setInt(1, 10);
+ preparedStatement.setString(2, "Sarah Glimmer");
+ preparedStatement.setString(3, "07-08-1997");
+ preparedStatement.setString(4, "[1, 2]");
+
+ preparedStatement.addBatch();
+
+ assertDoesNotThrow(() -> preparedStatement.executeBatch());
+ }
+ }
+
+
+ @Test
+ void whenExecuteJoinQuery_thenResultSuccess() throws SQLException {
+ final String JOIN_QUERY = "SELECT t.name as teacher_name, s.name as subject_name " +
+ "from Demo.teacher AS t INNER JOIN Demo.subject AS s ON t.subject_id = s.id";
+
+ try(Connection connection = getConnection()) {
+ Statement statement = connection.createStatement();
+
+
+ ResultSet resultSet = statement.executeQuery(JOIN_QUERY);
+ while (resultSet.next()) {
+ logger.info("Teacher Name:" + resultSet.getString("teacher_name") + " Subject Name:"
+ + resultSet.getString("subject_name"));
+ }
+
+
+ }
+
+ }
+
+ @Test
+ void whenExecuteStoredToCreateTable_thenSuccess() throws SQLException {
+ final String CREATE_TABLE_SQL = "CreateTable";
+ try(Connection connection = getConnection()) {
+ CallableStatement callableStatement = connection.prepareCall(CREATE_TABLE_SQL);
+
+ callableStatement.setString("SchemaName", "prod"); //schema gets created too
+ callableStatement.setString("TableName", "subject");
+ callableStatement.setString("PrimaryKey", "id");
+ Boolean result = callableStatement.execute();
+
+ ResultSet resultSet = callableStatement.getResultSet();
+
+ while(resultSet.next()) {
+ String tableCreated = resultSet.getString("Success");
+ assertEquals("true", tableCreated);
+ logger.info("result of the callable execute:" + tableCreated);
+ }
+ }
+ }
+}
diff --git a/persistence-modules/java-harperdb/src/test/java/com/baledung/harperdb/HarperDBLiveTestOld.java b/persistence-modules/java-harperdb/src/test/java/com/baledung/harperdb/HarperDBLiveTestOld.java
new file mode 100644
index 0000000000..8becea76a5
--- /dev/null
+++ b/persistence-modules/java-harperdb/src/test/java/com/baledung/harperdb/HarperDBLiveTestOld.java
@@ -0,0 +1,356 @@
+package com.baledung.harperdb;
+
+import cdata.jdbc.harperdb.HarperDBConnectionPoolDataSource;
+import com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.classic.methods.HttpPost;
+import com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+import com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.ClassicHttpRequest;
+import com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.HttpEntity;
+import com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io.entity.StringEntity;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.GenericContainer;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class HarperDBLiveTestOld {
+ private static final Logger logger = LoggerFactory.getLogger(HarperDBLiveTestOld.class);
+
+ private static String host;
+
+ private static Integer port;
+
+ private static GenericContainer harperDBContainer;
+
+ @BeforeAll
+ static void setupHarperDB() throws IOException, InterruptedException, URISyntaxException {
+ installHarperDB();
+ setupDB();
+ }
+
+ private static void installHarperDB() {
+ Map envMap = Map.of(
+ "HDB_ADMIN_USERNAME", "admin",
+ "HDB_ADMIN_PASSWORD", "password",
+ "OPERATIONSAPI_NETWORK_PORT", "9925",
+ "ROOTPATH", "/home/harperdb/hdb",
+ "LOGGING_STDSTREAMS", "true"
+ );
+
+ harperDBContainer = new GenericContainer("harperdb/harperdb:latest")
+ .withEnv(envMap)
+ .withExposedPorts(9925, 9926);
+ host = harperDBContainer.getHost();
+ harperDBContainer.start();
+ port = harperDBContainer.getFirstMappedPort();
+ logger.info("DB Host:" + host + "\n DB Port:" + port);
+ }
+
+ private static void setupDB() throws URISyntaxException, IOException {
+ setupSchema("demo");
+ createTable("demo", "student", "name", "grade", "subject_id");
+ createTable("demo", "teacher", "name", "joining_date", "subject_id");
+ insertRecords();
+ }
+
+ private static void setupSchema(String schema) throws URISyntaxException, IOException {
+ String requestBody = "{\"operation\":\"create_schema\", \"" + "schema\":\"" + schema + "\"" + "}";
+ executeHttpPostRequest(requestBody);
+ }
+
+ private static void executeHttpPostRequest(String httpRequest) throws IOException {
+ logger.info("Post request body:" + httpRequest);
+
+ try (CloseableHttpClient closeableHttpClient = HttpClientBuilder.create().build()) {
+ HttpPost request = new HttpPost("http://localhost:" + port + "/");
+ request.addHeader("Authorization", "Basic YWRtaW46cGFzc3dvcmQ=");
+ request.addHeader("Content-Type", "application/json");
+ request.setEntity((HttpEntity) new StringEntity(httpRequest));
+ CloseableHttpResponse response = closeableHttpClient.execute((ClassicHttpRequest) request);
+ logger.info("REST API response:" + response.toString());
+ assertEquals(200, response.getCode());
+ }
+ }
+
+ private void insertStudentRecords() {
+
+ }
+
+ private void insertSubjectRecords() {
+
+ }
+
+ private void insertTeacherRecords() {
+
+ }
+
+ private static void createTable(String schemaName, String tableName, String... attributes) throws IOException {
+ String createTableReq = "{\"operation\":\"create_table\",\"schema\":\""
+ + schemaName + "\",\"table\":\""
+ + tableName + "\",\"hash_attribute\":\"id\""
+ + "}";
+ executeHttpPostRequest(createTableReq);
+ logger.info("created table:" + tableName);
+ for (String attribute : attributes) {
+ String createAttrReq = "{\"operation\":\"create_attribute\",\"schema\":\""
+ + schemaName + "\",\"table\":\""
+ + tableName + "\",\"attribute\":\""
+ + attribute + "\""
+ + "}";
+ executeHttpPostRequest(createAttrReq);
+ logger.info("created attribute:" + attribute + " in table:" + tableName);
+ }
+ }
+
+ private static void insertRecords() throws IOException {
+
+ String table = "student";
+ String schema = "demo";
+ String operation = "insert";
+ String records = "[" +
+ "{\"id\":1, \"name\":\"John\", \"grade\":4},"
+ + "{\"id\":2, \"name\":\"James\", \"grade\":1},"
+ + "{\"id\":3, \"name\":\"Williams\", \"grade\":1},"
+ + "{\"id\":4, \"name\":\"Robin\", \"grade\":4},"
+ + "{\"id\":5, \"name\":\"Torry\", \"grade\":3},"
+ + "{\"id\":6, \"name\":\"Nancy\", \"grade\":5},"
+ + "{\"id\":7, \"name\":\"Mary\", \"grade\":5},"
+ + "{\"id\":8, \"name\":\"Jenny\", \"grade\":6},"
+ + "{\"id\":9, \"name\":\"Katy\", \"grade\":6},"
+ + "{\"id\":15, \"name\":\"Michael\", \"grade\":6}"
+ + "]";
+ String requestBody = "{\"table\":" + "\"" + table + "\","
+ + "\"schema\":" + "\"" + schema + "\"" + ","
+ + "\"operation\":" + "\"" + operation + "\"" + ","
+ + "\"records\":" + records
+ + "}";
+ String sql = "{"
+ + "\"operation\":\"sql\", "
+ + "\"sql\":\"insert into demo.student(id, name, grade) values"
+ + "(1, 'John', 4), (2, 'James', 1), (3, 'Williams', 1), (4, 'Robin', 4), (5, 'Torry', 3),"
+ + " (6, 'Nancy', 5), (7, 'Mary', 5), (8, 'Jenny', 6), (9, 'Katy', 6)\""
+ + "}";
+ executeHttpPostRequest(requestBody);
+ }
+
+ @AfterAll
+ static void stopHarperDB() {
+ harperDBContainer.stop();
+ }
+
+ @Test
+ void whenConnectionInfoInURL_thenConnectSuccess() throws SQLException {
+ assertDoesNotThrow(() -> {
+ String URL = "jdbc:harperdb:Server=127.0.0.1:" + port + ";User=admin;Password=password;";
+
+ try (Connection connection = DriverManager.getConnection(URL)) {
+ connection.createStatement().executeQuery("select 1");
+ logger.info("Connection Successful");
+ }
+ });
+ }
+
+ @Test
+ void whenConnectionInfoInProperties_thenConnectSuccess() throws SQLException {
+ assertDoesNotThrow(() -> {
+ Properties prop = new Properties();
+ prop.setProperty("Server", "127.0.0.1:" + port);
+ prop.setProperty("User", "admin");
+ prop.setProperty("Password", "password");
+
+ try (Connection connection = DriverManager.getConnection("jdbc:harperdb:", prop)) {
+ connection.createStatement().executeQuery("select 1");
+ logger.info("Connection Successful");
+ }
+ });
+ }
+
+ @Test
+ void whenConnectionPooling_thenConnectSuccess() throws SQLException {
+ assertDoesNotThrow(() -> {
+ HarperDBConnectionPoolDataSource harperdbPoolDataSource = new HarperDBConnectionPoolDataSource();
+ String URL = "jdbc:harperdb:UseConnectionPooling=true;PoolMaxSize=2;Server=127.0.0.1:" + port
+ + ";User=admin;Password=1234;";
+ harperdbPoolDataSource.setURL(URL);
+
+ try(Connection connection = harperdbPoolDataSource.getPooledConnection().getConnection()) {
+ connection.createStatement().executeQuery("select 1");
+ logger.info("Connection Successful");
+ }
+ });
+ }
+
+ private static Connection getConnection() throws SQLException {
+ String URL = "jdbc:harperdb:Server=127.0.0.1:" + port + ";User=admin;Password=password;";
+ return DriverManager.getConnection(URL);
+ }
+
+ @Test
+ void givenStatement_whenFetchRecord_thenSuccess() throws SQLException {
+ final String SQL_QUERY = "select id, name, grade from demo.student";
+
+ try(Connection connection = getConnection()) {
+ Statement statement = connection.createStatement();
+ ResultSet resultSet = statement.executeQuery(SQL_QUERY);
+ while (resultSet.next()) {
+ int id = resultSet.getInt("id");
+ String name = resultSet.getString("name");
+ int grade = resultSet.getInt("grade");
+ assertNotNull(Integer.valueOf(id));
+ logger.info("Student id:" + id + " Student Name:" + name + " grade:" + grade);
+ }
+ }
+ }
+
+ @Test
+ void givenStatement_whenInsertRecord_thenSuccess() throws SQLException {
+ final String INSERT_SQL = "insert into demo.student(id, name, grade) values (10, 'Barak', 3)";
+
+ try(Connection connection = getConnection()) {
+ Statement statement = connection.createStatement();
+ assertDoesNotThrow(() -> statement.execute(INSERT_SQL));
+ }
+ }
+
+ @Test
+ void givenStatement_whenInsertRecordInTableWithoutAttributes_thenSuccess() throws SQLException {
+ final String INSERT_SQL = "insert into demo.teacher(id, name, joining_date) "
+ + "values (1, 'David Martinez', '04-05-2004'), (2, 'Eric Martin', '04-10-2000')";
+ final String QUERY_SQL = "select name, joining_date from demo.teacher where name = ?";
+
+ try(Connection connection = getConnection()) {
+ Statement statement = connection.createStatement();
+ assertDoesNotThrow(() -> statement.execute(INSERT_SQL));
+ PreparedStatement preparedStatement = connection.prepareStatement(QUERY_SQL);
+ preparedStatement.setString(1, "Eric Martin");
+ ResultSet resultSet = preparedStatement.executeQuery();
+ while (resultSet.next()) {
+ String teacherName = resultSet.getString("name");
+ String joinDate = resultSet.getString("joining_date");
+ assertEquals("Eric Martin", teacherName);
+ assertEquals("04-10-2000", joinDate);
+ logger.info("name:" + teacherName + " joining date:" + joinDate);
+ }
+ }
+ }
+
+ @Test
+ void givenStatement_whenUpdateRecord_thenSuccess() throws SQLException {
+ final String UPDATE_SQL = "update demo.student set grade = 4 where id = 5";
+
+ try(Connection connection = getConnection()) {
+ Statement statement = connection.createStatement();
+ assertDoesNotThrow(() -> statement.execute(UPDATE_SQL));
+ assertEquals(1, statement.getUpdateCount());
+ }
+ }
+
+ @Test
+ void givenStatement_whenDeleteRecord_thenSuccess() throws SQLException {
+ final String DELETE_SQL = "delete from demo.student where id = 3";
+
+ try(Connection connection = getConnection()) {
+ Statement statement = connection.createStatement();
+ assertDoesNotThrow(() -> statement.execute(DELETE_SQL));
+ assertEquals(1, statement.getUpdateCount());
+ }
+ }
+
+ @Test
+ void givenPreparedStatement_whenFetchRecord_thenSuccess() throws SQLException {
+ final String SQL_QUERY = "select id, name, grade from demo.student where name = ? and grade = ?";
+
+ try(Connection connection = getConnection()) {
+ PreparedStatement preparedStatement = connection.prepareStatement(SQL_QUERY);
+ preparedStatement.setString(1, "Robin");
+ preparedStatement.setInt(2, 4);
+ ResultSet resultSet = preparedStatement.executeQuery();
+ while (resultSet.next()) {
+ int id = resultSet.getInt("id");
+ String name = resultSet.getString("name");
+ int grade = resultSet.getInt("grade");
+ assertNotNull(Integer.valueOf(id));
+ assertEquals("Robin", name);
+ logger.info("Student id:" + id + " Student Name:" + name + " grade:" + grade);
+ }
+ }
+ }
+
+ @Test
+ void givenPreparedStatement_whenDeleteRecord_thenSuccess() throws SQLException {
+ final String DELETE_SQL = "delete from demo.student where name = ?";
+
+ try(Connection connection = getConnection()) {
+ PreparedStatement preparedStatement = connection.prepareStatement(DELETE_SQL);
+ preparedStatement.setString(1, "James");
+ assertDoesNotThrow(() -> preparedStatement.execute());
+ assertEquals(1, preparedStatement.getUpdateCount());
+ }
+ }
+
+ @Test
+ void givenPreparedStatement_whenUpdateRecord_thenSuccess() throws SQLException {
+ final String UPDATE_SQL = "update demo.student set grade = ? where id = ? and name = ?";
+
+ try(Connection connection = getConnection()) {
+ PreparedStatement preparedStatement = connection.prepareStatement(UPDATE_SQL);
+ preparedStatement.setInt(1, 5);
+ preparedStatement.setInt(2, 1);
+ preparedStatement.setString(3, "John");
+ assertDoesNotThrow(() -> preparedStatement.execute());
+ assertEquals(1, preparedStatement.getUpdateCount());
+ }
+ }
+
+ @Test
+ void whenAddtoBatch_thenExecuteBatchIsSuccess() throws SQLException {
+ final String INSERT_SQL = "insert into demo.teacher(id, name, joining_date)"
+ + "values(?, ?, ?)";
+
+ try(Connection connection = getConnection()) {
+ PreparedStatement preparedStatement = connection.prepareStatement(INSERT_SQL);
+ preparedStatement.setInt(1, 1);
+ preparedStatement.setString(2, "Bret Lee");
+ preparedStatement.setString(3, "07-08-2002");
+ preparedStatement.addBatch();
+
+ preparedStatement.setInt(1, 2);
+ preparedStatement.setString(2, "Sarah Glimmer");
+ preparedStatement.setString(3, "07-08-1997");
+ preparedStatement.addBatch();
+
+ assertDoesNotThrow(() -> preparedStatement.executeBatch());
+ }
+ }
+
+ @Test
+ void whenExecuteStoredToCreateTable_thenSuccess() throws SQLException {
+ final String CREATE_TABLE_SQL = "CreateTable";
+ try(Connection connection = getConnection()) {
+ CallableStatement callableStatement = connection.prepareCall(CREATE_TABLE_SQL);
+
+ callableStatement.setString("SchemaName", "prod"); //schema gets created too
+ callableStatement.setString("TableName", "subject");
+ callableStatement.setString("PrimaryKey", "id");
+ Boolean result = callableStatement.execute();
+
+ ResultSet resultSet = callableStatement.getResultSet();
+
+ while(resultSet.next()) {
+ String tableCreated = resultSet.getString("Success");
+ assertEquals("true", tableCreated);
+ logger.info("result of the callable execute:" + tableCreated);
+ }
+ }
+ }
+}