diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index 39ce6b4..dfbee6c 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -11,6 +11,7 @@ application{ } dependencies{ + implementation(project(":bookmark")); implementation(project(":company")) implementation(project(":contact")) implementation(project(":core")) diff --git a/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java b/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java index 8ff9b8f..b9a9da0 100644 --- a/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java +++ b/backend/src/main/java/de/srsoftware/umbrella/backend/Application.java @@ -8,6 +8,7 @@ import static java.lang.System.Logger.Level.INFO; import com.sun.net.httpserver.HttpServer; import de.srsoftware.configuration.JsonConfig; import de.srsoftware.tools.ColorLogger; +import de.srsoftware.umbrella.bookmarks.BookmarkApi; import de.srsoftware.umbrella.company.CompanyModule; import de.srsoftware.umbrella.core.Util; import de.srsoftware.umbrella.core.exceptions.UmbrellaException; @@ -61,6 +62,7 @@ public class Application { var server = HttpServer.create(new InetSocketAddress(port), 0); var userModule = new UserModule(config,messageSystem); + var bookmarkApi = new BookmarkApi(config,userModule); var companyModule = new CompanyModule(config, userModule); var documentApi = new DocumentApi(companyModule, translationModule, config); var itemApi = new ItemApi(config,companyModule); @@ -74,6 +76,7 @@ public class Application { var timeModule = new TimeModule(config,taskModule); var webHandler = new WebHandler(); + bookmarkApi .bindPath("/api/bookmark") .on(server); documentApi .bindPath("/api/document") .on(server); companyModule .bindPath("/api/company") .on(server); itemApi .bindPath("/api/items") .on(server); diff --git a/bookmark/src/main/java/de/srsoftware/umbrella/bookmarks/BookmarkApi.java b/bookmark/src/main/java/de/srsoftware/umbrella/bookmarks/BookmarkApi.java new file mode 100644 index 0000000..a94e612 --- /dev/null +++ b/bookmark/src/main/java/de/srsoftware/umbrella/bookmarks/BookmarkApi.java @@ -0,0 +1,21 @@ +/* © SRSoftware 2025 */ +package de.srsoftware.umbrella.bookmarks; + +import static de.srsoftware.umbrella.bookmarks.Constants.CONFIG_DATABASE; +import static de.srsoftware.umbrella.core.ConnectionProvider.connect; +import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException; + +import de.srsoftware.configuration.Configuration; +import de.srsoftware.umbrella.core.BaseHandler; +import de.srsoftware.umbrella.core.api.UserService; + +public class BookmarkApi extends BaseHandler { + private final BookmarkDb db; + private final UserService users; + + public BookmarkApi(Configuration config, UserService userService) { + var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE)); + db = new SqliteDb(connect(dbFile)); + users = userService; + } +} diff --git a/bookmark/src/main/java/de/srsoftware/umbrella/bookmarks/BookmarkDb.java b/bookmark/src/main/java/de/srsoftware/umbrella/bookmarks/BookmarkDb.java new file mode 100644 index 0000000..e23a1e0 --- /dev/null +++ b/bookmark/src/main/java/de/srsoftware/umbrella/bookmarks/BookmarkDb.java @@ -0,0 +1,5 @@ +/* © SRSoftware 2025 */ +package de.srsoftware.umbrella.bookmarks; + +public interface BookmarkDb { +} diff --git a/bookmark/src/main/java/de/srsoftware/umbrella/bookmarks/Constants.java b/bookmark/src/main/java/de/srsoftware/umbrella/bookmarks/Constants.java new file mode 100644 index 0000000..4e816fd --- /dev/null +++ b/bookmark/src/main/java/de/srsoftware/umbrella/bookmarks/Constants.java @@ -0,0 +1,9 @@ +/* © SRSoftware 2025 */ +package de.srsoftware.umbrella.bookmarks; + +public class Constants { + public static final String CONFIG_DATABASE = "umbrella.modules.bookmark.database"; + public static final String TABLE_URLS = "urls"; + public static final String TABLE_URL_COMMENTS = "url_comments"; + +} diff --git a/bookmark/src/main/java/de/srsoftware/umbrella/bookmarks/SqliteDb.java b/bookmark/src/main/java/de/srsoftware/umbrella/bookmarks/SqliteDb.java new file mode 100644 index 0000000..e153593 --- /dev/null +++ b/bookmark/src/main/java/de/srsoftware/umbrella/bookmarks/SqliteDb.java @@ -0,0 +1,59 @@ +/* © SRSoftware 2025 */ +package de.srsoftware.umbrella.bookmarks; + +import static de.srsoftware.umbrella.bookmarks.Constants.TABLE_URLS; +import static de.srsoftware.umbrella.bookmarks.Constants.TABLE_URL_COMMENTS; +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 de.srsoftware.umbrella.core.BaseDb; +import java.sql.Connection; +import java.sql.SQLException; + +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 "url_comments" ( + `url_hash` VARCHAR ( 255 ) NOT NULL, + `user_id` LONG NOT NULL, + `comment` TEXT NOT NULL, + PRIMARY KEY (`url_hash`,`user_id`) +)"""; + try { + var stmt = db.prepareStatement(sql); + 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 (hash VARCHAR(255) PRIMARY KEY, url TEXT 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); + } + } +} diff --git a/core/src/main/java/de/srsoftware/umbrella/core/BaseDb.java b/core/src/main/java/de/srsoftware/umbrella/core/BaseDb.java index d752413..60d43e7 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/BaseDb.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/BaseDb.java @@ -1,10 +1,6 @@ +/* © SRSoftware 2025 */ package de.srsoftware.umbrella.core; -import de.srsoftware.tools.jdbc.Query; - -import java.sql.Connection; -import java.sql.SQLException; - import static de.srsoftware.tools.jdbc.Condition.equal; import static de.srsoftware.tools.jdbc.Query.replaceInto; import static de.srsoftware.tools.jdbc.Query.update; @@ -14,8 +10,12 @@ import static java.lang.System.Logger.Level.ERROR; import static java.lang.System.Logger.Level.INFO; import static java.text.MessageFormat.format; +import de.srsoftware.tools.jdbc.Query; +import java.sql.Connection; +import java.sql.SQLException; + public abstract class BaseDb { - private final System.Logger LOG = System.getLogger(getClass().getInterfaces()[0].getSimpleName()); + protected final System.Logger LOG = System.getLogger(getClass().getInterfaces()[0].getSimpleName()); protected final Connection db; diff --git a/core/src/main/java/de/srsoftware/umbrella/core/api/BookmarkService.java b/core/src/main/java/de/srsoftware/umbrella/core/api/BookmarkService.java new file mode 100644 index 0000000..27e008e --- /dev/null +++ b/core/src/main/java/de/srsoftware/umbrella/core/api/BookmarkService.java @@ -0,0 +1,5 @@ +/* © SRSoftware 2025 */ +package de.srsoftware.umbrella.core.api; + +public interface BookmarkService { +} diff --git a/core/src/main/java/de/srsoftware/umbrella/core/api/NoteService.java b/core/src/main/java/de/srsoftware/umbrella/core/api/NoteService.java index 1204899..7dcfe9f 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/api/NoteService.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/api/NoteService.java @@ -3,9 +3,6 @@ package de.srsoftware.umbrella.core.api; import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import de.srsoftware.umbrella.core.model.Note; -import de.srsoftware.umbrella.core.model.UmbrellaUser; - -import java.util.Collection; import java.util.Map; public interface NoteService { diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/Note.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Note.java index f933e7c..582fb66 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/model/Note.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Note.java @@ -1,18 +1,16 @@ /* © SRSoftware 2025 */ package de.srsoftware.umbrella.core.model; -import de.srsoftware.tools.Mappable; +import static de.srsoftware.umbrella.core.Constants.*; +import static de.srsoftware.umbrella.core.Util.markdown; +import static java.time.ZoneOffset.UTC; +import de.srsoftware.tools.Mappable; import java.sql.ResultSet; import java.sql.SQLException; import java.time.LocalDateTime; -import java.time.ZoneOffset; import java.util.Map; -import static de.srsoftware.umbrella.core.Constants.*; -import static de.srsoftware.umbrella.core.Util.markdown; -import static java.time.ZoneOffset.UTC; - public record Note(long id, String module, long entityId, long authorId, String text, LocalDateTime timestamp) implements Mappable { public static Note of(ResultSet rs) throws SQLException { return new Note( diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/Status.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Status.java index 1c8c3bd..856b6a3 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/model/Status.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Status.java @@ -1,17 +1,16 @@ /* © SRSoftware 2025 */ package de.srsoftware.umbrella.core.model; -import de.srsoftware.tools.Mappable; +import static de.srsoftware.umbrella.core.Constants.CODE; +import static de.srsoftware.umbrella.core.Constants.NAME; +import de.srsoftware.tools.Mappable; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; -import static de.srsoftware.umbrella.core.Constants.CODE; -import static de.srsoftware.umbrella.core.Constants.NAME; - public record Status(String name, int code) implements Mappable { public static final Status PENDING = new Status("PENDING", 10); // was 40 public static final Status OPEN = new Status("OPEN",20); // was 10