Internet-Technologien/src/main/java/de/hsel/itech/db/Database.java

397 lines
12 KiB
Java

package de.hsel.itech.db;
import de.hsel.itech.config.Configuration;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.json.JSONObject;
import org.mariadb.jdbc.MariaDbPoolDataSource;
import java.io.*;
import java.net.URL;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* base class for everything regarding the database.
*
* @author Johannes Theiner
* @version 0.1
* @since 0.1
*/
public class Database {
final String tableBook = "book";
final String tableAuthor = "author";
final String tableAuthorBook = "author_book";
final String tablePublisher = "publisher";
final String tableCategory = "category";
final String tableUser = "user";
final String tableUserAddress = "user_address";
final String tableAddress = "address";
final String tableCartBooks = "cart_books";
final String tableOrder = "`order`";
final String tableOrderBook = "order_book";
final String tablePaymentType = "payment_type";
final String tablePaymentPayPal = "payment_paypal";
final String tablePaymentCredit = "payment_credit";
final String tablePaymentDebit = "payment_debit";
final String tablePaymentInvoice = "payment_invoice";
final String tableUserPayment = "user_payment";
private AuthorDB authorDB;
private BookDB bookDB;
private CategoryDB categoryDB;
private PublisherDB publisherDB;
private UserDB userDB;
private AddressDB addressDB;
private ShoppingCartDB shoppingCartDB;
private OrderDB orderDB;
private PaymentDB paymentDB;
private static Database instance;
/**
* Singleton for database access.
*
* @return {@link Database}
*/
public static Database getInstance() {
if (instance == null)
instance = new Database();
return instance;
}
private MariaDbPoolDataSource dataSource;
/**
* initializes connection pool and executes database setup.
*/
private Database() {
Configuration config = Configuration.get();
dataSource = new MariaDbPoolDataSource("jdbc:mysql://" + config.getDatabase().getHostname()
+ ":" + config.getDatabase().getPort() + "/" + config.getDatabase().getDatabase() + "?useUnicode=true&characterEncoding=UTF-8&maxPoolSize=10&pool");
try {
dataSource.setUser(config.getDatabase().getUsername());
dataSource.setPassword(config.getDatabase().getPassword());
dataSource.initialize();
Connection connection = getConnection();
assert connection != null;
URL file = getClass().getClassLoader().getResource("database.sql");
assert file != null;
try (BufferedReader br = new BufferedReader(new FileReader(file.getFile()))) {
for (String line = br.readLine(); line != null; line = br.readLine()) {
PreparedStatement statement = connection.prepareStatement(line);
statement.executeUpdate();
statement.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* gets connection from connection pool.
*
* @return {@link java.sql.Connection}
*/
@Nullable
Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
@Contract
public BookDB book() {
if(bookDB == null)
bookDB = new BookDB(this);
return bookDB;
}
@Contract
public AuthorDB author() {
if(authorDB == null)
authorDB = new AuthorDB(this);
return authorDB;
}
@Contract
public CategoryDB category() {
if (categoryDB == null)
categoryDB = new CategoryDB(this);
return categoryDB;
}
@Contract
public PublisherDB publisher() {
if(publisherDB == null)
publisherDB = new PublisherDB(this);
return publisherDB;
}
@Contract
public UserDB user() {
if(userDB == null)
userDB = new UserDB(this);
return userDB;
}
@Contract
public AddressDB address() {
if(addressDB == null)
addressDB = new AddressDB(this);
return addressDB;
}
@Contract
public ShoppingCartDB shoppingCart() {
if(shoppingCartDB == null)
shoppingCartDB = new ShoppingCartDB(this);
return shoppingCartDB;
}
@Contract
public OrderDB order() {
if(orderDB == null)
orderDB = new OrderDB(this);
return orderDB;
}
@Contract
public PaymentDB payment() {
if(paymentDB == null)
paymentDB = new PaymentDB(this);
return paymentDB;
}
/**
* deletes entry from table.
*
* @param id database id
* @param table table name
* @return deletion count
*/
int delete(long id, @NotNull String table) {
Connection connection = getConnection();
assert connection != null;
int deleteCount = 0;
try {
PreparedStatement statement = connection.prepareStatement("DELETE FROM " + table + " WHERE id=?");
statement.setLong(1, id);
deleteCount = +statement.executeUpdate();
} catch (SQLException ex) {
ex.printStackTrace();
}
return deleteCount;
}
/**
* deletes entry from table.
*
* @param id id of entry to delete
* @param table table to delete from
* @param column column to delete id from
* @return deletion count
*/
int delete(long id, @NotNull String table, @NotNull String column) {
Connection connection = getConnection();
assert connection != null;
int deleteCount = 0;
try {
PreparedStatement statement = connection.prepareStatement("DELETE FROM " + table + " WHERE " + column + "=?");
statement.setLong(1, id);
deleteCount = +statement.executeUpdate();
} catch (SQLException ex) {
ex.printStackTrace();
}
return deleteCount;
}
/**
* getAll all ids from specified table.
*
* @param table table
* @return list of ids
*/
List<Long> getIds(@NotNull String table) {
Map.Entry<ResultSet, Connection> entry = getColumnsFromResultSet(table, "id");
assert entry != null;
List<Long> ids = new ArrayList<>();
try {
ResultSet rs = entry.getKey();
while (rs.next()) {
ids.add(rs.getLong("id"));
}
entry.getValue().close();
} catch (SQLException ex) {
ex.printStackTrace();
}
return ids;
}
/**
* gets specific entry from database.
*
* @param table table name
* @param id id from database
* @return {@link java.util.Map.Entry}
*/
@Nullable
Map.Entry<ResultSet, Connection> getResultSetById(@NotNull String table, long id) {
return getResultSetByValue(table, "id", id);
}
@Nullable
Map.Entry<ResultSet, Connection> getResultSetByValue(@NotNull String table, @NotNull String column, long value) {
Connection connection = getConnection();
try {
assert connection != null;
PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + table + " WHERE " + column + " = ?");
statement.setLong(1, value);
ResultSet resultSet = statement.executeQuery();
Map.Entry<ResultSet, Connection> entry = null;
while (resultSet.next()) {
entry = new AbstractMap.SimpleEntry<>(resultSet, connection);
}
return entry;
} catch (SQLException ex) {
ex.printStackTrace();
}
return null;
}
/**
* gets specific entries from table.
*
* @param table table name
* @param column column to match
* @param id id all entries should reference
* @return {@link java.util.Map.Entry}
*/
@Nullable
Map.Entry<ResultSet, Connection> getResultSetsById(@NotNull String table, @NotNull String column, long id) {
Connection connection = getConnection();
try {
assert connection != null;
PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + table + " WHERE " + column + " = ?");
statement.setLong(1, id);
return getAllEntriesFromResultSet(connection, statement);
} catch (SQLException ex) {
ex.printStackTrace();
}
return null;
}
/**
* gets specific entries from table.
*
* @param table table name
* @param column column to match
* @return {@link java.util.Map.Entry}
*/
@Nullable
Map.Entry<ResultSet, Connection> getResultSetsByValue(@NotNull String table, @NotNull String column, @NotNull String value) {
Connection connection = getConnection();
try {
assert connection != null;
PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + table + " WHERE " + column + " = ?");
statement.setString(1, value);
return getAllEntriesFromResultSet(connection, statement);
} catch (SQLException ex) {
ex.printStackTrace();
}
return null;
}
/**
* gets all specified columns from table.
*
* @param table table name
* @param columns columns as String array
* @return {@link java.util.Map.Entry}
*/
@Nullable
private Map.Entry<ResultSet, Connection> getColumnsFromResultSet(@NotNull String table, @NotNull String... columns) {
Connection connection = getConnection();
try {
assert connection != null;
PreparedStatement statement = connection.prepareStatement("SELECT (" + String.join(",", columns) + ") FROM " + table);
return getAllEntriesFromResultSet(connection, statement);
} catch (SQLException ex) {
ex.printStackTrace();
}
return null;
}
/**
* gets all entries contained in result set.
*
* @param connection Connection
* @param statement query statement
* @return {@link java.util.Map.Entry}
*/
@Nullable
private Map.Entry<ResultSet, Connection> getAllEntriesFromResultSet(@NotNull Connection connection, @NotNull PreparedStatement statement) {
try {
ResultSet resultSet = statement.executeQuery();
return new AbstractMap.SimpleEntry<>(resultSet, connection);
} catch (SQLException ex) {
ex.printStackTrace();
}
return null;
}
@Nullable
String getRandomImage() {
try {
try (InputStream is = new URL("https://api.unsplash.com/photos/random?client_id=" + Configuration.get().getUnsplash().getAccessKey()).openStream()) {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
JSONObject json = new JSONObject(sb.toString());
return json.getString("id");
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}