341 lines
13 KiB
Java
341 lines
13 KiB
Java
package de.anxietyprime.swajodel;
|
|
|
|
import org.springframework.http.HttpStatus;
|
|
import org.springframework.web.bind.annotation.*;
|
|
import org.springframework.web.server.ResponseStatusException;
|
|
|
|
import java.sql.*;
|
|
|
|
import java.util.Optional;
|
|
import java.util.Vector;
|
|
|
|
@RestController
|
|
@CrossOrigin(origins = "*", allowedHeaders = "*")
|
|
public class Routes {
|
|
|
|
@GetMapping("/posts/{longitude}/{latitude}")
|
|
public Vector<JodelPost> getPostsByLocation(@PathVariable("longitude") float longitude, @PathVariable("latitude") float latitude) {
|
|
// list of all posts (not comments) in range
|
|
Vector<JodelPost> posts = new Vector<>();
|
|
|
|
// DB connection and statement
|
|
Connection c;
|
|
PreparedStatement stmt;
|
|
|
|
// try to get data from db
|
|
try {
|
|
// check for the driver
|
|
Class.forName("org.postgresql.Driver");
|
|
// get the connection with credentials from env variables
|
|
c = DriverManager
|
|
.getConnection("jdbc:postgresql://"+
|
|
System.getenv("POSTGRES_IP")+"/"+System.getenv("POSTGRES_DB"),
|
|
System.getenv("POSTGRES_USER"), System.getenv("POSTGRES_PASSWORD"));
|
|
// disable auto commits
|
|
c.setAutoCommit(false);
|
|
|
|
// create a new statement
|
|
stmt = c.prepareStatement("""
|
|
WITH RECURSIVE targets AS (
|
|
SELECT
|
|
posts.id,
|
|
posts.id AS parent,
|
|
posts.author,
|
|
posts.title,
|
|
posts.content,
|
|
posts.postdate,
|
|
posts.postlocation[0] AS longitude,
|
|
posts.postlocation[1] AS latitude,
|
|
(SELECT count(*) FROM reactions WHERE reactions.post = posts.id AND reactions.positive = TRUE) AS positive,
|
|
(SELECT count(*) FROM reactions WHERE reactions.post = posts.id AND reactions.positive = FALSE) AS negative
|
|
FROM
|
|
posts
|
|
WHERE
|
|
deleted IS NULL
|
|
AND earth_distance(
|
|
ll_to_earth(posts.postlocation[0], posts.postlocation[1]),
|
|
ll_to_earth((?), (?))
|
|
) <= 10000
|
|
AND posts.id NOT IN (SELECT child FROM comments)
|
|
UNION
|
|
SELECT
|
|
com.child,
|
|
com.parent,
|
|
com.author,
|
|
com.title,
|
|
com.content,
|
|
com.postdate,
|
|
com.postlocation[0],
|
|
com.postlocation[1],
|
|
(SELECT count(*) FROM reactions WHERE reactions.post = com.child AND reactions.positive = TRUE) AS positive,
|
|
(SELECT count(*) FROM reactions WHERE reactions.post = com.child AND reactions.positive = FALSE) AS negative
|
|
FROM
|
|
(SELECT * FROM comments inner join posts ON comments.child = posts.id) com
|
|
inner join targets ON targets.id = com.parent
|
|
)
|
|
SELECT * FROM targets;""");
|
|
|
|
stmt.setObject(1, longitude);
|
|
stmt.setObject(2, latitude);
|
|
|
|
// query recursively for posts inside a 10km radius
|
|
ResultSet rs = stmt.executeQuery();
|
|
|
|
// for all the posts found
|
|
while ( rs.next() ) {
|
|
// create a post from the author id
|
|
JodelPost post = new JodelPost(rs);
|
|
|
|
// check if the parent is the own id
|
|
// if it is, it is a post
|
|
if (!post.isComment()) {
|
|
// add the post to the posts
|
|
posts.add(post);
|
|
}
|
|
// else it is a comment
|
|
else {
|
|
// iterate over all posts
|
|
for (JodelPost p : posts) {
|
|
// try to add the post to a parent
|
|
p.addComment(post);
|
|
}
|
|
}
|
|
}
|
|
|
|
// close all connections to db
|
|
rs.close();
|
|
stmt.close();
|
|
c.close();
|
|
}
|
|
|
|
// else log the error
|
|
catch ( Exception e ) {
|
|
System.err.println( e.getClass().getName()+": "+ e.getMessage() );
|
|
throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, "Database is offline");
|
|
}
|
|
|
|
// calculate anonymous IDs for the posts
|
|
posts.forEach(post -> post.anonymize(Optional.empty()));
|
|
// return the posts
|
|
return posts;
|
|
}
|
|
|
|
@GetMapping("/post/{id}")
|
|
public JodelPost getPostByID(@PathVariable("id") long id) {
|
|
// list of all posts (not comments) in range
|
|
Optional<JodelPost> root_post = Optional.empty();
|
|
|
|
// DB connection and statement
|
|
Connection c;
|
|
PreparedStatement stmt;
|
|
|
|
// try to get data from db
|
|
try {
|
|
// check for the driver
|
|
Class.forName("org.postgresql.Driver");
|
|
// get the connection with credentials from env variables
|
|
c = DriverManager
|
|
.getConnection("jdbc:postgresql://"+
|
|
System.getenv("POSTGRES_IP")+"/"+System.getenv("POSTGRES_DB"),
|
|
System.getenv("POSTGRES_USER"), System.getenv("POSTGRES_PASSWORD"));
|
|
// disable auto commits
|
|
c.setAutoCommit(false);
|
|
|
|
// create a new statement
|
|
stmt = c.prepareStatement("""
|
|
WITH RECURSIVE targets AS (
|
|
SELECT
|
|
posts.id,
|
|
posts.id AS parent,
|
|
posts.author,
|
|
posts.title,
|
|
posts.content,
|
|
posts.postdate,
|
|
posts.postlocation[0] AS longitude,
|
|
posts.postlocation[1] AS latitude,
|
|
(SELECT count(*) FROM reactions WHERE reactions.post = posts.id AND reactions.positive = TRUE) AS positive,
|
|
(SELECT count(*) FROM reactions WHERE reactions.post = posts.id AND reactions.positive = FALSE) AS negative
|
|
FROM
|
|
posts
|
|
WHERE
|
|
deleted IS NULL
|
|
AND posts.id = (?)
|
|
AND posts.id NOT IN (SELECT child FROM comments)
|
|
UNION
|
|
SELECT
|
|
com.child,
|
|
com.parent,
|
|
com.author,
|
|
com.title,
|
|
com.content,
|
|
com.postdate,
|
|
com.postlocation[0],
|
|
com.postlocation[1],
|
|
(SELECT count(*) FROM reactions WHERE reactions.post = com.child AND reactions.positive = TRUE) AS positive,
|
|
(SELECT count(*) FROM reactions WHERE reactions.post = com.child AND reactions.positive = FALSE) AS negative
|
|
FROM
|
|
(SELECT * FROM comments inner join posts ON comments.child = posts.id) com
|
|
inner join targets ON targets.id = com.parent
|
|
)
|
|
SELECT * FROM targets;""");
|
|
|
|
stmt.setObject(1, id);
|
|
|
|
// query recursively for posts inside a 10km radius
|
|
ResultSet rs = stmt.executeQuery();
|
|
|
|
// for all the posts found
|
|
while ( rs.next() ) {
|
|
// create a post from the author id
|
|
JodelPost post = new JodelPost(rs);
|
|
|
|
// get the posts parent
|
|
long parent = rs.getLong("parent");
|
|
|
|
// check if the parent is the own id
|
|
// if it is, it is a post
|
|
if (parent == post.id) {
|
|
// add the post to the posts
|
|
root_post = Optional.of(post);
|
|
}
|
|
// else it is a comment
|
|
else {
|
|
// try to add the post to parent
|
|
root_post.ifPresent(root -> root.addComment(post));
|
|
}
|
|
}
|
|
|
|
// close all connections to db
|
|
rs.close();
|
|
stmt.close();
|
|
c.close();
|
|
}
|
|
|
|
// else log the error
|
|
catch ( Exception e ) {
|
|
System.err.println( e.getClass().getName()+": "+ e.getMessage() );
|
|
throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, "Database is offline");
|
|
}
|
|
|
|
// calculate anonymous IDs for the post
|
|
root_post.ifPresent(root -> root.anonymize(Optional.empty()));
|
|
|
|
// return the posts
|
|
if (root_post.isEmpty()) throw new ResponseStatusException(HttpStatus.NOT_FOUND, "No post found");
|
|
return root_post.get();
|
|
}
|
|
|
|
@PostMapping("/posts")
|
|
public JodelPost postPost(@RequestBody JodelPost post) {
|
|
// DB connection and statement
|
|
Connection c;
|
|
PreparedStatement stmt;
|
|
|
|
// try to get data from db
|
|
try {
|
|
// check for the driver
|
|
Class.forName("org.postgresql.Driver");
|
|
// get the connection with credentials from env variables
|
|
c = DriverManager
|
|
.getConnection("jdbc:postgresql://"+
|
|
System.getenv("POSTGRES_IP")+"/"+System.getenv("POSTGRES_DB"),
|
|
System.getenv("POSTGRES_USER"), System.getenv("POSTGRES_PASSWORD"));
|
|
// disable auto commits
|
|
c.setAutoCommit(false);
|
|
|
|
// create a new statement
|
|
stmt = c.prepareStatement("INSERT INTO Posts(author, title, content, postdate, postlocation) " +
|
|
"VALUES (?, ?, ?, ?, Point(?, ?)) RETURNING id");
|
|
|
|
stmt.setObject(1, post.getAuthorID());
|
|
stmt.setObject(2, post.title);
|
|
stmt.setObject(3, post.content);
|
|
stmt.setObject(4, post.date);
|
|
stmt.setObject(5, post.location.longitude);
|
|
stmt.setObject(6, post.location.latitude);
|
|
|
|
// insert post and get its id
|
|
ResultSet rs = stmt.executeQuery();
|
|
|
|
// get the id of the new post
|
|
rs.next();
|
|
post.id = rs.getLong("id");
|
|
|
|
// check if there is a parent
|
|
if (post.parent.isPresent()) {
|
|
// create a new statement
|
|
stmt = c.prepareStatement("INSERT INTO comments(parent, child) VALUES (?, ?)");
|
|
|
|
// fill statement
|
|
stmt.setObject(1, post.parent.get());
|
|
stmt.setObject(2, post.id);
|
|
|
|
// execute statement
|
|
stmt.execute();
|
|
}
|
|
|
|
// commit the changes
|
|
c.commit();
|
|
|
|
// close all connections to db
|
|
stmt.close();
|
|
c.close();
|
|
}
|
|
|
|
// else log the error
|
|
catch ( Exception e ) {
|
|
System.err.println( e.getClass().getName()+": "+ e.getMessage() );
|
|
throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, "Database is offline");
|
|
}
|
|
|
|
// fill missing post values
|
|
if (post.parent.isEmpty()) post.parent = Optional.of(post.id);
|
|
post.reactions = new Reactions(0, 0);
|
|
post.reaction = Optional.empty();
|
|
|
|
// anonymize code
|
|
post.anonymize(Optional.empty());
|
|
|
|
return post;
|
|
}
|
|
|
|
@DeleteMapping("/post/{id}")
|
|
public void deletePost(@PathVariable long id) {
|
|
// DB connection and statement
|
|
Connection c;
|
|
PreparedStatement stmt;
|
|
|
|
// try to get data from db
|
|
try {
|
|
// check for the driver
|
|
Class.forName("org.postgresql.Driver");
|
|
// get the connection with credentials from env variables
|
|
c = DriverManager
|
|
.getConnection("jdbc:postgresql://"+
|
|
System.getenv("POSTGRES_IP")+"/"+System.getenv("POSTGRES_DB"),
|
|
System.getenv("POSTGRES_USER"), System.getenv("POSTGRES_PASSWORD"));
|
|
// disable auto commits
|
|
c.setAutoCommit(false);
|
|
|
|
// create a new statement
|
|
stmt = c.prepareStatement("UPDATE Posts SET deleted = now() WHERE id = ? AND deleted IS NULL");
|
|
|
|
stmt.setObject(1, id);
|
|
|
|
// insert delete time
|
|
stmt.execute();
|
|
|
|
// close all connections to db
|
|
stmt.close();
|
|
c.commit();
|
|
c.close();
|
|
}
|
|
|
|
// else log the error
|
|
catch ( Exception e ) {
|
|
System.err.println( e.getClass().getName()+": "+ e.getMessage() );
|
|
throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, "Database is offline");
|
|
}
|
|
}
|
|
}
|