Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
ea314415dc | |||
0c7e35c42f | |||
|
2cf4b63e2e | ||
|
2723d6cd45 |
@ -2,7 +2,7 @@ name: Publish Release
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [master, develop]
|
branches: [master]
|
||||||
tags:
|
tags:
|
||||||
- '*'
|
- '*'
|
||||||
|
|
||||||
@ -58,13 +58,14 @@ jobs:
|
|||||||
|
|
||||||
# Publish to Maven
|
# Publish to Maven
|
||||||
- name: Publish to Maven
|
- name: Publish to Maven
|
||||||
run: mvn deploy -Pgen-javadocs -B -Dstyle.color=always --update-snapshots -T6C -e
|
run: |
|
||||||
|
chmod +x ./scripts/deploy.sh
|
||||||
|
./scripts/deploy.sh
|
||||||
|
|
||||||
# Generate changelog
|
# Generate changelog
|
||||||
- name: Generate Changelog
|
- name: Generate Changelog
|
||||||
id: changelog
|
id: changelog
|
||||||
uses: https://github.com/mathiasvr/command-output@v2.0.0
|
uses: https://github.com/mathiasvr/command-output@v2.0.0
|
||||||
if: ${{ github.ref.action == 'master' }}
|
|
||||||
with:
|
with:
|
||||||
run: |
|
run: |
|
||||||
npx conventional-changelog-cli -p angular -i CHANGELOG.md -s --skip-unstable
|
npx conventional-changelog-cli -p angular -i CHANGELOG.md -s --skip-unstable
|
||||||
@ -75,7 +76,6 @@ jobs:
|
|||||||
# so we can use it later
|
# so we can use it later
|
||||||
- name: Extract Maven project version
|
- name: Extract Maven project version
|
||||||
shell: bash -l {0}
|
shell: bash -l {0}
|
||||||
if: ${{ github.ref.action == 'master' }}
|
|
||||||
run: |
|
run: |
|
||||||
RELEASE_VERSION=$(mvn -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec)
|
RELEASE_VERSION=$(mvn -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec)
|
||||||
echo "Project version: $RELEASE_VERSION"
|
echo "Project version: $RELEASE_VERSION"
|
||||||
@ -85,7 +85,6 @@ jobs:
|
|||||||
- name: Publish Release
|
- name: Publish Release
|
||||||
id: publish-release
|
id: publish-release
|
||||||
uses: https://git.rainnny.club/Rainnny/release-action@main
|
uses: https://git.rainnny.club/Rainnny/release-action@main
|
||||||
if: ${{ github.ref.action == 'master' }}
|
|
||||||
with:
|
with:
|
||||||
api_key: ${{ secrets.RELEASE_ACCESS_TOKEN }}
|
api_key: ${{ secrets.RELEASE_ACCESS_TOKEN }}
|
||||||
tag: Feather-${{ env.RELEASE_VERSION }}
|
tag: Feather-${{ env.RELEASE_VERSION }}
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -18,7 +18,6 @@ cmake-build-*/
|
|||||||
out/
|
out/
|
||||||
build/
|
build/
|
||||||
work/
|
work/
|
||||||
target/
|
|
||||||
.idea_modules/
|
.idea_modules/
|
||||||
atlassian-ide-plugin.xml
|
atlassian-ide-plugin.xml
|
||||||
com_crashlytics_export_strings.xml
|
com_crashlytics_export_strings.xml
|
||||||
|
@ -91,6 +91,9 @@
|
|||||||
<!-- See: https://checkstyle.org/checks/javadoc/javadocmissingwhitespaceafterasterisk.html#JavadocMissingWhitespaceAfterAsterisk -->
|
<!-- See: https://checkstyle.org/checks/javadoc/javadocmissingwhitespaceafterasterisk.html#JavadocMissingWhitespaceAfterAsterisk -->
|
||||||
<module name="JavadocMissingWhitespaceAfterAsterisk" />
|
<module name="JavadocMissingWhitespaceAfterAsterisk" />
|
||||||
|
|
||||||
|
<!-- See: https://checkstyle.org/checks/javadoc/javadocparagraph.html#JavadocParagraph -->
|
||||||
|
<module name="JavadocParagraph" />
|
||||||
|
|
||||||
<!-- See: https://checkstyle.org/checks/javadoc/javadocstyle.html#JavadocStyle -->
|
<!-- See: https://checkstyle.org/checks/javadoc/javadocstyle.html#JavadocStyle -->
|
||||||
<module name="JavadocStyle" />
|
<module name="JavadocStyle" />
|
||||||
|
|
||||||
@ -212,6 +215,11 @@
|
|||||||
<!-- See: https://checkstyle.org/checks/javadoc/singlelinejavadoc.html#SingleLineJavadoc -->
|
<!-- See: https://checkstyle.org/checks/javadoc/singlelinejavadoc.html#SingleLineJavadoc -->
|
||||||
<module name="SingleLineJavadoc" />
|
<module name="SingleLineJavadoc" />
|
||||||
|
|
||||||
|
<!-- See: https://checkstyle.org/checks/javadoc/requireemptylinebeforeblocktaggroup.html#RequireEmptyLineBeforeBlockTagGroup -->
|
||||||
|
<module name="RequireEmptyLineBeforeBlockTagGroup">
|
||||||
|
<property name="violateExecutionOnNonTightHtml" value="true" />
|
||||||
|
</module>
|
||||||
|
|
||||||
<!-- See: https://checkstyle.org/checks/whitespace/singlespaceseparator.html#SingleSpaceSeparator -->
|
<!-- See: https://checkstyle.org/checks/whitespace/singlespaceseparator.html#SingleSpaceSeparator -->
|
||||||
<module name="SingleSpaceSeparator" />
|
<module name="SingleSpaceSeparator" />
|
||||||
|
|
||||||
|
51
pom.xml
51
pom.xml
@ -7,7 +7,7 @@
|
|||||||
<!--Project Details-->
|
<!--Project Details-->
|
||||||
<groupId>me.braydon</groupId>
|
<groupId>me.braydon</groupId>
|
||||||
<artifactId>Feather</artifactId>
|
<artifactId>Feather</artifactId>
|
||||||
<version>1.0.1-dev</version>
|
<version>1.0.0</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>8</java.version>
|
<java.version>8</java.version>
|
||||||
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<!-- Used for compiling the source code with the proper Java version -->
|
<!--Used for compiling the source code with the proper Java version-->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
@ -27,17 +27,17 @@
|
|||||||
<source>${java.version}</source>
|
<source>${java.version}</source>
|
||||||
<target>${java.version}</target>
|
<target>${java.version}</target>
|
||||||
|
|
||||||
<!-- Enable incremental builds, this is reversed due to -->
|
<!--Enable incremental builds, this is reversed due to-->
|
||||||
<!-- a bug as seen in https://issues.apache.org/jira/browse/MCOMPILER-209 -->
|
<!--a bug as seen in https://issues.apache.org/jira/browse/MCOMPILER-209-->
|
||||||
<useIncrementalCompilation>false</useIncrementalCompilation>
|
<useIncrementalCompilation>false</useIncrementalCompilation>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<!-- Handles shading of dependencies in the final output jar -->
|
<!--Handles shading of dependencies in the final output jar-->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>3.5.1</version>
|
<version>3.5.2</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
</configuration>
|
</configuration>
|
||||||
@ -70,7 +70,7 @@
|
|||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<!-- Used for generating a git properties file during build -->
|
<!--Used for generating a git properties file during build-->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>pl.project13.maven</groupId>
|
<groupId>pl.project13.maven</groupId>
|
||||||
<artifactId>git-commit-id-plugin</artifactId>
|
<artifactId>git-commit-id-plugin</artifactId>
|
||||||
@ -168,13 +168,6 @@
|
|||||||
</repository>
|
</repository>
|
||||||
</distributionManagement>
|
</distributionManagement>
|
||||||
|
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>rainnny-repo-public</id>
|
|
||||||
<url>https://maven.rainnny.club/public</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
||||||
|
|
||||||
<!-- Depends -->
|
<!-- Depends -->
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -184,15 +177,15 @@
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>2.10.1</version>
|
<version>32.1.3-jre</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.netty</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>netty-common</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<version>4.1.104.Final</version>
|
<version>2.10.1</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@ -201,25 +194,13 @@
|
|||||||
<groupId>org.mongodb</groupId>
|
<groupId>org.mongodb</groupId>
|
||||||
<artifactId>mongodb-driver-sync</artifactId>
|
<artifactId>mongodb-driver-sync</artifactId>
|
||||||
<version>4.11.1</version>
|
<version>4.11.1</version>
|
||||||
<scope>provided</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.lettuce</groupId>
|
<groupId>io.lettuce</groupId>
|
||||||
<artifactId>lettuce-core</artifactId>
|
<artifactId>lettuce-core</artifactId>
|
||||||
<version>7.0.0-SNAPSHOT</version>
|
<version>6.3.2.RELEASE</version>
|
||||||
<scope>provided</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.zaxxer</groupId>
|
|
||||||
<artifactId>HikariCP</artifactId>
|
|
||||||
<version>4.0.3</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mariadb.jdbc</groupId>
|
|
||||||
<artifactId>mariadb-java-client</artifactId>
|
|
||||||
<version>3.3.1</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
7
scripts/deploy.sh
Normal file
7
scripts/deploy.sh
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Switch dir
|
||||||
|
cd "$(dirname "$0")/.." || exit
|
||||||
|
|
||||||
|
# Deploy
|
||||||
|
mvn deploy -Pgen-javadocs -B -Dstyle.color=always --update-snapshots -T6C -e
|
@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
|
|
||||||
*
|
|
||||||
* For inquiries, please contact braydonrainnny@gmail.com
|
|
||||||
*/
|
|
||||||
package me.braydon.feather.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link Field}'s tagged with this annotation
|
|
||||||
* will be set to the raw data from the document
|
|
||||||
* it is in.
|
|
||||||
*
|
|
||||||
* @author Braydon
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.FIELD)
|
|
||||||
@Documented @Inherited
|
|
||||||
public @interface RawData { }
|
|
@ -7,17 +7,16 @@ package me.braydon.feather.data;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import me.braydon.feather.FeatherSettings;
|
import me.braydon.feather.FeatherSettings;
|
||||||
import me.braydon.feather.annotation.Field;
|
import me.braydon.feather.annotation.Field;
|
||||||
import me.braydon.feather.annotation.Id;
|
import me.braydon.feather.annotation.Id;
|
||||||
import me.braydon.feather.annotation.RawData;
|
|
||||||
import me.braydon.feather.annotation.Serializable;
|
import me.braydon.feather.annotation.Serializable;
|
||||||
import me.braydon.feather.common.FieldUtils;
|
import me.braydon.feather.common.FieldUtils;
|
||||||
import me.braydon.feather.common.Tuple;
|
import me.braydon.feather.common.Tuple;
|
||||||
import me.braydon.feather.database.IDatabase;
|
import me.braydon.feather.database.IDatabase;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -30,9 +29,10 @@ import java.util.UUID;
|
|||||||
* document is universal between all {@link IDatabase}'s.
|
* document is universal between all {@link IDatabase}'s.
|
||||||
*
|
*
|
||||||
* @author Braydon
|
* @author Braydon
|
||||||
|
* @param <V> the type of value this document holds
|
||||||
*/
|
*/
|
||||||
@Getter @ToString
|
@ThreadSafe @Getter @ToString
|
||||||
public class Document {
|
public class Document<V> {
|
||||||
/**
|
/**
|
||||||
* The key to use for the id field.
|
* The key to use for the id field.
|
||||||
*/
|
*/
|
||||||
@ -51,20 +51,15 @@ public class Document {
|
|||||||
* a tuple that contains the Java field, as well as
|
* a tuple that contains the Java field, as well as
|
||||||
* the field value.
|
* the field value.
|
||||||
* </p>
|
* </p>
|
||||||
|
*
|
||||||
|
* @see V for value type
|
||||||
*/
|
*/
|
||||||
private final Map<String, Tuple<java.lang.reflect.Field, Object>> mappedData = Collections.synchronizedMap(new LinkedHashMap<>());
|
private final Map<String, Tuple<java.lang.reflect.Field, V>> mappedData = Collections.synchronizedMap(new LinkedHashMap<>());
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
public Document(@NonNull Object element) {
|
public Document(@NonNull Object element) {
|
||||||
Class<?> clazz = element.getClass(); // Get the element class
|
Class<?> clazz = element.getClass(); // Get the element class
|
||||||
String idKey = null; // The key for the id field
|
String idKey = null; // The key for the id field
|
||||||
java.lang.reflect.Field rawDataField = null; // The raw data field if defined
|
|
||||||
for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {
|
for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {
|
||||||
// Raw data field, save it for later
|
|
||||||
if (field.isAnnotationPresent(RawData.class)) {
|
|
||||||
rawDataField = field;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Field is missing the @Field annotation, skip it
|
// Field is missing the @Field annotation, skip it
|
||||||
if (!field.isAnnotationPresent(Field.class)) {
|
if (!field.isAnnotationPresent(Field.class)) {
|
||||||
continue;
|
continue;
|
||||||
@ -77,24 +72,24 @@ public class Document {
|
|||||||
idKey = key;
|
idKey = key;
|
||||||
}
|
}
|
||||||
Class<?> fieldType = field.getType(); // The type of the field
|
Class<?> fieldType = field.getType(); // The type of the field
|
||||||
Object value = field.get(element); // The value of the field
|
try {
|
||||||
|
Object value = field.get(element); // The value of the field
|
||||||
if (field.isAnnotationPresent(Serializable.class)) { // Serialize the field if @Serializable is present
|
|
||||||
value = FeatherSettings.getGson().toJson(field.get(element));
|
if (field.isAnnotationPresent(Serializable.class)) { // Serialize the field if @Serializable is present
|
||||||
} else if (fieldType == UUID.class) { // Convert UUIDs into strings
|
value = FeatherSettings.getGson().toJson(field.get(element));
|
||||||
value = value.toString();
|
} else if (fieldType == UUID.class) { // Convert UUIDs into strings
|
||||||
|
value = value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
mappedData.put(key, new Tuple<>(field, (V) value)); // Store in our map
|
||||||
|
} catch (IllegalAccessException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
mappedData.put(key, new Tuple<>(field, value)); // Store in our map
|
|
||||||
}
|
}
|
||||||
assert idKey != null; // We need an id key
|
assert idKey != null; // We need an id key
|
||||||
if (rawDataField != null) { // We have a raw data field, set it
|
|
||||||
rawDataField.setAccessible(true); // Make our field accessible
|
|
||||||
rawDataField.set(element, toMappedData()); // Set the raw data field to our mapped document
|
|
||||||
}
|
|
||||||
this.idKey = idKey; // Set our id key
|
this.idKey = idKey; // Set our id key
|
||||||
|
|
||||||
Tuple<java.lang.reflect.Field, Object> key = mappedData.get(idKey); // Get the id from the data map
|
Tuple<java.lang.reflect.Field, V> key = mappedData.get(idKey); // Get the id from the data map
|
||||||
if (key == null) { // The element is missing an id field
|
if (key == null) { // The element is missing an id field
|
||||||
throw new IllegalArgumentException("No @Id annotated field found in " + clazz.getSimpleName());
|
throw new IllegalArgumentException("No @Id annotated field found in " + clazz.getSimpleName());
|
||||||
}
|
}
|
||||||
@ -108,9 +103,9 @@ public class Document {
|
|||||||
* @see #mappedData for stored data
|
* @see #mappedData for stored data
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public Map<String, Object> toMappedData() {
|
public Map<String, V> toMappedData() {
|
||||||
Map<String, Object> mappedData = new LinkedHashMap<>(); // The mapped data
|
Map<String, V> mappedData = new LinkedHashMap<>(); // The mapped data
|
||||||
for (Map.Entry<String, Tuple<java.lang.reflect.Field, Object>> entry : this.mappedData.entrySet()) {
|
for (Map.Entry<String, Tuple<java.lang.reflect.Field, V>> entry : this.mappedData.entrySet()) {
|
||||||
mappedData.put(entry.getKey(), entry.getValue().getRight());
|
mappedData.put(entry.getKey(), entry.getValue().getRight());
|
||||||
}
|
}
|
||||||
return mappedData;
|
return mappedData;
|
||||||
|
@ -29,7 +29,6 @@ public interface IDatabase<B, C> extends Closeable {
|
|||||||
*
|
*
|
||||||
* @param credentials the optional credentials to use
|
* @param credentials the optional credentials to use
|
||||||
* @throws IllegalStateException if already connected
|
* @throws IllegalStateException if already connected
|
||||||
* @see C for credentials
|
|
||||||
*/
|
*/
|
||||||
void connect(C credentials) throws IllegalStateException;
|
void connect(C credentials) throws IllegalStateException;
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import me.braydon.feather.FeatherSettings;
|
import me.braydon.feather.FeatherSettings;
|
||||||
import me.braydon.feather.annotation.RawData;
|
|
||||||
import me.braydon.feather.annotation.Serializable;
|
import me.braydon.feather.annotation.Serializable;
|
||||||
import me.braydon.feather.common.FieldUtils;
|
import me.braydon.feather.common.FieldUtils;
|
||||||
|
|
||||||
@ -22,7 +21,7 @@ import java.util.Map;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A repository belonging to an {@link IDatabase}.
|
* A repository belonging to a {@link IDatabase}.
|
||||||
*
|
*
|
||||||
* @author Braydon
|
* @author Braydon
|
||||||
* @param <D> the database this repository uses
|
* @param <D> the database this repository uses
|
||||||
@ -121,18 +120,8 @@ public abstract class Repository<D extends IDatabase<?, ?>, ID, E> {
|
|||||||
Constructor<? extends E> constructor = entityClass.getConstructor(); // Get the no args constructor
|
Constructor<? extends E> constructor = entityClass.getConstructor(); // Get the no args constructor
|
||||||
E entity = constructor.newInstance(); // Create the entity
|
E entity = constructor.newInstance(); // Create the entity
|
||||||
|
|
||||||
// Get the field tagged with @Field
|
// Get the field tagged with @Id
|
||||||
java.lang.reflect.Field rawDataField = null; // The raw data field if defined
|
|
||||||
for (Field field : entityClass.getDeclaredFields()) {
|
for (Field field : entityClass.getDeclaredFields()) {
|
||||||
// Raw data field, save it for later
|
|
||||||
if (field.isAnnotationPresent(RawData.class)) {
|
|
||||||
rawDataField = field;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Not the field we're looking for
|
|
||||||
if (!field.isAnnotationPresent(me.braydon.feather.annotation.Field.class)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String key = FieldUtils.extractKey(field); // The key of the database field
|
String key = FieldUtils.extractKey(field); // The key of the database field
|
||||||
Class<?> type = field.getType(); // The type of the field
|
Class<?> type = field.getType(); // The type of the field
|
||||||
Object value = mappedData.get(key); // The value of the field
|
Object value = mappedData.get(key); // The value of the field
|
||||||
@ -148,10 +137,6 @@ public abstract class Repository<D extends IDatabase<?, ?>, ID, E> {
|
|||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
field.set(entity, value);
|
field.set(entity, value);
|
||||||
}
|
}
|
||||||
if (rawDataField != null) { // We have a raw data field, set it
|
|
||||||
rawDataField.setAccessible(true); // Make our field accessible
|
|
||||||
rawDataField.set(entity, mappedData); // Set the raw data field to our mapped document
|
|
||||||
}
|
|
||||||
return entity;
|
return entity;
|
||||||
} catch (NoSuchMethodException ex) { // We need our no args constructor
|
} catch (NoSuchMethodException ex) { // We need our no args constructor
|
||||||
throw new IllegalStateException("Entity " + entityClass.getName() + " is missing no args constructor");
|
throw new IllegalStateException("Entity " + entityClass.getName() + " is missing no args constructor");
|
||||||
|
@ -1,110 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
|
|
||||||
*
|
|
||||||
* For inquiries, please contact braydonrainnny@gmail.com
|
|
||||||
*/
|
|
||||||
package me.braydon.feather.database.impl.mariadb;
|
|
||||||
|
|
||||||
import com.zaxxer.hikari.HikariDataSource;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import me.braydon.feather.database.IDatabase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link IDatabase} implementation for MariaDB (and other MySQL servers).
|
|
||||||
*
|
|
||||||
* @author Braydon
|
|
||||||
* @see HikariDataSource for the bootstrap class
|
|
||||||
* @see MariaDBAuthorization for the credentials class
|
|
||||||
* @see <a href="https://github.com/brettwooldridge/HikariCP">HikariCP Official GitHub</a>
|
|
||||||
*/
|
|
||||||
public class MariaDB implements IDatabase<HikariDataSource, MariaDBAuthorization> {
|
|
||||||
/**
|
|
||||||
* The current {@link HikariDataSource} instance.
|
|
||||||
*/
|
|
||||||
private HikariDataSource dataSource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the name of this database.
|
|
||||||
*
|
|
||||||
* @return the database name
|
|
||||||
*/
|
|
||||||
@Override @NonNull
|
|
||||||
public String getName() {
|
|
||||||
return "MariaDB";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize a connection to this database.
|
|
||||||
*
|
|
||||||
* @param credentials the optional credentials to use
|
|
||||||
* @throws IllegalArgumentException if no credentials are provided
|
|
||||||
* @throws IllegalStateException if already connected
|
|
||||||
* @see MariaDBAuthorization for credentials
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void connect(MariaDBAuthorization credentials) throws IllegalArgumentException, IllegalStateException {
|
|
||||||
// if (credentials == null) { // We need valid credentials
|
|
||||||
// throw new IllegalArgumentException("No credentials defined");
|
|
||||||
// }
|
|
||||||
// if (isConnected()) { // Already connected
|
|
||||||
// throw new IllegalStateException("Already connected");
|
|
||||||
// }
|
|
||||||
// if (dataSource != null) { // We have a data source, close it first
|
|
||||||
// dataSource.close();
|
|
||||||
// }
|
|
||||||
// HikariConfig config = credentials.getHikariConfig(); // Get the custom config
|
|
||||||
// if (config == null) { // No custom config, make a new one
|
|
||||||
// config = new HikariConfig();
|
|
||||||
// }
|
|
||||||
// config.setJdbcUrl(credentials.getJdbcUrl()); // Set the JDBC connection URL
|
|
||||||
// config.setUsername(credentials.getUsername()); // Set the username
|
|
||||||
// config.setPassword(credentials.getPassword()); // Set the password
|
|
||||||
// dataSource = new HikariDataSource(config); // Create a new data source
|
|
||||||
throw new UnsupportedOperationException(); // Not impl yet
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if this database is connected.
|
|
||||||
*
|
|
||||||
* @return the database connection state
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean isConnected() {
|
|
||||||
return dataSource != null && (dataSource.isRunning() && !dataSource.isClosed());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the latency to this database.
|
|
||||||
*
|
|
||||||
* @return the latency, -1 if not connected
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public long getLatency() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the bootstrap class
|
|
||||||
* instance for this database.
|
|
||||||
*
|
|
||||||
* @return the bootstrap class instance, null if none
|
|
||||||
* @see HikariDataSource for bootstrap class
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public HikariDataSource getBootstrap() {
|
|
||||||
return dataSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes this stream and releases any system resources associated
|
|
||||||
* with it. If the stream is already closed then invoking this
|
|
||||||
* method has no effect.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
if (dataSource != null) {
|
|
||||||
dataSource.close();
|
|
||||||
}
|
|
||||||
dataSource = null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
|
|
||||||
*
|
|
||||||
* For inquiries, please contact braydonrainnny@gmail.com
|
|
||||||
*/
|
|
||||||
package me.braydon.feather.database.impl.mariadb;
|
|
||||||
|
|
||||||
import com.zaxxer.hikari.HikariConfig;
|
|
||||||
import lombok.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Authorization for a {@link MariaDB} database.
|
|
||||||
*
|
|
||||||
* @author Braydon
|
|
||||||
*/
|
|
||||||
@RequiredArgsConstructor @AllArgsConstructor @Getter @ToString
|
|
||||||
public final class MariaDBAuthorization {
|
|
||||||
/**
|
|
||||||
* The JDBC connection URL for the database.
|
|
||||||
*/
|
|
||||||
@NonNull private final String jdbcUrl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The username to use for authenticating with the database.
|
|
||||||
*/
|
|
||||||
@NonNull private final String username;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The password to use for authenticating with the database.
|
|
||||||
*/
|
|
||||||
@NonNull private final String password;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The optional {@link HikariConfig} to use.
|
|
||||||
*/
|
|
||||||
private HikariConfig hikariConfig;
|
|
||||||
}
|
|
@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
|
|
||||||
*
|
|
||||||
* For inquiries, please contact braydonrainnny@gmail.com
|
|
||||||
*/
|
|
||||||
package me.braydon.feather.database.impl.mariadb;
|
|
||||||
|
|
||||||
import lombok.NonNull;
|
|
||||||
import me.braydon.feather.database.Repository;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link MariaDB} {@link Repository} implementation.
|
|
||||||
*
|
|
||||||
* @author Braydon
|
|
||||||
* @param <ID> the identifier for type for entities
|
|
||||||
* @param <E> the entity type this repository stores
|
|
||||||
*/
|
|
||||||
public class MariaDBRepository<ID, E> extends Repository<MariaDB, ID, E> {
|
|
||||||
public MariaDBRepository(@NonNull MariaDB database, @NonNull Class<? extends E> entityClass) {
|
|
||||||
super(database, entityClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the entity with the given id.
|
|
||||||
*
|
|
||||||
* @param id the entity id
|
|
||||||
* @return the entity with the id, null if none
|
|
||||||
* @see ID for id
|
|
||||||
* @see E for entity
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public E find(@NonNull ID id) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all entities within this repository.
|
|
||||||
*
|
|
||||||
* @return the entities
|
|
||||||
* @see E for entity
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<E> findAll() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save the given entities.
|
|
||||||
*
|
|
||||||
* @param entities the entities to save
|
|
||||||
* @see E for entity
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void saveAll(@NonNull E... entities) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the amount of stored entities.
|
|
||||||
*
|
|
||||||
* @return the amount of stored entities
|
|
||||||
* @see E for entity
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public long count() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Drop the entity with the given id.
|
|
||||||
*
|
|
||||||
* @param id the entity id to drop
|
|
||||||
* @see ID for id
|
|
||||||
* @see E for entity
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void dropById(@NonNull ID id) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Drop the given entity.
|
|
||||||
*
|
|
||||||
* @param entity the entity to drop
|
|
||||||
* @see E for entity
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void drop(@NonNull E entity) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
|
|
||||||
*
|
|
||||||
* For inquiries, please contact braydonrainnny@gmail.com
|
|
||||||
*/
|
|
||||||
package me.braydon.feather.database.impl.mariadb.queries;
|
|
||||||
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import lombok.Singular;
|
|
||||||
import me.braydon.feather.database.impl.mariadb.MariaDB;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A builder for {@link MariaDB} update queries.
|
|
||||||
*
|
|
||||||
* @author Braydon
|
|
||||||
*/
|
|
||||||
@Builder @Getter
|
|
||||||
public class UpdateQuery {
|
|
||||||
/**
|
|
||||||
* The table to execute the update in.
|
|
||||||
*/
|
|
||||||
@NonNull private String table;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The mapped values (by column) for this query.
|
|
||||||
*/
|
|
||||||
@NonNull @Singular private Map<String, Object> values;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The where clause for this query.
|
|
||||||
*/
|
|
||||||
@NonNull private WhereClause whereClause;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build this query.
|
|
||||||
*
|
|
||||||
* @return the built query
|
|
||||||
*/
|
|
||||||
@Override @NonNull
|
|
||||||
public String toString() {
|
|
||||||
// Build the values
|
|
||||||
StringBuilder valuesBuilder = new StringBuilder();
|
|
||||||
for (Map.Entry<String, Object> entry : values.entrySet()) {
|
|
||||||
valuesBuilder.append("`").append(entry.getKey()).append("`")
|
|
||||||
.append("='").append(entry.getValue()).append("', ");
|
|
||||||
}
|
|
||||||
String values = valuesBuilder.toString(); // The built values string
|
|
||||||
values = values.substring(0, values.length() - 2); // Remove the trailing comma
|
|
||||||
|
|
||||||
// Build the query
|
|
||||||
return String.format("UPDATE `%s` SET %s WHERE %s;",
|
|
||||||
table, values, whereClause
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The where clause for this query.
|
|
||||||
*/
|
|
||||||
@Builder @Getter
|
|
||||||
public static class WhereClause {
|
|
||||||
/**
|
|
||||||
* The column to target.
|
|
||||||
*/
|
|
||||||
@NonNull private String column;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The value of the column to target.
|
|
||||||
*/
|
|
||||||
@NonNull private Object value;
|
|
||||||
|
|
||||||
@Override @NonNull
|
|
||||||
public String toString() {
|
|
||||||
return column + "='" + value + "'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -49,7 +49,6 @@ public class MongoDB implements IDatabase<MongoClient, ConnectionString> {
|
|||||||
* @param credentials the optional credentials to use
|
* @param credentials the optional credentials to use
|
||||||
* @throws IllegalArgumentException if no credentials or database name is provided
|
* @throws IllegalArgumentException if no credentials or database name is provided
|
||||||
* @throws IllegalStateException if already connected
|
* @throws IllegalStateException if already connected
|
||||||
* @see ConnectionString for credentials
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void connect(ConnectionString credentials) throws IllegalArgumentException, IllegalStateException {
|
public void connect(ConnectionString credentials) throws IllegalArgumentException, IllegalStateException {
|
||||||
@ -92,8 +91,8 @@ public class MongoDB implements IDatabase<MongoClient, ConnectionString> {
|
|||||||
}
|
}
|
||||||
// Return ping
|
// Return ping
|
||||||
long before = System.currentTimeMillis();
|
long before = System.currentTimeMillis();
|
||||||
database.runCommand(new BasicDBObject("ping", "1")); // Send a ping command
|
database.runCommand(new BasicDBObject("ping", "1"));
|
||||||
return System.currentTimeMillis() - before; // Return time difference
|
return System.currentTimeMillis() - before;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -124,7 +123,7 @@ public class MongoDB implements IDatabase<MongoClient, ConnectionString> {
|
|||||||
if (!isConnected()) { // Not connected
|
if (!isConnected()) { // Not connected
|
||||||
throw new IllegalStateException("Not connected");
|
throw new IllegalStateException("Not connected");
|
||||||
}
|
}
|
||||||
return new MongoRepository<>(this, entityClass, collectionName);
|
return new MongoRepository<>(this, entityClass, database.getCollection(collectionName));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,16 +12,16 @@ import com.mongodb.client.model.Indexes;
|
|||||||
import com.mongodb.client.model.UpdateOneModel;
|
import com.mongodb.client.model.UpdateOneModel;
|
||||||
import com.mongodb.client.model.UpdateOptions;
|
import com.mongodb.client.model.UpdateOptions;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import me.braydon.feather.common.Tuple;
|
import me.braydon.feather.common.Tuple;
|
||||||
import me.braydon.feather.database.Repository;
|
import me.braydon.feather.database.Repository;
|
||||||
import me.braydon.feather.database.impl.mongodb.annotation.CustomDocument;
|
|
||||||
import me.braydon.feather.database.impl.mongodb.annotation.Index;
|
import me.braydon.feather.database.impl.mongodb.annotation.Index;
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.util.ArrayList;
|
||||||
import java.util.*;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link MongoDB} {@link Repository} implementation.
|
* The {@link MongoDB} {@link Repository} implementation.
|
||||||
@ -36,10 +36,6 @@ public class MongoRepository<ID, E> extends Repository<MongoDB, ID, E> {
|
|||||||
*/
|
*/
|
||||||
@NonNull private final MongoCollection<Document> collection;
|
@NonNull private final MongoCollection<Document> collection;
|
||||||
|
|
||||||
public MongoRepository(@NonNull MongoDB database, @NonNull Class<? extends E> entityClass, @NonNull String collectionName) {
|
|
||||||
this(database, entityClass, database.getDatabase().getCollection(collectionName));
|
|
||||||
}
|
|
||||||
|
|
||||||
public MongoRepository(@NonNull MongoDB database, @NonNull Class<? extends E> entityClass, @NonNull MongoCollection<Document> collection) {
|
public MongoRepository(@NonNull MongoDB database, @NonNull Class<? extends E> entityClass, @NonNull MongoCollection<Document> collection) {
|
||||||
super(database, entityClass);
|
super(database, entityClass);
|
||||||
this.collection = collection;
|
this.collection = collection;
|
||||||
@ -94,29 +90,17 @@ public class MongoRepository<ID, E> extends Repository<MongoDB, ID, E> {
|
|||||||
* @param entities the entities to save
|
* @param entities the entities to save
|
||||||
* @see E for entity
|
* @see E for entity
|
||||||
*/
|
*/
|
||||||
@Override @SneakyThrows
|
@Override
|
||||||
public void saveAll(@NonNull E... entities) {
|
public void saveAll(@NonNull E... entities) {
|
||||||
List<UpdateOneModel<Document>> updateModels = new ArrayList<>(); // The update models to bulk write
|
List<UpdateOneModel<Document>> updateModels = new ArrayList<>(); // The update models to bulk write
|
||||||
|
|
||||||
for (E entity : entities) {
|
for (E entity : entities) {
|
||||||
me.braydon.feather.data.Document document = new me.braydon.feather.data.Document(entity); // Create a document from the entity
|
me.braydon.feather.data.Document<Object> document = new me.braydon.feather.data.Document<>(entity); // Create a document from the entity
|
||||||
Document bsonDocument; // The Bson document to save
|
|
||||||
|
|
||||||
Method customDocumentMethod = Arrays.stream(entity.getClass().getDeclaredMethods())
|
|
||||||
.filter(method -> method.isAnnotationPresent(CustomDocument.class))
|
|
||||||
.findFirst().orElse(null); // Get the @CustomDocument method
|
|
||||||
|
|
||||||
// We have a custom document method
|
|
||||||
if (customDocumentMethod != null && (customDocumentMethod.getReturnType() == Document.class)) {
|
|
||||||
bsonDocument = (Document) customDocumentMethod.invoke(entity); // Get our custom document
|
|
||||||
} else { // Otherwise, use our mapped data
|
|
||||||
bsonDocument = new Document(document.toMappedData());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add our update model to the list
|
// Add our update model to the list
|
||||||
updateModels.add(new UpdateOneModel<>(
|
updateModels.add(new UpdateOneModel<>(
|
||||||
Filters.eq(document.getIdKey(), document.getKey()),
|
Filters.eq(document.getIdKey(), document.getKey()),
|
||||||
new Document("$set", bsonDocument),
|
new Document("$set", new Document(document.toMappedData())),
|
||||||
new UpdateOptions().upsert(true)
|
new UpdateOptions().upsert(true)
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -178,7 +162,7 @@ public class MongoRepository<ID, E> extends Repository<MongoDB, ID, E> {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void drop(@NonNull E entity) {
|
public void drop(@NonNull E entity) {
|
||||||
me.braydon.feather.data.Document document = new me.braydon.feather.data.Document(entity); // Create a document from the entity
|
me.braydon.feather.data.Document<Object> document = new me.braydon.feather.data.Document<>(entity); // Create a document from the entity
|
||||||
collection.deleteOne(new Document(document.getIdKey(), document.getKey())); // Delete the entity
|
collection.deleteOne(new Document(document.getIdKey(), document.getKey())); // Delete the entity
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
|
|
||||||
*
|
|
||||||
* For inquiries, please contact braydonrainnny@gmail.com
|
|
||||||
*/
|
|
||||||
package me.braydon.feather.database.impl.mongodb.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Methods tagged with this annotation will be invoked
|
|
||||||
* when a document is being saved to the database, this
|
|
||||||
* allows is to save a custom document, rather than
|
|
||||||
* parsing the entity and creating one that way.
|
|
||||||
*
|
|
||||||
* @author Braydon
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
@Documented @Inherited
|
|
||||||
public @interface CustomDocument { }
|
|
@ -19,7 +19,7 @@ import me.braydon.feather.database.IDatabase;
|
|||||||
* @see RedisURI for the credentials class
|
* @see RedisURI for the credentials class
|
||||||
* @see <a href="https://redis.io">Redis Official Site</a>
|
* @see <a href="https://redis.io">Redis Official Site</a>
|
||||||
*/
|
*/
|
||||||
public class Redis implements IDatabase<StatefulRedisConnection<String, String>, String> {
|
public class Redis implements IDatabase<StatefulRedisConnection<String, String>, RedisURI> {
|
||||||
/**
|
/**
|
||||||
* The current {@link RedisClient} instance.
|
* The current {@link RedisClient} instance.
|
||||||
*/
|
*/
|
||||||
@ -43,25 +43,25 @@ public class Redis implements IDatabase<StatefulRedisConnection<String, String>,
|
|||||||
/**
|
/**
|
||||||
* Initialize a connection to this database.
|
* Initialize a connection to this database.
|
||||||
*
|
*
|
||||||
* @param uri the optional credentials to use
|
* @param credentials the optional credentials to use
|
||||||
* @throws IllegalArgumentException if no credentials are provided
|
* @throws IllegalArgumentException if no credentials are provided
|
||||||
* @throws IllegalStateException if already connected
|
* @throws IllegalStateException if already connected
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void connect(String uri) throws IllegalArgumentException, IllegalStateException {
|
public void connect(RedisURI credentials) throws IllegalArgumentException, IllegalStateException {
|
||||||
if (uri == null) { // We need valid credentials
|
if (credentials == null) { // We need valid credentials
|
||||||
throw new IllegalArgumentException("No credentials defined");
|
throw new IllegalArgumentException("No credentials defined");
|
||||||
}
|
}
|
||||||
if (isConnected()) { // Already connected
|
if (isConnected()) { // Already connected
|
||||||
throw new IllegalStateException("Already connected");
|
throw new IllegalStateException("Already connected");
|
||||||
}
|
}
|
||||||
if (client != null) { // We have a client, close it first
|
if (client != null) { // We have a client, close it first
|
||||||
client.shutdown();
|
client.close();
|
||||||
}
|
}
|
||||||
if (connection != null) { // We have a connection, close it first
|
if (connection != null) { // We have a connection, close it first
|
||||||
connection.close();
|
connection.close();
|
||||||
}
|
}
|
||||||
client = RedisClient.create(uri); // Create a new client
|
client = RedisClient.create(credentials); // Create a new client
|
||||||
connection = client.connect(); // Connect to the Redis server
|
connection = client.connect(); // Connect to the Redis server
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,13 +82,7 @@ public class Redis implements IDatabase<StatefulRedisConnection<String, String>,
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public long getLatency() {
|
public long getLatency() {
|
||||||
if (!isConnected()) { // Not connected
|
return 0;
|
||||||
return -1L;
|
|
||||||
}
|
|
||||||
// Return ping
|
|
||||||
long before = System.currentTimeMillis();
|
|
||||||
connection.sync().ping(); // Send a ping command
|
|
||||||
return System.currentTimeMillis() - before; // Return time difference
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -145,7 +139,7 @@ public class Redis implements IDatabase<StatefulRedisConnection<String, String>,
|
|||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
client.shutdown();
|
client.close();
|
||||||
}
|
}
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
connection.close();
|
connection.close();
|
||||||
|
@ -7,13 +7,12 @@ package me.braydon.feather.database.impl.redis;
|
|||||||
|
|
||||||
import io.lettuce.core.api.sync.RedisCommands;
|
import io.lettuce.core.api.sync.RedisCommands;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import me.braydon.feather.common.Tuple;
|
|
||||||
import me.braydon.feather.data.Document;
|
import me.braydon.feather.data.Document;
|
||||||
import me.braydon.feather.database.Repository;
|
import me.braydon.feather.database.Repository;
|
||||||
import me.braydon.feather.database.impl.redis.annotation.TTL;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.util.ArrayList;
|
||||||
import java.util.*;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link Redis} {@link Repository} implementation.
|
* The {@link Redis} {@link Repository} implementation.
|
||||||
@ -79,24 +78,8 @@ public class RedisRepository<ID, E> extends Repository<Redis, ID, E> {
|
|||||||
commands.multi();
|
commands.multi();
|
||||||
}
|
}
|
||||||
for (E entity : entities) { // Set our entities
|
for (E entity : entities) { // Set our entities
|
||||||
Document document = new Document(entity); // Create a document from the entity
|
Document<String> document = new Document<>(entity); // Create a document from the entity
|
||||||
String key = keyPrefix + ":" + document.getKey(); // The key of this entity
|
commands.hmset(keyPrefix + ":" + document.getKey(), document.toMappedData());
|
||||||
|
|
||||||
Map<String, String> mappedData = new HashMap<>();
|
|
||||||
for (Map.Entry<String, Tuple<Field, Object>> entry : document.getMappedData().entrySet()) {
|
|
||||||
mappedData.put(entry.getKey(), String.valueOf(entry.getValue().getRight()));
|
|
||||||
}
|
|
||||||
commands.hmset(key, mappedData); // Set the mapped document in the database
|
|
||||||
|
|
||||||
// Handling @TTL annotations
|
|
||||||
Class<?> clazz = entity.getClass(); // The entity class
|
|
||||||
if (!clazz.isAnnotationPresent(TTL.class)) { // Missing @TTL
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
long ttl = clazz.getAnnotation(TTL.class).value(); // Get the ttl value
|
|
||||||
if (ttl > 0L) { // Value is above zero, set it
|
|
||||||
commands.expire(key, ttl);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (multi) { // Execute the commands in bulk
|
if (multi) { // Execute the commands in bulk
|
||||||
commands.exec();
|
commands.exec();
|
||||||
@ -134,7 +117,7 @@ public class RedisRepository<ID, E> extends Repository<Redis, ID, E> {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void drop(@NonNull E entity) {
|
public void drop(@NonNull E entity) {
|
||||||
me.braydon.feather.data.Document document = new me.braydon.feather.data.Document(entity); // Create a document from the entity
|
me.braydon.feather.data.Document<Object> document = new me.braydon.feather.data.Document<>(entity); // Create a document from the entity
|
||||||
getDatabase().getBootstrap().sync().del(keyPrefix + ":" + document.getKey());
|
getDatabase().getBootstrap().sync().del(keyPrefix + ":" + document.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023 Braydon (Rainnny). All rights reserved.
|
|
||||||
*
|
|
||||||
* For inquiries, please contact braydonrainnny@gmail.com
|
|
||||||
*/
|
|
||||||
package me.braydon.feather.database.impl.redis.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Entities tagged with this annotation will
|
|
||||||
* expire after the amount of defined seconds.
|
|
||||||
*
|
|
||||||
* @author Braydon
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.FIELD)
|
|
||||||
@Documented @Inherited
|
|
||||||
public @interface TTL {
|
|
||||||
/**
|
|
||||||
* The time-to-live value.
|
|
||||||
* <p>
|
|
||||||
* If the value is zero or
|
|
||||||
* below, then there will
|
|
||||||
* be no expiration.
|
|
||||||
* <p>
|
|
||||||
* The key this TTL rule is assigned
|
|
||||||
* to will expire in the defined amount
|
|
||||||
* of seconds from when the key was updated.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @return the value in seconds
|
|
||||||
*/
|
|
||||||
long value() default -1L;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user