implemented adding new pages

This commit is contained in:
2025-09-12 13:20:34 +02:00
parent 7ddd32bb72
commit 7e52e02684
13 changed files with 155 additions and 21 deletions

View File

@@ -1,6 +1,7 @@
/* © SRSoftware 2025 */
package de.srsoftware.umbrella.wiki;
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.core.Constants.*;
@@ -142,10 +143,37 @@ public class SqliteDb extends BaseDb implements WikiDb {
}
}
@Override
@Override
public long getNextId() {
try {
var id = 0L;
var rs = select("MAX(ID)").from(TABLE_PAGES).exec(db);
if (rs.next()) id = rs.getLong(1);
rs.close();
return id+1;
} catch (SQLException e) {
throw databaseException("Failed to query next free page id!");
}
}
@Override
public boolean isAvailable(String title) {
if (title==null||title.isBlank())return false;
try {
var count = 1;
var rs = select("COUNT(ID)").from(TABLE_PAGES).where(TITLE,equal(title)).exec(db);
if (rs.next()) count = rs.getInt(1);
rs.close();
return count < 1;
} catch (SQLException e) {
throw databaseException("Failed to query availability of {0}!",title);
}
}
@Override
public List<String> listUserPages(long userId) {
try {
var rs = select(TITLE,"MAX(version) AS version").from(TABLE_PAGES).leftJoin(ID,TABLE_PAGES_USERS,PAGE_ID).where(USER_ID, Condition.equal(userId)).groupBy(TITLE).sort("TITLE COLLATE NOCASE ASC").exec(db);
var rs = select(TITLE,"MAX(version) AS version").from(TABLE_PAGES).leftJoin(ID,TABLE_PAGES_USERS,PAGE_ID).where(USER_ID, equal(userId)).groupBy(TITLE).sort("TITLE COLLATE NOCASE ASC").exec(db);
var set = new ArrayList<String>();
while (rs.next()) set.add(rs.getString(TITLE));
rs.close();
@@ -160,11 +188,11 @@ public class SqliteDb extends BaseDb implements WikiDb {
WikiPage page = null;
try { // Try to load by id
long id = Long.parseLong(title);
var query = select(ALL).from(TABLE_PAGES).where(ID,Condition.equal(id));
var query = select(ALL).from(TABLE_PAGES).where(ID, equal(id));
if (version == null) {
query.sort(VERSION+" DESC").limit(1);
} else {
query.where(VERSION,Condition.equal(version));
query.where(VERSION, equal(version));
}
var rs = query.exec(db);
if (rs.next()) page = WikiPage.of(rs);
@@ -175,11 +203,11 @@ public class SqliteDb extends BaseDb implements WikiDb {
throw databaseException("Failed to load wiki page \"{0}\" from database!",title);
}
if (page == null) try { // page was not loaded by ID
var query = select(ALL).from(TABLE_PAGES).where(TITLE,Condition.equal(title));
var query = select(ALL).from(TABLE_PAGES).where(TITLE, equal(title));
if (version == null) {
query.sort(VERSION+" DESC").limit(1);
} else {
query.where(VERSION,Condition.equal(version));
query.where(VERSION, equal(version));
}
var rs = query.exec(db);
if (rs.next()) page = WikiPage.of(rs);
@@ -189,7 +217,7 @@ public class SqliteDb extends BaseDb implements WikiDb {
}
if (page == null) throw notFound("Failed to load wiki page \"{0}\" from database!",title);
try {
var rs = select(VERSION).from(TABLE_PAGES).where(ID,Condition.equal(page.id())).sort(VERSION).exec(db);
var rs = select(VERSION).from(TABLE_PAGES).where(ID, equal(page.id())).sort(VERSION).exec(db);
var versions = page.versions();
while (rs.next()) versions.add(rs.getInt(VERSION));
rs.close();
@@ -291,7 +319,7 @@ public class SqliteDb extends BaseDb implements WikiDb {
public Map<Long, Permission> loadMembers(WikiPage page) {
try {
var map = new HashMap<Long, Permission>();
var rs = select(ALL).from(TABLE_PAGES_USERS).where(PAGE_ID,Condition.equal(page.id())).exec(db);
var rs = select(ALL).from(TABLE_PAGES_USERS).where(PAGE_ID, equal(page.id())).exec(db);
while (rs.next()){
var permission = wikiPermission(rs.getInt(PERMISSIONS));
if (permission != null) map.put(rs.getLong(USER_ID),permission);
@@ -309,7 +337,7 @@ public class SqliteDb extends BaseDb implements WikiDb {
if (page.isDirty(CONTENT) || page.isDirty(ID) || page.isDirty(TITLE)) insertInto(TABLE_PAGES,ID,VERSION,TITLE,CONTENT)
.values(page.id(),page.version(),page.title(),page.content()).execute(db).close();
if (page.isDirty(MEMBERS)){
Query.delete().from(TABLE_PAGES_USERS).where(PAGE_ID,Condition.equal(page.title())).where(USER_ID,Condition.notIn(page.members().keySet().toArray())).execute(db);
Query.delete().from(TABLE_PAGES_USERS).where(PAGE_ID, equal(page.title())).where(USER_ID,Condition.notIn(page.members().keySet().toArray())).execute(db);
var query = replaceInto(TABLE_PAGES_USERS,PAGE_ID,USER_ID,PERMISSIONS);
for (var member : page.members().entrySet()) query.values(page.id(),member.getKey(),wikiPermissionCode(member.getValue().permission()));
query.execute(db).close();

View File

@@ -9,6 +9,10 @@ import java.util.Map;
public interface WikiDb {
long getNextId();
boolean isAvailable(String title);
List<String> listUserPages(long userId);
WikiPage load(String id, Integer version);

View File

@@ -4,6 +4,7 @@ package de.srsoftware.umbrella.wiki;
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
import static de.srsoftware.umbrella.core.Constants.VERSION;
import static de.srsoftware.umbrella.core.ModuleRegistry.userService;
import static de.srsoftware.umbrella.core.Paths.AVAILABLE;
import static de.srsoftware.umbrella.core.Paths.PAGE;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
import static de.srsoftware.umbrella.core.model.Permission.EDIT;
@@ -43,6 +44,7 @@ public class WikiModule extends BaseHandler implements WikiService {
var head = path.pop();
return switch (head) {
case null -> getUserPages(user.get(),ex);
case AVAILABLE -> getAvailability(path,ex);
case PAGE -> getPage(path, user.get(), ex);
default -> super.doGet(path,ex);
};
@@ -51,7 +53,7 @@ public class WikiModule extends BaseHandler implements WikiService {
}
}
@Override
@Override
public boolean doPatch(Path path, HttpExchange ex) throws IOException {
addCors(ex);
try {
@@ -69,6 +71,25 @@ public class WikiModule extends BaseHandler implements WikiService {
}
}
@Override
public boolean doPost(Path path, HttpExchange ex) throws IOException {
addCors(ex);
try {
Optional<Token> token = SessionToken.from(ex).map(Token::of);
var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex);
var title = path.pop();
if (!path.empty()) return super.doPost(path,ex);
return postNewPage(title,user.get(),ex);
} catch (UmbrellaException e){
return send(ex,e);
}
}
private boolean getAvailability(Path path, HttpExchange ex) throws IOException {
return sendContent(ex,wikiDb.isAvailable(path.pop()));
}
private boolean getPage(Path path, UmbrellaUser user, HttpExchange ex) throws IOException {
var id = path.pop();
Integer version = null;
@@ -118,4 +139,11 @@ public class WikiModule extends BaseHandler implements WikiService {
var json = json(ex);
return sendContent(ex,wikiDb.save(page.patch(json, userService())));
}
private boolean postNewPage(String title, UmbrellaUser user, HttpExchange ex) throws IOException {
var content = body(ex);
var page = new WikiPage(wikiDb.getNextId(),title,1,content);
page.members().put(user.id(),new Member(user,EDIT));
return sendContent(ex,wikiDb.save(page.setNew()));
}
}