Przeglądaj źródła

Merge 3bd53f8089e93d70f4d98c4d03ffa9a4e606083a into f91a622cc731197181dd1b1e4b17c9bcb450ae8a

Mitch Taylor 8 lat temu
rodzic
commit
0aae528f8a
Brak konta powiązanego z e-mailem autora

+ 9
- 8
README.md Wyświetl plik

@@ -134,7 +134,7 @@ public ResponseEntity<Iterable<Poll>> getAllPolls() {
134 134
 
135 135
 ### Part 3.1.2 - Testing via Postman
136 136
 
137
-* Ensure that the `start-class` tag in your `pom.xml` encapsulates `io.zipcoder.springdemo.QuickPollApplication`
137
+* Ensure that the `start-class` tag in your `pom.xml` encapsulates `io.zipcoder.tc_spring_poll_application.QuickPollApplication`
138 138
 * Open a command line and navigate to the project's root directory and run this command:
139 139
 	* `mvn spring-boot:run`
140 140
 * Launch the [Postman](https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en) app and enter the URI `http://localhost:8080/polls` and hit Send.
@@ -152,7 +152,7 @@ public ResponseEntity<Iterable<Poll>> getAllPolls() {
152 152
 @RequestMapping(value="/polls", method=RequestMethod.POST)
153 153
 public ResponseEntity<?> createPoll(@RequestBody Poll poll) {
154 154
         poll = pollRepository.save(poll);
155
-        return new ResponseEntity<>(null, HttpStatus.CREATED);
155
+        return new ResponseEntity<Poll>(null, HttpStatus.CREATED);
156 156
 }
157 157
 ```
158 158
 
@@ -323,7 +323,7 @@ public interface VoteRepository extends CrudRepository<Vote, Long> {
323 323
             "FROM Option o, Vote v " +
324 324
             "WHERE o.POLL_ID = ?1 " +
325 325
             "AND v.OPTION_ID = o.OPTION_ID", nativeQuery = true)
326
-    public Iterable<Vote> findVotesByPoll(Long pollId);
326
+    Iterable<Vote> findVotesByPoll(Long pollId);
327 327
 }
328 328
 ```
329 329
 
@@ -349,7 +349,7 @@ public Iterable<Vote> getAllVotes() {
349 349
 ```java
350 350
 @RequestMapping(value="/polls/{pollId}/votes", method=RequestMethod.GET)
351 351
 public Iterable<Vote> getVote(@PathVariable Long pollId) {
352
-	return voteRepository.findById(pollId);
352
+	return voteRepository.findVotesByPoll(pollId);
353 353
 }
354 354
 ```
355 355
 
@@ -441,6 +441,7 @@ public class ComputeResultController {
441 441
         //TODO: Implement algorithm to count votes
442 442
         return new ResponseEntity<VoteResult>(voteResult, HttpStatus.OK);
443 443
     }
444
+}    
444 445
 ```
445 446
 
446 447
 
@@ -506,7 +507,7 @@ public ResponseEntity<?> handleResourceNotFoundException(ResourceNotFoundExcepti
506 507
 
507 508
 
508 509
 
509
-## Part 5.4 - Validating domain entities
510
+## Part 5.5 - Validating domain entities
510 511
 
511 512
 Now it's time to make sure that all objects persisted to the database actually contain valid values. Use the `org.hibernate.validator.constraints.NotEmpty` and `javax.validation.constraints.Size` and `javax.validation.Valid` annotations for validation.
512 513
 
@@ -515,7 +516,7 @@ Now it's time to make sure that all objects persisted to the database actually c
515 516
   - `question` should be `@NotEmpty`
516 517
 - To enforce these validations, add `@Valid` annotations to Poll objects in `RequestMapping`-annotated controller methods (there should be 2)
517 518
 
518
-## Part 5.5 - Customizing validation errors
519
+## Part 5.6 - Customizing validation errors
519 520
 
520 521
 In order to customize validation errors we'll need a class for error information. Create a `ValidationError` class in `io.zipcoder.tc_spring_poll_application.dto.error` with the following fields and appropriate getters and setters:
521 522
 
@@ -525,7 +526,7 @@ In order to customize validation errors we'll need a class for error information
525 526
 We also need a new field in the `ErrorDetail` class to hold errors. There may be multiple validation errors associated with a request, sometimes more than one of the same type, so this field will be a collection, specifically a `Map<String, List<ValidationError>> errors` field.
526 527
 
527 528
 
528
-## Part 5.6 - Create a validation error handler
529
+## Part 5.7 - Create a validation error handler
529 530
 
530 531
 - add below handler to `RestExceptionHandler`
531 532
 
@@ -559,7 +560,7 @@ for(FieldError fe : fieldErrors) {
559 560
 }
560 561
 ```
561 562
 
562
-## Part 5.7 - Externalize strings in a messages.properties file
563
+## Part 5.8 - Externalize strings in a messages.properties file
563 564
 
564 565
 Commonly used strings in your Java program can be removed from the source code and placed in a separate file. This is called externalizing, and is useful for allowing changes to text displayed without impacting actual program logic. One example of where this is done is in internationalization, the practice of providing multilingual support in an application, allowing users to use an application in their native language.
565 566
 

+ 24
- 0
src/main/java/dtos/OptionCount.java Wyświetl plik

@@ -0,0 +1,24 @@
1
+package dtos;
2
+
3
+public class OptionCount {
4
+
5
+    private Long optionId;
6
+    private int count;
7
+
8
+    public Long getOptionId() {
9
+        return optionId;
10
+    }
11
+
12
+    public void setOptionId(Long optionId) {
13
+        this.optionId = optionId;
14
+    }
15
+
16
+    public int getCount() {
17
+        return count;
18
+    }
19
+
20
+    public void setCount(int count) {
21
+        this.count = count;
22
+    }
23
+
24
+}

+ 26
- 0
src/main/java/dtos/VoteResult.java Wyświetl plik

@@ -0,0 +1,26 @@
1
+package dtos;
2
+
3
+import java.util.Collection;
4
+
5
+public class VoteResult {
6
+
7
+    private int totalVotes;
8
+    private Collection<OptionCount> results;
9
+
10
+    public int getTotalVotes() {
11
+        return totalVotes;
12
+    }
13
+
14
+    public void setTotalVotes(int totalVotes) {
15
+        this.totalVotes = totalVotes;
16
+    }
17
+
18
+    public Collection<OptionCount> getResults() {
19
+        return results;
20
+    }
21
+
22
+    public void setResults(Collection<OptionCount> results) {
23
+        this.results = results;
24
+    }
25
+
26
+}

+ 63
- 0
src/main/java/dtos/error/ErrorDetail.java Wyświetl plik

@@ -0,0 +1,63 @@
1
+package dtos.error;
2
+
3
+import java.util.List;
4
+import java.util.Map;
5
+
6
+public class ErrorDetail {
7
+
8
+    private String title;
9
+    private int status;
10
+    private String detail;
11
+    private long timeStamp;
12
+    private String developerMessage;
13
+    private Map<String, List<ValidationError>> errors;
14
+
15
+    public String getTitle() {
16
+        return title;
17
+    }
18
+
19
+    public void setTitle(String title) {
20
+        this.title = title;
21
+    }
22
+
23
+    public int getStatus() {
24
+        return status;
25
+    }
26
+
27
+    public void setStatus(int status) {
28
+        this.status = status;
29
+    }
30
+
31
+    public String getDetail() {
32
+        return detail;
33
+    }
34
+
35
+    public void setDetail(String detail) {
36
+        this.detail = detail;
37
+    }
38
+
39
+    public long getTimeStamp() {
40
+        return timeStamp;
41
+    }
42
+
43
+    public void setTimeStamp(long timeStamp) {
44
+        this.timeStamp = timeStamp;
45
+    }
46
+
47
+    public String getDeveloperMessage() {
48
+        return developerMessage;
49
+    }
50
+
51
+    public void setDeveloperMessage(String developerMessage) {
52
+        this.developerMessage = developerMessage;
53
+    }
54
+
55
+    public Map<String, List<ValidationError>> getErrors() {
56
+        return errors;
57
+    }
58
+
59
+    public void setErrors(Map<String, List<ValidationError>> errors) {
60
+        this.errors = errors;
61
+    }
62
+
63
+}

+ 24
- 0
src/main/java/dtos/error/ValidationError.java Wyświetl plik

@@ -0,0 +1,24 @@
1
+package dtos.error;
2
+
3
+public class ValidationError {
4
+
5
+    private String code;
6
+    private String message;
7
+
8
+    public String getCode() {
9
+        return code;
10
+    }
11
+
12
+    public void setCode(String code) {
13
+        this.code = code;
14
+    }
15
+
16
+    public String getMessage() {
17
+        return message;
18
+    }
19
+
20
+    public void setMessage(String message) {
21
+        this.message = message;
22
+    }
23
+
24
+}

+ 49
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/controller/ComputeResultController.java Wyświetl plik

@@ -0,0 +1,49 @@
1
+package io.zipcoder.tc_spring_poll_application.controller;
2
+
3
+import dtos.OptionCount;
4
+import dtos.VoteResult;
5
+import io.zipcoder.tc_spring_poll_application.domain.Vote;
6
+import io.zipcoder.tc_spring_poll_application.repositories.VoteRepository;
7
+import org.springframework.http.HttpStatus;
8
+import org.springframework.http.ResponseEntity;
9
+import org.springframework.web.bind.annotation.RequestMapping;
10
+import org.springframework.web.bind.annotation.RequestMethod;
11
+import org.springframework.web.bind.annotation.RequestParam;
12
+import org.springframework.web.bind.annotation.RestController;
13
+
14
+import javax.inject.Inject;
15
+import java.util.HashMap;
16
+import java.util.Map;
17
+
18
+@RestController
19
+public class ComputeResultController {
20
+
21
+    @Inject
22
+    private VoteRepository voteRepository;
23
+
24
+    @RequestMapping(value = "/computeresult", method = RequestMethod.GET)
25
+    public ResponseEntity<VoteResult> computeResult(@RequestParam Long pollId) {
26
+        VoteResult voteResult = new VoteResult();
27
+        Iterable<Vote> allVotes = voteRepository.findVotesByPoll(pollId);
28
+        countVotes(voteResult, allVotes);
29
+        return new ResponseEntity<>(voteResult, HttpStatus.OK);
30
+    }
31
+
32
+    private void countVotes(VoteResult voteResult, Iterable<Vote> allVotes) {
33
+        int totalVotes = 0;
34
+        Map<Long, OptionCount> map = new HashMap<>();
35
+        for(Vote v : allVotes) {
36
+            totalVotes ++;
37
+            OptionCount optionCount = map.get(v.getOption().getId());
38
+            if(optionCount == null) {
39
+                optionCount = new OptionCount();
40
+                optionCount.setOptionId(v.getOption().getId());
41
+                map.put(v.getOption().getId(), optionCount);
42
+            }
43
+            optionCount.setCount(optionCount.getCount()+1);
44
+        }
45
+        voteResult.setTotalVotes(totalVotes);
46
+        voteResult.setResults((map.values()));
47
+    }
48
+
49
+}

+ 69
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/controller/PollController.java Wyświetl plik

@@ -0,0 +1,69 @@
1
+package io.zipcoder.tc_spring_poll_application.controller;
2
+
3
+import io.zipcoder.tc_spring_poll_application.domain.Poll;
4
+import io.zipcoder.tc_spring_poll_application.exception.ResourceNotFoundException;
5
+import io.zipcoder.tc_spring_poll_application.repositories.PollRepository;
6
+import org.springframework.http.HttpHeaders;
7
+import org.springframework.http.HttpStatus;
8
+import org.springframework.http.ResponseEntity;
9
+import org.springframework.web.bind.annotation.*;
10
+import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
11
+
12
+import javax.inject.Inject;
13
+import javax.validation.Valid;
14
+import java.net.URI;
15
+
16
+@RestController
17
+public class PollController {
18
+
19
+    @Inject
20
+    private PollRepository pollRepository;
21
+
22
+    @RequestMapping(value="/polls", method= RequestMethod.GET)
23
+    public ResponseEntity<Iterable<Poll>> getAllPolls() {
24
+        Iterable<Poll> allPolls = pollRepository.findAll();
25
+        return new ResponseEntity<>(allPolls, HttpStatus.OK);
26
+    }
27
+
28
+    @RequestMapping(value="/polls/{pollId}", method=RequestMethod.GET)
29
+    public ResponseEntity<?> getPoll(@PathVariable Long pollId) {
30
+        verifyPoll(pollId);
31
+        Poll p = pollRepository.findOne(pollId);
32
+        return new ResponseEntity<> (p, HttpStatus.OK);
33
+    }
34
+
35
+    @RequestMapping(value="/polls", method=RequestMethod.POST)
36
+    public ResponseEntity<?> createPoll(@Valid @RequestBody Poll poll) {
37
+        poll = pollRepository.save(poll);
38
+        URI newPollUri = ServletUriComponentsBuilder
39
+                .fromCurrentRequest()
40
+                .path("/{id}")
41
+                .buildAndExpand(poll.getId())
42
+                .toUri();
43
+        HttpHeaders httpHeaders = new HttpHeaders();
44
+        httpHeaders.setLocation(newPollUri);
45
+        return new ResponseEntity<Poll>(httpHeaders, HttpStatus.CREATED);
46
+    }
47
+
48
+    @RequestMapping(value="/polls/{pollId}", method=RequestMethod.PUT)
49
+    public ResponseEntity<?> updatePoll(@Valid @RequestBody Poll poll, @PathVariable Long pollId) {
50
+        verifyPoll(pollId);
51
+        Poll p = pollRepository.save(poll);
52
+        return new ResponseEntity<>(HttpStatus.OK);
53
+    }
54
+
55
+    @RequestMapping(value="/polls/{pollId}", method=RequestMethod.DELETE)
56
+    public ResponseEntity<?> deletePoll(@PathVariable Long pollId) {
57
+        verifyPoll(pollId);
58
+        pollRepository.delete(pollId);
59
+        return new ResponseEntity<>(HttpStatus.OK);
60
+    }
61
+
62
+    private void verifyPoll(long pollId) throws ResourceNotFoundException{
63
+        Poll poll = pollRepository.findOne(pollId);
64
+        if (poll == null) {
65
+            throw new ResourceNotFoundException("Poll with this id not found: " + pollId);
66
+        }
67
+    }
68
+
69
+}

+ 40
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/controller/VoteController.java Wyświetl plik

@@ -0,0 +1,40 @@
1
+package io.zipcoder.tc_spring_poll_application.controller;
2
+
3
+import io.zipcoder.tc_spring_poll_application.domain.Vote;
4
+import io.zipcoder.tc_spring_poll_application.repositories.VoteRepository;
5
+import org.springframework.http.HttpHeaders;
6
+import org.springframework.http.HttpStatus;
7
+import org.springframework.http.ResponseEntity;
8
+import org.springframework.web.bind.annotation.*;
9
+import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
10
+
11
+import javax.inject.Inject;
12
+
13
+@RestController
14
+public class VoteController {
15
+
16
+    @Inject
17
+    private VoteRepository voteRepository;
18
+
19
+    @RequestMapping(value = "/polls/{pollId}/votes", method = RequestMethod.POST)
20
+    public ResponseEntity<?> createVote(@PathVariable Long pollId, @RequestBody Vote
21
+            vote) {
22
+        vote = voteRepository.save(vote);
23
+        // Set the headers for the newly created resource
24
+        HttpHeaders responseHeaders = new HttpHeaders();
25
+        responseHeaders.setLocation(ServletUriComponentsBuilder.
26
+                fromCurrentRequest().path("/{id}").buildAndExpand(vote.getId()).toUri());
27
+        return new ResponseEntity<>(null, responseHeaders, HttpStatus.CREATED);
28
+    }
29
+
30
+    @RequestMapping(value="/polls/votes", method=RequestMethod.GET)
31
+    public Iterable<Vote> getAllVotes() {
32
+        return voteRepository.findAll();
33
+    }
34
+
35
+    @RequestMapping(value="/polls/{pollId}/votes", method=RequestMethod.GET)
36
+    public Iterable<Vote> getVote(@PathVariable Long pollId) {
37
+        return voteRepository.findVotesByPoll(pollId);
38
+    }
39
+
40
+}

+ 35
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/domain/Option.java Wyświetl plik

@@ -0,0 +1,35 @@
1
+package io.zipcoder.tc_spring_poll_application.domain;
2
+
3
+import javax.persistence.Column;
4
+import javax.persistence.Entity;
5
+import javax.persistence.GeneratedValue;
6
+import javax.persistence.Id;
7
+
8
+@Entity
9
+public class Option {
10
+
11
+    @Id
12
+    @GeneratedValue
13
+    @Column(name = "OPTION_ID")
14
+    private Long id;
15
+
16
+    @Column(name = "OPTION_VALUE")
17
+    private String value;
18
+
19
+    public Long getId() {
20
+        return id;
21
+    }
22
+
23
+    public void setId(Long id) {
24
+        this.id = id;
25
+    }
26
+
27
+    public String getValue() {
28
+        return value;
29
+    }
30
+
31
+    public void setValue(String value) {
32
+        this.value = value;
33
+    }
34
+
35
+}

+ 51
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/domain/Poll.java Wyświetl plik

@@ -0,0 +1,51 @@
1
+package io.zipcoder.tc_spring_poll_application.domain;
2
+
3
+import org.hibernate.validator.constraints.NotEmpty;
4
+
5
+import javax.persistence.*;
6
+import javax.validation.constraints.Size;
7
+import java.util.Set;
8
+
9
+@Entity
10
+public class Poll {
11
+
12
+    @Id
13
+    @GeneratedValue
14
+    @Column(name = "POLL_ID")
15
+    private Long id;
16
+
17
+    @NotEmpty
18
+    @Column(name = "QUESTION")
19
+    private String question;
20
+
21
+    @OneToMany(cascade = CascadeType.ALL)
22
+    @JoinColumn(name = "POLL_ID")
23
+    @OrderBy
24
+    @Size(min=2, max = 6)
25
+    private Set<Option> options;
26
+
27
+    public Long getId() {
28
+        return id;
29
+    }
30
+
31
+    public void setId(Long id) {
32
+        this.id = id;
33
+    }
34
+
35
+    public String getQuestion() {
36
+        return question;
37
+    }
38
+
39
+    public void setQuestion(String question) {
40
+        this.question = question;
41
+    }
42
+
43
+    public Set<Option> getOptions() {
44
+        return options;
45
+    }
46
+
47
+    public void setOptions(Set<Option> options) {
48
+        this.options = options;
49
+    }
50
+
51
+}

+ 33
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/domain/Vote.java Wyświetl plik

@@ -0,0 +1,33 @@
1
+package io.zipcoder.tc_spring_poll_application.domain;
2
+
3
+import javax.persistence.*;
4
+
5
+@Entity
6
+public class Vote {
7
+
8
+    @Id
9
+    @GeneratedValue
10
+    @Column(name = "VOTE_ID")
11
+    private Long id;
12
+
13
+    @ManyToOne
14
+    @JoinColumn(name = "OPTION_ID")
15
+    private Option option;
16
+
17
+    public Long getId() {
18
+        return id;
19
+    }
20
+
21
+    public void setId(Long id) {
22
+        this.id = id;
23
+    }
24
+
25
+    public Option getOption() {
26
+        return option;
27
+    }
28
+
29
+    public void setOption(Option option) {
30
+        this.option = option;
31
+    }
32
+
33
+}

+ 20
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/exception/ResourceNotFoundException.java Wyświetl plik

@@ -0,0 +1,20 @@
1
+package io.zipcoder.tc_spring_poll_application.exception;
2
+
3
+import org.springframework.http.HttpStatus;
4
+import org.springframework.web.bind.annotation.ResponseStatus;
5
+
6
+@ResponseStatus(HttpStatus.NOT_FOUND)
7
+public class ResourceNotFoundException extends RuntimeException {
8
+
9
+    public ResourceNotFoundException() {
10
+    }
11
+
12
+    public ResourceNotFoundException(String message) {
13
+        super(message);
14
+    }
15
+
16
+    public ResourceNotFoundException(String message, Throwable cause) {
17
+        super(message, cause);
18
+    }
19
+
20
+}

+ 68
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/exception/RestExceptionHandler.java Wyświetl plik

@@ -0,0 +1,68 @@
1
+package io.zipcoder.tc_spring_poll_application.exception;
2
+
3
+import java.util.ArrayList;
4
+import java.util.Date;
5
+import java.util.List;
6
+import javax.inject.Inject;
7
+import javax.servlet.http.HttpServletRequest;
8
+import dtos.error.ErrorDetail;
9
+import dtos.error.ValidationError;
10
+import org.springframework.beans.factory.annotation.Autowired;
11
+import org.springframework.context.MessageSource;
12
+import org.springframework.http.HttpStatus;
13
+import org.springframework.http.ResponseEntity;
14
+import org.springframework.validation.FieldError;
15
+import org.springframework.web.bind.MethodArgumentNotValidException;
16
+import org.springframework.web.bind.annotation.ControllerAdvice;
17
+import org.springframework.web.bind.annotation.ExceptionHandler;
18
+import org.springframework.web.bind.annotation.ResponseBody;
19
+import org.springframework.web.bind.annotation.ResponseStatus;
20
+
21
+@ControllerAdvice
22
+public class RestExceptionHandler {
23
+
24
+    @Autowired
25
+    @Inject
26
+    private MessageSource messageSource;
27
+
28
+    @ExceptionHandler(ResourceNotFoundException.class)
29
+    public ResponseEntity<?> handleResourceNotFoundException(ResourceNotFoundException rnfe, HttpServletRequest request) {
30
+        ErrorDetail errorDetail = new ErrorDetail();
31
+        errorDetail.setTimeStamp(new Date().getTime());
32
+        errorDetail.setStatus(HttpStatus.NOT_FOUND.value());
33
+        errorDetail.setTitle("Resource Not Found");
34
+        errorDetail.setDetail(rnfe.getMessage());
35
+        errorDetail.setDeveloperMessage(rnfe.getClass().getName());
36
+        return new ResponseEntity<>(errorDetail, null, HttpStatus.NOT_FOUND);
37
+    }
38
+
39
+    @ExceptionHandler(MethodArgumentNotValidException.class)
40
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
41
+    public @ResponseBody ErrorDetail handleValidationError(MethodArgumentNotValidException manve, HttpServletRequest request) {
42
+        ErrorDetail errorDetail = new ErrorDetail();
43
+        // Populate errorDetail instance
44
+        errorDetail.setTimeStamp(new Date().getTime());
45
+        errorDetail.setStatus(HttpStatus.BAD_REQUEST.value());
46
+        String requestPath = (String) request.getAttribute("javax.servlet.error.request_uri");
47
+        if(requestPath == null) {
48
+            requestPath = request.getRequestURI();
49
+        }
50
+        errorDetail.setTitle("Validation Failed");
51
+        errorDetail.setDetail("Input validation failed");
52
+        errorDetail.setDeveloperMessage(manve.getClass().getName());
53
+        List<FieldError> fieldErrors =  manve.getBindingResult().getFieldErrors();
54
+        for(FieldError fe : fieldErrors) {
55
+            List<ValidationError> validationErrorList = errorDetail.getErrors().get(fe.getField());
56
+            if(validationErrorList == null) {
57
+                validationErrorList = new ArrayList<>();
58
+                errorDetail.getErrors().put(fe.getField(), validationErrorList);
59
+            }
60
+            ValidationError validationError = new ValidationError();
61
+            validationError.setCode(fe.getCode());
62
+            validationError.setMessage(messageSource.getMessage(fe, null));
63
+            validationErrorList.add(validationError);
64
+        }
65
+        return errorDetail;
66
+    }
67
+
68
+}

+ 10
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/repositories/OptionRepository.java Wyświetl plik

@@ -0,0 +1,10 @@
1
+package io.zipcoder.tc_spring_poll_application.repositories;
2
+
3
+import io.zipcoder.tc_spring_poll_application.domain.Option;
4
+import org.springframework.data.repository.CrudRepository;
5
+
6
+public interface OptionRepository extends CrudRepository<Option, Long>{
7
+
8
+
9
+
10
+}

+ 10
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/repositories/PollRepository.java Wyświetl plik

@@ -0,0 +1,10 @@
1
+package io.zipcoder.tc_spring_poll_application.repositories;
2
+
3
+import io.zipcoder.tc_spring_poll_application.domain.Poll;
4
+import org.springframework.data.repository.CrudRepository;
5
+
6
+public interface PollRepository extends CrudRepository<Poll, Long>{
7
+
8
+
9
+
10
+}

+ 13
- 0
src/main/java/io/zipcoder/tc_spring_poll_application/repositories/VoteRepository.java Wyświetl plik

@@ -0,0 +1,13 @@
1
+package io.zipcoder.tc_spring_poll_application.repositories;
2
+
3
+import io.zipcoder.tc_spring_poll_application.domain.Vote;
4
+import org.springframework.data.jpa.repository.Query;
5
+import org.springframework.data.repository.CrudRepository;
6
+
7
+public interface VoteRepository extends CrudRepository<Vote, Long> {
8
+    @Query(value = "SELECT v.* " +
9
+            "FROM Option o, Vote v " +
10
+            "WHERE o.POLL_ID = ?1 " +
11
+            "AND v.OPTION_ID = o.OPTION_ID", nativeQuery = true)
12
+    Iterable<Vote> findVotesByPoll(Long pollId);
13
+}

+ 37
- 0
src/main/resources/import.sql Wyświetl plik

@@ -0,0 +1,37 @@
1
+insert into poll (poll_id, question) values (1, 'What is your favorite color?');
2
+insert into poll (poll_id, question) values (2, 'What is your favorite anime?');
3
+insert into poll (poll_id, question) values (3, 'What is your favorite game?');
4
+insert into poll (poll_id, question) values (4, 'What is your favorite instructor?');
5
+insert into poll (poll_id, question) values (5, 'What is your favorite ide?');
6
+insert into poll (poll_id, question) values (6, 'What is your favorite Dark Souls?');
7
+
8
+insert into option (option_id, option_value, poll_id) values (1, 'Red', 1);
9
+insert into option (option_id, option_value, poll_id) values (2, 'Green', 1);
10
+insert into option (option_id, option_value, poll_id) values (3, 'Blue', 1);
11
+insert into option (option_id, option_value, poll_id) values (4, 'Pink', 1);
12
+insert into option (option_id, option_value, poll_id) values (5, 'Yellow', 1);
13
+
14
+insert into option (option_id, option_value, poll_id) values (1, 'Phantom Blood', 2);
15
+insert into option (option_id, option_value, poll_id) values (2, 'Battle Tendency', 2);
16
+insert into option (option_id, option_value, poll_id) values (3, 'Stardust Crusaders', 2);
17
+insert into option (option_id, option_value, poll_id) values (4, 'Diamond is Unbreakable', 2);
18
+
19
+insert into option (option_id, option_value, poll_id) values (1, 'Cuphead', 3);
20
+insert into option (option_id, option_value, poll_id) values (2, 'Hotline Miami', 3);
21
+insert into option (option_id, option_value, poll_id) values (3, 'Hotline Miami 2', 3);
22
+
23
+insert into option (option_id, option_value, poll_id) values (1, 'Leon', 4);
24
+insert into option (option_id, option_value, poll_id) values (2, 'Chris', 4);
25
+insert into option (option_id, option_value, poll_id) values (3, 'Wilhem', 4);
26
+insert into option (option_id, option_value, poll_id) values (4, 'Not Tariq', 4);
27
+
28
+insert into option (option_id, option_value, poll_id) values (1, 'Eclipse', 5);
29
+insert into option (option_id, option_value, poll_id) values (2, 'Net Beans', 5);
30
+insert into option (option_id, option_value, poll_id) values (3, 'IntelliJ', 5);
31
+insert into option (option_id, option_value, poll_id) values (4, 'ides are for babies', 5);
32
+
33
+insert into option (option_id, option_value, poll_id) values (1, '1', 6);
34
+insert into option (option_id, option_value, poll_id) values (2, '2', 6);
35
+insert into option (option_id, option_value, poll_id) values (3, '3', 6);
36
+insert into option (option_id, option_value, poll_id) values (4, 'Demons', 6);
37
+insert into option (option_id, option_value, poll_id) values (5, 'BB', 6);

+ 2
- 0
src/main/resources/message.properties Wyświetl plik

@@ -0,0 +1,2 @@
1
+NotEmpty.poll.question=Question is a required field
2
+Size.poll.options=Options must be greater than {2} and less than {1}