From 9f4f09502395b33e0105a70d396201b978da682b Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Tue, 2 Sep 2025 09:06:35 +0200 Subject: [PATCH] implemented search in companies Signed-off-by: Stephan Richter --- .../umbrella/company/CompanyModule.java | 16 ++++++++-- .../umbrella/company/Constants.java | 1 + .../srsoftware/umbrella/company/SqliteDb.java | 31 +++++++++++++++---- .../umbrella/company/api/CompanyDb.java | 3 ++ frontend/src/routes/search/Search.svelte | 27 +++++++++++++++- 5 files changed, 69 insertions(+), 9 deletions(-) diff --git a/company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java b/company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java index 726b198..e14236a 100644 --- a/company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java +++ b/company/src/main/java/de/srsoftware/umbrella/company/CompanyModule.java @@ -3,9 +3,11 @@ package de.srsoftware.umbrella.company; import static de.srsoftware.umbrella.company.Constants.CONFIG_DATABASE; import static de.srsoftware.umbrella.core.ConnectionProvider.connect; -import static de.srsoftware.umbrella.core.Constants.ID; -import static de.srsoftware.umbrella.core.Constants.MEMBERS; +import static de.srsoftware.umbrella.core.Constants.*; +import static de.srsoftware.umbrella.core.Constants.FULLTEXT; import static de.srsoftware.umbrella.core.Paths.LIST; +import static de.srsoftware.umbrella.core.Paths.SEARCH; +import static de.srsoftware.umbrella.core.Util.mapValues; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*; import com.sun.net.httpserver.HttpExchange; @@ -105,6 +107,7 @@ public class CompanyModule extends BaseHandler implements CompanyService { if (user.isEmpty()) return unauthorized(ex); var head = path.pop(); return switch (head) { + case SEARCH -> postSearch(user.get(),ex); case null -> postNewCompany(user.get(),ex); default -> super.doPost(path,ex); }; @@ -193,4 +196,13 @@ public class CompanyModule extends BaseHandler implements CompanyService { companyDb.addUser(company.id(),user.id()); return sendContent(ex,company); } + + private boolean postSearch(UmbrellaUser user, HttpExchange ex) throws IOException { + var json = json(ex); + if (!(json.has(KEY) && json.get(KEY) instanceof String key)) throw missingFieldException(KEY); + var keys = Arrays.asList(key.split(" ")); + var fulltext = json.has(FULLTEXT) && json.get(FULLTEXT) instanceof Boolean val && val; + var companies = companyDb.find(user.id(),keys); + return sendContent(ex,mapValues(companies)); + } } diff --git a/company/src/main/java/de/srsoftware/umbrella/company/Constants.java b/company/src/main/java/de/srsoftware/umbrella/company/Constants.java index 489a04e..3b0a524 100644 --- a/company/src/main/java/de/srsoftware/umbrella/company/Constants.java +++ b/company/src/main/java/de/srsoftware/umbrella/company/Constants.java @@ -5,6 +5,7 @@ public class Constants { private Constants(){} public static final String CONFIG_DATABASE = "umbrella.modules.company.database"; + public static final String DISTINCT = "DISTINCT *"; public static final String TABLE_COMPANIES_USERS = "companies_users"; public static final String TABLE_COMPANIES = "companies"; } diff --git a/company/src/main/java/de/srsoftware/umbrella/company/SqliteDb.java b/company/src/main/java/de/srsoftware/umbrella/company/SqliteDb.java index 76a4117..217b69a 100644 --- a/company/src/main/java/de/srsoftware/umbrella/company/SqliteDb.java +++ b/company/src/main/java/de/srsoftware/umbrella/company/SqliteDb.java @@ -2,14 +2,15 @@ package de.srsoftware.umbrella.company; import static de.srsoftware.tools.jdbc.Condition.equal; +import static de.srsoftware.tools.jdbc.Condition.like; import static de.srsoftware.tools.jdbc.Query.*; import static de.srsoftware.tools.jdbc.Query.Dialect.SQLITE; import static de.srsoftware.tools.jdbc.Query.SelectQuery.ALL; -import static de.srsoftware.umbrella.company.Constants.TABLE_COMPANIES; -import static de.srsoftware.umbrella.company.Constants.TABLE_COMPANIES_USERS; +import static de.srsoftware.umbrella.company.Constants.*; import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.databaseException; import static java.lang.System.Logger.Level.ERROR; +import static java.text.MessageFormat.format; import de.srsoftware.umbrella.company.api.CompanyDb; import de.srsoftware.umbrella.core.BaseDb; @@ -17,10 +18,8 @@ import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import de.srsoftware.umbrella.core.model.Company; import java.sql.Connection; import java.sql.SQLException; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; +import java.util.*; + import org.json.JSONObject; public class SqliteDb extends BaseDb implements CompanyDb { @@ -126,6 +125,26 @@ CREATE TABLE IF NOT EXISTS "companies" ( } } + @Override + public HashMap find(long userId, Collection keys) { + try { + var query = select(DISTINCT).from(TABLE_COMPANIES).leftJoin(ID,TABLE_COMPANIES_USERS,COMPANY_ID) + .where(USER_ID,equal(userId)); + for (var key : keys){ + query.where(format("CONCAT({0},\" \",{1},\" \",{2},\" \",{3},\" \",{4})",NAME,ADDRESS,EMAIL,FIELD_PHONE,FIELD_BANK_ACCOUNT),like("%"+key+"%")); + } + var rs = query.exec(db); + var companies = new HashMap(); + while (rs.next()) { + var company = Company.of(rs); + companies.put(company.id(),company); + } + rs.close(); + return companies; + } catch (SQLException ex){ + throw databaseException("Failed to search in company database!"); + } + } @Override public Map listCompaniesOf(long userId) throws UmbrellaException { diff --git a/company/src/main/java/de/srsoftware/umbrella/company/api/CompanyDb.java b/company/src/main/java/de/srsoftware/umbrella/company/api/CompanyDb.java index b62d495..23972b3 100644 --- a/company/src/main/java/de/srsoftware/umbrella/company/api/CompanyDb.java +++ b/company/src/main/java/de/srsoftware/umbrella/company/api/CompanyDb.java @@ -4,6 +4,7 @@ package de.srsoftware.umbrella.company.api; import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import de.srsoftware.umbrella.core.model.Company; import java.util.Collection; +import java.util.HashMap; import java.util.Map; public interface CompanyDb { @@ -13,6 +14,8 @@ public interface CompanyDb { void dropUser(long company_id, long user_id); + HashMap find(long userId, Collection keys); + Collection getMembers(long companyId) throws UmbrellaException; Map listCompaniesOf(long id) throws UmbrellaException; diff --git a/frontend/src/routes/search/Search.svelte b/frontend/src/routes/search/Search.svelte index 791b94f..fa0b0db 100644 --- a/frontend/src/routes/search/Search.svelte +++ b/frontend/src/routes/search/Search.svelte @@ -9,6 +9,7 @@ const router = useTinyRouter(); console.log(router); let bookmarks = $state(null); + let companies = $state(null); let error = $state(null); let fulltext = false; let key = $state(router.getQueryParam('key')); @@ -39,6 +40,7 @@ body: JSON.stringify(data) }; fetch(api('bookmark/search'),options).then(handleBookmarks); + fetch(api('company/search'),options).then(handleCompanies); fetch(api('project/search'),options).then(handleProjects); fetch(api('task/search'),options).then(handleTasks); } @@ -57,6 +59,15 @@ } } + async function handleCompanies(resp){ + if (resp.ok){ + const json = await resp.json(); + companies = Object.keys(json).length ? json : null; + } else { + error = await resp.text(); + } + } + async function handleProjects(resp){ if (resp.ok){ const res = await resp.json(); @@ -140,4 +151,18 @@ {/each} -{/if} \ No newline at end of file +{/if} +{#if companies} +
+ + {t('companies')} + + +
+{/if}