Skip to content

Commit 141d135

Browse files
authored
feat: adds in-memory repository for todos that is config swappable (#662)
* feat: adds in-memory repository for todos that is config swappable * chore: default to in-memory database
1 parent dc44f41 commit 141d135

File tree

5 files changed

+154
-54
lines changed

5 files changed

+154
-54
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.codedifferently.fullstack_demo.repository;
2+
3+
import java.util.ArrayList;
4+
import java.util.HashMap;
5+
import java.util.List;
6+
import java.util.Map;
7+
8+
import org.springframework.stereotype.Service;
9+
10+
import com.codedifferently.fullstack_demo.model.Todo;
11+
12+
@Service
13+
public class InMemoryTodosRepository implements TodosRepository {
14+
15+
private final Map<String, List<Todo>> todosStorage = new HashMap<>();
16+
17+
@Override
18+
public List<Todo> getAll(String userId) {
19+
return todosStorage.getOrDefault(userId, new ArrayList<>());
20+
}
21+
22+
@Override
23+
public long create(String userId, Todo todo) {
24+
List<Todo> userTodos = todosStorage.computeIfAbsent(userId, k -> new ArrayList<>());
25+
long newId = System.currentTimeMillis();
26+
todo.setId(newId);
27+
userTodos.add(todo);
28+
return newId;
29+
}
30+
31+
@Override
32+
public void patch(String userId, Todo todo) {
33+
List<Todo> userTodos = todosStorage.get(userId);
34+
if (userTodos != null) {
35+
for (int i = 0; i < userTodos.size(); i++) {
36+
if (userTodos.get(i).getId() == todo.getId()) {
37+
userTodos.set(i, todo);
38+
break;
39+
}
40+
}
41+
}
42+
}
43+
44+
@Override
45+
public void delete(String userId, long id) {
46+
List<Todo> userTodos = todosStorage.get(userId);
47+
if (userTodos != null) {
48+
userTodos.removeIf(todo -> todo.getId() == id);
49+
}
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.codedifferently.fullstack_demo.repository;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
import com.codedifferently.fullstack_demo.model.Todo;
7+
import com.google.gson.Gson;
8+
9+
import redis.clients.jedis.Jedis;
10+
11+
public class RedisTodosRepository implements TodosRepository {
12+
13+
private final Jedis jedis;
14+
15+
public RedisTodosRepository(
16+
String host,
17+
int port,
18+
String password
19+
) {
20+
21+
this.jedis = new Jedis(host, port, true);
22+
this.jedis.auth(password);
23+
}
24+
25+
@Override
26+
public List<Todo> getAll(String userId) {
27+
String json = this.jedis.get("todos:" + userId);
28+
return List.of(new Gson().fromJson(json, Todo[].class));
29+
}
30+
31+
@Override
32+
public long create(String userId, Todo todo) {
33+
List<Todo> todos = new ArrayList(this.getAll(userId));
34+
35+
todo.setId(System.currentTimeMillis());
36+
todos.add(todo);
37+
38+
this.jedis.set("todos:" + userId, new Gson().toJson(todos));
39+
return todo.getId();
40+
}
41+
42+
@Override
43+
public void patch(String userId, Todo todo) {
44+
List<Todo> todos = new ArrayList(this.getAll(userId));
45+
46+
List<Todo> updatedTodos = todos.stream()
47+
.map(t -> t.getId() == todo.getId() ? todo : t)
48+
.toList();
49+
50+
this.jedis.set("todos:" + userId, new Gson().toJson(updatedTodos));
51+
}
52+
53+
@Override
54+
public void delete(String userId, long id) {
55+
List<Todo> todos = this.getAll(userId);
56+
57+
List<Todo> updatedTodos = todos.stream()
58+
.filter(t -> t.getId() != id)
59+
.toList();
60+
61+
this.jedis.set("todos:" + userId, new Gson().toJson(updatedTodos));
62+
}
63+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.codedifferently.fullstack_demo.repository;
2+
3+
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.springframework.beans.factory.annotation.Value;
5+
import org.springframework.context.ApplicationContext;
6+
import org.springframework.context.annotation.Bean;
7+
import org.springframework.context.annotation.Configuration;
8+
import org.springframework.core.env.Environment;
9+
10+
@Configuration
11+
public class RepositoryConfiguration {
12+
13+
@Autowired
14+
private Environment env;
15+
16+
@Bean
17+
public TodosRepository todosRepository(
18+
@Value("${app.repository.type:in-memory}") String type,
19+
ApplicationContext context
20+
) {
21+
if (type.equals("redis")) {
22+
String host = env.getProperty("app.repository.redis.host");
23+
int port = env.getProperty("app.repository.redis.port", int.class);
24+
String password = env.getProperty("app.repository.redis.password");
25+
return new RedisTodosRepository(host, port, password);
26+
}
27+
return context.getBean(InMemoryTodosRepository.class);
28+
}
29+
}
Lines changed: 5 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,17 @@
11
package com.codedifferently.fullstack_demo.repository;
22

3-
import java.util.ArrayList;
43
import java.util.List;
54

6-
import org.springframework.beans.factory.annotation.Value;
7-
import org.springframework.stereotype.Service;
8-
95
import com.codedifferently.fullstack_demo.model.Todo;
10-
import com.google.gson.Gson;
11-
12-
import redis.clients.jedis.Jedis;
13-
14-
@Service
15-
public class TodosRepository {
16-
17-
private final Jedis jedis;
18-
19-
public TodosRepository(
20-
@Value("${app.redis.host}") String host,
21-
@Value("${app.redis.port}") int port,
22-
@Value("${app.redis.password}") String password
23-
) {
24-
this.jedis = new Jedis(host, port, true);
25-
this.jedis.auth(password);
26-
}
27-
28-
public List<Todo> getAll(String userId) {
29-
String json = this.jedis.get("todos:" + userId);
30-
return List.of(new Gson().fromJson(json, Todo[].class));
31-
}
32-
33-
public long create(String userId, Todo todo) {
34-
List<Todo> todos = new ArrayList(this.getAll(userId));
35-
36-
todo.setId(System.currentTimeMillis());
37-
todos.add(todo);
38-
39-
this.jedis.set("todos:" + userId, new Gson().toJson(todos));
40-
return todo.getId();
41-
}
426

43-
public void patch(String userId, Todo todo) {
44-
List<Todo> todos = new ArrayList(this.getAll(userId));
7+
public interface TodosRepository {
458

46-
List<Todo> updatedTodos = todos.stream()
47-
.map(t -> t.getId() == todo.getId() ? todo : t)
48-
.toList();
9+
List<Todo> getAll(String userId);
4910

50-
this.jedis.set("todos:" + userId, new Gson().toJson(updatedTodos));
51-
}
11+
long create(String userId, Todo todo);
5212

53-
public void delete(String userId, long id) {
54-
List<Todo> todos = this.getAll(userId);
13+
void patch(String userId, Todo todo);
5514

56-
List<Todo> updatedTodos = todos.stream()
57-
.filter(t -> t.getId() != id)
58-
.toList();
15+
void delete(String userId, long id);
5916

60-
this.jedis.set("todos:" + userId, new Gson().toJson(updatedTodos));
61-
}
6217
}

lib/java/fullstack_demo/src/main/resources/application.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ app:
99
clerk:
1010
perishableKey: ${CLERK_PERISHABLE_KEY}
1111
secretKey: ${CLERK_SECRET_KEY}
12-
redis:
13-
host: ${REDIS_HOST}
14-
port: ${REDIS_PORT}
15-
password: ${REDIS_PASSWORD}
12+
# repository:
13+
# type: redis
14+
# redis:
15+
# host: ${REDIS_HOST}
16+
# port: ${REDIS_PORT}
17+
# password: ${REDIS_PASSWORD}
1618
env: dev

0 commit comments

Comments
 (0)