From 59b6b817f4a6e02cd56d781283f148e7e65c04aa Mon Sep 17 00:00:00 2001 From: Amit Dixit Date: Mon, 4 Apr 2016 15:31:43 +0530 Subject: [PATCH] Test/Doc added Test/Doc added --- data-mapper/etc/data-mapper.png | Bin 0 -> 54062 bytes data-mapper/etc/data-mapper.ucls | 94 ++++++++ data-mapper/index.md | 2 +- .../java/com/iluwatar/datamapper/App.java | 34 +-- .../java/com/iluwatar/datamapper/Student.java | 66 ++++-- .../datamapper/StudentDataMapper.java | 8 +- ...apper.java => StudentFirstDataMapper.java} | 204 +++++++++--------- ...pper.java => StudentSecondDataMapper.java} | 203 +++++++++-------- .../java/com/iluwatar/datamapper/AppTest.java | 84 +------- .../iluwatar/datamapper/DataMapperTest.java | 108 ++++++++++ 10 files changed, 475 insertions(+), 328 deletions(-) create mode 100644 data-mapper/etc/data-mapper.png create mode 100644 data-mapper/etc/data-mapper.ucls rename data-mapper/src/main/java/com/iluwatar/datamapper/{StudentMySQLDataMapper.java => StudentFirstDataMapper.java} (85%) rename data-mapper/src/main/java/com/iluwatar/datamapper/{StudentOracleDataMapper.java => StudentSecondDataMapper.java} (85%) create mode 100644 data-mapper/src/test/java/com/iluwatar/datamapper/DataMapperTest.java diff --git a/data-mapper/etc/data-mapper.png b/data-mapper/etc/data-mapper.png new file mode 100644 index 0000000000000000000000000000000000000000..8fc90f591deb0c08aa2479c37a268ef0b5d5de2c GIT binary patch literal 54062 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 literal 0 HcmV?d00001 diff --git a/data-mapper/etc/data-mapper.ucls b/data-mapper/etc/data-mapper.ucls new file mode 100644 index 000000000..ff10fc32f --- /dev/null +++ b/data-mapper/etc/data-mapper.ucls @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data-mapper/index.md b/data-mapper/index.md index 4e640d5d6..684595c53 100644 --- a/data-mapper/index.md +++ b/data-mapper/index.md @@ -13,7 +13,7 @@ tags: Object provides an abstract interface to some type of database or other persistence mechanism. -![alt text](./etc/dm.png "Data Mapper") +![alt text](./etc/data-mapper.png "Data Mapper") ## Applicability Use the Data Mapper in any of the following situations diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/App.java b/data-mapper/src/main/java/com/iluwatar/datamapper/App.java index d8a968a17..63e3af41d 100644 --- a/data-mapper/src/main/java/com/iluwatar/datamapper/App.java +++ b/data-mapper/src/main/java/com/iluwatar/datamapper/App.java @@ -23,7 +23,6 @@ import java.util.Optional; import org.apache.log4j.Logger; /** - * * The Data Mapper (DM) is a layer of software that separates the in-memory objects from the * database. Its responsibility is to transfer data between the two and also to isolate them from * each other. With Data Mapper the in-memory objects needn't know even that there's a database @@ -39,43 +38,18 @@ public final class App { private static Logger log = Logger.getLogger(App.class); - private static final String DB_TYPE_ORACLE = "Oracle"; - private static final String DB_TYPE_MYSQL = "MySQL"; - /** * Program entry point. * * @param args command line args. */ - public static final void main(final String... args) { + public static void main(final String... args) { - if (log.isInfoEnabled() & args.length > 0) { - log.debug("App.main(), db type: " + args[0]); - } - StudentDataMapper mapper = null; - - /* Check the desired db type from runtime arguments */ - if (args.length == 0) { - - /* Create default data mapper for mysql */ - mapper = new StudentMySQLDataMapper(); - - } else if (args.length > 0 && DB_TYPE_ORACLE.equalsIgnoreCase(args[0])) { - - /* Create new data mapper for mysql */ - mapper = new StudentMySQLDataMapper(); - - } else if (args.length > 0 && DB_TYPE_MYSQL.equalsIgnoreCase(args[0])) { - - /* Create new data mapper for oracle */ - mapper = new StudentMySQLDataMapper(); - } else { - - /* Don't couple any Data Mapper to java.sql.SQLException */ - throw new DataMapperException("Following data mapping type(" + args[0] + ") is not supported"); - } + /* Create any type of mapper at implementation which is desired */ + /* final StudentDataMapper mapper = new StudentFirstDataMapper(); */ + final StudentDataMapper mapper = new StudentSecondDataMapper(); /* Create new student */ Student student = new Student(1, "Adam", 'A'); diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/Student.java b/data-mapper/src/main/java/com/iluwatar/datamapper/Student.java index 2f0c6d0a6..0164533c8 100644 --- a/data-mapper/src/main/java/com/iluwatar/datamapper/Student.java +++ b/data-mapper/src/main/java/com/iluwatar/datamapper/Student.java @@ -29,10 +29,14 @@ public final class Student implements Serializable { private String name; private char grade; - public Student() { - - } + /** + * Use this constructor to create a Student with all details + * + * @param studentId as unique student id + * @param name as student name + * @param grade as respective grade of student + */ public Student(final int studentId, final String name, final char grade) { super(); @@ -41,30 +45,57 @@ public final class Student implements Serializable { this.grade = grade; } - public final int getStudentId() { + /** + * + * @return the student id + */ + public int getStudentId() { return studentId; } - public final void setStudentId(final int studentId) { + /** + * + * @param studentId as unique student id + */ + public void setStudentId(final int studentId) { this.studentId = studentId; } - public final String getName() { + /** + * + * @return name of student + */ + public String getName() { return name; } - public final void setName(final String name) { + /** + * + * @param name as 'name' of student + */ + public void setName(final String name) { this.name = name; } - public final char getGrade() { + /** + * + * @return grade of student + */ + public char getGrade() { return grade; } - public final void setGrade(final char grade) { + /** + * + * @param grade as 'grade of student' + */ + public void setGrade(final char grade) { this.grade = grade; } + /** + * + */ @Override public boolean equals(final Object inputObject) { @@ -74,21 +105,23 @@ public final class Student implements Serializable { if (this == inputObject) { isEqual = true; - } - /* Check if objects belong to same class */ - else if (inputObject != null && getClass() == inputObject.getClass()) { + } else if (inputObject != null && getClass() == inputObject.getClass()) { - final Student student = (Student) inputObject; + final Student inputStudent = (Student) inputObject; /* If student id matched */ - if (this.getStudentId() == student.getStudentId()) { + if (this.getStudentId() == inputStudent.getStudentId()) { isEqual = true; } } + return isEqual; } + /** + * + */ @Override public int hashCode() { @@ -96,8 +129,11 @@ public final class Student implements Serializable { return this.getStudentId(); } + /** + * + */ @Override - public final String toString() { + public String toString() { return "Student [studentId=" + studentId + ", name=" + name + ", grade=" + grade + "]"; } } diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapper.java b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapper.java index 1fa33e067..40f0c5c72 100644 --- a/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapper.java +++ b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapper.java @@ -22,11 +22,11 @@ import java.util.Optional; public interface StudentDataMapper { - public Optional find(final int studentId); + Optional find(int studentId); - public void insert(final Student student) throws DataMapperException; + void insert(Student student) throws DataMapperException; - public void update(final Student student) throws DataMapperException; + void update(Student student) throws DataMapperException; - public void delete(final Student student) throws DataMapperException; + void delete(Student student) throws DataMapperException; } diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/StudentMySQLDataMapper.java b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentFirstDataMapper.java similarity index 85% rename from data-mapper/src/main/java/com/iluwatar/datamapper/StudentMySQLDataMapper.java rename to data-mapper/src/main/java/com/iluwatar/datamapper/StudentFirstDataMapper.java index ec7507eed..97f6d395d 100644 --- a/data-mapper/src/main/java/com/iluwatar/datamapper/StudentMySQLDataMapper.java +++ b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentFirstDataMapper.java @@ -1,102 +1,102 @@ -/** - * The MIT License Copyright (c) 2016 Amit Dixit - * - * 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.datamapper; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -public final class StudentMySQLDataMapper implements StudentDataMapper { - - /* Note: Normally this would be in the form of an actual database */ - private List students = new ArrayList<>(); - - @Override - public final Optional find(final int studentId) { - - /* Compare with existing students */ - for (final Student student : this.getStudents()) { - - /* Check if student is found */ - if (student.getStudentId() == studentId) { - - return Optional.of(student); - } - } - - /* Return empty value */ - return Optional.empty(); - } - - @Override - public final void update(final Student studentToBeUpdated) throws DataMapperException { - - - /* Check with existing students */ - if (this.getStudents().contains(studentToBeUpdated)) { - - /* Get the index of student in list */ - final int index = this.getStudents().indexOf(studentToBeUpdated); - - /* Update the student in list */ - this.getStudents().set(index, studentToBeUpdated); - - } else { - - /* Throw user error */ - throw new DataMapperException("Student [" + studentToBeUpdated.getName() + "] is not found"); - } - } - - @Override - public final void insert(final Student studentToBeInserted) throws DataMapperException { - - /* Check with existing students */ - if (!this.getStudents().contains(studentToBeInserted)) { - - /* Add student in list */ - this.getStudents().add(studentToBeInserted); - - } else { - - /* Throw user error */ - throw new DataMapperException("Student already [" + studentToBeInserted.getName() + "] exists"); - } - } - - @Override - public final void delete(final Student studentToBeDeleted) throws DataMapperException { - - /* Check with existing students */ - if (this.getStudents().contains(studentToBeDeleted)) { - - /* Delete the student from list */ - this.getStudents().remove(studentToBeDeleted); - - } else { - - /* Throw user error */ - throw new DataMapperException("Student [" + studentToBeDeleted.getName() + "] is not found"); - } - } - - public List getStudents() { - return this.students; - } -} +/** + * The MIT License Copyright (c) 2016 Amit Dixit + * + * 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.datamapper; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public final class StudentFirstDataMapper implements StudentDataMapper { + + /* Note: Normally this would be in the form of an actual database */ + private List students = new ArrayList<>(); + + @Override + public Optional find(int studentId) { + + /* Compare with existing students */ + for (final Student student : this.getStudents()) { + + /* Check if student is found */ + if (student.getStudentId() == studentId) { + + return Optional.of(student); + } + } + + /* Return empty value */ + return Optional.empty(); + } + + @Override + public void update(Student studentToBeUpdated) throws DataMapperException { + + + /* Check with existing students */ + if (this.getStudents().contains(studentToBeUpdated)) { + + /* Get the index of student in list */ + final int index = this.getStudents().indexOf(studentToBeUpdated); + + /* Update the student in list */ + this.getStudents().set(index, studentToBeUpdated); + + } else { + + /* Throw user error */ + throw new DataMapperException("Student [" + studentToBeUpdated.getName() + "] is not found"); + } + } + + @Override + public void insert(Student studentToBeInserted) throws DataMapperException { + + /* Check with existing students */ + if (!this.getStudents().contains(studentToBeInserted)) { + + /* Add student in list */ + this.getStudents().add(studentToBeInserted); + + } else { + + /* Throw user error */ + throw new DataMapperException("Student already [" + studentToBeInserted.getName() + "] exists"); + } + } + + @Override + public void delete(Student studentToBeDeleted) throws DataMapperException { + + /* Check with existing students */ + if (this.getStudents().contains(studentToBeDeleted)) { + + /* Delete the student from list */ + this.getStudents().remove(studentToBeDeleted); + + } else { + + /* Throw user error */ + throw new DataMapperException("Student [" + studentToBeDeleted.getName() + "] is not found"); + } + } + + public List getStudents() { + return this.students; + } +} diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/StudentOracleDataMapper.java b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentSecondDataMapper.java similarity index 85% rename from data-mapper/src/main/java/com/iluwatar/datamapper/StudentOracleDataMapper.java rename to data-mapper/src/main/java/com/iluwatar/datamapper/StudentSecondDataMapper.java index ca66f11c9..62d39f90d 100644 --- a/data-mapper/src/main/java/com/iluwatar/datamapper/StudentOracleDataMapper.java +++ b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentSecondDataMapper.java @@ -1,102 +1,101 @@ -/** - * The MIT License Copyright (c) 2016 Amit Dixit - * - * 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.datamapper; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -public final class StudentOracleDataMapper implements StudentDataMapper { - - /* Note: Normally this would be in the form of an actual database */ - private List students = new ArrayList<>(); - - @Override - public final Optional find(final int studentId) { - - /* Compare with existing students */ - for (final Student student : this.getStudents()) { - - /* Check if student is found */ - if (student.getStudentId() == studentId) { - - return Optional.of(student); - } - } - - /* Return empty value */ - return Optional.empty(); - } - - @Override - public final void update(final Student studentToBeUpdated) throws DataMapperException { - - - /* Check with existing students */ - if (this.getStudents().contains(studentToBeUpdated)) { - - /* Get the index of student in list */ - final int index = this.getStudents().indexOf(studentToBeUpdated); - - /* Update the student in list */ - this.getStudents().set(index, studentToBeUpdated); - - } else { - - /* Throw user error */ - throw new DataMapperException("Student [" + studentToBeUpdated.getName() + "] is not found"); - } - } - - @Override - public final void insert(final Student studentToBeInserted) throws DataMapperException { - - /* Check with existing students */ - if (!this.getStudents().contains(studentToBeInserted)) { - - /* Add student in list */ - this.getStudents().add(studentToBeInserted); - - } else { - - /* Throw user error */ - throw new DataMapperException("Student already [" + studentToBeInserted.getName() + "] exists"); - } - } - - @Override - public final void delete(final Student studentToBeDeleted) throws DataMapperException { - - /* Check with existing students */ - if (this.getStudents().contains(studentToBeDeleted)) { - - /* Delete the student from list */ - this.getStudents().remove(studentToBeDeleted); - - } else { - - /* Throw user error */ - throw new DataMapperException("Student [" + studentToBeDeleted.getName() + "] is not found"); - } - } - - public List getStudents() { - return this.students; - } -} +/** + * The MIT License Copyright (c) 2016 Amit Dixit + * + * 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.datamapper; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public final class StudentSecondDataMapper implements StudentDataMapper { + + /* Note: Normally this would be in the form of an actual database */ + private List students = new ArrayList<>(); + + @Override + public Optional find(int studentId) { + + /* Compare with existing students */ + for (final Student student : this.getStudents()) { + + /* Check if student is found */ + if (student.getStudentId() == studentId) { + + return Optional.of(student); + } + } + + /* Return empty value */ + return Optional.empty(); + } + + @Override + public void update(Student studentToBeUpdated) throws DataMapperException { + + /* Check with existing students */ + if (this.getStudents().contains(studentToBeUpdated)) { + + /* Get the index of student in list */ + final int index = this.getStudents().indexOf(studentToBeUpdated); + + /* Update the student in list */ + this.getStudents().set(index, studentToBeUpdated); + + } else { + + /* Throw user error */ + throw new DataMapperException("Student [" + studentToBeUpdated.getName() + "] is not found"); + } + } + + @Override + public void insert(Student studentToBeInserted) throws DataMapperException { + + /* Check with existing students */ + if (!this.getStudents().contains(studentToBeInserted)) { + + /* Add student in list */ + this.getStudents().add(studentToBeInserted); + + } else { + + /* Throw user error */ + throw new DataMapperException("Student already [" + studentToBeInserted.getName() + "] exists"); + } + } + + @Override + public void delete(Student studentToBeDeleted) throws DataMapperException { + + /* Check with existing students */ + if (this.getStudents().contains(studentToBeDeleted)) { + + /* Delete the student from list */ + this.getStudents().remove(studentToBeDeleted); + + } else { + + /* Throw user error */ + throw new DataMapperException("Student [" + studentToBeDeleted.getName() + "] is not found"); + } + } + + public List getStudents() { + return this.students; + } +} diff --git a/data-mapper/src/test/java/com/iluwatar/datamapper/AppTest.java b/data-mapper/src/test/java/com/iluwatar/datamapper/AppTest.java index 6e415bccb..d3ad2dcb3 100644 --- a/data-mapper/src/test/java/com/iluwatar/datamapper/AppTest.java +++ b/data-mapper/src/test/java/com/iluwatar/datamapper/AppTest.java @@ -1,5 +1,6 @@ /** - * The MIT License Copyright (c) 2014 Ilkka Seppälä + * The MIT License Copyright (c) 2016 Amit Dixit + * * * 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, @@ -18,82 +19,17 @@ */ package com.iluwatar.datamapper; -import java.util.Optional; -import java.util.UUID; - -import org.apache.log4j.Logger; +import com.iluwatar.datamapper.App; +import org.junit.Test; /** - * The Data Mapper (DM) is a layer of software that separates the in-memory objects from the - * database. Its responsibility is to transfer data between the two and also to isolate them from - * each other. With Data Mapper the in-memory objects needn't know even that there's a database - * present; they need no SQL interface code, and certainly no knowledge of the database schema. (The - * database schema is always ignorant of the objects that use it.) Since it's a form of Mapper , - * Data Mapper itself is even unknown to the domain layer. - *

- * The below example demonstrates basic CRUD operations: select, add, update, and delete. - * + * Tests that Data-Mapper example runs without errors. */ -public final class App { +public final class AppTest { - private static Logger log = Logger.getLogger(App.class); - - - private static final String DB_TYPE_ORACLE = "Oracle"; - private static final String DB_TYPE_MYSQL = "MySQL"; - - - /** - * Program entry point. - * - * @param args command line args. - */ - public static final void main(final String... args) { - - if (log.isInfoEnabled() & args.length > 0) { - log.debug("App.main(), db type: " + args[0]); - } - - StudentDataMapper mapper = null; - - /* Check the desired db type from runtime arguments */ - if (DB_TYPE_ORACLE.equalsIgnoreCase(args[0])) { - - /* Create new data mapper for mysql */ - mapper = new StudentMySQLDataMapper(); - - } else if (DB_TYPE_MYSQL.equalsIgnoreCase(args[0])) { - - /* Create new data mapper for oracle */ - mapper = new StudentMySQLDataMapper(); - } else { - - /* Don't couple any Data Mapper to java.sql.SQLException */ - throw new DataMapperException("Following data source(" + args[0] + ") is not supported"); - } - - /* Create new student */ - Student student = new Student(UUID.randomUUID(), 1, "Adam", 'A'); - - /* Add student in respectibe db */ - mapper.insert(student); - - /* Find this student */ - final Optional studentToBeFound = mapper.find(student.getGuId()); - - if (log.isDebugEnabled()) { - log.debug("App.main(), db find returned : " + studentToBeFound); - } - - /* Update existing student object */ - student = new Student(student.getGuId(), 1, "AdamUpdated", 'A'); - - /* Update student in respectibe db */ - mapper.update(student); - - /* Delete student in db */ - mapper.delete(student); + @Test + public void test() { + final String[] args = {}; + App.main(args); } - - private App() {} } diff --git a/data-mapper/src/test/java/com/iluwatar/datamapper/DataMapperTest.java b/data-mapper/src/test/java/com/iluwatar/datamapper/DataMapperTest.java new file mode 100644 index 000000000..f77097df8 --- /dev/null +++ b/data-mapper/src/test/java/com/iluwatar/datamapper/DataMapperTest.java @@ -0,0 +1,108 @@ +/** + * The MIT License Copyright (c) 2016 Amit Dixit + * + * 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.datamapper; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.iluwatar.datamapper.Student; +import com.iluwatar.datamapper.StudentDataMapper; +import com.iluwatar.datamapper.StudentFirstDataMapper; +import com.iluwatar.datamapper.StudentSecondDataMapper; + +/** + * The Data Mapper (DM) is a layer of software that separates the in-memory objects from the + * database. Its responsibility is to transfer data between the two and also to isolate them from + * each other. With Data Mapper the in-memory objects needn't know even that there's a database + * present; they need no SQL interface code, and certainly no knowledge of the database schema. (The + * database schema is always ignorant of the objects that use it.) Since it's a form of Mapper , + * Data Mapper itself is even unknown to the domain layer. + *

+ */ +public class DataMapperTest { + + /** + * This test verify that first data mapper is able to perform all CRUD operations on Student + */ + @Test + public void testFirstDataMapper() { + + /* Create new data mapper of first type */ + final StudentDataMapper mapper = new StudentFirstDataMapper(); + + /* Create new student */ + Student student = new Student(1, "Adam", 'A'); + + /* Add student in respectibe db */ + mapper.insert(student); + + /* Check if student is added in db */ + assertEquals(student.getStudentId(), mapper.find(student.getStudentId()).get().getStudentId()); + + /* Update existing student object */ + student = new Student(student.getStudentId(), "AdamUpdated", 'A'); + + /* Update student in respectibe db */ + mapper.update(student); + + /* Check if student is updated in db */ + assertEquals(mapper.find(student.getStudentId()).get().getName(), "AdamUpdated"); + + /* Delete student in db */ + mapper.delete(student); + + /* Result should be false */ + assertEquals(false, mapper.find(student.getStudentId()).isPresent()); + } + + /** + * This test verify that second data mapper is able to perform all CRUD operations on Student + */ + @Test + public void testSecondDataMapper() { + + /* Create new data mapper of second type */ + final StudentDataMapper mapper = new StudentSecondDataMapper(); + + /* Create new student */ + Student student = new Student(1, "Adam", 'A'); + + /* Add student in respectibe db */ + mapper.insert(student); + + /* Check if student is added in db */ + assertEquals(student.getStudentId(), mapper.find(student.getStudentId()).get().getStudentId()); + + /* Update existing student object */ + student = new Student(student.getStudentId(), "AdamUpdated", 'A'); + + /* Update student in respectibe db */ + mapper.update(student); + + /* Check if student is updated in db */ + assertEquals(mapper.find(student.getStudentId()).get().getName(), "AdamUpdated"); + + /* Delete student in db */ + mapper.delete(student); + + /* Result should be false */ + assertEquals(false, mapper.find(student.getStudentId()).isPresent()); + } +}