-
Notifications
You must be signed in to change notification settings - Fork 46
/
PostsResource.java
122 lines (105 loc) · 4.78 KB
/
PostsResource.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package com.bendb.example.resources;
import com.bendb.dropwizard.jooq.jersey.JooqInject;
import com.bendb.example.core.BlogPost;
import com.bendb.example.db.tables.PostTag;
import com.bendb.example.db.tables.records.BlogPostRecord;
import com.bendb.example.db.tables.records.PostTagRecord;
import io.dropwizard.jersey.params.IntParam;
import java.time.OffsetDateTime;
import org.jooq.*;
import org.jooq.impl.DSL;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import java.util.Arrays;
import java.util.List;
import static com.bendb.dropwizard.jooq.PostgresSupport.arrayAgg;
import static com.bendb.example.db.Tables.BLOG_POST;
import static com.bendb.example.db.Tables.POST_TAG;
import static org.jooq.impl.DSL.*;
@Path("posts")
@Produces(MediaType.APPLICATION_JSON)
public class PostsResource {
@Context
@JooqInject("primary")
DSLContext primary;
@GET
public List<BlogPost> findPostsByTag(@QueryParam("tag") String tag, @JooqInject("replica") DSLContext db) {
final PostTag pt = POST_TAG.as("pt");
// Try *that* in JPA
return db.with("postIds").as(
select(POST_TAG.POST_ID.as("id"))
.from(POST_TAG)
.where(POST_TAG.TAG_NAME.equal(DSL.lower(tag))))
.select(BLOG_POST.ID, BLOG_POST.BODY, BLOG_POST.CREATED_AT, arrayAgg(pt.TAG_NAME))
.from(BLOG_POST)
.leftOuterJoin(pt)
.on(BLOG_POST.ID.equal(pt.POST_ID))
.whereExists(selectOne()
.from(DSL.name("postIds"))
.where(field("id").equal(BLOG_POST.ID)))
.groupBy(BLOG_POST.ID, BLOG_POST.BODY, BLOG_POST.CREATED_AT)
.orderBy(BLOG_POST.CREATED_AT.desc())
.fetch(new RecordMapper<Record4<Integer, String, OffsetDateTime, String[]>, BlogPost>() {
@Override
public BlogPost map(Record4<Integer, String, OffsetDateTime, String[]> record) {
final Integer postId = record.value1();
final String text = record.value2();
final OffsetDateTime createdAt = record.value3();
final List<String> tags = Arrays.asList(record.value4());
return BlogPost.create(postId, text, createdAt, tags);
}
});
}
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response createPost(
final @FormParam("text") String text,
final @FormParam("tags") List<String> tags) {
// TODO(ben): implement something like @UnitOfWork
return primary.transactionResult(new TransactionalCallable<Response>() {
@Override
public Response run(Configuration configuration) throws Exception {
DSLContext cxt = DSL.using(configuration);
BlogPostRecord post = cxt
.insertInto(BLOG_POST, BLOG_POST.BODY)
.values(text)
.returning(BLOG_POST.ID, BLOG_POST.CREATED_AT)
.fetchOne();
if (tags != null && tags.size() > 0) {
InsertValuesStep2<PostTagRecord, Integer, String> insert = cxt.insertInto(
POST_TAG, POST_TAG.POST_ID, POST_TAG.TAG_NAME);
for (String tag : tags) {
insert = insert.values(post.getId(), tag);
}
insert.execute();
}
return Response.ok()
.location(UriBuilder.fromPath("/" + post.getId()).build())
.build();
}
});
}
@GET
@Path("/{id}")
public BlogPost getPost(@PathParam("id") IntParam id, @Context DSLContext create) {
final Record4<Integer, String, OffsetDateTime, String[]> record = create
.select(BLOG_POST.ID, BLOG_POST.BODY, BLOG_POST.CREATED_AT, arrayAgg(POST_TAG.TAG_NAME))
.from(BLOG_POST)
.leftOuterJoin(POST_TAG)
.on(BLOG_POST.ID.equal(POST_TAG.POST_ID))
.where(BLOG_POST.ID.equal(id.get()))
.groupBy(BLOG_POST.ID, BLOG_POST.BODY, BLOG_POST.CREATED_AT)
.fetchOne();
if (record == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
final Integer postId = record.value1();
final String text = record.value2();
final OffsetDateTime createdAt = record.value3();
final List<String> tags = Arrays.asList(record.value4());
return BlogPost.create(postId, text, createdAt, tags);
}
}