@@ -0,0 +1,185 @@
|
||||
package br.com.tasknoteapp.java_api.controller;
|
||||
|
||||
import br.com.tasknoteapp.java_api.entity.NoteEntity;
|
||||
import br.com.tasknoteapp.java_api.request.NotePatchRequest;
|
||||
import br.com.tasknoteapp.java_api.request.NoteRequest;
|
||||
import br.com.tasknoteapp.java_api.response.NoteResponse;
|
||||
import br.com.tasknoteapp.java_api.service.NoteService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/rest/notes")
|
||||
@AllArgsConstructor
|
||||
@Tag(name = "Notes", description = "Notes resources to handle stored notes.")
|
||||
public class NoteController {
|
||||
|
||||
private final NoteService noteService;
|
||||
|
||||
/**
|
||||
* Get all notes.
|
||||
*
|
||||
* @return List of NoteResponse with all found notes and its urls, if any.
|
||||
*/
|
||||
@GetMapping
|
||||
@Operation(
|
||||
summary = "Get all notes",
|
||||
description = "Get all notes for the current user and its urls, if any",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "Notes successfully retrieved",
|
||||
content =
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
schema = @Schema(implementation = NoteResponse.class, type = "array"))),
|
||||
@ApiResponse(
|
||||
responseCode = "403",
|
||||
description = "Forbidden. Access Denied",
|
||||
content = @Content(schema = @Schema(implementation = Void.class)))
|
||||
})
|
||||
public List<NoteResponse> getAllNotes() {
|
||||
return noteService.getAllNotes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch a note.
|
||||
*
|
||||
* @param id The note id to be patched.
|
||||
* @param noteRequest Note data to be patched, including optionally its urls.
|
||||
* @return NoteResponse containing data that was updated.
|
||||
* @throws NoteNotFoundException when note not found.
|
||||
*/
|
||||
@PatchMapping("/{id}")
|
||||
@Operation(
|
||||
summary = "Patch a note",
|
||||
description = "Patch a note and all its urls. Option to patch only the urls.",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "Note successfully patched",
|
||||
content =
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
schema = @Schema(implementation = NoteResponse.class))),
|
||||
@ApiResponse(
|
||||
responseCode = "403",
|
||||
description = "Forbidden. Access Denied",
|
||||
content = @Content(schema = @Schema(implementation = Void.class))),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "Note not found",
|
||||
content = @Content(schema = @Schema(implementation = Void.class)))
|
||||
})
|
||||
public ResponseEntity<NoteResponse> putNote(
|
||||
@Parameter(
|
||||
name = "id",
|
||||
in = ParameterIn.PATH,
|
||||
description = "Note id to be patched.",
|
||||
required = true,
|
||||
schema = @Schema(type = "integer", format = "int64"))
|
||||
@PathVariable
|
||||
Long id,
|
||||
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
||||
description = "Note data to be patched, including optionally its urls.",
|
||||
required = true)
|
||||
@RequestBody
|
||||
@Valid
|
||||
NotePatchRequest noteRequest) {
|
||||
return ResponseEntity.ok(noteService.patchNote(id, noteRequest));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a note.
|
||||
*
|
||||
* @param noteRequest Note data to be created, including optionally its urls. Following RESTful
|
||||
* API pattern from https://restfulapi.net/rest-put-vs-post/.
|
||||
* @return NoteResponse containing data that was created.
|
||||
*/
|
||||
@PostMapping
|
||||
@Operation(
|
||||
summary = "Create a note",
|
||||
description = "Create a note and all its urls.",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "201",
|
||||
description = "Note successfully crated.",
|
||||
content =
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
schema = @Schema(implementation = NoteResponse.class))),
|
||||
@ApiResponse(
|
||||
responseCode = "400",
|
||||
description = "Wrong or missing information",
|
||||
content = @Content(schema = @Schema(implementation = Void.class))),
|
||||
@ApiResponse(
|
||||
responseCode = "403",
|
||||
description = "Forbidden. Access Denied",
|
||||
content = @Content(schema = @Schema(implementation = Void.class))),
|
||||
})
|
||||
public ResponseEntity<NoteResponse> postNotes(
|
||||
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
||||
description = "Note data to be created, including optionally its urls.",
|
||||
required = true)
|
||||
@RequestBody
|
||||
@Valid
|
||||
NoteRequest noteRequest) {
|
||||
NoteEntity createdNote = noteService.createNote(noteRequest);
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(NoteResponse.fromEntity(createdNote));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a note given its ID.
|
||||
*
|
||||
* @param id Note identification.
|
||||
* @throws NoteNotFoundException when note not found.
|
||||
*/
|
||||
@DeleteMapping("/{id}")
|
||||
@Operation(
|
||||
summary = "Delete a note",
|
||||
description = "Delete a note given its ID.",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "204",
|
||||
description = "Note successfully deleted",
|
||||
content = @Content(schema = @Schema(implementation = Void.class))),
|
||||
@ApiResponse(
|
||||
responseCode = "403",
|
||||
description = "Forbidden. Access Denied",
|
||||
content = @Content(schema = @Schema(implementation = Void.class))),
|
||||
@ApiResponse(
|
||||
responseCode = "404",
|
||||
description = "Note not found",
|
||||
content = @Content(schema = @Schema(implementation = Void.class)))
|
||||
})
|
||||
public ResponseEntity<Void> deleteNotes(
|
||||
@Parameter(
|
||||
name = "id",
|
||||
in = ParameterIn.PATH,
|
||||
description = "Note id to be patched.",
|
||||
required = true,
|
||||
schema = @Schema(type = "integer", format = "int64"))
|
||||
@PathVariable
|
||||
Long id) {
|
||||
noteService.deleteNote(id);
|
||||
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package br.com.tasknoteapp.java_api.entity;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "notes")
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
public class NoteEntity {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
private String description;
|
||||
|
||||
@JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false, updatable = false)
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
private UserEntity user;
|
||||
|
||||
@OneToMany(mappedBy = "note", fetch = FetchType.LAZY)
|
||||
private List<NoteUrlEntity> urls;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package br.com.tasknoteapp.java_api.entity;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
@ToString
|
||||
@Table(name = "note_urls")
|
||||
@EqualsAndHashCode
|
||||
public class NoteUrlEntity {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
private String url;
|
||||
|
||||
@JoinColumn(name = "note_id", referencedColumnName = "id", nullable = false, updatable = false)
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
private NoteEntity note;
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package br.com.tasknoteapp.java_api.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
/** This class represents a Note Not Found request. */
|
||||
@ResponseStatus(code = HttpStatus.NOT_FOUND)
|
||||
public class NoteNotFoundException extends ResponseStatusException {
|
||||
|
||||
public NoteNotFoundException() {
|
||||
super(HttpStatus.NOT_FOUND, "Task not found");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package br.com.tasknoteapp.java_api.repository;
|
||||
|
||||
import br.com.tasknoteapp.java_api.entity.NoteEntity;
|
||||
import java.util.List;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
|
||||
public interface NoteRepository extends JpaRepository<NoteEntity, Long> {
|
||||
|
||||
List<NoteEntity> findAllByUser_id(Long userId);
|
||||
|
||||
@Query("select n from NoteEntity n where upper(n.description) like %?1% and n.user.id = ?2")
|
||||
List<NoteEntity> findAllBySearchTerm(String searchTerm, Long userId);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package br.com.tasknoteapp.java_api.repository;
|
||||
|
||||
import br.com.tasknoteapp.java_api.entity.NoteUrlEntity;
|
||||
import java.util.List;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface NoteUrlRepository extends JpaRepository<NoteUrlEntity, Long> {
|
||||
|
||||
void deleteAllByIdIn(List<Long> ids);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package br.com.tasknoteapp.java_api.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.List;
|
||||
|
||||
/** This record represents a note patch payload. */
|
||||
@Schema(description = "Note patch payload.")
|
||||
public record NotePatchRequest(
|
||||
@Schema(description = "Note description. Optional.") String description,
|
||||
@Schema(description = "Note urls. Optional.") List<NoteUrlPatchRequest> urls) {}
|
||||
@@ -0,0 +1,11 @@
|
||||
package br.com.tasknoteapp.java_api.request;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/** This record represents a note request to be created. */
|
||||
@Schema(description = "Note request to be created.")
|
||||
public record NoteRequest(
|
||||
@Schema(description = "Note description.") @NotNull String description,
|
||||
@Schema(description = "Note urls. Optional.") List<String> urls) {}
|
||||
@@ -0,0 +1,3 @@
|
||||
package br.com.tasknoteapp.java_api.request;
|
||||
|
||||
public record NoteUrlPatchRequest(Long id, String url) {}
|
||||
@@ -0,0 +1,38 @@
|
||||
package br.com.tasknoteapp.java_api.response;
|
||||
|
||||
import br.com.tasknoteapp.java_api.entity.NoteEntity;
|
||||
import br.com.tasknoteapp.java_api.entity.NoteUrlEntity;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/** This record represents a task and its urls object to be returned. */
|
||||
@Schema(description = "This record represents a task and its urls object to be returned.")
|
||||
public record NoteResponse(
|
||||
@Schema(description = "The id of the note", example = "1") Long id,
|
||||
@Schema(description = "The description of the note", example = "Note 1") String description,
|
||||
@Schema(description = "The urls of the task, zero, one or more.", example = "[]")
|
||||
List<NoteUrlResponse> urls) {
|
||||
|
||||
/**
|
||||
* Creates a NoteResponse given a NoteEntity and its Urls.
|
||||
*
|
||||
* @param entity The NoteEntity source data.
|
||||
* @return NoteResponse instance with all note data and urls, if any.
|
||||
*/
|
||||
public static NoteResponse fromEntity(NoteEntity entity) {
|
||||
List<NoteUrlEntity> urls = entity.getUrls();
|
||||
List<NoteUrlResponse> urlsResponse = new ArrayList<>();
|
||||
if (Objects.isNull(urls)) {
|
||||
urls = List.of();
|
||||
} else {
|
||||
for (NoteUrlEntity url : urls) {
|
||||
NoteUrlResponse urlResponse = new NoteUrlResponse(url.getId(), url.getUrl());
|
||||
urlsResponse.add(urlResponse);
|
||||
}
|
||||
}
|
||||
|
||||
return new NoteResponse(entity.getId(), entity.getDescription(), urlsResponse);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package br.com.tasknoteapp.java_api.response;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
/** This record represents a note url object. */
|
||||
@Schema(description = "This record represents a note url object.")
|
||||
public record NoteUrlResponse(
|
||||
@Schema(description = "Note url id", example = "1") Long id,
|
||||
@Schema(description = "Note url link", example = "http://duckduckgo.com") String url) {}
|
||||
@@ -0,0 +1,20 @@
|
||||
package br.com.tasknoteapp.java_api.service;
|
||||
|
||||
import br.com.tasknoteapp.java_api.entity.NoteEntity;
|
||||
import br.com.tasknoteapp.java_api.request.NotePatchRequest;
|
||||
import br.com.tasknoteapp.java_api.request.NoteRequest;
|
||||
import br.com.tasknoteapp.java_api.response.NoteResponse;
|
||||
import java.util.List;
|
||||
|
||||
public interface NoteService {
|
||||
|
||||
public List<NoteResponse> getAllNotes();
|
||||
|
||||
public NoteEntity createNote(NoteRequest noteRequest);
|
||||
|
||||
public NoteResponse patchNote(Long taskId, NotePatchRequest taskRequest);
|
||||
|
||||
public void deleteNote(Long noteId);
|
||||
|
||||
public List<NoteResponse> searchNotes(String searchTerm);
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package br.com.tasknoteapp.java_api.service.impl;
|
||||
|
||||
import br.com.tasknoteapp.java_api.entity.NoteEntity;
|
||||
import br.com.tasknoteapp.java_api.entity.NoteUrlEntity;
|
||||
import br.com.tasknoteapp.java_api.entity.UserEntity;
|
||||
import br.com.tasknoteapp.java_api.exception.NoteNotFoundException;
|
||||
import br.com.tasknoteapp.java_api.repository.NoteRepository;
|
||||
import br.com.tasknoteapp.java_api.repository.NoteUrlRepository;
|
||||
import br.com.tasknoteapp.java_api.request.NotePatchRequest;
|
||||
import br.com.tasknoteapp.java_api.request.NoteRequest;
|
||||
import br.com.tasknoteapp.java_api.request.NoteUrlPatchRequest;
|
||||
import br.com.tasknoteapp.java_api.response.NoteResponse;
|
||||
import br.com.tasknoteapp.java_api.service.AuthService;
|
||||
import br.com.tasknoteapp.java_api.service.NoteService;
|
||||
import br.com.tasknoteapp.java_api.util.AuthUtil;
|
||||
import jakarta.transaction.Transactional;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class NoteServiceImpl implements NoteService {
|
||||
|
||||
private final NoteRepository noteRepository;
|
||||
|
||||
private final AuthService authService;
|
||||
|
||||
private final AuthUtil authUtil;
|
||||
|
||||
private final NoteUrlRepository noteUrlRepository;
|
||||
|
||||
@Override
|
||||
public List<NoteResponse> getAllNotes() {
|
||||
UserEntity user = getCurrentUser();
|
||||
|
||||
log.info("Get all notes to user {}", user.getId());
|
||||
|
||||
List<NoteEntity> notes = noteRepository.findAllByUser_id(user.getId());
|
||||
log.info("{} notes found!", notes.size());
|
||||
|
||||
return notes.stream().map(NoteResponse::fromEntity).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoteEntity createNote(NoteRequest noteRequest) {
|
||||
UserEntity user = getCurrentUser();
|
||||
|
||||
log.info("Creating note to user {}", user.getId());
|
||||
|
||||
NoteEntity note = new NoteEntity();
|
||||
note.setDescription(noteRequest.description());
|
||||
note.setUser(user);
|
||||
NoteEntity created = noteRepository.save(note);
|
||||
|
||||
if (!Objects.isNull(noteRequest.urls()) && !noteRequest.urls().isEmpty()) {
|
||||
List<NoteUrlEntity> urls = saveUrls(note, noteRequest.urls());
|
||||
note.setUrls(urls);
|
||||
}
|
||||
|
||||
log.info("Note created! Id {}", created.getId());
|
||||
return created;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public NoteResponse patchNote(Long noteId, NotePatchRequest patch) {
|
||||
UserEntity user = getCurrentUser();
|
||||
|
||||
log.info("Patching task {} to user {}", noteId, user.getId());
|
||||
|
||||
Optional<NoteEntity> note = noteRepository.findById(noteId);
|
||||
if (note.isEmpty()) {
|
||||
throw new NoteNotFoundException();
|
||||
}
|
||||
|
||||
NoteEntity noteEntity = note.get();
|
||||
if (!Objects.isNull(patch.description()) && !patch.description().isBlank()) {
|
||||
noteEntity.setDescription(patch.description());
|
||||
}
|
||||
|
||||
if (!Objects.isNull(patch.urls())) {
|
||||
List<Long> urlIds =
|
||||
patch.urls().stream().filter(p -> p.id() != null).map(NoteUrlPatchRequest::id).toList();
|
||||
if (!urlIds.isEmpty()) {
|
||||
noteUrlRepository.deleteAllByIdIn(urlIds);
|
||||
log.info("Deleted {} urls from task {}", urlIds.size(), noteId);
|
||||
} else {
|
||||
log.info("No urls to patch for task {}", noteId);
|
||||
}
|
||||
|
||||
List<String> urlsList =
|
||||
patch.urls().stream().filter(p -> p.id() == null).map(NoteUrlPatchRequest::url).toList();
|
||||
List<NoteUrlEntity> urls = saveUrls(noteEntity, urlsList);
|
||||
|
||||
noteEntity.setUrls(urls);
|
||||
}
|
||||
|
||||
NoteEntity patchedNote = noteRepository.save(noteEntity);
|
||||
|
||||
log.info("Note patched! Id {}", patchedNote.getId());
|
||||
|
||||
return NoteResponse.fromEntity(patchedNote);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void deleteNote(Long noteId) {
|
||||
UserEntity user = getCurrentUser();
|
||||
|
||||
log.info("Deleting note {} to user {}", noteId, user.getId());
|
||||
|
||||
Optional<NoteEntity> note = noteRepository.findById(noteId);
|
||||
if (note.isEmpty()) {
|
||||
throw new NoteNotFoundException();
|
||||
}
|
||||
|
||||
List<NoteUrlEntity> urls = note.get().getUrls();
|
||||
if (!urls.isEmpty()) {
|
||||
noteUrlRepository.deleteAll(urls);
|
||||
log.info("Deleted {} urls from task {}", urls.size(), noteId);
|
||||
} else {
|
||||
log.info("No urls to delete for task {}", noteId);
|
||||
}
|
||||
|
||||
noteRepository.delete(note.get());
|
||||
|
||||
log.info("Note deleted! Id {}", noteId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NoteResponse> searchNotes(String searchTerm) {
|
||||
UserEntity user = getCurrentUser();
|
||||
|
||||
log.info("Searching notes to user {}", user.getId());
|
||||
|
||||
List<NoteEntity> notes = noteRepository.findAllBySearchTerm(searchTerm, user.getId());
|
||||
log.info("{} tasks found!", notes.size());
|
||||
|
||||
return notes.stream().map(NoteResponse::fromEntity).toList();
|
||||
}
|
||||
|
||||
private UserEntity getCurrentUser() {
|
||||
Optional<String> currentUserEmail = authUtil.getCurrentUserEmail();
|
||||
String email = currentUserEmail.orElseThrow();
|
||||
return authService.findByEmail(email).orElseThrow();
|
||||
}
|
||||
|
||||
private List<NoteUrlEntity> saveUrls(NoteEntity noteEntity, List<String> urls) {
|
||||
List<NoteUrlEntity> tasksUrl = new ArrayList<>();
|
||||
for (String url : urls) {
|
||||
NoteUrlEntity taskUrl = new NoteUrlEntity();
|
||||
taskUrl.setUrl(url);
|
||||
taskUrl.setNote(noteEntity);
|
||||
tasksUrl.add(taskUrl);
|
||||
}
|
||||
|
||||
List<NoteUrlEntity> savedUrls = noteUrlRepository.saveAll(tasksUrl);
|
||||
log.info("Saved {} urls to note {}", savedUrls.size(), noteEntity.getId());
|
||||
|
||||
return savedUrls;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
CREATE TABLE IF NOT EXISTS tasknote.notes (
|
||||
id SERIAL,
|
||||
user_id INTEGER NOT NULL,
|
||||
description VARCHAR(300) NOT NULL,
|
||||
CONSTRAINT notes_pk PRIMARY KEY (id),
|
||||
CONSTRAINT notes_user_id_fk FOREIGN KEY (user_id) REFERENCES tasknote.users (id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tasknote.note_urls (
|
||||
id SERIAL,
|
||||
note_id INTEGER NOT NULL,
|
||||
url VARCHAR(200) NOT NULL,
|
||||
CONSTRAINT note_url_pk PRIMARY KEY (id),
|
||||
CONSTRAINT note_url_note_id_fk FOREIGN KEY (note_id) REFERENCES tasknote.notes (id)
|
||||
);
|
||||
Reference in New Issue
Block a user