Skip to content

Commit

Permalink
feat: switch cache with db implementation
Browse files Browse the repository at this point in the history
library may now be instantiated with a custom database implementation to fit everyone's needs.

support for nameless, temporary books added

BREAKING CHANGE: feeding books to listener is no longer necessary.

Signed-off-by: Jasper Lutz Severino <jasperlutzseverino@gmail.com>
  • Loading branch information
lutzseverino committed Aug 8, 2022
1 parent c313d80 commit 9d547dd
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 105 deletions.
58 changes: 33 additions & 25 deletions core/src/main/java/com/lutzseverino/discordbooks/DiscordBooks.java
Original file line number Diff line number Diff line change
@@ -1,44 +1,52 @@
package com.lutzseverino.discordbooks;

import com.lutzseverino.discordbooks.book.Book;
import com.lutzseverino.discordbooks.cache.BookCache;
import com.lutzseverino.discordbooks.cache.Cache;
import com.lutzseverino.discordbooks.database.BookDB;
import com.lutzseverino.discordbooks.database.impl.MapDB;
import org.jetbrains.annotations.NotNull;

public class DiscordBooks {
protected final Cache<Book> books = new BookCache();
private static BookDB namelessDatabase = new MapDB();
private static BookDB database = new MapDB();

/**
* Registers new books to the cache.
*
* @param books the books to add
*/
public void addBooks(@NotNull Book... books) {
for (Book book : books)
this.books.add(book);
public DiscordBooks() {
}

/**
* Registers a new book to the cache.
*
* @param book the book to add
*/
public void addBook(Book book) {
addBooks(book);
public static BookDB getNamelessDatabase() {
return namelessDatabase;
}

public DiscordBooks setNamelessDatabase(BookDB database) {
namelessDatabase = database;
return this;
}

public static BookDB getDatabase() {
return database;
}

public DiscordBooks setDatabase(BookDB database) {
DiscordBooks.database = database;
return this;
}

/**
* @param name the name of the book
* @return the book with the given name
* @param id the id of the book
* @return the book with the given id, or null if it doesn't exist
*/
public Book getBook(String name) {
return books.get(name);
public static Book getBook(String id) {
return database.get(id);
}

/**
* @return the book cache
* Registers books. These will persist
* as long as they exist in your source,
* assuming you add them on every startup.
*
* @param books the books to add
*/
public Cache<Book> getBooks() {
return books;
public void registerBooks(@NotNull Book... books) {
for (var book : books)
database.set(book.getId(), book);
}
}

This file was deleted.

15 changes: 0 additions & 15 deletions core/src/main/java/com/lutzseverino/discordbooks/cache/Cache.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.lutzseverino.discordbooks.database;

import com.lutzseverino.discordbooks.book.Book;

public interface BookDB {
Book get(String key);

void set(String key, Book value);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.lutzseverino.discordbooks.database.impl;

import com.lutzseverino.discordbooks.book.Book;
import com.lutzseverino.discordbooks.database.BookDB;

import java.util.HashMap;


public class MapDB implements BookDB {
private final java.util.Map<String, Book> map = new HashMap<>();

@Override public Book get(String key) {
return map.get(key);
}

@Override public void set(String key, Book value) {
map.put(key, value);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package com.lutzseverino.discordbooks.discord.channel;

import com.lutzseverino.discordbooks.book.Book;
import com.lutzseverino.discordbooks.discord.message.Sendable;
import org.jetbrains.annotations.NotNull;

public interface Receivable {
Receivable receive(Sendable message);
void receive(Sendable message);

void receive(Book book);

void receive(@NotNull Book book, int index);
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,10 @@ public JDAReceivable(@NotNull Guild guild, String channelId) {
}

@Override public void receive(@NotNull Book book, int index) {
MessageAction action = channel.sendMessage(JDAMessage.buildMessage(book.build(index)));
MessageAction action = channel.sendMessage(JDAMessage.buildMessage(book.getPage(index)));

if (book.getName() == null) action.queue(message -> {
book.setName(message.getId());
DiscordBooks.addCachedBook(book);
});
if (book.getId().isEmpty())
action.queue(message -> DiscordBooks.getNamelessDatabase().set(message.getId(), book));
else action.queue();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,57 @@

import com.lutzseverino.discordbooks.DiscordBooks;
import com.lutzseverino.discordbooks.book.Book;
import com.lutzseverino.discordbooks.database.BookDB;
import com.lutzseverino.discordbooks.jda.discord.message.JDAMessage;
import com.lutzseverino.discordbooks.jda.errors.JDABookErrorHandler;
import com.lutzseverino.discordbooks.jda.errors.JDABookErrorHandlerImpl;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
import org.jetbrains.annotations.NotNull;

import java.util.List;
import java.util.Map;

public class JDABookButtonListener extends ListenerAdapter {
private final Map<String, Book> books;
private final JDABookErrorHandler errorHandler;

public JDABookButtonListener(Map<String, Book> books, JDABookErrorHandler errorHandler) {
this.books = books;
public JDABookButtonListener(JDABookErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}

public JDABookButtonListener(Map<String, Book> books) {
this(books, new JDABookErrorHandlerImpl());
public JDABookButtonListener() {
this(new JDABookErrorHandlerImpl());
}

@Override public void onButtonInteraction(@NotNull ButtonInteractionEvent event) {
if (event.getButton().getStyle() != ButtonStyle.LINK) {
String id = event.getButton().getId();
String buttonId = event.getButton().getId();
if (buttonId == null || !buttonId.startsWith("book:")) return;

// ID cannot be null, we're preventing this event from
// firing if the button is of type LINK.
assert id != null;
buttonId = buttonId.substring("book:".length());

if (!id.startsWith("book:")) return;
id = id.substring("book:".length());
String[] split = buttonId.split("@");
String bookId = split[0];
int index = Integer.parseInt(split[1]);

String[] split = id.split("@");
String bookID = split[0];
int pageToSet = Integer.parseInt(split[1]);
boolean nameless = bookId.isEmpty();
bookId = nameless ? event.getMessageId() : bookId;
BookDB database = nameless ? DiscordBooks.getNamelessDatabase() : DiscordBooks.getDatabase();

// We search for source books, if none, search the cache for temporary ones.
Book book = books.getOrDefault(bookID, DiscordBooks.getCachedBook(event.getMessageId()));
Book book = database.get(bookId);

if (book != null) {
List<String> owners = book.getOwners();
if (book != null) {
List<String> owners = book.getOwners();

if (!owners.isEmpty() && owners.stream().noneMatch(s -> event.getUser().getId().equals(s))) {
errorHandler.whenUserIsNotOwner(event);
return;
}
if (!owners.isEmpty() && owners.stream().noneMatch(s -> event.getUser().getId().equals(s))) {
errorHandler.whenUserIsNotOwner(event);
return;
}

event.editMessage(JDAMessage.buildMessage(book.build(pageToSet))).queue();
event.editMessage(JDAMessage.buildMessage(book.getPage(index))).queue();

// If the book has no name, we'll need to update it in the database.
if (nameless) database.set(event.getMessageId(), book);

} else errorHandler.whenBookIsNull(event);

} else errorHandler.whenBookIsNull(event);
}
}
}

0 comments on commit 9d547dd

Please sign in to comment.