Skip to content

Commit

Permalink
Add templating system to account for differences in PSQL syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
jpenilla committed Sep 15, 2023
1 parent e065d78 commit 5707c94
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ public DatabaseUserManager create(final String migrationsLocation, final Consume
return new DatabaseUserManager(
jdbi,
dataSource,
new QueriesLocator(),
new QueriesLocator(this.configManager.primaryConfig().storageType()),
this.logger,
this.profileResolver,
this.playerInjector,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,35 +21,72 @@

import com.google.common.base.Splitter;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import net.draycia.carbon.api.CarbonChat;
import net.draycia.carbon.common.config.PrimaryConfig;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;
import org.jdbi.v3.core.locator.ClasspathSqlLocator;
import org.jdbi.v3.core.locator.internal.ClasspathBuilder;

@DefaultQualifier(NonNull.class)
public final class QueriesLocator {

private static final String PREFIX = "queries/";
private static final Splitter SPLITTER = Splitter.on(';');
private final ClasspathSqlLocator locator = ClasspathSqlLocator.create();
private final PrimaryConfig.StorageType storageType;
private final Pattern templatePattern = Pattern.compile("\\{([^}]*?)}");
private final Map<String, String> cache = new ConcurrentHashMap<>();

public QueriesLocator() {
public QueriesLocator(final PrimaryConfig.StorageType storageType) {
this.storageType = storageType;
}

public @NonNull String query(final @NonNull String name) {
return this.locate(PREFIX + name);
public List<String> queries(final String name) {
return SPLITTER.splitToList(this.query(name));
}

public @NonNull List<@NonNull String> queries(final @NonNull String name) {
return SPLITTER.splitToList(this.locator.locate(PREFIX + name));
public String query(final String name) {
return this.locate(PREFIX + name);
}

private String locate(final String name) {
return this.locator.getResource(
CarbonChat.class.getClassLoader(),
new ClasspathBuilder()
.appendDotPath(name)
.setExtension("sql")
.build());
return this.cache.computeIfAbsent(name, $ -> {
final String sql = this.locator.getResource(
CarbonChat.class.getClassLoader(),
new ClasspathBuilder()
.appendDotPath(name)
.setExtension("sql")
.build());
return this.processTemplates(sql);
});
}

private String processTemplates(final String sql) {
return this.templatePattern.matcher(sql).replaceAll(match -> {
final String insideBraces = match.group(1);
try {
final int colonIndex = insideBraces.indexOf(':');
String prefix = insideBraces.substring(0, colonIndex);
final String content = insideBraces.substring(colonIndex + 1);
boolean not = false;
if (prefix.startsWith("!")) {
not = true;
prefix = prefix.substring(1);
}
final PrimaryConfig.StorageType storageType = PrimaryConfig.StorageType.valueOf(prefix);
if (not) {
return storageType != this.storageType ? content : "";
} else {
return storageType == this.storageType ? content : "";
}
} catch (final Exception ex) {
return match.group(0);
}
});
}

}
31 changes: 21 additions & 10 deletions common/src/main/resources/queries/insert-player.sql
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
INSERT IGNORE INTO carbon_users SET
id = :id,
muted = :muted,
deafened = :deafened,
selectedchannel = :selectedchannel,
displayname = :displayname,
lastwhispertarget = :lastwhispertarget,
whisperreplytarget = :whisperreplytarget,
spying = :spying,
ignoringdms = :ignoringdms;
INSERT{!PSQL: IGNORE} INTO carbon_users(
id,
muted,
deafened,
selectedchannel,
displayname,
lastwhispertarget,
whisperreplytarget,
spying,
ignoringdms
) VALUES (
:id,
:muted,
:deafened,
:selectedchannel,
:displayname,
:lastwhispertarget,
:whisperreplytarget,
:spying,
:ignoringdms
){PSQL: ON CONFLICT DO NOTHING};
2 changes: 1 addition & 1 deletion common/src/main/resources/queries/save-ignores.sql
Original file line number Diff line number Diff line change
@@ -1 +1 @@
INSERT IGNORE INTO carbon_ignores (id, ignoredplayer) VALUES(:id, :ignoredplayer)
INSERT{!PSQL: IGNORE} INTO carbon_ignores (id, ignoredplayer) VALUES(:id, :ignoredplayer){PSQL: ON CONFLICT DO NOTHING};
2 changes: 1 addition & 1 deletion common/src/main/resources/queries/save-leftchannels.sql
Original file line number Diff line number Diff line change
@@ -1 +1 @@
INSERT IGNORE INTO carbon_leftchannels (id, channel) VALUES(:id, :channel)
INSERT{!PSQL: IGNORE} INTO carbon_leftchannels (id, channel) VALUES(:id, :channel){PSQL: ON CONFLICT DO NOTHING};

0 comments on commit 5707c94

Please sign in to comment.