Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ea660d5

Browse files
committed
1
1 parent be4ab93 commit ea660d5

File tree

8 files changed

+225
-35
lines changed

8 files changed

+225
-35
lines changed
Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11
package ru.javawebinar.topjava.repository.jdbc;
22

3+
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.springframework.dao.support.DataAccessUtils;
5+
import org.springframework.jdbc.core.JdbcTemplate;
6+
import org.springframework.jdbc.core.RowMapper;
7+
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
8+
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
9+
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
310
import org.springframework.stereotype.Repository;
11+
import org.springframework.util.CollectionUtils;
412
import ru.javawebinar.topjava.model.UserMeal;
513
import ru.javawebinar.topjava.repository.UserMealRepository;
614

15+
import javax.sql.DataSource;
16+
import java.sql.Timestamp;
717
import java.time.LocalDateTime;
818
import java.util.List;
919

@@ -15,33 +25,74 @@
1525
@Repository
1626
public class JdbcUserMealRepositoryImpl implements UserMealRepository {
1727

28+
private static final RowMapper<UserMeal> ROW_MAPPER =
29+
(rs, rowNum) ->
30+
new UserMeal(rs.getInt("id"), rs.getTimestamp("dateTime").toLocalDateTime(), rs.getString("description"), rs.getInt("calories"));
31+
32+
@Autowired
33+
private JdbcTemplate jdbcTemplate;
34+
35+
@Autowired
36+
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
37+
38+
private SimpleJdbcInsert insertUserMeal;
39+
40+
@Autowired
41+
public JdbcUserMealRepositoryImpl(DataSource dataSource) {
42+
this.insertUserMeal = new SimpleJdbcInsert(dataSource)
43+
.withTableName("meals")
44+
.usingGeneratedKeyColumns("id");
45+
}
46+
1847
@Override
19-
public UserMeal save(UserMeal UserMeal, int userId) {
20-
return null;
48+
public UserMeal save(UserMeal userMeal, int userId) {
49+
MapSqlParameterSource map = new MapSqlParameterSource()
50+
.addValue("id", userMeal.getId())
51+
.addValue("description", userMeal.getDescription())
52+
.addValue("calories", userMeal.getCalories())
53+
.addValue("datetime", Timestamp.valueOf(userMeal.getDateTime()))
54+
.addValue("user_id", userId);
55+
56+
if (userMeal.isNew()) {
57+
Number newId = insertUserMeal.executeAndReturnKey(map);
58+
userMeal.setId(newId.intValue());
59+
} else {
60+
if (namedParameterJdbcTemplate.update(
61+
"UPDATE meals SET description=:description, calories=:calories, datetime=:datetime " +
62+
" WHERE id=:id AND user_id=:user_id", map) == 0) {
63+
return null;
64+
}
65+
}
66+
return userMeal;
2167
}
2268

2369
@Override
2470
public boolean delete(int id, int userId) {
25-
return false;
71+
return jdbcTemplate.update("DELETE FROM meals WHERE id=? AND user_id=?", id, userId) != 0;
2672
}
2773

2874
@Override
29-
public UserMeal get(int id, int userId) {
30-
return null;
75+
public void deleteAll(int userId) {
76+
jdbcTemplate.update("DELETE FROM meals WHERE user_id=?", userId);
3177
}
3278

3379
@Override
34-
public List<UserMeal> getAll(int userId) {
35-
return null;
80+
public UserMeal get(int id, int userId) {
81+
List<UserMeal> userMeals = jdbcTemplate.query(
82+
"SELECT * FROM meals WHERE id = ? AND user_id = ?", ROW_MAPPER, id, userId);
83+
return CollectionUtils.isEmpty(userMeals) ? null : DataAccessUtils.requiredSingleResult(userMeals);
3684
}
3785

3886
@Override
39-
public void deleteAll(int userId) {
40-
87+
public List<UserMeal> getAll(int userId) {
88+
return jdbcTemplate.query(
89+
"SELECT * FROM meals WHERE user_id=? ORDER BY dateTime DESC", ROW_MAPPER, userId);
4190
}
4291

4392
@Override
4493
public List<UserMeal> getBetween(LocalDateTime startDate, LocalDateTime endDate, int userId) {
45-
return null;
94+
return jdbcTemplate.query(
95+
"SELECT * FROM meals WHERE user_id=? AND dateTime BETWEEN ? AND ? ORDER BY dateTime DESC",
96+
ROW_MAPPER, userId, Timestamp.valueOf(startDate), Timestamp.valueOf(endDate));
4697
}
47-
}
98+
}

src/main/resources/db/initDB.sql

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
DROP TABLE IF EXISTS USER_ROLES;
2-
DROP TABLE IF EXISTS USERS;
3-
DROP SEQUENCE IF EXISTS GLOBAL_SEQ;
1+
DROP TABLE IF EXISTS user_roles;
2+
DROP TABLE IF EXISTS meals;
3+
DROP TABLE IF EXISTS users;
4+
DROP SEQUENCE IF EXISTS global_seq;
45

5-
CREATE SEQUENCE GLOBAL_SEQ START 100000;
6+
CREATE SEQUENCE global_seq START 100000;
67

7-
CREATE TABLE USERS
8+
CREATE TABLE users
89
(
9-
id INTEGER PRIMARY KEY DEFAULT nextval('GLOBAL_SEQ'),
10+
id INTEGER PRIMARY KEY DEFAULT nextval('global_seq'),
1011
name VARCHAR,
1112
email VARCHAR NOT NULL,
1213
password VARCHAR NOT NULL,
@@ -15,10 +16,19 @@ CREATE TABLE USERS
1516
);
1617
CREATE UNIQUE INDEX unique_email ON USERS (email);
1718

18-
CREATE TABLE USER_ROLES
19+
CREATE TABLE user_roles
1920
(
2021
user_id INTEGER NOT NULL,
2122
role VARCHAR,
2223
CONSTRAINT user_roles_idx UNIQUE (user_id, role),
2324
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
2425
);
26+
27+
CREATE TABLE meals (
28+
id INTEGER PRIMARY KEY DEFAULT nextval('global_seq'),
29+
user_id INTEGER NOT NULL,
30+
datetime TIMESTAMP,
31+
description TEXT,
32+
calories INT,
33+
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
34+
);

src/main/resources/db/populateDB.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
DELETE FROM user_roles;
2+
DELETE FROM meals;
23
DELETE FROM users;
34
ALTER SEQUENCE global_seq RESTART WITH 100000;
45

@@ -11,3 +12,11 @@ VALUES ('Admin', '[email protected]', 'admin');
1112

1213
INSERT INTO user_roles (role, user_id) VALUES ('ROLE_USER', 100000);
1314
INSERT INTO user_roles (role, user_id) VALUES ('ROLE_ADMIN', 100001);
15+
16+
INSERT INTO meals (datetime, description, calories, user_id) VALUES ('2015-05-30 10:00:00', 'Завтрак', 500, 100000);
17+
INSERT INTO meals (datetime, description, calories, user_id) VALUES ('2015-05-30 13:00:00', 'Обед', 1000, 100000);
18+
INSERT INTO meals (datetime, description, calories, user_id) VALUES ('2015-05-30 20:00:00', 'Ужин', 500, 100000);
19+
INSERT INTO meals (datetime, description, calories, user_id) VALUES ('2015-05-31 10:00:00', 'Завтрак', 500, 100000);
20+
INSERT INTO meals (datetime, description, calories, user_id) VALUES ('2015-05-31 13:00:00', 'Обед', 1000, 100000);
21+
INSERT INTO meals (datetime, description, calories, user_id) VALUES ('2015-05-31 20:00:00', 'Ужин', 510, 100000);
22+
INSERT INTO meals (datetime, description, calories, user_id) VALUES ('2015-06-01 14:00:00', 'Админ-Ланч', 2001, 100001);

src/test/java/ru/javawebinar/topjava/MealTestData.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,39 @@
33
import ru.javawebinar.topjava.matcher.ModelMatcher;
44
import ru.javawebinar.topjava.model.UserMeal;
55

6+
import java.time.LocalDateTime;
7+
import java.time.Month;
8+
import java.util.Arrays;
9+
import java.util.List;
10+
11+
import static java.time.LocalDateTime.of;
12+
import static ru.javawebinar.topjava.model.BaseEntity.START_SEQ;
13+
614
/**
715
* GKislin
816
* 13.03.2015.
917
*/
1018
public class MealTestData {
19+
public static final int MEAL1_ID = START_SEQ + 2;
20+
public static final int ADMIN_MEAL_ID = START_SEQ + 8;
1121

12-
public static final ModelMatcher<UserMeal, String> MATCHER = new ModelMatcher<>(UserMeal::toString);
22+
public static final UserMeal MEAL1 = new UserMeal(MEAL1_ID, LocalDateTime.of(2015, Month.MAY, 30, 10, 0), "Завтрак", 500);
23+
public static final UserMeal MEAL2 = new UserMeal(START_SEQ + 3, LocalDateTime.of(2015, Month.MAY, 30, 13, 0), "Обед", 1000);
24+
public static final UserMeal MEAL3 = new UserMeal(START_SEQ + 4, LocalDateTime.of(2015, Month.MAY, 30, 20, 0), "Ужин", 500);
25+
public static final UserMeal MEAL4 = new UserMeal(START_SEQ + 5, LocalDateTime.of(2015, Month.MAY, 31, 10, 0), "Завтрак", 500);
26+
public static final UserMeal MEAL5 = new UserMeal(START_SEQ + 6, LocalDateTime.of(2015, Month.MAY, 31, 13, 0), "Обед", 1000);
27+
public static final UserMeal MEAL6 = new UserMeal(START_SEQ + 7, LocalDateTime.of(2015, Month.MAY, 31, 20, 0), "Ужин", 510);
28+
public static final UserMeal ADMIN_MEAL = new UserMeal(ADMIN_MEAL_ID, LocalDateTime.of(2015, Month.JUNE, 1, 14, 0), "Админ-Ланч", 2001);
29+
30+
public static final List<UserMeal> USER_MEALS = Arrays.asList(MEAL6, MEAL5, MEAL4, MEAL3, MEAL2, MEAL1);
1331

32+
public static UserMeal getCreated() {
33+
return new UserMeal(null, of(2015, Month.JUNE, 1, 18, 0), "Созданный ужин", 300);
34+
}
35+
36+
public static UserMeal getUpdated() {
37+
return new UserMeal(MEAL1_ID, MEAL1.getDateTime(), "Обновленный завтрак", 200);
38+
}
39+
40+
public static final ModelMatcher<UserMeal, String> MATCHER = new ModelMatcher<>(UserMeal::toString);
1441
}

src/test/java/ru/javawebinar/topjava/UserTestData.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,15 @@
99
import java.util.Objects;
1010
import java.util.Set;
1111

12+
import static ru.javawebinar.topjava.model.BaseEntity.START_SEQ;
13+
1214
/**
1315
* User: gkislin
1416
* Date: 26.08.2014
1517
*/
1618
public class UserTestData {
19+
public static final int USER_ID = START_SEQ;
20+
public static final int ADMIN_ID = START_SEQ + 1;
1721

1822
public static final TestUser USER = new TestUser(BaseEntity.START_SEQ, "User", "[email protected]", "password", true, Role.ROLE_USER);
1923
public static final User ADMIN = new TestUser(BaseEntity.START_SEQ + 1, "Admin", "[email protected]", "admin", true, Role.ROLE_ADMIN);

src/test/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22

33
import org.springframework.stereotype.Repository;
44
import ru.javawebinar.topjava.LoggerWrapper;
5+
import ru.javawebinar.topjava.MealTestData;
56
import ru.javawebinar.topjava.model.UserMeal;
67
import ru.javawebinar.topjava.repository.UserMealRepository;
78

89
import java.time.LocalDateTime;
9-
import java.time.Month;
10-
import java.util.Arrays;
1110
import java.util.List;
1211

1312
/**
@@ -17,14 +16,6 @@
1716
@Repository
1817
public class MockUserMealRepositoryImpl implements UserMealRepository {
1918
private static final LoggerWrapper LOG = LoggerWrapper.get(MockUserRepositoryImpl.class);
20-
private static final List<UserMeal> mealList = Arrays.asList(
21-
new UserMeal(1, LocalDateTime.of(2015, Month.MAY, 30, 10, 0), "Завтрак", 500),
22-
new UserMeal(2, LocalDateTime.of(2015, Month.MAY, 30, 13, 0), "Обед", 1000),
23-
new UserMeal(3, LocalDateTime.of(2015, Month.MAY, 30, 20, 0), "Ужин", 500),
24-
new UserMeal(4, LocalDateTime.of(2015, Month.MAY, 31, 10, 0), "Завтрак", 500),
25-
new UserMeal(5, LocalDateTime.of(2015, Month.MAY, 31, 13, 0), "Обед", 1000),
26-
new UserMeal(6, LocalDateTime.of(2015, Month.MAY, 31, 20, 0), "Ужин", 510)
27-
);
2819

2920
@Override
3021
public boolean delete(int id, int userId) {
@@ -47,7 +38,7 @@ public UserMeal get(int id, int userId) {
4738
@Override
4839
public List<UserMeal> getAll(int userId) {
4940
LOG.info("getAll for User {}", userId);
50-
return mealList;
41+
return MealTestData.USER_MEALS;
5142
}
5243

5344
@Override
@@ -58,6 +49,6 @@ public void deleteAll(int userId) {
5849
@Override
5950
public List<UserMeal> getBetween(LocalDateTime startDate, LocalDateTime endDate, int userId) {
6051
LOG.info("getBetween {} - {} for User {}", startDate, endDate, userId);
61-
return mealList;
52+
return MealTestData.USER_MEALS;
6253
}
6354
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package ru.javawebinar.topjava.service;
2+
3+
import org.junit.Assert;
4+
import org.junit.Before;
5+
import org.junit.Test;
6+
import org.junit.runner.RunWith;
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
import org.springframework.test.context.ContextConfiguration;
9+
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
10+
import ru.javawebinar.topjava.MealTestData;
11+
import ru.javawebinar.topjava.model.UserMeal;
12+
import ru.javawebinar.topjava.util.DbPopulator;
13+
import ru.javawebinar.topjava.util.exception.NotFoundException;
14+
15+
import java.time.LocalDate;
16+
import java.time.Month;
17+
import java.util.Arrays;
18+
19+
import static ru.javawebinar.topjava.MealTestData.*;
20+
import static ru.javawebinar.topjava.UserTestData.ADMIN_ID;
21+
import static ru.javawebinar.topjava.UserTestData.USER_ID;
22+
23+
@ContextConfiguration({
24+
"classpath:spring/spring-app.xml",
25+
"classpath:spring/spring-db.xml"
26+
})
27+
@RunWith(SpringJUnit4ClassRunner.class)
28+
public class UserMealServiceTest {
29+
30+
@Autowired
31+
protected UserMealService service;
32+
33+
@Autowired
34+
private DbPopulator dbPopulator;
35+
36+
@Before
37+
public void setUp() throws Exception {
38+
dbPopulator.execute();
39+
}
40+
41+
@Test
42+
public void testDelete() throws Exception {
43+
service.delete(MealTestData.MEAL1_ID, USER_ID);
44+
MATCHER.assertListEquals(Arrays.asList(MEAL6, MEAL5, MEAL4, MEAL3, MEAL2), service.getAll(USER_ID));
45+
}
46+
47+
@Test(expected = NotFoundException.class)
48+
public void testDeleteNotFound() throws Exception {
49+
service.delete(MEAL1_ID, 1);
50+
}
51+
52+
@Test
53+
public void testSave() throws Exception {
54+
UserMeal created = getCreated();
55+
service.save(created, USER_ID);
56+
MATCHER.assertListEquals(Arrays.asList(created, MEAL6, MEAL5, MEAL4, MEAL3, MEAL2, MEAL1), service.getAll(USER_ID));
57+
}
58+
59+
@Test
60+
public void testGet() throws Exception {
61+
UserMeal actual = service.get(ADMIN_MEAL_ID, ADMIN_ID);
62+
MATCHER.assertEquals(ADMIN_MEAL, actual);
63+
}
64+
65+
@Test(expected = NotFoundException.class)
66+
public void testGetNotFound() throws Exception {
67+
service.get(MEAL1_ID, ADMIN_ID);
68+
}
69+
70+
@Test
71+
public void testUpdate() throws Exception {
72+
UserMeal updated = getUpdated();
73+
service.update(updated, USER_ID);
74+
MATCHER.assertEquals(updated, service.get(MEAL1_ID, USER_ID));
75+
}
76+
77+
@Test(expected = NotFoundException.class)
78+
public void testNotFoundUpdate() throws Exception {
79+
UserMeal item = service.get(MEAL1_ID, USER_ID);
80+
service.update(item, ADMIN_ID);
81+
}
82+
83+
@Test
84+
public void testGetAll() throws Exception {
85+
MATCHER.assertListEquals(USER_MEALS, service.getAll(USER_ID));
86+
}
87+
88+
@Test
89+
public void testGetBetween() throws Exception {
90+
MATCHER.assertListEquals(Arrays.asList(MEAL3, MEAL2, MEAL1),
91+
service.getBetweenDates(LocalDate.of(2015, Month.MAY, 30), LocalDate.of(2015, Month.MAY, 30), USER_ID));
92+
}
93+
94+
@Test
95+
public void testDeleteAll() throws Exception {
96+
service.deleteAll(USER_ID);
97+
Assert.assertEquals(0, service.getAll(USER_ID).size());
98+
}
99+
}

0 commit comments

Comments
 (0)