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 + 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); + } + } + } +}