Compare commits

...

2 Commits

40 changed files with 13059 additions and 0 deletions

23
library-ui/.gitignore vendored Normal file
View File

@ -0,0 +1,23 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

24
library-ui/README.md Normal file
View File

@ -0,0 +1,24 @@
# library-ui
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

View File

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

19
library-ui/jsconfig.json Normal file
View File

@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}

12033
library-ui/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

43
library-ui/package.json Normal file
View File

@ -0,0 +1,43 @@
{
"name": "library-ui",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.8.3",
"vue": "^3.2.13"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

26
library-ui/src/App.vue Normal file
View File

@ -0,0 +1,26 @@
<template>
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -0,0 +1,58 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

4
library-ui/src/main.js Normal file
View File

@ -0,0 +1,4 @@
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')

4
library-ui/vue.config.js Normal file
View File

@ -0,0 +1,4 @@
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true
})

View File

@ -19,6 +19,9 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.6.0'
runtimeOnly 'com.h2database:h2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

BIN
network/data/home.mv.db Normal file

Binary file not shown.

View File

@ -0,0 +1,3 @@
2024-11-25 15:24:18.380541+04:00 jdbc[3]: exception
org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "AUTHOR" not found (this database is empty); SQL statement:
insert into author (email,first_name,last_name,password,id) values (?,?,?,?,default) [42104-224]

View File

@ -0,0 +1,40 @@
package com.ulstu.network.advice;
import com.ulstu.network.exceptions.AuthorNotFoundException;
import com.ulstu.network.exceptions.BookNotFoundException;
import com.ulstu.network.exceptions.ValidationException;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.util.stream.Collectors;
@ControllerAdvice
public class AdviceController {
@ExceptionHandler({
AuthorNotFoundException.class,
BookNotFoundException.class,
ValidationException.class
})
public ResponseEntity<Object> handleException(Throwable e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Object> handleBindException(MethodArgumentNotValidException e) {
final ValidationException validationException = new ValidationException(
e.getBindingResult().getAllErrors().stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.toSet()));
return handleException(validationException);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleUnknownException(Throwable e) {
e.printStackTrace();
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}

View File

@ -0,0 +1,54 @@
package com.ulstu.network.controllers;
import com.ulstu.network.dto.AuthorDTO;
import com.ulstu.network.models.Author;
import com.ulstu.network.services.AuthorService;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/author")
public class AuthorController {
private final AuthorService authorService;
public AuthorController(AuthorService authorService){
this.authorService = authorService;
}
@GetMapping("/{id}")
public AuthorDTO getAuthor(@PathVariable Long id) {
return new AuthorDTO(authorService.findAuthor(id));
}
@GetMapping
public List<AuthorDTO> getAuthors() {
return authorService.findAllAuthors().stream()
.map(AuthorDTO::new)
.toList();
}
@PostMapping
public AuthorDTO createAuthor(@RequestBody @Valid Author author) {
return new AuthorDTO(authorService.addAuthor(author));
}
@PostMapping("/{id}")
public AuthorDTO attachBookToAuthor(@PathVariable Long id, @RequestParam Long bookId) {
return new AuthorDTO(authorService.attachBookToAuthor(id, bookId));
}
@PutMapping("/{id}")
public AuthorDTO updateAuthor(@PathVariable Long id, @RequestBody @Valid Author author ){
return new AuthorDTO(authorService.updateAuthor(id, author));
}
@DeleteMapping("/{id}")
public void deleteAuthor(@PathVariable Long id){
authorService.deleteAuthor(id);
}
}

View File

@ -0,0 +1,42 @@
package com.ulstu.network.controllers;
import com.ulstu.network.dto.BookDTO;
import com.ulstu.network.dto.BookDataDTO;
import com.ulstu.network.models.Book;
import com.ulstu.network.services.BookService;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/book")
public class BookController {
private final BookService bookService;
public BookController(BookService bookService) { this.bookService = bookService; }
@GetMapping("/{id}")
public BookDTO getBook(@PathVariable long id) { return new BookDTO(bookService.findBook(id)); }
@GetMapping
public List<BookDTO> getBooks() {
return bookService.findAllBooks().stream()
.map(BookDTO::new)
.toList();
}
@PostMapping
public BookDTO createBook(@RequestBody @Valid BookDataDTO bookData) {
return new BookDTO(bookService.addBook(bookData));
}
@PutMapping("/{id}")
public BookDTO updateBook(@PathVariable Long id, @RequestBody @Valid BookDataDTO bookData) {
return new BookDTO(bookService.updateBook(id, bookData));
}
@DeleteMapping("/{id}")
public void deleteBook(@PathVariable Long id) {bookService.deleteBook(id);}
}

View File

@ -0,0 +1,34 @@
package com.ulstu.network.dto;
import com.ulstu.network.models.Author;
import com.ulstu.network.models.Book;
import java.util.List;
public class AuthorDTO {
private final long id;
private final String name;
private final String email;
private final List<Book> books;
public AuthorDTO(Author author) {
this.id = author.getId();
this.name = String.format("%s %s", author.getFirstName(), author.getLastName());
this.email = author.getEmail();
this.books = author.getBooks();
}
public long getId() {
return id;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public List<Book> getBooks(){
return books;
}
}

View File

@ -0,0 +1,25 @@
package com.ulstu.network.dto;
import com.ulstu.network.models.Author;
import com.ulstu.network.models.Book;
import java.util.List;
public class BookDTO {
private final long id;
private final String title;
private final String isbn;
private final List<Author> authors;
public BookDTO(Book book) {
this.id = book.getId();
this.title = book.getTitle();
this.isbn = book.getIsbn();
this.authors = book.getAuthors();
}
public long getId() {return id;}
public String getTitle() {return title;}
public String getIsbn() {return isbn;}
public List<Author> getAuthors() {return authors;}
}

View File

@ -0,0 +1,39 @@
package com.ulstu.network.dto;
import jakarta.validation.constraints.NotBlank;
import java.util.List;
public class BookDataDTO {
@NotBlank(message = "Title can't be empty")
private String title;
@NotBlank(message = "ISBN can't be empty")
private String isbn;
private List<Long> authors;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public List<Long> getAuthors() {
return authors;
}
public void setAuthors(List<Long> authors) {
this.authors = authors;
}
}

View File

@ -0,0 +1,4 @@
package com.ulstu.network.dto;
public class LibraryDTO {
}

View File

@ -0,0 +1,7 @@
package com.ulstu.network.exceptions;
public class AuthorNotFoundException extends RuntimeException{
public AuthorNotFoundException(Long id){
super(String.format("Author with id [%s] is not found", id));
}
}

View File

@ -0,0 +1,8 @@
package com.ulstu.network.exceptions;
public class BookNotFoundException extends RuntimeException{
public BookNotFoundException(Long id){
super(String.format("Book with id [%s] is not found", id));
}
}

View File

@ -0,0 +1,9 @@
package com.ulstu.network.exceptions;
import java.util.Set;
public class ValidationException extends RuntimeException {
public <T> ValidationException(Set<String> errors) {
super(String.join("\n", errors));
}
}

View File

@ -0,0 +1,85 @@
package com.ulstu.network.models;
import jakarta.persistence.*;
import jakarta.validation.constraints.*;
import java.util.List;
@Entity
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(nullable = false)
@NotBlank(message = "First Name can't be empty")
private String firstName;
@Column(nullable = false)
@NotBlank(message = "Last Name can't be empty")
private String lastName;
@Email(message = "Please enter a correct email address")
@NotBlank(message = "Email can't be empty")
private String email;
/*@Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\\\d).{8}$",
message = "Password is not valid")*/
@NotBlank
private String password;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "book_author", joinColumns = @JoinColumn(name = "book_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "author_id", referencedColumnName = "id"))
private List<Book> books;
public Author() {
}
public Author(String firstName, String lastName, String email, String password) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.password = password;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setEmail (String email) { this.email = email; }
public String getEmail () { return email; }
public void setPassword (String password) { this.password = password; }
public String getPassword () { return password; }
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
}

View File

@ -0,0 +1,64 @@
package com.ulstu.network.models;
import jakarta.persistence.*;
import java.util.List;
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String isbn;
@ManyToMany(mappedBy = "books", fetch = FetchType.EAGER)
private List<Author> authors;
public Book() {
}
public Book(String title, String isbn) {
super();
this.title = title;
this.isbn = isbn;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public List<Author> getAuthors() {
return authors;
}
public void setAuthors(List<Author> authors) {
this.authors = authors;
}
}

View File

@ -0,0 +1,66 @@
package com.ulstu.network.models;
import jakarta.persistence.*;
import java.util.List;
@Entity
public class Library {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column
private String name;
@Column
private String address;
@OneToMany
@JoinTable(name = "books_in_library",
joinColumns = @JoinColumn(name = "library_id"),
inverseJoinColumns = @JoinColumn(name = "book_id"))
private List<Book> books;
public Library() {
}
public Library(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
}

View File

@ -0,0 +1,69 @@
package com.ulstu.network.models;
import jakarta.persistence.*;
import java.util.List;
@Entity
@Table(name = "USERS")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column
private String name;
@Column
private String email;
@Column
private String password;
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="user_books",
joinColumns=@JoinColumn(name="user_id", referencedColumnName = "id"),
inverseJoinColumns=@JoinColumn(name="book_id", referencedColumnName = "id"))
private List<Book> books;
public User(){
}
public User(String name, String email, String password){
super();
this.name = name;
this.email = email;
this.password = password;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public void setName (String name) { this.name = name; }
public String getName () { return name; }
public void setEmail (String email) { this.email = email; }
public String getEmail () { return email; }
public void setPassword (String password) { this.password = password; }
public String getPassword () { return password; }
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
public void addBook(Book book) { this.books.add(book); }
}

View File

@ -0,0 +1,6 @@
package com.ulstu.network.repositories;
import com.ulstu.network.models.Author;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AuthorRepository extends JpaRepository<Author, Long> {}

View File

@ -0,0 +1,6 @@
package com.ulstu.network.repositories;
import com.ulstu.network.models.Book;
import org.springframework.data.jpa.repository.JpaRepository;
public interface BookRepository extends JpaRepository<Book, Long> {}

View File

@ -0,0 +1,11 @@
package com.ulstu.network.repositories;
import com.ulstu.network.models.Library;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
public interface LibraryRepository extends JpaRepository<Library, Long> {}

View File

@ -0,0 +1,7 @@
package com.ulstu.network.repositories;
import com.ulstu.network.models.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}

View File

@ -0,0 +1,73 @@
package com.ulstu.network.services;
import com.ulstu.network.models.Book;
import com.ulstu.network.repositories.BookRepository;
import com.ulstu.network.validation.ValidatorUtil;
import com.ulstu.network.exceptions.AuthorNotFoundException;
import com.ulstu.network.models.Author;
import com.ulstu.network.repositories.AuthorRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class AuthorService {
private final AuthorRepository authorRepository;
private final BookService bookService;
private final ValidatorUtil validatorUtil;
public AuthorService(AuthorRepository authorRepository, BookService bookService, ValidatorUtil validatorUtil){
this.authorRepository = authorRepository;
this.bookService = bookService;
this.validatorUtil = validatorUtil;
}
@Transactional(readOnly = true)
public Author findAuthor(Long id) {
return authorRepository.findById(id).orElseThrow(()->new AuthorNotFoundException(id));
}
@Transactional(readOnly = true)
public List<Author> findAllAuthors() {
return authorRepository.findAll();
}
@Transactional
public Author addAuthor(Author author) {
validatorUtil.validate(author);
return authorRepository.save(author);
}
@Transactional
public Author attachBookToAuthor(Long authorId, Long bookId) {
final Author currentAuthor = findAuthor(authorId);
currentAuthor.getBooks().add(bookService.findBook(bookId));
return authorRepository.save(currentAuthor);
}
@Transactional
public Author updateAuthor(Long id, Author author) {
validatorUtil.validate(author);
final Author currentAuthor = findAuthor(id);
currentAuthor.setFirstName(author.getFirstName());
currentAuthor.setLastName(author.getLastName());
currentAuthor.setEmail(author.getEmail());
currentAuthor.setPassword(author.getPassword());
return authorRepository.save(currentAuthor);
}
@Transactional
public void deleteAuthor(Long id) {
final Author currentAuthor = findAuthor(id);
authorRepository.delete(currentAuthor);
}
@Transactional
public void deleteAllAuthors() {
authorRepository.deleteAll();
}
}

View File

@ -0,0 +1,85 @@
package com.ulstu.network.services;
import com.ulstu.network.dto.BookDataDTO;
import com.ulstu.network.exceptions.AuthorNotFoundException;
import com.ulstu.network.exceptions.BookNotFoundException;
import com.ulstu.network.models.Author;
import com.ulstu.network.models.Book;
import com.ulstu.network.repositories.AuthorRepository;
import com.ulstu.network.repositories.BookRepository;
import com.ulstu.network.validation.ValidatorUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static java.util.Collections.emptyList;
@Service
public class BookService {
private final BookRepository bookRepository;
private final AuthorRepository authorRepository;
private final ValidatorUtil validatorUtil;
public BookService(BookRepository bookRepository, AuthorRepository authorRepository, ValidatorUtil validatorUtil){
this.bookRepository = bookRepository;
this.authorRepository = authorRepository;
this.validatorUtil = validatorUtil;
}
@Transactional(readOnly = true)
public Book findBook(Long id) {
return bookRepository.findById(id).orElseThrow(()->new BookNotFoundException(id));
}
@Transactional(readOnly = true)
public List<Book> findAllBooks() {
return bookRepository.findAll();
}
@Transactional
public Book addBook(BookDataDTO bookData) {
validatorUtil.validate(bookData);
Book newBook = new Book(bookData.getTitle(), bookData.getIsbn());
List<Author> authors = new ArrayList<>();
for (long id : bookData.getAuthors())
{
authorRepository.findById(id).ifPresent(authors::add);
}
newBook.setAuthors(authors);
return bookRepository.save(newBook);
}
@Transactional
public Book updateBook(Long id, BookDataDTO bookData) {
validatorUtil.validate(bookData);
final Book currentBook = findBook(id);
currentBook.setTitle(bookData.getTitle());
currentBook.setIsbn(bookData.getIsbn());
List<Author> authors = emptyList();
for (long auth : bookData.getAuthors())
{
authorRepository.findById(auth).ifPresent(authors::add);
}
currentBook.setAuthors(authors);
return bookRepository.save(currentBook);
}
@Transactional
public void deleteBook(Long id) {
final Book currentBook = findBook(id);
bookRepository.delete(currentBook);
}
public void deleteAllBooks(){
bookRepository.deleteAll();
}
}

View File

@ -0,0 +1,4 @@
package com.ulstu.network.services;
public class LibraryService {
}

View File

@ -0,0 +1,24 @@
/*
package com.ulstu.network.swagger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.controller")) // Replace with your controller package
.paths(PathSelectors.any())
.build();
}
}
*/

View File

@ -0,0 +1,26 @@
package com.ulstu.network.validation;
import com.ulstu.network.exceptions.ValidationException;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import org.springframework.stereotype.Component;
import java.util.Set;
import java.util.stream.Collectors;
@Component
public class ValidatorUtil {
private final Validator validator;
public ValidatorUtil() {
this.validator = Validation.buildDefaultValidatorFactory().getValidator();
}
public <T> void validate(T object) {
final Set<ConstraintViolation<T>> errors = validator.validate(object);
if (!errors.isEmpty()) {
throw new ValidationException(errors.stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.toSet()));
}
}
}

View File

@ -1 +1,10 @@
spring.application.name=network
# H2 Database
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:file:C://tmp/data
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect