Skip to content
Merged
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
.claude/

### IntelliJ IDEA ###
.idea/modules.xml
Expand Down
79 changes: 30 additions & 49 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@ import java.util.Locale

plugins {
`java-library`
id("com.github.johnrengelman.shadow") version "7.1.2" // Pour remplacer maven-shade-plugin
id("re.alwyn974.groupez.publish") version "1.0.0"
id("com.gradleup.shadow") version "9.0.0-beta11"
`maven-publish`
}

rootProject.extra.properties["sha"]?.let { sha ->
version = sha
}

group = "fr.maxlego08.sarah"
version = "1.20.2"


extra.set("targetFolder", file("target/"))
extra.set("apiFolder", file("target-api/"))
extra.set("classifier", System.getProperty("archive.classifier"))
extra.set("sha", System.getProperty("github.sha"))

group = "fr.maxlego08.sarah"
version = "1.21"

rootProject.extra.properties["sha"]?.let { sha ->
version = sha
}

java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
Expand All @@ -33,6 +32,16 @@ repositories {

dependencies {
implementation("com.zaxxer:HikariCP:4.0.3")

// Test dependencies
testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3")
testImplementation("org.junit.jupiter:junit-jupiter-params:5.9.3")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.3")
testImplementation("org.mockito:mockito-core:5.3.1")
testImplementation("org.mockito:mockito-junit-jupiter:5.3.1")
testImplementation("org.xerial:sqlite-jdbc:3.42.0.0")
testImplementation("org.mariadb.jdbc:mariadb-java-client:3.1.4")
testImplementation("com.mysql:mysql-connector-j:8.2.0")
}

tasks.withType<Jar> {
Expand All @@ -52,44 +61,16 @@ tasks.build {
dependsOn(tasks.shadowJar)
}

publishing {

var repository = System.getProperty("repository.name", "snapshots").replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }

repositories {
maven {
name = "groupez${repository}"
url = uri("https://repo.groupez.dev/${repository.lowercase()}")
credentials {
username = findProperty("${name}Username") as String? ?: System.getenv("MAVEN_USERNAME")
password = findProperty("${name}Password") as String? ?: System.getenv("MAVEN_PASSWORD")
}
authentication {
create<BasicAuthentication>("basic")
}
}
}
tasks.shadowJar {
archiveClassifier.set("")
destinationDirectory.set(rootProject.extra["targetFolder"] as File)
}

publications {
register<MavenPublication>("groupez${repository}") {
pom {
groupId = project.group as String?
artifactId = rootProject.name.lowercase()
version = if (repository.lowercase() == "snapshots") {
System.getProperty("github.sha")
} else {
project.version as String?
}

scm {
connection = "scm:git:git://github.com/GroupeZ-dev/${rootProject.name}.git"
developerConnection = "scm:git:ssh://github.com/GroupeZ-dev/${rootProject.name}.git"
url = "https://github.com/GroupeZ-dev/${rootProject.name}/"
}
}
artifact(tasks.shadowJar)
// artifact(tasks.javadocJar)
// artifact(tasks.sourcesJar)
}
}
tasks.test {
useJUnitPlatform()
}

publishConfig {
githubOwner = "GroupeZ-dev"
useRootProjectName = true
}
Empty file modified gradlew
100755 → 100644
Empty file.
12 changes: 11 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
rootProject.name = "Sarah"
rootProject.name = "Sarah"

pluginManagement {
repositories {
maven {
name = "groupezReleases"
url = uri("https://repo.groupez.dev/releases")
}
gradlePluginPortal()
}
}
2 changes: 2 additions & 0 deletions src/main/java/fr/maxlego08/sarah/Column.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@
String type() default "";

boolean nullable() default false;

boolean unique() default false;
}
18 changes: 16 additions & 2 deletions src/main/java/fr/maxlego08/sarah/ConsumerConstructor.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;
import java.util.function.Consumer;
Expand Down Expand Up @@ -39,8 +40,18 @@ public static Consumer<Schema> createConsumerFromTemplate(Class<?> template, Obj
Constructor<?> firstConstructor = constructors[0];
firstConstructor.setAccessible(true);

Field[] fields = template.getDeclaredFields();
if (fields.length != firstConstructor.getParameterCount()) {
Field[] allFields = template.getDeclaredFields();
// Filter out synthetic fields (added by compiler for local/anonymous classes)
Field[] fields = Arrays.stream(allFields)
.filter(f -> !f.isSynthetic())
.toArray(Field[]::new);

// For local/anonymous classes, count only non-synthetic constructor parameters
long nonSyntheticParamCount = Arrays.stream(firstConstructor.getParameters())
.filter(p -> !p.isSynthetic())
.count();

if (fields.length != nonSyntheticParamCount) {
throw new IllegalArgumentException("Fields count does not match constructor parameters count");
}

Expand Down Expand Up @@ -102,6 +113,9 @@ public static Consumer<Schema> createConsumerFromTemplate(Class<?> template, Obj
if (column.nullable()) {
schema.nullable();
}
if (column.unique()) {
schema.unique();
}
}

if (i == 0 && !primaryAlready) {
Expand Down
44 changes: 34 additions & 10 deletions src/main/java/fr/maxlego08/sarah/DatabaseConnection.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package fr.maxlego08.sarah;

import fr.maxlego08.sarah.database.DatabaseType;
import fr.maxlego08.sarah.exceptions.DatabaseException;
import fr.maxlego08.sarah.logger.Logger;
import fr.maxlego08.sarah.transaction.Transaction;

import java.sql.Connection;
import java.sql.SQLException;
Expand All @@ -12,10 +15,12 @@
public abstract class DatabaseConnection {

protected final DatabaseConfiguration databaseConfiguration;
protected final Logger logger;
protected Connection connection;

public DatabaseConnection(DatabaseConfiguration databaseConfiguration) {
public DatabaseConnection(DatabaseConfiguration databaseConfiguration, Logger logger) {
this.databaseConfiguration = databaseConfiguration;
this.logger = logger;
}

/**
Expand Down Expand Up @@ -46,14 +51,10 @@ public boolean isValid() {
}

if (!isConnected(connection)) {
try {
Connection temp_connection = this.connectToDatabase();

if (isConnected(temp_connection)) {
temp_connection.close();
}
try (Connection tempConnection = this.connectToDatabase()) {
return isConnected(tempConnection);
} catch (Exception exception) {
exception.printStackTrace();
this.logger.info("Failed to validate database connection: " + exception.getMessage());
return false;
}
}
Expand Down Expand Up @@ -87,7 +88,7 @@ public void disconnect() {
try {
connection.close();
} catch (SQLException exception) {
exception.printStackTrace();
this.logger.info("Failed to disconnect from database: " + exception.getMessage());
}
}
}
Expand All @@ -100,7 +101,8 @@ public void connect() {
try {
connection = this.connectToDatabase();
} catch (Exception exception) {
exception.printStackTrace();
this.logger.info("Failed to connect to database: " + exception.getMessage());
throw new DatabaseException("connect", exception);
}
}
}
Expand All @@ -117,4 +119,26 @@ public Connection getConnection() {
connect();
return connection;
}

/**
* Begins a new database transaction.
* Use try-with-resources to ensure proper cleanup:
* <pre>
* try (Transaction tx = connection.beginTransaction()) {
* // Execute operations
* tx.commit();
* } // Automatically rolls back if not committed
* </pre>
*
* @return a new Transaction instance
* @throws DatabaseException if the transaction cannot be started
*/
public Transaction beginTransaction() {
try {
return new Transaction(getConnection());
} catch (SQLException exception) {
this.logger.info("Failed to begin transaction: " + exception.getMessage());
throw new DatabaseException("begin-transaction", exception);
}
}
}
10 changes: 6 additions & 4 deletions src/main/java/fr/maxlego08/sarah/HikariDatabaseConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import fr.maxlego08.sarah.database.DatabaseType;
import fr.maxlego08.sarah.exceptions.DatabaseException;
import fr.maxlego08.sarah.logger.Logger;

import javax.sql.DataSource;
import java.sql.Connection;
Expand All @@ -26,8 +28,8 @@ public class HikariDatabaseConnection extends DatabaseConnection {

private HikariDataSource dataSource;

public HikariDatabaseConnection(DatabaseConfiguration databaseConfiguration) {
super(databaseConfiguration);
public HikariDatabaseConnection(DatabaseConfiguration databaseConfiguration, Logger logger) {
super(databaseConfiguration, logger);
this.initializeDataSource();
}

Expand Down Expand Up @@ -126,8 +128,8 @@ public Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException exception) {
exception.printStackTrace();
return null;
this.logger.info("Failed to get connection from Hikari pool: " + exception.getMessage());
throw new DatabaseException("getConnection", exception);
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/main/java/fr/maxlego08/sarah/MariaDbConnection.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package fr.maxlego08.sarah;

import fr.maxlego08.sarah.logger.Logger;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
Expand All @@ -9,8 +11,8 @@
*/
public class MariaDbConnection extends DatabaseConnection {

public MariaDbConnection(DatabaseConfiguration databaseConfiguration) {
super(databaseConfiguration);
public MariaDbConnection(DatabaseConfiguration databaseConfiguration, Logger logger) {
super(databaseConfiguration, logger);
}

@Override
Expand Down
12 changes: 8 additions & 4 deletions src/main/java/fr/maxlego08/sarah/MigrationManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import fr.maxlego08.sarah.database.DatabaseType;
import fr.maxlego08.sarah.database.Migration;
import fr.maxlego08.sarah.database.Schema;
import fr.maxlego08.sarah.exceptions.DatabaseException;
import fr.maxlego08.sarah.logger.Logger;

import java.sql.Connection;
Expand Down Expand Up @@ -120,7 +121,8 @@ public static void execute(DatabaseConnection databaseConnection, Logger logger)
}
mustBeAdd.addAll(columnDefinitions);
} catch (SQLException exception) {
exception.printStackTrace();
logger.info("Failed to get table info for migration: " + exception.getMessage());
throw new DatabaseException("migration-table-info", tableName, exception);
}
} else {
for (ColumnDefinition column : schema.getColumns()) {
Expand Down Expand Up @@ -187,7 +189,8 @@ private static void createMigrationTable(DatabaseConnection databaseConnection,
try {
schema.execute(databaseConnection, logger);
} catch (SQLException exception) {
exception.printStackTrace();
logger.info("Failed to create migration table: " + exception.getMessage());
throw new DatabaseException("create-migration-table", migrationTableName, exception);
}
}

Expand All @@ -203,7 +206,7 @@ private static List<String> getMigrations(DatabaseConnection databaseConnection,
try {
return schema.executeSelect(MigrationTable.class, databaseConnection, logger).stream().map(MigrationTable::getMigration).collect(Collectors.toList());
} catch (Exception exception) {
exception.printStackTrace();
logger.info("Failed to get migrations list: " + exception.getMessage());
}
return new ArrayList<>();
}
Expand All @@ -221,7 +224,8 @@ private static void insertMigration(DatabaseConnection databaseConnection, Logge
try {
SchemaBuilder.insert(migrationTableName, schema -> schema.string("migration", migration.getClass().getSimpleName())).execute(databaseConnection, logger);
} catch (SQLException exception) {
exception.printStackTrace();
logger.info("Failed to insert migration record: " + exception.getMessage());
throw new DatabaseException("insert-migration", migrationTableName, exception);
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/main/java/fr/maxlego08/sarah/MySqlConnection.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package fr.maxlego08.sarah;

import fr.maxlego08.sarah.logger.Logger;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

public class MySqlConnection extends DatabaseConnection {

public MySqlConnection(DatabaseConfiguration databaseConfiguration) {
super(databaseConfiguration);
public MySqlConnection(DatabaseConfiguration databaseConfiguration, Logger logger) {
super(databaseConfiguration, logger);
}

@Override
Expand Down
Loading
Loading