Skip to content
This repository was archived by the owner on Jun 11, 2022. It is now read-only.

Commit cb8fb4a

Browse files
authored
Merge pull request #3 from jakub-balinski/develop
Finish all major functionalities
2 parents e0748f5 + 82b1a7a commit cb8fb4a

36 files changed

+806
-401
lines changed

.gitattributes

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
/* linguist-vendored
1+
./* linguist-vendored
22
sakila-min.sql linguist-vendored=true

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
To use your own database, configure properly properties file under server/src/main/resources/database.properties,
2+
then initialize the database with sakila-min.sql script.
3+
4+
API Default Admin User: user=sa, token=bdd69043cade8ba513813e2e17cd25e241e259bdac956dab2d437b43f40d9514

pom.xml

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
<version>1.0-SNAPSHOT</version>
1111
<modules>
1212
<module>server</module>
13-
<module>webapp</module>
1413
</modules>
1514

1615

sakila-min.sql

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
CREATE CACHED TABLE PUBLIC.USER(
44
USER_ID INT IDENTITY NOT NULL PRIMARY KEY,
5-
NAME VARCHAR(45) NOT NULL UNIQUE,
5+
ROLE VARCHAR(5) NOT NULL,
6+
NAME VARCHAR(45) NOT NULL,
67
TOKEN VARCHAR(64) NOT NULL,
78
REQUESTS_SENT INT NOT NULL DEFAULT 0,
89
USE_LIMIT INT NOT NULL,
@@ -38,6 +39,8 @@ CREATE CACHED TABLE PUBLIC.LANGUAGE(
3839
LAST_UPDATE TIMESTAMP NOT NULL
3940
);
4041

42+
INSERT INTO PUBLIC.USER (ROLE, NAME, TOKEN, REQUESTS_SENT, USE_LIMIT, DATE_REGISTERED, LAST_UPDATE) VALUES ('admin', 'sa', 'bdd69043cade8ba513813e2e17cd25e241e259bdac956dab2d437b43f40d9514', 0, 100000000, '1970-01-01', '1970-01-01');
43+
4144
INSERT INTO PUBLIC.ACTOR (FIRST_NAME, LAST_NAME, LAST_UPDATE) VALUES ('PENELOPE', 'GUINESS', '2006-02-15 04:34:33.000000000');
4245
INSERT INTO PUBLIC.ACTOR (FIRST_NAME, LAST_NAME, LAST_UPDATE) VALUES ('NICK', 'WAHLBERG', '2006-02-15 04:34:33.000000000');
4346
INSERT INTO PUBLIC.ACTOR (FIRST_NAME, LAST_NAME, LAST_UPDATE) VALUES ('ED', 'CHASE', '2006-02-15 04:34:33.000000000');

server/pom.xml

-5
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@
2929
<artifactId>jetty-servlet</artifactId>
3030
<version>9.4.25.v20191220</version>
3131
</dependency>
32-
<dependency>
33-
<groupId>org.eclipse.jetty</groupId>
34-
<artifactId>jetty-webapp</artifactId>
35-
<version>9.4.25.v20191220</version>
36-
</dependency>
3732
<dependency>
3833
<groupId>com.h2database</groupId>
3934
<artifactId>h2</artifactId>

server/src/main/java/com/balinski/api_project/Main.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.balinski.api_project;
22

3-
import com.balinski.api_project.database.DaoManager;
3+
import com.balinski.api_project.database.dao.DaoManager;
44

55
import com.balinski.api_project.database.dao.DaoException;
66
import com.balinski.api_project.database.model.Film;
@@ -9,9 +9,9 @@
99
import java.util.List;
1010

1111
public class Main {
12-
12+
//"name":"jakub","token":"7f078d288631a4de5fc1ce01fa4e0addeebed19ad5c6d6f543fcc160c5c5cdfc"
1313
public static void main(String[] args) {
14-
testDatabase();
14+
//testDatabase();
1515
runApplication();
1616
}
1717

@@ -27,7 +27,7 @@ static void runApplication() {
2727

2828
static void testDatabase() {
2929
try {
30-
List<Film> list = new DaoManager().getFilmDao().getAvailableInLanguage("jaPANESE");
30+
List<Film> list = DaoManager.getFilmDao().getAll();
3131
for(var film : list)
3232
System.out.println(film.getTitle());
3333
} catch (DaoException e) {

server/src/main/java/com/balinski/api_project/database/DaoManager.java

-120
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.balinski.api_project.database;
2+
3+
public class DatabaseException extends RuntimeException {
4+
public DatabaseException(String message) {
5+
super(message);
6+
}
7+
8+
public DatabaseException(Throwable cause) {
9+
super(cause);
10+
}
11+
12+
public DatabaseException(String message, Throwable cause) {
13+
super(message, cause);
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,118 @@
11
package com.balinski.api_project.database;
22

3-
import com.balinski.api_project.util.SqlExceptionPrinter;
43
import org.apache.commons.dbcp2.BasicDataSource;
54

5+
import java.io.IOException;
66
import java.sql.*;
77
import java.util.*;
88
import java.util.stream.Stream;
99

1010
public class DatabaseProxy {
11-
private BasicDataSource dataSource;
12-
private Connection connection;
13-
private String url;
14-
private String username;
15-
private String password;
11+
protected static BasicDataSource dataSource;
12+
protected static Connection connection;
13+
protected static String driver;
14+
protected static String url;
15+
protected static String username;
16+
protected static String password;
1617

17-
public DatabaseProxy(Properties props) {
18-
try {
19-
loadDatabaseProperties(props);
20-
initDataSource();
21-
} catch (Exception e) {
22-
System.err.println("Cannot initialize database data source: " + e.getMessage());
18+
static {
19+
loadDatabaseProperties();
20+
loadDriver();
21+
testConnection();
22+
initDataSource();
23+
}
24+
25+
private DatabaseProxy(){};
26+
27+
public static List<Map<String, Object>> querySelect(String sql) throws DatabaseException {
28+
List<Map<String, Object>> data;
29+
30+
try(Connection connection = getConnection()) {
31+
try(Statement statement = connection.createStatement()) {
32+
try(ResultSet rs = statement.executeQuery(sql)) {
33+
ResultSetMetaData md = rs.getMetaData();
34+
int columns = md.getColumnCount();
35+
data = new LinkedList<>();
36+
37+
while(rs.next()) {
38+
Map<String, Object> row = new HashMap<>(columns);
39+
40+
for(int i = 1; i <= columns; i++)
41+
row.put(md.getColumnName(i), rs.getObject(i));
42+
43+
data.add(row);
44+
}
45+
}
46+
}
47+
} catch (SQLException e) {
48+
throw new DatabaseException("An error occurred when trying to query the database.", e);
49+
} finally {
50+
closeConnection();
51+
}
52+
53+
return data;
54+
}
55+
56+
public static int queryUpdate(String sql, boolean transaction) throws DatabaseException {
57+
int rowsAffected = 0;
58+
59+
try(Connection connection = getConnection()) {
60+
if(transaction)
61+
connection.setAutoCommit(false);
62+
63+
try(Statement statement = connection.createStatement()) {
64+
rowsAffected = statement.executeUpdate(sql);
65+
}
66+
67+
if(transaction) {
68+
connection.setAutoCommit(true);
69+
connection.commit();
70+
}
71+
} catch (SQLException e) {
72+
e.printStackTrace();
73+
throw new DatabaseException("An error occurred when trying to update the database.", e);
74+
} finally {
75+
closeConnection();
2376
}
77+
78+
return rowsAffected;
2479
}
2580

26-
public Connection getConnection() {
81+
protected static Connection getConnection() throws DatabaseException {
2782
try {
28-
this.connection = dataSource.getConnection();
83+
connection = dataSource.getConnection();
2984
} catch (SQLException e) {
30-
SqlExceptionPrinter.print("Could not obtain an instance of connection from given data source.", e);
85+
throw new DatabaseException("Could not obtain an instance of connection from given data source.", e);
3186
}
3287

3388
return connection;
3489
}
3590

36-
public void closeConnection() {
91+
protected static void closeConnection() throws DatabaseException {
3792
if(connection == null)
3893
return;
3994

4095
try {
41-
this.connection.close();
96+
connection.close();
97+
} catch (SQLException e) {
98+
throw new DatabaseException("Cannot close the connection.", e);
99+
}
100+
}
101+
102+
private static void testConnection() throws DatabaseException {
103+
if(Stream.of(url, driver, username, password).anyMatch(Objects::isNull)) {
104+
throw new DatabaseException("One of the database properties (url, driver, username, password) is missing. " +
105+
"Check the file containing database properties.");
106+
}
107+
108+
try(Connection ignored = DriverManager.getConnection(url, username, password)) {
109+
System.out.println("The database connection was configured successfully.");
42110
} catch (SQLException e) {
43-
SqlExceptionPrinter.print("Cannot close the connection.", e);
111+
throw new DatabaseException("Wrong credentials or internal database error.", e);
44112
}
45113
}
46114

47-
private void initDataSource() {
115+
protected static void initDataSource() {
48116
dataSource = new BasicDataSource();
49117
dataSource.setUrl(url);
50118
dataSource.setUsername(username);
@@ -54,20 +122,26 @@ private void initDataSource() {
54122
dataSource.setMaxOpenPreparedStatements(100);
55123
}
56124

57-
private void loadDatabaseProperties(Properties props) throws NullPointerException, ClassNotFoundException {
125+
protected static void loadDatabaseProperties() throws DatabaseException {
126+
Properties props;
127+
try {
128+
props = FilePropertiesLoader.load("server/src/main/resources/database.properties");
129+
} catch (IOException e) {
130+
throw new DatabaseException("Could not find database properties file under given path: "
131+
+ "server/src/main/resources/database.properties", e);
132+
}
133+
58134
url = props.getProperty("url");
59-
String driver = props.getProperty("driver");
135+
driver = props.getProperty("driver");
60136
username = props.getProperty("username");
61137
password = props.getProperty("password");
138+
}
62139

63-
if(Stream.of(url, driver, username, password).anyMatch(Objects::isNull)) {
64-
throw new NullPointerException("One or more of properties (url, driver, username, password) is missing");
65-
}
66-
140+
private static void loadDriver() throws DatabaseException {
67141
try {
68142
Class.forName(driver);
69143
} catch (ClassNotFoundException e) {
70-
throw new ClassNotFoundException("Driver class " + driver + " not found.", e);
144+
throw new DatabaseException("Driver class " + driver + " not found.", e);
71145
}
72146
}
73147
}

0 commit comments

Comments
 (0)