[AB-197] splitting utility maven module into separate maven modules

aligning some package names
removing some unnecessary computed values from liquibase
This commit is contained in:
Sheldan
2021-03-12 17:29:49 +01:00
parent e2da800d84
commit 2ed456c164
835 changed files with 12790 additions and 3310 deletions

View File

@@ -0,0 +1,18 @@
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
<id>liquibase</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<outputDirectory>.</outputDirectory>
<directory>${project.basedir}/src/main/resources/migrations</directory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
</fileSets>
</assembly>

View File

@@ -0,0 +1,10 @@
package dev.sheldan.abstracto.linkembed.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("classpath:link-embed-config.properties")
public class LinkEmbedConfig {
}

View File

@@ -0,0 +1,125 @@
package dev.sheldan.abstracto.linkembed.listener;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.execution.result.ExecutionResult;
import dev.sheldan.abstracto.core.execution.result.MessageReceivedListenerResult;
import dev.sheldan.abstracto.core.listener.sync.jda.MessageReceivedListener;
import dev.sheldan.abstracto.core.metric.service.CounterMetric;
import dev.sheldan.abstracto.core.metric.service.MetricService;
import dev.sheldan.abstracto.core.metric.service.MetricTag;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.service.MessageCache;
import dev.sheldan.abstracto.core.service.MessageService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureDefinition;
import dev.sheldan.abstracto.linkembed.model.MessageEmbedLink;
import dev.sheldan.abstracto.linkembed.service.MessageEmbedService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.Event;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
@Component
@Slf4j
public class MessageEmbedListener implements MessageReceivedListener {
@Autowired
private MessageCache messageCache;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private MessageEmbedService messageEmbedService;
@Autowired
private MessageEmbedListener self;
@Autowired
private MetricService metricService;
@Autowired
private MessageService messageService;
public static final String MESSAGE_EMBEDDED = "message.embedded";
public static final String MESSAGE_EMBED_ACTION = "action";
private static final CounterMetric MESSAGE_EMBED_CREATED = CounterMetric
.builder()
.name(MESSAGE_EMBEDDED)
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "created")))
.build();
@Override
public MessageReceivedListenerResult execute(Message message) {
String messageRaw = message.getContentRaw();
List<MessageEmbedLink> links = messageEmbedService.getLinksInMessage(messageRaw);
if(!links.isEmpty()) {
log.trace("We found {} links to embed in message {} in channel {} in guild {}.", links.size(), message.getId(), message.getChannel().getId(), message.getGuild().getId());
Long userEmbeddingUserInServerId = userInServerManagementService.loadOrCreateUser(message.getMember()).getUserInServerId();
for (MessageEmbedLink messageEmbedLink : links) {
if(!messageEmbedLink.getServerId().equals(message.getGuild().getIdLong())) {
log.info("Link for message {} was from a foreign server {}. Do not embed.", messageEmbedLink.getMessageId(), messageEmbedLink.getServerId());
continue;
}
messageRaw = messageRaw.replace(messageEmbedLink.getWholeUrl(), "");
Consumer<CachedMessage> cachedMessageConsumer = cachedMessage -> self.embedSingleLink(message, userEmbeddingUserInServerId, cachedMessage);
messageCache.getMessageFromCache(messageEmbedLink.getServerId(), messageEmbedLink.getChannelId(), messageEmbedLink.getMessageId())
.thenAccept(cachedMessageConsumer)
.exceptionally(throwable -> {
log.error("Error when embedding link for message {}", message.getId(), throwable);
return null;
});
}
}
if(StringUtils.isBlank(messageRaw) && !links.isEmpty()) {
messageService.deleteMessage(message);
return MessageReceivedListenerResult.DELETED;
}
if(!links.isEmpty()) {
return MessageReceivedListenerResult.PROCESSED;
}
return MessageReceivedListenerResult.IGNORED;
}
@Transactional
public void embedSingleLink(Message message, Long cause, CachedMessage cachedMessage) {
log.info("Embedding link to message {} in channel {} in server {} to channel {} and server {}.",
cachedMessage.getMessageId(), cachedMessage.getChannelId(), cachedMessage.getServerId(), message.getChannel().getId(), message.getGuild().getId());
messageEmbedService.embedLink(cachedMessage, message.getTextChannel(), cause , message).thenAccept(unused ->
metricService.incrementCounter(MESSAGE_EMBED_CREATED)
).exceptionally(throwable -> {
log.error("Failed to embed link towards message {} in channel {} in sever {} linked from message {} in channel {} in server {}.", cachedMessage.getMessageId(), cachedMessage.getChannelId(), cachedMessage.getServerId(),
message.getId(), message.getChannel().getId(), message.getGuild().getId(), throwable);
return null;
});
}
@Override
public boolean shouldConsume(Event event, ExecutionResult result) {
return result.equals(MessageReceivedListenerResult.DELETED);
}
@Override
public FeatureDefinition getFeature() {
return LinkEmbedFeatureDefinition.LINK_EMBEDS;
}
@Override
public Integer getPriority() {
return ListenerPriority.MEDIUM;
}
@PostConstruct
public void postConstruct() {
metricService.registerCounter(MESSAGE_EMBED_CREATED, "Message embeds created");
}
}

View File

@@ -0,0 +1,106 @@
package dev.sheldan.abstracto.linkembed.listener;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncReactionAddedListener;
import dev.sheldan.abstracto.core.metric.service.CounterMetric;
import dev.sheldan.abstracto.core.metric.service.MetricService;
import dev.sheldan.abstracto.core.metric.service.MetricTag;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.cache.CachedReactions;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.EmoteService;
import dev.sheldan.abstracto.core.service.MessageService;
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureDefinition;
import dev.sheldan.abstracto.linkembed.model.database.EmbeddedMessage;
import dev.sheldan.abstracto.linkembed.service.management.MessageEmbedPostManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.Optional;
import static dev.sheldan.abstracto.linkembed.listener.MessageEmbedListener.MESSAGE_EMBEDDED;
import static dev.sheldan.abstracto.linkembed.listener.MessageEmbedListener.MESSAGE_EMBED_ACTION;
@Component
@Slf4j
public class MessageEmbedRemovalReactionListener implements AsyncReactionAddedListener {
public static final String REMOVAL_EMOTE = "removeEmbed";
@Autowired
private BotService botService;
@Autowired
private MessageEmbedPostManagementService messageEmbedPostManagementService;
@Autowired
private MessageService messageService;
@Autowired
private EmoteService emoteService;
@Autowired
private MetricService metricService;
private static final CounterMetric MESSAGE_EMBED_REMOVED_CREATOR = CounterMetric
.builder()
.name(MESSAGE_EMBEDDED)
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "removed.creator")))
.build();
private static final CounterMetric MESSAGE_EMBED_REMOVED_SOURCE = CounterMetric
.builder()
.name(MESSAGE_EMBEDDED)
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "removed.source")))
.build();
@Override
public void executeReactionAdded(CachedMessage message, CachedReactions cachedReaction, ServerUser serverUser) {
Long guildId = message.getServerId();
AEmote aEmote = emoteService.getEmoteOrDefaultEmote(REMOVAL_EMOTE, guildId);
if(emoteService.compareCachedEmoteWithAEmote(cachedReaction.getEmote(), aEmote)) {
Optional<EmbeddedMessage> embeddedMessageOptional = messageEmbedPostManagementService.findEmbeddedPostByMessageId(message.getMessageId());
if(embeddedMessageOptional.isPresent()) {
EmbeddedMessage embeddedMessage = embeddedMessageOptional.get();
boolean embeddedUserRemoves = embeddedMessage.getEmbeddedUser().getUserReference().getId().equals(serverUser.getUserId());
boolean embeddingUserRemoves = embeddedMessage.getEmbeddingUser().getUserReference().getId().equals(serverUser.getUserId());
if(embeddedUserRemoves || embeddingUserRemoves) {
log.info("Removing embed in message {} in channel {} in server {} because of a user reaction.", message.getMessageId(), message.getChannelId(), message.getServerId());
messageService.deleteMessageInChannelInServer(message.getServerId(), message.getChannelId(), message.getMessageId()).thenAccept(aVoid -> {
Optional<EmbeddedMessage> innerOptional = messageEmbedPostManagementService.findEmbeddedPostByMessageId(message.getMessageId());
innerOptional.ifPresent(value -> messageEmbedPostManagementService.deleteEmbeddedMessage(value));
if(embeddedUserRemoves) {
metricService.incrementCounter(MESSAGE_EMBED_REMOVED_SOURCE);
} else {
metricService.incrementCounter(MESSAGE_EMBED_REMOVED_CREATOR);
}
});
} else {
log.trace("Somebody besides the original author and the user embedding added the removal reaction to the message {} in channel {} in server {}.",
message.getMessageId(), message.getChannelId(), message.getServerId());
}
} else {
log.trace("Removal emote was placed on a message which was not recognized as an embedded message.");
}
}
}
@Override
public FeatureDefinition getFeature() {
return LinkEmbedFeatureDefinition.LINK_EMBEDS;
}
@PostConstruct
public void postConstruct() {
metricService.registerCounter(MESSAGE_EMBED_REMOVED_CREATOR, "Message embeds which are created by the embedding user.");
metricService.registerCounter(MESSAGE_EMBED_REMOVED_SOURCE, "Message embeds which are created by the embedded user.");
}
}

View File

@@ -0,0 +1,10 @@
package dev.sheldan.abstracto.linkembed.repository;
import dev.sheldan.abstracto.linkembed.model.database.EmbeddedMessage;
import org.springframework.data.jpa.repository.JpaRepository;
public interface EmbeddedMessageRepository extends JpaRepository<EmbeddedMessage, Long> {
EmbeddedMessage findByEmbeddingMessageId(Long messageId);
}

View File

@@ -0,0 +1,161 @@
package dev.sheldan.abstracto.linkembed.service;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.template.listener.MessageEmbeddedModel;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.linkembed.model.MessageEmbedLink;
import dev.sheldan.abstracto.linkembed.service.management.MessageEmbedPostManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Component
@Slf4j
public class MessageEmbedServiceBean implements MessageEmbedService {
private Pattern messageRegex = Pattern.compile("(?<whole>https://discord(?:app)?.com/channels/(?<server>\\d+)/(?<channel>\\d+)/(?<message>\\d+)(?:.*?))+");
public static final String MESSAGE_EMBED_TEMPLATE = "message_embed";
public static final String REMOVAL_EMOTE = "removeEmbed";
@Autowired
private ChannelManagementService channelManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private MemberService memberService;
@Autowired
private TemplateService templateService;
@Autowired
private ChannelService channelService;
@Autowired
private MessageEmbedServiceBean self;
@Autowired
private MessageCache messageCache;
@Autowired
private MessageEmbedPostManagementService messageEmbedPostManagementService;
@Autowired
private ReactionService reactionService;
@Override
public List<MessageEmbedLink> getLinksInMessage(String message) {
List<MessageEmbedLink> links = new ArrayList<>();
Matcher matcher = messageRegex.matcher(message);
while(matcher.find()) {
String serverId = matcher.group("server");
String channelId = matcher.group("channel");
String messageId = matcher.group("message");
String wholeLink = matcher.group("whole");
Long serverIdLong = Long.parseLong(serverId);
Long channelIdLong = Long.parseLong(channelId);
Long messageIdLong = Long.parseLong(messageId);
MessageEmbedLink messageEmbedLink = MessageEmbedLink
.builder()
.serverId(serverIdLong)
.channelId(channelIdLong)
.messageId(messageIdLong)
.wholeUrl(wholeLink)
.build();
links.add(messageEmbedLink);
}
return links;
}
@Override
public void embedLinks(List<MessageEmbedLink> linksToEmbed, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage) {
linksToEmbed.forEach(messageEmbedLink ->
messageCache.getMessageFromCache(messageEmbedLink.getServerId(), messageEmbedLink.getChannelId(), messageEmbedLink.getMessageId())
.thenAccept(cachedMessage -> self.embedLink(cachedMessage, target, userEmbeddingUserInServerId, embeddingMessage)
).exceptionally(throwable -> {
log.error("Message embedding from cache failed for message {}.", messageEmbedLink.getMessageId(), throwable);
return null;
})
);
}
@Override
@Transactional
public CompletableFuture<Void> embedLink(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage) {
Optional<AUserInAServer> causeOpt = userInServerManagementService.loadUserOptional(userEmbeddingUserInServerId);
if(causeOpt.isPresent()) {
return buildTemplateParameter(embeddingMessage, cachedMessage).thenCompose(messageEmbeddedModel ->
self.sendEmbeddingMessage(cachedMessage, target, userEmbeddingUserInServerId, messageEmbeddedModel)
);
} else {
log.warn("User {} which was not found in database wanted to embed link in message {}.", userEmbeddingUserInServerId, embeddingMessage.getJumpUrl());
return CompletableFuture.completedFuture(null);
}
}
@Transactional
public CompletableFuture<Void> sendEmbeddingMessage(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, MessageEmbeddedModel messageEmbeddedModel) {
MessageToSend embed = templateService.renderEmbedTemplate(MESSAGE_EMBED_TEMPLATE, messageEmbeddedModel);
AUserInAServer cause = userInServerManagementService.loadOrCreateUser(userEmbeddingUserInServerId);
List<CompletableFuture<Message>> completableFutures = channelService.sendMessageToSendToChannel(embed, target);
log.trace("Embedding message {} from channel {} from server {}, because of user {}", cachedMessage.getMessageId(),
cachedMessage.getChannelId(), cachedMessage.getServerId(), cause.getUserReference().getId());
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenCompose(aVoid -> {
Message createdMessage = completableFutures.get(0).join();
return reactionService.addReactionToMessageAsync(REMOVAL_EMOTE, cachedMessage.getServerId(), createdMessage).thenAccept(aVoid1 ->
self.loadUserAndPersistMessage(cachedMessage, userEmbeddingUserInServerId, createdMessage)
);
});
}
@Transactional
public void loadUserAndPersistMessage(CachedMessage cachedMessage, Long userInServerId, Message createdMessage) {
AUserInAServer innerCause = userInServerManagementService.loadOrCreateUser(userInServerId);
messageEmbedPostManagementService.createMessageEmbed(cachedMessage, createdMessage, innerCause);
}
private CompletableFuture<MessageEmbeddedModel> buildTemplateParameter(Message message, CachedMessage embeddedMessage) {
return memberService.getMemberInServerAsync(embeddedMessage.getServerId(), embeddedMessage.getAuthor().getAuthorId()).thenApply(member ->
self.loadMessageEmbedModel(message, embeddedMessage, member)
);
}
@Transactional
public MessageEmbeddedModel loadMessageEmbedModel(Message message, CachedMessage embeddedMessage, Member member) {
Optional<TextChannel> textChannelFromServer = channelService.getTextChannelFromServerOptional(embeddedMessage.getServerId(), embeddedMessage.getChannelId());
TextChannel sourceChannel = textChannelFromServer.orElse(null);
return MessageEmbeddedModel
.builder()
.member(message.getMember())
.author(member)
.sourceChannel(sourceChannel)
.embeddingUser(message.getMember())
.messageChannel(message.getChannel())
.guild(message.getGuild())
.embeddedMessage(embeddedMessage)
.build();
}
}

View File

@@ -0,0 +1,79 @@
package dev.sheldan.abstracto.linkembed.service.management;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.linkembed.exception.CrossServerEmbedException;
import dev.sheldan.abstracto.linkembed.model.database.EmbeddedMessage;
import dev.sheldan.abstracto.linkembed.repository.EmbeddedMessageRepository;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
@Component
@Slf4j
public class MessageEmbedPostManagementServiceBean implements MessageEmbedPostManagementService {
@Autowired
private EmbeddedMessageRepository embeddedMessageRepository;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private ChannelManagementService channelManagementService;
@Override
@Transactional
public void createMessageEmbed(CachedMessage embeddedMessage, Message messageContainingEmbed, AUserInAServer embeddingUser) {
AServer embeddedServer = serverManagementService.loadOrCreate(embeddedMessage.getServerId());
AServer embeddingServer = serverManagementService.loadOrCreate(messageContainingEmbed.getGuild().getIdLong());
if(!embeddedServer.getId().equals(embeddingServer.getId())) {
throw new CrossServerEmbedException(String.format("Message %s is not from server %s", embeddedMessage.getMessageUrl(), embeddingServer.getId()));
}
AChannel embeddingChannel = channelManagementService.loadChannel(messageContainingEmbed.getChannel().getIdLong());
AChannel embeddedChannel = channelManagementService.loadChannel(embeddedMessage.getChannelId());
AUserInAServer embeddedAuthor = userInServerManagementService.loadOrCreateUser(embeddedMessage.getServerId(), embeddedMessage.getAuthor().getAuthorId());
EmbeddedMessage messageEmbedPost = EmbeddedMessage
.builder()
.embeddedMessageId(embeddedMessage.getMessageId())
.embeddedChannel(embeddedChannel)
.embeddedServer(embeddedServer)
.embeddingServer(embeddingServer)
.embeddingChannel(embeddingChannel)
.embeddingMessageId(messageContainingEmbed.getIdLong())
.embeddedUser(embeddedAuthor)
.embeddingUser(embeddingUser)
.build();
log.info("Saving embedded post: message {} by user {} in channel {} in server {} embedded message {} by user {} in channel {} in server {}.",
messageContainingEmbed.getIdLong(), messageContainingEmbed.getAuthor().getIdLong(), embeddingChannel.getId(), messageContainingEmbed.getChannel().getIdLong(),
embeddedMessage.getMessageId(), embeddedMessage.getAuthor().getAuthorId(), embeddedMessage.getChannelId(), embeddedMessage.getServerId());
embeddedMessageRepository.save(messageEmbedPost);
}
@Override
public Optional<EmbeddedMessage> findEmbeddedPostByMessageId(Long messageId) {
return Optional.ofNullable(embeddedMessageRepository.findByEmbeddingMessageId(messageId));
}
@Override
@Transactional
public void deleteEmbeddedMessage(EmbeddedMessage embeddedMessage) {
log.info("Deleting embedded message {}.", embeddedMessage.getEmbeddingMessageId());
embeddedMessageRepository.delete(embeddedMessage);
}
}

View File

@@ -0,0 +1,2 @@
abstracto.featureFlags.linkEmbeds.featureName=linkEmbeds
abstracto.featureFlags.linkEmbeds.enabled=false

View File

@@ -0,0 +1,11 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../dbchangelog-3.8.xsd" >
<include file="link-embed-tables/tables.xml" relativeToChangelogFile="true"/>
<include file="link-embed-seedData/data.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,11 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<include file="default_emote.xml" relativeToChangelogFile="true"/>
<include file="feature.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,15 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="link-embed_default_emote-insert">
<insert tableName="default_emote">
<column name="emote_key" value="removeEmbed"/>
<column name="name" value="🗑"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,14 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="link-embed_feature-insertion">
<insert tableName="feature">
<column name="key" value="linkEmbeds"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,56 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<changeSet author="Sheldan" id="embedded_message-table">
<createTable tableName="embedded_message">
<column name="embedding_message_id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="embedded_message_pkey"/>
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="true"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
<column name="embedded_message_id" type="BIGINT">
<constraints nullable="true"/>
</column>
<column name="embedded_channel_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="embedded_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="embedded_user_in_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="embedding_channel_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="embedding_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="embedding_user_in_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
</createTable>
<addForeignKeyConstraint baseColumnNames="embedding_channel_id" baseTableName="embedded_message" constraintName="fk_embed_channel_channel" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel" validate="true"/>
<addForeignKeyConstraint baseColumnNames="embedded_channel_id" baseTableName="embedded_message" constraintName="fk_embed_embedded_channel_id_channel" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel" validate="true"/>
<addForeignKeyConstraint baseColumnNames="embedding_user_in_server_id" baseTableName="embedded_message" constraintName="fk_embedded_user_in_server_id_user" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="embedded_user_in_server_id" baseTableName="embedded_message" constraintName="fk_embedding_user_in_server_id_user" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="embedding_server_id" baseTableName="embedded_message" constraintName="fk_embedding_server_id_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="embedded_server_id" baseTableName="embedded_message" constraintName="fk_embed_embedded_server_id_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS embedded_message_update_trigger ON embedded_message;
CREATE TRIGGER embedded_message_update_trigger BEFORE UPDATE ON embedded_message FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
</sql>
<sql>
DROP TRIGGER IF EXISTS embedded_message_insert_trigger ON embedded_message;
CREATE TRIGGER embedded_message_insert_trigger BEFORE INSERT ON embedded_message FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,10 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
<include file="embedded_message.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,10 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog-3.8.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog-3.8.xsd" >
<include file="1.0-link-embed/collection.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>