Java-basierte Mailinglisten-Anwendung, die auf IMAP+SMTP aufsetzt, und damit (fast) jede Mailbox in eine Mailingliste verwandeln kann.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

167 lines
5.6 KiB

package de.srsoftware.widerhall.data;
import de.srsoftware.widerhall.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import static de.srsoftware.widerhall.Util.t;
public class Database {
public static final String EMAIL = "email";
public static final String NAME = "name";
public static final String HASHED_PASS = "hashedPassword";
public static final String SALT = "salt";
private static final Logger LOG = LoggerFactory.getLogger(Database.class);
private static final String VARCHAR = "VARCHAR(255)";
private static Database singleton = null;
private static Connection conn;
public Request insertInto(String tbName) {
return query("INSERT INTO "+tbName);
}
public class Request{
private final String sql;
private HashMap<String,List<Object>> where = new HashMap<>();
private HashMap<String,Object> values = new HashMap<>();
public Request(String sql) {
this.sql = sql;
}
public Request where(String key, Object ... values) {
for (var val : values) where(key,val);
return this;
}
public Request where(String key, Object value) {
var list = where.get(key);
if (list == null) where.put(key,list = new ArrayList<Object>());
list.add(value);
return this;
}
public Request values(Map<String,Object> newValues) {
values.putAll(newValues);
return this;
}
public Request values(String key, Object value) {
values.put(key,value);
return this;
}
public void run() throws SQLException {
var sb = new StringBuilder(sql);
var args = new ArrayList<Object>();
if (!values.isEmpty()){
var keys = new ArrayList<String>();
for (var entry : values.entrySet()) {
keys.add(entry.getKey());
args.add(entry.getValue());
}
sb.append("("+String.join(", ",keys)+")");
sb.append(" VALUES ");
var arr = new String[args.size()];
Arrays.fill(arr,"?");
var marks = String.join(", ",arr);
sb.append("(").append(marks).append(")");
}
var sql = sb.toString();
LOG.debug(sql);
try {
var stmt = conn.prepareStatement(sql);
if (!args.isEmpty()) {
for (int i = 0; i < args.size(); i++) stmt.setObject(i+1, args.get(i));
}
stmt.execute();
} catch (SQLException sqle) {
throw new SQLException(t("Query '{}' failed:",sql),sqle);
}
}
public ResultSet exec() throws SQLException {
var sb = new StringBuilder(sql);
var args = new ArrayList<Object>();
if (!where.isEmpty()){
var clauses = new ArrayList<String>();
sb.append(" WHERE ");
for (var entry : where.entrySet()){
var arr = new String[entry.getValue().size()];
Arrays.fill(arr,"?");
var marks = String.join(", ",arr);
clauses.add("("+entry.getKey()+" IN ("+marks+"))");
args.addAll(entry.getValue());
}
sb.append(String.join(" AND ",clauses));
}
var sql = sb.toString();
LOG.debug(sql);
try {
var stmt = conn.prepareStatement(sql);
if (!args.isEmpty()) {
for (int i = 0; i < args.size(); i++) stmt.setObject(i+1, args.get(i));
}
return stmt.executeQuery();
} catch (SQLException sqle) {
throw new SQLException(t("Query '{}' failed:",sql),sqle);
}
}
}
public Database(Connection connection) {
this.conn = connection;
}
public static Database open() {
if (singleton == null){
Configuration config = Configuration.instance();
var dbFile = config.dbFile();
String url = "jdbc:sqlite:"+dbFile;
LOG.debug("Opening {}",url);
dbFile.getParentFile().mkdirs();
try {
singleton = new Database(DriverManager.getConnection(url)).assertTables();
} catch (SQLException sqle) {
sqle.printStackTrace();
}
}
return singleton;
}
private Database assertTables() throws SQLException {
if (!tableExists("Users")) createUsersTable();
return this;
}
private void createUsersTable() throws SQLException {
query("CREATE TABLE Users ("+EMAIL+" "+ VARCHAR +", "+SALT+" "+VARCHAR+", "+HASHED_PASS+" "+VARCHAR+", "+NAME+" "+VARCHAR+");").run();
}
private boolean tableExists(String tbName) throws SQLException {
try {
ResultSet rs = query("SELECT EXISTS (SELECT name FROM sqlite_schema WHERE type='table' AND name='" + tbName + "')").exec();
int val = 0;
if (rs.next()) val = rs.getInt(1);
rs.close();
return val > 0;
} catch (SQLException e) {
throw new SQLException(t("Was not able to check existence of table {}!",tbName),e);
}
}
public Request query(String sql) {
return new Request(sql);
}
}