diff --git a/pom.xml b/pom.xml
index 436fa4f..a6fd2c3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -196,5 +196,17 @@
6.3.0.RELEASE
provided
+
+ com.zaxxer
+ HikariCP
+ 4.0.3
+ compile
+
+
+ org.mariadb.jdbc
+ mariadb-java-client
+ 3.3.1
+ compile
+
\ No newline at end of file
diff --git a/src/main/java/me/braydon/feather/database/IDatabase.java b/src/main/java/me/braydon/feather/database/IDatabase.java
index 4a63c34..e700a67 100644
--- a/src/main/java/me/braydon/feather/database/IDatabase.java
+++ b/src/main/java/me/braydon/feather/database/IDatabase.java
@@ -29,6 +29,7 @@ public interface IDatabase extends Closeable {
*
* @param credentials the optional credentials to use
* @throws IllegalStateException if already connected
+ * @see C for credentials
*/
void connect(C credentials) throws IllegalStateException;
diff --git a/src/main/java/me/braydon/feather/database/impl/mariadb/MariaDB.java b/src/main/java/me/braydon/feather/database/impl/mariadb/MariaDB.java
new file mode 100644
index 0000000..a03c290
--- /dev/null
+++ b/src/main/java/me/braydon/feather/database/impl/mariadb/MariaDB.java
@@ -0,0 +1,110 @@
+/*
+ * 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 com.zaxxer.hikari.HikariDataSource;
+import lombok.NonNull;
+import me.braydon.feather.database.IDatabase;
+
+/**
+ * The {@link IDatabase} implementation for MariaDB (& other MySQL servers).
+ *
+ * @author Braydon
+ * @see HikariDataSource for the bootstrap class
+ * @see MariaDBAuthorization for the credentials class
+ * @see HikariCP Official GitHub
+ */
+public class MariaDB implements IDatabase {
+ /**
+ * 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
+ }
+
+ /**
+ * 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;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/braydon/feather/database/impl/mariadb/MariaDBAuthorization.java b/src/main/java/me/braydon/feather/database/impl/mariadb/MariaDBAuthorization.java
new file mode 100644
index 0000000..3df9e9c
--- /dev/null
+++ b/src/main/java/me/braydon/feather/database/impl/mariadb/MariaDBAuthorization.java
@@ -0,0 +1,37 @@
+/*
+ * 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;
+}
\ No newline at end of file
diff --git a/src/main/java/me/braydon/feather/database/impl/mariadb/MariaDBRepository.java b/src/main/java/me/braydon/feather/database/impl/mariadb/MariaDBRepository.java
new file mode 100644
index 0000000..cc5a203
--- /dev/null
+++ b/src/main/java/me/braydon/feather/database/impl/mariadb/MariaDBRepository.java
@@ -0,0 +1,93 @@
+/*
+ * 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 the identifier for type for entities
+ * @param the entity type this repository stores
+ */
+public class MariaDBRepository extends Repository {
+ 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 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();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/braydon/feather/database/impl/mariadb/queries/UpdateQuery.java b/src/main/java/me/braydon/feather/database/impl/mariadb/queries/UpdateQuery.java
new file mode 100644
index 0000000..c76f9c6
--- /dev/null
+++ b/src/main/java/me/braydon/feather/database/impl/mariadb/queries/UpdateQuery.java
@@ -0,0 +1,80 @@
+/*
+ * 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 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 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 + "'";
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/braydon/feather/database/impl/mongodb/MongoDB.java b/src/main/java/me/braydon/feather/database/impl/mongodb/MongoDB.java
index 3326e53..ec449c3 100644
--- a/src/main/java/me/braydon/feather/database/impl/mongodb/MongoDB.java
+++ b/src/main/java/me/braydon/feather/database/impl/mongodb/MongoDB.java
@@ -49,6 +49,7 @@ public class MongoDB implements IDatabase {
* @param credentials the optional credentials to use
* @throws IllegalArgumentException if no credentials or database name is provided
* @throws IllegalStateException if already connected
+ * @see ConnectionString for credentials
*/
@Override
public void connect(ConnectionString credentials) throws IllegalArgumentException, IllegalStateException {
@@ -91,8 +92,8 @@ public class MongoDB implements IDatabase {
}
// Return ping
long before = System.currentTimeMillis();
- database.runCommand(new BasicDBObject("ping", "1"));
- return System.currentTimeMillis() - before;
+ database.runCommand(new BasicDBObject("ping", "1")); // Send a ping command
+ return System.currentTimeMillis() - before; // Return time difference
}
/**
diff --git a/src/main/java/me/braydon/feather/database/impl/redis/Redis.java b/src/main/java/me/braydon/feather/database/impl/redis/Redis.java
index d47e8df..772105c 100644
--- a/src/main/java/me/braydon/feather/database/impl/redis/Redis.java
+++ b/src/main/java/me/braydon/feather/database/impl/redis/Redis.java
@@ -46,6 +46,7 @@ public class Redis implements IDatabase,
* @param credentials the optional credentials to use
* @throws IllegalArgumentException if no credentials are provided
* @throws IllegalStateException if already connected
+ * @see RedisURI for credentials
*/
@Override
public void connect(RedisURI credentials) throws IllegalArgumentException, IllegalStateException {
@@ -82,7 +83,13 @@ public class Redis implements IDatabase,
*/
@Override
public long getLatency() {
- return 0;
+ if (!isConnected()) { // Not connected
+ return -1L;
+ }
+ // Return ping
+ long before = System.currentTimeMillis();
+ connection.sync().ping(); // Send a ping command
+ return System.currentTimeMillis() - before; // Return time difference
}
/**