OpenSource Projekt-Management-Software
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.
 
 
 
 
 

124 lines
3.8 KiB

/* © SRSoftware 2025 */
package de.srsoftware.umbrella.bookmarks;
import static de.srsoftware.tools.jdbc.Condition.equal;
import static de.srsoftware.tools.jdbc.Query.*;
import static de.srsoftware.tools.jdbc.Query.SelectQuery.ALL;
import static de.srsoftware.umbrella.bookmarks.Constants.*;
import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Constants.ERROR_FAILED_CREATE_TABLE;
import static java.lang.System.Logger.Level.ERROR;
import static java.text.MessageFormat.format;
import static java.time.ZoneOffset.UTC;
import de.srsoftware.umbrella.core.BaseDb;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import de.srsoftware.umbrella.core.model.Bookmark;
import java.sql.Connection;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class SqliteDb extends BaseDb implements BookmarkDb {
public SqliteDb(Connection conn) {
super(conn);
}
@Override
protected int createTables() {
var version = createSettingsTable();
switch (version){
case 0:
createUrlsTable();
createUrlCommentsTable();
}
return setCurrentVersion(1);
}
private void createUrlCommentsTable() {
var sql = """
CREATE TABLE IF NOT EXISTS {0} (
`{1}` INTEGER NOT NULL,
`{2}` INTEGER NOT NULL,
`{3}` TEXT NOT NULL,
`{4}` DATETIME NOT NULL,
PRIMARY KEY (`{1}`,`{2}`)
)""";
try {
var stmt = db.prepareStatement(format(sql,TABLE_URL_COMMENTS,URL_ID,USER_ID,COMMENT,TIMESTAMP));
stmt.execute();
stmt.close();
} catch (SQLException e) {
LOG.log(ERROR, ERROR_FAILED_CREATE_TABLE, TABLE_URL_COMMENTS, e);
throw new RuntimeException(e);
}
}
private void createUrlsTable() {
var sql = "CREATE TABLE IF NOT EXISTS urls (ID INTEGER PRIMARY KEY, url TEXT UNIQUE NOT NULL)";
try {
var stmt = db.prepareStatement(sql);
stmt.execute();
stmt.close();
} catch (SQLException e) {
LOG.log(ERROR, ERROR_FAILED_CREATE_TABLE, TABLE_URLS, e);
throw new RuntimeException(e);
}
}
@Override
public Map<Long, Bookmark> list(long userId) {
try {
var map = new HashMap<Long,Bookmark>();
var rs = select(ALL).from(TABLE_URL_COMMENTS).leftJoin(URL_ID,TABLE_URLS,ID).where(USER_ID, equal(userId)).exec(db);
while (rs.next()){
var bookmark = Bookmark.of(rs);
map.put(bookmark.id(),bookmark);
}
rs.close();;
return map;
} catch (SQLException e) {
throw new UmbrellaException("Failed to load bookmark list");
}
}
@Override
public Bookmark load(long id, long userId) {
try {
Bookmark result = null;
var rs = select(ALL).from(TABLE_URLS).leftJoin(ID,TABLE_URL_COMMENTS,URL_ID).where(ID,equal(id)).where(USER_ID,equal(userId)).exec(db);
if (rs.next()) result = Bookmark.of(rs);
rs.close();
if (result != null) return result;
throw UmbrellaException.notFound("No bookmark with id {0}",id);
} catch (SQLException e) {
throw new UmbrellaException("Failed to load bookmark");
}
}
@Override
public Bookmark save(String url, String comment, Collection<Long> userIds) {
try {
var timestamp = LocalDateTime.now();
var rs = select(ID).from(TABLE_URLS).where(URL, equal(url)).exec(db);
var id = 0L;
if (rs.next()) id = rs.getLong(ID);
rs.close();
if (id == 0) {
var stmt = insertInto(TABLE_URLS, URL).values(url).execute(db);
rs = stmt.getGeneratedKeys();
if (rs.next()) id = rs.getLong(1);
rs.close();
stmt.close();
}
var query = replaceInto(TABLE_URL_COMMENTS,URL_ID,USER_ID,COMMENT, TIMESTAMP);
for (long userId : userIds) query.values(id,userId,comment,timestamp.toEpochSecond(UTC));
query.execute(db).close();
return Bookmark.of(id,url,comment,timestamp);
} catch (SQLException e) {
throw new UmbrellaException("Failed to store url");
}
}
}