diff --git a/pom.xml b/pom.xml
index ef3a39265d53..9fde5a87122b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -201,6 +201,7 @@
currying
serialized-entity
identity-map
+ row-data-gateway
component
context-object
optimistic-offline-lock
@@ -218,6 +219,7 @@
function-composition
microservices-distributed-tracing
microservices-idempotent-consumer
+ row-data-gateway
diff --git a/row-data-gateway/README.md b/row-data-gateway/README.md
new file mode 100644
index 000000000000..39b0430ce8c6
--- /dev/null
+++ b/row-data-gateway/README.md
@@ -0,0 +1,99 @@
+
+---
+title: "Row Data Pattern: Ensuring Efficient Data Handling in Java"
+shortTitle: Row Data
+description: "Explore the Row Data Pattern in Java for handling large sets of data efficiently and ensuring proper management of row-level operations in distributed systems."
+category: Data Management
+language: en
+tag:
+- Performance
+- Data Processing
+- Scalability
+- Microservices
+- Data Integrity
+---
+
+## Intent of Row Data Pattern
+
+To manage large datasets efficiently and ensure row-level operations are optimized, reducing memory overhead in distributed systems.
+
+## Detailed Explanation of Row Data Pattern
+
+### Real-world example
+
+> Imagine a system that processes large batches of customer data. Each customer record is handled as a row in the database. With the Row Data Pattern, operations such as data validation, updates, or deletions are performed at the row level, ensuring minimal resource consumption and better scalability.
+
+### In plain words
+
+> The Row Data Pattern focuses on processing and managing individual rows of data efficiently, ensuring that large datasets are handled without compromising system performance.
+
+## Programmatic Example of Row Data Pattern in Java
+
+The Row Data Pattern can be implemented by iterating over each row in a dataset, performing necessary operations, and ensuring that each row is processed independently, allowing for better scalability.
+
+**Snippet 1: Process Data Rows**
+
+```java
+public void processRows(List rows) {
+ for (RowData row : rows) {
+ processRow(row);
+ }
+}
+
+private void processRow(RowData row) {
+ // Perform row-level operations such as validation or transformation
+}
+```
+
+**Snippet 2: Handling Large Data Sets**
+
+```java
+public void handleLargeDataSet(List largeDataSet) {
+ for (int i = 0; i < largeDataSet.size(); i++) {
+ processRow(largeDataSet.get(i));
+ }
+}
+```
+
+### Key Components of Row Data Pattern
+
+1. **Row**: Represents a single unit of data in a dataset. Operations are applied to individual rows, making it more memory efficient.
+2. **Row Processor**: Handles the logic for processing or transforming the data in each row.
+3. **Dataset**: A collection of rows that need to be processed or updated.
+
+## When to Use the Row Data Pattern in Java
+
+* When dealing with large datasets that need to be processed row by row.
+* When memory optimization is a priority in handling large amounts of data.
+* In systems that require efficient batch processing without overwhelming system resources.
+
+## Real-World Applications of Row Data Pattern
+
+* Financial systems processing individual transactions.
+* Data analytics platforms handling large-scale data processing.
+* Microservices managing row-level database operations for customer records.
+
+## Benefits and Trade-offs of Row Data Pattern
+
+Benefits:
+
+* Memory-efficient when handling large datasets.
+* Scalable for batch processing in distributed systems.
+
+Trade-offs:
+
+* Might introduce performance overhead for complex row operations.
+* Requires careful management of row-level operations to ensure efficiency.
+
+## Related Java Design Patterns
+
+* [Iterator Pattern](https://java-design-patterns.com/patterns/iterator/): Used to iterate over collections, which complements the Row Data Pattern in handling individual data elements.
+* [Batch Processing](https://java-design-patterns.com/patterns/batch-processing/): A pattern for managing large batches of data, working well with Row Data for scalable data operations.
+
+## References and Credits
+
+* [Java Design Patterns](https://java-design-patterns.com/)
+* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3y6yv1z)
+```
+
+This README provides a high-level overview of the Row Data Pattern, illustrating how it optimizes large dataset handling, with sample Java code. For additional details, refer to [Java Design Patterns](https://java-design-patterns.com/).
\ No newline at end of file
diff --git a/row-data-gateway/etc/row data.puml b/row-data-gateway/etc/row data.puml
new file mode 100644
index 000000000000..4ef60882a8c1
--- /dev/null
+++ b/row-data-gateway/etc/row data.puml
@@ -0,0 +1,33 @@
+@startuml
+package com.iluwatar.rowdata {
+ class UserGateway {
+ - rowdata : RowData
+ - connection : Connection
+ - logger : Logger
+ + UserGateway(RowData rowData, Connection connection)
+ + RowData read()
+ + void insert()
+ + void update()
+ + void delete()
+ }
+
+ class RowData {
+ - int id
+ - String name
+ - int value
+ + int getId()
+ + String getName()
+ + int getValue()
+ }
+
+ UserGateway --> RowData : "uses"
+
+
+ class App {
+ + main(args : String[]) : void
+ }
+ App --> RowData : "uses"
+ App --> UserGateway : "uses"
+ }
+}
+@enduml
\ No newline at end of file
diff --git a/row-data-gateway/pom.xml b/row-data-gateway/pom.xml
new file mode 100644
index 000000000000..b3649843bd2f
--- /dev/null
+++ b/row-data-gateway/pom.xml
@@ -0,0 +1,108 @@
+
+
+
+ 4.0.0
+
+ com.iluwatar
+ java-design-patterns
+ 1.26.0-SNAPSHOT
+
+ row-data-gateway
+
+
+
+ org.slf4j
+ slf4j-api
+ 1.7.36
+
+
+ ch.qos.logback
+ logback-classic
+ 1.4.12
+
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+ junit
+ junit
+ test
+
+
+ org.xerial
+ sqlite-jdbc
+ 3.36.0.3
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.10.1
+
+ 17
+ 17
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+ com.iluwatar.rowdata.App
+
+
+
+ jar-with-dependencies
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/row-data-gateway/src/main/java/com/iluwatar/rowdata/App.java b/row-data-gateway/src/main/java/com/iluwatar/rowdata/App.java
new file mode 100644
index 000000000000..8e151e28a971
--- /dev/null
+++ b/row-data-gateway/src/main/java/com/iluwatar/rowdata/App.java
@@ -0,0 +1,142 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.rowdata;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+/**
+ * Main application to interact with the database.
+ */
+public class App {
+ private static final Logger logger = LoggerFactory.getLogger(App.class);
+ private static Connection connection;
+
+ /**
+ * Initializes the database connection.
+ */
+ public static void initialize() {
+ try {
+ connection = DriverManager.getConnection("jdbc:sqlite:/path/to/sample.db");
+ } catch (SQLException e) {
+ throw new DatabaseOperationException("Failed to initialize the database connection", e);
+ }
+ }
+
+ /**
+ * Returns the active database connection.
+ *
+ * @return the active connection
+ */
+ public static Connection getConnection() {
+ if (connection == null) {
+ throw new IllegalStateException("Connection is not initialized. Call initialize() first.");
+ }
+ return connection;
+ }
+
+ /**
+ * Closes the database connection.
+ */
+ public static void closeConnection() {
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ throw new DatabaseOperationException("Failed to close the database connection", e);
+ }
+ }
+ }
+
+ /**
+ * Creates the rowDataTable if it doesn't exist.
+ */
+ public static void createTable() {
+ String sql = "CREATE TABLE IF NOT EXISTS rowDataTable "
+ + "(ID INTEGER PRIMARY KEY AUTOINCREMENT, "
+ + "NAME TEXT NOT NULL, "
+ + "VALUE INTEGER NOT NULL)";
+ try (Statement stmt = connection.createStatement()) {
+ stmt.executeUpdate(sql);
+ logger.info("Table created or already exists.");
+ } catch (SQLException e) {
+ logger.error("Error creating table: {}", e.getMessage());
+ }
+ }
+
+ /**
+ * Displays the content of the rowDataTable.
+ */
+ public static void display() {
+ String sql = "SELECT ID, NAME FROM rowDataTable";
+ try (Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery(sql)) {
+ while (rs.next()) {
+ int id = rs.getInt("ID");
+ String name = rs.getString("NAME");
+ int value = rs.getInt("VALUE");
+ if (logger.isInfoEnabled()) {
+ logger.info("ID = {}, NAME = {}, VALUE = {}", id, name, value);
+ }
+ }
+ } catch (SQLException e) {
+ logger.error("Error displaying table: {}", e.getMessage());
+ }
+ }
+ /**
+ * Starting point for the program.
+ * @param args command line args
+ * @throws SQLException if any error occur, since SQL code is necessary in {@link UserGateway}
+ */
+ public static void main(String[] args) {
+ initialize();
+ createTable();
+
+ RowData row1 = new RowData(1, "John", 20);
+ RowData row2 = new RowData(2, "Mary", 30);
+ RowData row3 = new RowData(3, "Doe", 40);
+
+ UserGateway rowGateway1 = new UserGateway(row1, connection);
+ UserGateway rowGateway2 = new UserGateway(row2, connection);
+ UserGateway rowGateway3 = new UserGateway(row3, connection);
+
+ rowGateway1.insert();
+ rowGateway2.insert();
+ rowGateway3.insert();
+ display();
+
+ row3.setName("Dorothy");
+ rowGateway3.setRowData(row3);
+ rowGateway3.update();
+ display();
+
+ rowGateway2.delete();
+ display();
+
+ closeConnection();
+ }
+}
diff --git a/row-data-gateway/src/main/java/com/iluwatar/rowdata/DatabaseOperationException.java b/row-data-gateway/src/main/java/com/iluwatar/rowdata/DatabaseOperationException.java
new file mode 100644
index 000000000000..4d050ea319ea
--- /dev/null
+++ b/row-data-gateway/src/main/java/com/iluwatar/rowdata/DatabaseOperationException.java
@@ -0,0 +1,15 @@
+package com.iluwatar.rowdata;
+/**
+ * Custom exception for database operation errors.
+ */
+public class DatabaseOperationException extends RuntimeException {
+ /**
+ * Constructs a new DatabaseOperationException with the specified detail message and cause.
+ *
+ * @param message the detail message
+ * @param cause the cause
+ */
+ public DatabaseOperationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/row-data-gateway/src/main/java/com/iluwatar/rowdata/RowData.java b/row-data-gateway/src/main/java/com/iluwatar/rowdata/RowData.java
new file mode 100644
index 000000000000..925781375836
--- /dev/null
+++ b/row-data-gateway/src/main/java/com/iluwatar/rowdata/RowData.java
@@ -0,0 +1,140 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.rowdata;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * The RowData class represents a single row of data in the database.
+ * It contains properties like ID, Name, and Value, along with getters and setters for each property.
+ */
+@Getter
+@Setter
+public class RowData {
+
+ private int id;
+ private String name;
+ private int value;
+
+ /**
+ * Constructor to initialize RowData object with the specified values.
+ *
+ * @param id the ID of the row
+ * @param name the name of the row
+ * @param value the value of the row
+ */
+ public RowData(int id, String name, int value) {
+ this.id = id;
+ this.name = name;
+ this.value = value;
+ }
+
+ /**
+ * Gets the current name of the RowData.
+ *
+ * @return the name of the row
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the name of the RowData.
+ *
+ * @param name the new name of the row
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Gets the current value of the RowData.
+ *
+ * @return the value of the row
+ */
+ public int getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the value of the RowData.
+ *
+ * @param value the new value of the row
+ */
+ public void setValue(int value) {
+ this.value = value;
+ }
+
+ /**
+ * Gets the current ID of the RowData.
+ *
+ * @return the ID of the row
+ */
+ public int getId() {
+ return id;
+ }
+
+ /**
+ * Sets the ID of the RowData.
+ *
+ * @param id the new ID of the row
+ */
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ /**
+ * Compares two RowData objects for equality.
+ * Rows are considered equal if their ID, name, and value are identical.
+ *
+ * @param obj the object to compare this RowData to
+ * @return true if the RowData objects are equal, false otherwise
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ RowData rowData = (RowData) obj;
+ return id == rowData.id && value == rowData.value && name.equals(rowData.name);
+ }
+
+ /**
+ * Returns a hash code for the RowData object, based on its ID, name, and value.
+ *
+ * @return the hash code for the RowData
+ */
+ @Override
+ public int hashCode() {
+ int result = Integer.hashCode(id);
+ result = 31 * result + name.hashCode();
+ result = 31 * result + Integer.hashCode(value);
+ return result;
+ }
+}
diff --git a/row-data-gateway/src/main/java/com/iluwatar/rowdata/UserGateway.java b/row-data-gateway/src/main/java/com/iluwatar/rowdata/UserGateway.java
new file mode 100644
index 000000000000..2103d0eb9312
--- /dev/null
+++ b/row-data-gateway/src/main/java/com/iluwatar/rowdata/UserGateway.java
@@ -0,0 +1,137 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.rowdata;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Optional;
+import lombok.Getter;
+import lombok.Setter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+/**
+ * This class is responsible for performing CRUD operations on RowData.
+ * It provides methods to insert, update, and delete rows in the rowDataTable.
+ */
+@Getter
+@Setter
+public class UserGateway {
+
+ private static final Logger logger = LoggerFactory.getLogger(UserGateway.class);
+
+ @Getter
+ @Setter
+ private RowData rowData;
+
+ private Connection connection;
+
+ /**
+ * Constructs a UserGateway with a RowData object and a database connection.
+ *
+ * @param rowData the RowData object to be operated on.
+ * @param connection the database connection to interact with.
+ */
+ public UserGateway(RowData rowData, Connection connection) {
+ this.rowData = rowData;
+ this.connection = connection;
+ }
+
+ /**
+ * Reads a row from the database by ID.
+ *
+ * @return the retrieved RowData object, or null if no matching row is found.
+ */
+ public Optional read() {
+ String sql = "SELECT ID, NAME, VALUE FROM rowDataTable WHERE ID = ?";
+ try (PreparedStatement stmt = connection.prepareStatement(sql)) {
+ stmt.setInt(1, rowData.getId());
+ try (ResultSet rs = stmt.executeQuery()) {
+ if (rs.next()) {
+ int id = rs.getInt("ID");
+ String name = rs.getString("NAME");
+ int value = rs.getInt("VALUE");
+ logger.info("Row retrieved: ID={}, NAME={}, VALUE={}", id, name, value);
+ return Optional.of(new RowData(id, name, value));
+ }
+ }
+ } catch (SQLException e) {
+ logger.error("Error reading row: {}", e.getMessage());
+ }
+ return Optional.empty();
+ }
+
+
+ /**
+ * Inserts the current RowData object into the rowDataTable.
+ * Logs the SQL query upon successful insertion.
+ */
+ public void insert() {
+ String sql = "INSERT INTO rowDataTable (NAME, VALUE) VALUES (?, ?)";
+ try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
+ pstmt.setString(1, rowData.getName());
+ pstmt.setInt(2, rowData.getValue());
+ pstmt.executeUpdate();
+ logger.info("Row inserted with name: {} and value: {}", rowData.getName(),
+ rowData.getValue());
+ } catch (SQLException e) {
+ logger.error("Error inserting row: {}", e.getMessage());
+ }
+ }
+
+ /**
+ * Updates the row in rowDataTable corresponding to the current RowData object.
+ * The row is updated based on the ID of the RowData object.
+ * Logs the SQL query upon successful update.
+ */
+ public void update() {
+ String sql = "UPDATE rowDataTable SET NAME = ?, VALUE = ? WHERE ID = ?";
+ try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
+ pstmt.setString(1, rowData.getName());
+ pstmt.setInt(2, rowData.getValue());
+ pstmt.setInt(3, rowData.getId());
+ int affectedRows = pstmt.executeUpdate();
+ logger.info("Row updated, affected rows: {}", affectedRows);
+ } catch (SQLException e) {
+ logger.error("Error updating row: {}", e.getMessage());
+ }
+ }
+
+ /**
+ * Deletes the row in rowDataTable corresponding to the current RowData object.
+ * The row is deleted based on the ID of the RowData object.
+ * Logs the SQL query upon successful deletion.
+ */
+ public void delete() {
+ String sql = "DELETE FROM rowDataTable WHERE ID = ?";
+ try (PreparedStatement stmt = connection.prepareStatement(sql)) {
+ stmt.setInt(1, rowData.getId());
+ int rowsAffected = stmt.executeUpdate();
+ logger.info("Row deleted. Rows affected: {}", rowsAffected);
+ } catch (SQLException e) {
+ logger.error("Error deleting row: {}", e.getMessage());
+ }
+ }
+}
diff --git a/row-data-gateway/src/test/java/com/iluwatar/rowdata/UserGatewayTest.java b/row-data-gateway/src/test/java/com/iluwatar/rowdata/UserGatewayTest.java
new file mode 100644
index 000000000000..e042de0fcb8b
--- /dev/null
+++ b/row-data-gateway/src/test/java/com/iluwatar/rowdata/UserGatewayTest.java
@@ -0,0 +1,84 @@
+/*
+ * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+ *
+ * The MIT License
+ * Copyright © 2014-2022 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.rowdata;
+import org.junit.jupiter.api.Test;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import static org.junit.jupiter.api.Assertions.*;
+
+class UserGatewayTest {
+
+ @Test
+ void insertTest() {
+ var r1 = new RowData(1, "John", 25);
+ try (Connection conn = DriverManager.getConnection("jdbc:sqlite:test.db")) {
+ UserGateway userGateway = new UserGateway(r1, conn);
+ assertDoesNotThrow(userGateway::insert);
+ } catch (SQLException e) {
+ fail("Database connection failed");
+ }
+ }
+
+ @Test
+ void updateTest() {
+ var r1 = new RowData(1, "John", 25);
+ var r2 = new RowData(1, "Johnny", 30);
+ try (Connection conn = DriverManager.getConnection("jdbc:sqlite:test.db")) {
+ UserGateway userGateway = new UserGateway(r1, conn);
+ userGateway.insert();
+ userGateway.setRowData(r2);
+ assertDoesNotThrow(userGateway::update);
+ } catch (SQLException e) {
+ fail("Database connection failed");
+ }
+ }
+
+ @Test
+ void deleteTest() {
+ var r1 = new RowData(1, "John", 25);
+ try (Connection conn = DriverManager.getConnection("jdbc:sqlite:test.db")) {
+ UserGateway userGateway = new UserGateway(r1, conn);
+ userGateway.insert();
+ assertDoesNotThrow(userGateway::delete);
+ } catch (SQLException e) {
+ fail("Database connection failed");
+ }
+ }
+
+
+ @Test
+ void readTest() {
+ var r1 = new RowData(1, "John", 25);
+ var r2 = new RowData(1, "Johnny", 30);
+ try (Connection conn = DriverManager.getConnection("jdbc:sqlite:test.db")) {
+ UserGateway userGateway = new UserGateway(r1, conn);
+ userGateway.setRowData(r2);
+ assertEquals(r2, userGateway.getRowData());
+ } catch (SQLException e) {
+ fail("Database connection failed");
+ }
+ }
+}
diff --git a/update-header.sh b/update-header.sh
index 48da4dcd6125..568d00d52a03 100755
--- a/update-header.sh
+++ b/update-header.sh
@@ -1,4 +1,29 @@
#!/bin/bash
+#
+# This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
+#
+# The MIT License
+# Copyright © 2014-2022 Ilkka Seppälä
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
# Find all README.md files in subdirectories one level deep
# and replace "### " with "## " at the beginning of lines