diff --git a/basics/src/main/java/ru/msu/vmk/NumberSample.java b/basics/src/main/java/ru/msu/vmk/NumberSample.java
index 9961ed3..9405c88 100644
--- a/basics/src/main/java/ru/msu/vmk/NumberSample.java
+++ b/basics/src/main/java/ru/msu/vmk/NumberSample.java
@@ -1,11 +1,23 @@
package ru.msu.vmk;
-
import java.math.BigDecimal;
-
public class NumberSample {
+
public static BigDecimal[] split(BigDecimal amount, int n) {
- // разделить amount на n частей
- // если остается остаток, прибавить его к первому числу
- return null;
+ var array = new BigDecimal[n];
+ double temp = amount.doubleValue();
+ int previousSize = n;
+ for (int i = 0; n > 0; i++, n--) {
+ double size = temp / n;
+ if (previousSize > 2) {
+ array[i] = BigDecimal.valueOf((int) size);
+ } else {
+ array[i] = BigDecimal.valueOf(size);
+ }
+ temp -= size;
+ }
+ if (previousSize > 2) {
+ array[0] = BigDecimal.valueOf((int) (amount.doubleValue() / previousSize)).add(BigDecimal.valueOf(amount.doubleValue() % previousSize));
+ }
+ return array;
}
}
diff --git a/collections/pom.xml b/collections/pom.xml
index 38c543e..4b1b835 100644
--- a/collections/pom.xml
+++ b/collections/pom.xml
@@ -23,6 +23,16 @@
junit-jupiter
5.9.2
+
+ org.apache.derby
+ derby
+ 10.14.2.0
+
+
+ org.apache.derby
+ derbynet
+ 10.6.2.1
+
org.junit.jupiter
junit-jupiter-api
@@ -47,4 +57,4 @@
-
\ No newline at end of file
+
diff --git a/collections/src/main/java/ru/msu/vmk/Book.java b/collections/src/main/java/ru/msu/vmk/Book.java
index f2af0e5..4e0b36f 100644
--- a/collections/src/main/java/ru/msu/vmk/Book.java
+++ b/collections/src/main/java/ru/msu/vmk/Book.java
@@ -1,13 +1,55 @@
package ru.msu.vmk;
+import java.util.Objects;
+
public class Book {
+
+ private int bookId;
private String title;
+ private int isReserved;
+
+ public Book() {
+ }
+
public Book(String title){
this.title = title;
}
+ public int getBookId() {
+ return bookId;
+ }
+
+ public void setBookId(int bookId) {
+ this.bookId = bookId;
+ }
+
public String getTitle(){
return title;
}
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public int getIsReserved() {
+ return isReserved;
+ }
+
+ public void setIsReserved(int isReserved) {
+ this.isReserved = isReserved;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Book book = (Book) o;
+ return bookId == book.bookId && isReserved == book.isReserved && Objects.equals(title, book.title);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(bookId, title, isReserved);
+ }
}
diff --git a/collections/src/main/java/ru/msu/vmk/Library.java b/collections/src/main/java/ru/msu/vmk/Library.java
index b5e3b9b..c9fd666 100644
--- a/collections/src/main/java/ru/msu/vmk/Library.java
+++ b/collections/src/main/java/ru/msu/vmk/Library.java
@@ -1,15 +1,38 @@
package ru.msu.vmk;
+import java.sql.Connection;
+import java.sql.SQLException;
import java.util.List;
/* Институтская библиотека */
public interface Library {
/* Регистрация новой книги */
- void addNewBook(Book book);
+ void addNewBook(Book book) throws SQLException;
+
/* Студент берет книгу */
- void borrowBook(Book book, String student);
+ void borrowBook(Book book, String student) throws SQLException;
+
/* Студент возвращает книгу */
- void returnBook(Book book, String student);
+ void returnBook(Book book, String student) throws SQLException;
+
/* Получить список свободных книг */
- List findAvailableBooks();
+ List findAvailableBooks() throws SQLException;
+ /*Инициализация базы данных*/
+ void init() throws SQLException;
+
+ Connection getConnection() throws SQLException;
+
+ Book getBookByTitle(String title) throws SQLException;
+
+ void updateIsReservedFlag(int bookId, int isReserved) throws SQLException;
+
+ Student getStudentByName(String name) throws SQLException;
+
+ List getRelationByStudentId(int studentId) throws SQLException;
+
+ void insertNewStudent(String student) throws SQLException;
+
+ void insertNewRelation(int bookId, int studentId) throws SQLException;
+
+ boolean deleteRelation(int relationId) throws SQLException;
}
diff --git a/collections/src/main/java/ru/msu/vmk/LibraryImpl.java b/collections/src/main/java/ru/msu/vmk/LibraryImpl.java
index 60162b9..5e28963 100644
--- a/collections/src/main/java/ru/msu/vmk/LibraryImpl.java
+++ b/collections/src/main/java/ru/msu/vmk/LibraryImpl.java
@@ -1,25 +1,240 @@
package ru.msu.vmk;
+import java.sql.*;
+import java.util.ArrayList;
import java.util.List;
+import java.util.logging.Logger;
+
+public class LibraryImpl implements Library {
+
+ private final Logger logger = Logger.getLogger(LibraryImpl.class.getName());
+
+ private final String jdbcUrl;
+ private final String user;
+ private final String password;
+
+ public LibraryImpl(String jdbcUrl, String user, String password) {
+ this.jdbcUrl = jdbcUrl;
+ this.user = user;
+ this.password = password;
+ }
-public class LibraryImpl implements Library{
@Override
- public void addNewBook(Book book) {
+ public void addNewBook(Book book) throws SQLException {
+ Book bookInLibrary = getBookByTitle(book.getTitle());
+ if (bookInLibrary == null) {
+ String sql = "insert into LIBRARY.BOOK (TITLE, IS_RESERVED) values (?,?)";
+ try (Connection connection = getConnection(); PreparedStatement pr = connection.prepareStatement(sql)) {
+ pr.setString(1, book.getTitle());
+ pr.setInt(2, 0);
+ int row = pr.executeUpdate();
+ if (row > 0) {
+ logger.info("Книга добавлена.");
+ }
+ }
+ } else {
+ logger.info("Книга уже есть в библиотеке!");
+ }
+ }
+ @Override
+ public void borrowBook(Book book, String student) throws SQLException {
+ Book bookInLibrary = getBookByTitle(book.getTitle());
+ if (bookInLibrary != null && bookInLibrary.getIsReserved() != 1) {
+ updateIsReservedFlag(bookInLibrary.getBookId(), 1);
+ Student studentInDB = getStudentByName(student);
+ if (studentInDB == null) {
+ insertNewStudent(student);
+ studentInDB = getStudentByName(student);
+ }
+ List relations = getRelationByStudentId(studentInDB.getStudentId());
+ if (!relations.isEmpty()) {
+ if (relations.stream().anyMatch(rel -> rel.getBookId() != bookInLibrary.getBookId())) {
+ insertNewRelation(bookInLibrary.getBookId(), studentInDB.getStudentId());
+ }
+ } else {
+ insertNewRelation(bookInLibrary.getBookId(), studentInDB.getStudentId());
+ }
+ logger.info("Книга выдана.");
+ } else {
+ logger.info("Книги нет в библиотеки.");
+ }
}
@Override
- public void borrowBook(Book book, String student) {
+ public void returnBook(Book book, String student) throws SQLException {
+ Student studentInDB = getStudentByName(student);
+ if (studentInDB != null) {
+ List relations = getRelationByStudentId(studentInDB.getStudentId());
+ if (!relations.isEmpty()) {
+ relations.stream().filter(rel -> rel.getBookId() == book.getBookId()).forEach(relation -> {
+ try {
+ updateIsReservedFlag(relation.getBookId(), 0);
+ deleteRelation(relation.getRelationId());
+ logger.info("Книгу вернули.");
+ } catch (SQLException e) {
+ logger.severe(e.getMessage());
+ }
+ });
+ } else {
+ logger.info("За студентом не числится эта книга!");
+ }
+ } else {
+ logger.info("Студент не найден!");
+ }
+ }
+ @Override
+ public List findAvailableBooks() throws SQLException {
+ List out = new ArrayList<>();
+ String sql = "select * from LIBRARY.BOOK where is_reserved = 0";
+ try (Connection connection = getConnection(); PreparedStatement pr = connection.prepareStatement(sql)) {
+ ResultSet resultSet = pr.executeQuery();
+ while (resultSet.next()) {
+ Book book = new Book();
+ book.setBookId(resultSet.getInt("BOOK_ID"));
+ book.setTitle(resultSet.getString("TITLE"));
+ book.setIsReserved(resultSet.getInt("IS_RESERVED"));
+ out.add(book);
+ }
+ }
+ return out;
}
@Override
- public void returnBook(Book book, String student) {
+ public void init() throws SQLException {
+ try (Statement stmt = getConnection().createStatement()) {
+ stmt.execute("create schema LIBRARY");
+ stmt.execute("set schema LIBRARY");
+ stmt.execute("CREATE TABLE LIBRARY.BOOK " +
+ " (BOOK_ID INT NOT NULL GENERATED ALWAYS AS IDENTITY " +
+ " (START WITH 1, INCREMENT BY 1), TITLE VARCHAR(1000), IS_RESERVED INT)");
+ stmt.execute("CREATE TABLE LIBRARY.STUDENT " +
+ " (STUDENT_ID INT NOT NULL GENERATED ALWAYS AS IDENTITY " +
+ " (START WITH 1, INCREMENT BY 1), NAME VARCHAR(100))");
+ stmt.execute("CREATE TABLE LIBRARY.RELATION " +
+ " (RELATION_ID INT NOT NULL GENERATED ALWAYS AS IDENTITY " +
+ " (START WITH 1, INCREMENT BY 1), STUDENT_ID INT NOT NULL, BOOK_ID INT NOT NULL)");
+ }
+ }
+ @Override
+ public Connection getConnection() throws SQLException {
+ return DriverManager.getConnection(jdbcUrl, user, password);
+ }
+
+ @Override
+ public Book getBookByTitle(String title) throws SQLException {
+ Book out = null;
+ String sql = "select * from LIBRARY.BOOK where title = ?";
+ try (Connection connection = getConnection(); PreparedStatement pr = connection.prepareStatement(sql)) {
+ pr.setString(1, title);
+ ResultSet resultSet = pr.executeQuery();
+ while (resultSet.next()) {
+ out = new Book();
+ out.setBookId(resultSet.getInt("BOOK_ID"));
+ out.setTitle(resultSet.getString("TITLE"));
+ out.setIsReserved(resultSet.getInt("IS_RESERVED"));
+ }
+ }
+ return out;
+ }
+
+ @Override
+ public void updateIsReservedFlag(int bookId, int isReserved) throws SQLException {
+ String sql = "update LIBRARY.BOOK set is_reserved = ? where book_id = ?";
+ try (Connection connection = getConnection(); PreparedStatement pr = connection.prepareStatement(sql)) {
+ pr.setInt(1, isReserved);
+ pr.setInt(2, bookId);
+ pr.executeUpdate();
+ }
+ }
+
+ @Override
+ public Student getStudentByName(String name) throws SQLException {
+ Student out = null;
+ String sql = "select * from LIBRARY.STUDENT where name = ?";
+ try (Connection connection = getConnection(); PreparedStatement pr = connection.prepareStatement(sql)) {
+ pr.setString(1, name);
+ ResultSet resultSet = pr.executeQuery();
+ while (resultSet.next()) {
+ out = new Student();
+ out.setStudentId(resultSet.getInt("STUDENT_ID"));
+ out.setStudentName(resultSet.getString("NAME"));
+ }
+ }
+ return out;
+ }
+
+ @Override
+ public List getRelationByStudentId(int studentId) throws SQLException {
+ List out = new ArrayList<>();
+ String sql = "select * from LIBRARY.RELATION where student_id = ?";
+ try (Connection connection = getConnection(); PreparedStatement pr = connection.prepareStatement(sql)) {
+ pr.setInt(1, studentId);
+ ResultSet resultSet = pr.executeQuery();
+ while (resultSet.next()) {
+ Relation relation = new Relation();
+ relation.setRelationId(resultSet.getInt("RELATION_ID"));
+ relation.setStudentId(resultSet.getInt("STUDENT_ID"));
+ relation.setBookId(resultSet.getInt("BOOK_ID"));
+ out.add(relation);
+ }
+ }
+ return out;
+ }
+
+ @Override
+ public void insertNewStudent(String student) throws SQLException {
+ String sql = "insert into LIBRARY.STUDENT (NAME) " +
+ "values (?)";
+ try (Connection connection = getConnection()) {
+ connection.setAutoCommit(false);
+ try (PreparedStatement pr = connection.prepareStatement(sql)) {
+ pr.setString(1, student);
+ pr.execute();
+ connection.commit();
+ } catch (SQLException e) {
+ logger.severe(e.getMessage());
+ getConnection().rollback();
+ }
+ }
+ }
+
+ @Override
+ public void insertNewRelation(int bookId, int studentId) throws SQLException {
+ String sql = "insert into LIBRARY.RELATION (STUDENT_ID, BOOK_ID) " +
+ "values (?, ?)";
+ try (Connection connection = getConnection()) {
+ connection.setAutoCommit(false);
+ try (PreparedStatement pr = connection.prepareStatement(sql)) {
+ pr.setInt(1, studentId);
+ pr.setInt(2, bookId);
+ pr.execute();
+ connection.commit();
+ } catch (SQLException e) {
+ logger.severe(e.getMessage());
+ getConnection().rollback();
+ }
+ }
}
@Override
- public List findAvailableBooks() {
- return null;
+ public boolean deleteRelation(int relationId) throws SQLException {
+ boolean flag = false;
+ String sql = "delete from LIBRARY.RELATION where relation_id = ?";
+ try (Connection connection = getConnection()) {
+ try (PreparedStatement pr = connection.prepareStatement(sql)) {
+ pr.setInt(1, relationId);
+ int row = pr.executeUpdate();
+ if (row > 0) {
+ flag = true;
+ }
+ } catch (SQLException e) {
+ logger.severe(e.getMessage());
+ getConnection().rollback();
+ }
+ }
+ return flag;
}
}
diff --git a/collections/src/main/java/ru/msu/vmk/Main.java b/collections/src/main/java/ru/msu/vmk/Main.java
index 50c42f1..dbbe6f7 100644
--- a/collections/src/main/java/ru/msu/vmk/Main.java
+++ b/collections/src/main/java/ru/msu/vmk/Main.java
@@ -1,62 +1,34 @@
package ru.msu.vmk;
+import org.apache.derby.drda.NetworkServerControl;
+
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.sql.*;
import java.util.*;
public class Main {
- public static void main(String[] args) {
- var set = new HashSet();
-
- set.add("test");
- set.add("test1");
-
- for (var element: set){
- // System.out.println(element);
- }
-
- var map = new HashMap();
-
- map.putIfAbsent(1, "test1");
- map.putIfAbsent(1, "test3");
- map.putIfAbsent(2, "test2");
-
+ public static void main(String[] args) throws Exception {
- for (var key: map.keySet()){
- System.out.println("key=" + key + " value=" + map.get(key));
- }
-
- var array = new ArrayList();
+ Library library = new LibraryImpl("jdbc:derby:memory:testdb;create=true", "test", "test");
+ library.init();
- array.add("first");
- array.add("second");
- array.add("third");
+ NetworkServerControl nsc = new NetworkServerControl(InetAddress.getByName("localhost"), 1527);
+ nsc.start(new PrintWriter(System.out, true));
- array.add(1, "modified");
- System.out.println(array.set(1, "modified1"));
-
- for (var element: array){
- System.out.println("index = " + array.indexOf(element) + " element =" + element);
- }
+ Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
- var deque = new ArrayDeque();
+ Connection c = DriverManager.getConnection("jdbc:derby:memory:testdb;create=true");
+ try(Connection conn = c;
+ PreparedStatement ps = conn.prepareStatement("create schema TEST");) {
- deque.offer("first");
- deque.offer("second");
- deque.offer("third");
+ boolean success = ps.execute();
+ System.out.println("Memory database created: " + success);
- while (!deque.isEmpty()){
- var element = deque.removeLast();
- System.out.println(element);
+ } catch (SQLException e) {
+ e.printStackTrace();
}
- var stack = new Stack();
-
- stack.push("first");
- stack.push("second");
- stack.push("third");
-
- while (!stack.isEmpty()){
- var element = stack.pop();
- System.out.println(element);
- }
}
-}
\ No newline at end of file
+}
diff --git a/collections/src/main/java/ru/msu/vmk/Relation.java b/collections/src/main/java/ru/msu/vmk/Relation.java
new file mode 100644
index 0000000..aaaa608
--- /dev/null
+++ b/collections/src/main/java/ru/msu/vmk/Relation.java
@@ -0,0 +1,50 @@
+package ru.msu.vmk;
+
+import java.util.Objects;
+
+public class Relation {
+
+ private int relationId;
+ private int bookId;
+ private int studentId;
+
+ public Relation() {
+ }
+
+ public int getRelationId() {
+ return relationId;
+ }
+
+ public void setRelationId(int relationId) {
+ this.relationId = relationId;
+ }
+
+ public int getBookId(){
+ return bookId;
+ }
+
+ public void setBookId(int bookId) {
+ this.bookId = bookId;
+ }
+
+ public int getStudentId() {
+ return studentId;
+ }
+
+ public void setStudentId(int studentId) {
+ this.studentId = studentId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Relation relation = (Relation) o;
+ return relationId == relation.relationId && bookId == relation.bookId && studentId == relation.studentId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(relationId, bookId, studentId);
+ }
+}
diff --git a/collections/src/main/java/ru/msu/vmk/Student.java b/collections/src/main/java/ru/msu/vmk/Student.java
new file mode 100644
index 0000000..e0514e6
--- /dev/null
+++ b/collections/src/main/java/ru/msu/vmk/Student.java
@@ -0,0 +1,45 @@
+package ru.msu.vmk;
+
+import java.util.Objects;
+
+public class Student {
+
+ private int studentId;
+ private String studentName;
+
+ public Student() {
+ }
+
+ public Student(String studentName){
+ this.studentName = studentName;
+ }
+
+ public int getStudentId() {
+ return studentId;
+ }
+
+ public void setStudentId(int studentId) {
+ this.studentId = studentId;
+ }
+
+ public String getStudentName(){
+ return studentName;
+ }
+
+ public void setStudentName(String studentName) {
+ this.studentName = studentName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Student book = (Student) o;
+ return studentId == book.studentId && Objects.equals(studentName, book.studentName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(studentId, studentName);
+ }
+}
diff --git a/object-oriented-programming/pom.xml b/object-oriented-programming/pom.xml
index 08c5893..6d9c60d 100644
--- a/object-oriented-programming/pom.xml
+++ b/object-oriented-programming/pom.xml
@@ -23,6 +23,12 @@
junit-jupiter
5.9.2
+
+ ru.msu.vmk
+ basics
+ 1.0-SNAPSHOT
+ compile
+
@@ -35,4 +41,4 @@
-
\ No newline at end of file
+
diff --git a/object-oriented-programming/src/main/java/ru/msu/vmk/Quantity.java b/object-oriented-programming/src/main/java/ru/msu/vmk/Quantity.java
index 6c1810e..ea1b336 100644
--- a/object-oriented-programming/src/main/java/ru/msu/vmk/Quantity.java
+++ b/object-oriented-programming/src/main/java/ru/msu/vmk/Quantity.java
@@ -1,6 +1,9 @@
package ru.msu.vmk;
import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* По примеру класса {@link Money} реализовать класс Quantity:
@@ -13,11 +16,23 @@
*
- для проверки работы реализовать функцию main() или Unit-test
*/
public class Quantity {
+
+ private final BigDecimal amount;
+ private final String unitOfMeasurement;
+
/**
* @param amount - сумма
* @param unitOfMeasurement - единица измерения
*/
public Quantity(BigDecimal amount, String unitOfMeasurement) {
+ if (amount == null) {
+ throw new IllegalArgumentException("amount cannot be null");
+ }
+ if (unitOfMeasurement == null || unitOfMeasurement.isBlank()) {
+ throw new IllegalArgumentException("currency cannot be empty");
+ }
+ this.amount = amount.setScale(2, RoundingMode.HALF_EVEN);
+ this.unitOfMeasurement = unitOfMeasurement;
}
/**
@@ -25,7 +40,7 @@ public Quantity(BigDecimal amount, String unitOfMeasurement) {
* @return {@link Quantity#amount}
*/
public BigDecimal getAmount() {
- return null;
+ return amount;
}
/**
@@ -35,7 +50,9 @@ public BigDecimal getAmount() {
* @return сумма чисел
*/
public Quantity add(Quantity quantity) throws Exception {
- return null;
+ validateCurrenciesAreEqual(quantity);
+ BigDecimal sum = this.amount.add(quantity.amount);
+ return new Quantity(sum, this.unitOfMeasurement);
}
/**
@@ -45,7 +62,9 @@ public Quantity add(Quantity quantity) throws Exception {
* @return разность чисел
*/
public Quantity subtract(Quantity quantity) throws Exception {
- return null;
+ validateCurrenciesAreEqual(quantity);
+ BigDecimal result = this.amount.subtract(quantity.amount);
+ return new Quantity(result, this.unitOfMeasurement);
}
/**
@@ -55,7 +74,9 @@ public Quantity subtract(Quantity quantity) throws Exception {
* @return произведение
*/
public Quantity multiply(Quantity quantity) throws Exception {
- return null;
+ validateCurrenciesAreEqual(quantity);
+ BigDecimal result = this.amount.multiply(quantity.amount);
+ return new Quantity(result, this.unitOfMeasurement);
}
/**
@@ -65,7 +86,9 @@ public Quantity multiply(Quantity quantity) throws Exception {
* @return частное
*/
public Quantity divide(Quantity quantity) throws Exception {
- return null;
+ validateCurrenciesAreEqual(quantity);
+ BigDecimal result = this.amount.divide(quantity.amount, RoundingMode.HALF_EVEN);
+ return new Quantity(result, this.unitOfMeasurement);
}
/**
@@ -75,6 +98,12 @@ public Quantity divide(Quantity quantity) throws Exception {
* @return равные части числа
*/
public Quantity[] divide(int n) throws Exception {
- return null;
+ return Arrays.stream(NumberSample.split(this.amount, n)).map(bigDecimal -> new Quantity(bigDecimal, this.unitOfMeasurement)).toArray(Quantity[]::new);
+ }
+
+ private void validateCurrenciesAreEqual(Quantity quantity) {
+ if (!this.unitOfMeasurement.equals(quantity.unitOfMeasurement)) {
+ throw new IllegalArgumentException("Валюты не совпадают: " + this.unitOfMeasurement + " " + quantity.unitOfMeasurement);
+ }
}
}