[DEV] work On test and api correction

This commit is contained in:
Edouard DUPIN 2023-10-25 23:53:55 +02:00
parent 88b945285b
commit bfb329b5be
20 changed files with 741 additions and 254 deletions

View File

@ -18,6 +18,13 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="out/maven/test-classes" path="test/resources">
<attributes>
<attribute name="test" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="optional" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>achi-data</name>
<name>archi-data</name>
<comment></comment>
<projects>
</projects>
@ -10,6 +10,16 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
<dictionary>
<key>LaunchConfigHandle</key>
<value>&lt;project&gt;/.externalToolBuilders/org.eclipse.jdt.core.javabuilder.launch</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>

83
pom.xml
View File

@ -1,35 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>kangaroo-and-rabbit</groupId>
<artifactId>archidata</artifactId>
<version>0.4.0</version>
<modelVersion>4.0.0</modelVersion>
<groupId>kangaroo-and-rabbit</groupId>
<artifactId>archidata</artifactId>
<version>0.4.0</version>
<properties>
<jersey.version>3.1.1</jersey.version>
<jaxb.version>2.3.1</jaxb.version>
<istack.version>4.1.1</istack.version>
<maven.compiler.version>3.1</maven.compiler.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.dependency.version>3.1.1</maven.dependency.version>
<jersey.version>3.1.1</jersey.version>
<jaxb.version>2.3.1</jaxb.version>
<istack.version>4.1.1</istack.version>
</properties>
<repositories>
<repository>
<id>gitea</id>
<url>https://gitea.atria-soft.org/api/packages/kangaroo-and-rabbit/maven</url>
</repository>
<repository>
<id>gitea</id>
<url>https://gitea.atria-soft.org/api/packages/kangaroo-and-rabbit/maven</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>gitea</id>
<url>https://gitea.atria-soft.org/api/packages/kangaroo-and-rabbit/maven</url>
</repository>
<snapshotRepository>
<id>gitea</id>
<url>https://gitea.atria-soft.org/api/packages/kangaroo-and-rabbit/maven</url>
</snapshotRepository>
<repository>
<id>gitea</id>
<url>https://gitea.atria-soft.org/api/packages/kangaroo-and-rabbit/maven</url>
</repository>
<snapshotRepository>
<id>gitea</id>
<url>https://gitea.atria-soft.org/api/packages/kangaroo-and-rabbit/maven</url>
</snapshotRepository>
</distributionManagement>
<dependencyManagement>
@ -47,9 +48,15 @@
<dependencies>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.7</version>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.7</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-multipart -->
<dependency>
@ -128,25 +135,41 @@
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>9.30</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.2</version>
<scope>test</scope>
<version>9.37</version>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.1.0</version>
</dependency>
<!--
************************************************************
** TEST dependency **
************************************************************
-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<testSourceDirectory>test/src</testSourceDirectory>
<directory>${project.basedir}/out/maven/</directory>
<testResources>
<testResource>
<directory>${basedir}/test/resources</directory>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>

View File

@ -17,14 +17,15 @@ public class AnnotationTools {
public static String getTableName(final Class<?> element) throws Exception {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Table.class);
if (annotation.length == 0) {
return null;
// when no annotation is detected, then the table name is the class name
return element.getSimpleName();
}
if (annotation.length > 1) {
throw new Exception("Must not have more than 1 element @SQLTableName on " + element.getClass().getCanonicalName());
}
final String tmp = ((Table) annotation[0]).name();
if (tmp == null) {
return null;
return element.getSimpleName();
}
return tmp;
}
@ -37,11 +38,7 @@ public class AnnotationTools {
if (annotation.length > 1) {
throw new Exception("Must not have more than 1 element @SQLComment on " + element.getClass().getCanonicalName());
}
final String tmp = ((SQLComment) annotation[0]).value();
if (tmp == null) {
return null;
}
return tmp;
return ((SQLComment) annotation[0]).value();
}
public static String getDefault(final Field element) throws Exception {
@ -52,11 +49,7 @@ public class AnnotationTools {
if (annotation.length > 1) {
throw new Exception("Must not have more than 1 element @SQLDefault on " + element.getClass().getCanonicalName());
}
final String tmp = ((SQLDefault) annotation[0]).value();
if (tmp == null) {
return null;
}
return tmp;
return ((SQLDefault) annotation[0]).value();
}
public static Integer getLimitSize(final Field element) throws Exception {
@ -141,4 +134,50 @@ public class AnnotationTools {
return ((GeneratedValue) annotation[0]).strategy();
}
public static boolean isDeletedField(final Field element) throws Exception {
return element.getDeclaredAnnotationsByType(SQLDeleted.class).length != 0;
}
public static boolean isUpdateField(final Field element) throws Exception {
return element.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0;
}
public static boolean isdefaultNotRead(final Field element) throws Exception {
return element.getDeclaredAnnotationsByType(SQLNotRead.class).length != 0;
}
public static String getDeletedFieldName(final Class<?> clazz) throws Exception {
try {
for (final Field elem : clazz.getFields()) {
// static field is only for internal global declaration ==> remove it ..
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
continue;
}
if (AnnotationTools.isDeletedField(elem)) {
return AnnotationTools.getFieldName(elem);
}
}
} catch (final Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String getUpdatedFieldName(final Class<?> clazz) throws Exception {
try {
for (final Field elem : clazz.getFields()) {
// static field is only for internal global declaration ==> remove it ..
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
continue;
}
if (AnnotationTools.isUpdateField(elem)) {
return AnnotationTools.getFieldName(elem);
}
}
} catch (final Exception ex) {
ex.printStackTrace();
}
return null;
}
}

View File

@ -3,7 +3,7 @@ package org.kar.archidata.migration;
import org.kar.archidata.annotation.SQLComment;
import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLIfNotExists;
import org.kar.archidata.model.GenericTable;
import org.kar.archidata.model.GenericDataSoftDelete;
import com.fasterxml.jackson.annotation.JsonInclude;
@ -16,7 +16,7 @@ import jakarta.persistence.Table;
@Table(name = "KAR_migration")
@SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MigrationModel extends GenericTable {
public class MigrationModel extends GenericDataSoftDelete {
@SQLComment("Name of the migration")
@Column(length = 256)
public String name;

View File

@ -11,8 +11,8 @@ import jakarta.persistence.Table;
@Table(name = "data")
@SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Data extends GenericTable {
public class Data extends GenericDataSoftDelete {
@Column(length = 128, nullable = false)
@SQLComment("Sha512 of the data")
public String sha512;

View File

@ -4,8 +4,6 @@ import java.sql.Timestamp;
import org.kar.archidata.annotation.CreationTimestamp;
import org.kar.archidata.annotation.SQLComment;
import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLDeleted;
import org.kar.archidata.annotation.SQLNotRead;
import org.kar.archidata.annotation.UpdateTimestamp;
@ -14,19 +12,13 @@ import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
public class GenericTable {
public class GenericData {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false, unique = true)
@SQLComment("Primary key of the base")
public Long id = null;
@SQLNotRead
@Column(nullable = false)
@SQLDefault("'0'")
@SQLDeleted
@SQLComment("When delete, they are not removed, they are just set in a deleted state")
public Boolean deleted = null;
@SQLNotRead
@CreationTimestamp
@Column(nullable = false)
@SQLComment("Create time of the object")

View File

@ -0,0 +1,17 @@
package org.kar.archidata.model;
import org.kar.archidata.annotation.SQLComment;
import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLDeleted;
import org.kar.archidata.annotation.SQLNotRead;
import jakarta.persistence.Column;
public class GenericDataSoftDelete extends GenericData {
@SQLNotRead
@Column(nullable = false)
@SQLDefault("'0'")
@SQLDeleted
@SQLComment("When delete, they are not removed, they are just set in a deleted state")
public Boolean deleted = null;
}

View File

@ -1,31 +0,0 @@
package org.kar.archidata.model;
import java.sql.Timestamp;
import org.kar.archidata.annotation.CreationTimestamp;
import org.kar.archidata.annotation.SQLComment;
import org.kar.archidata.annotation.SQLNotRead;
import org.kar.archidata.annotation.UpdateTimestamp;
import jakarta.persistence.Column;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
public class GenericTableHardDelete {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false, unique = true)
@SQLComment("Primary key of the base")
public Long id = null;
@SQLNotRead
@CreationTimestamp
@Column(nullable = false)
@SQLComment("Create time of the object")
public Timestamp createdAt = null;
@SQLNotRead
@UpdateTimestamp
@Column(nullable = false)
@SQLComment("When update the object")
public Timestamp updatedAt = null;
}

View File

@ -12,7 +12,7 @@ import jakarta.persistence.Table;
@Table(name = "applicationToken")
@SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL)
public class GenericToken extends GenericTable {
public class GenericToken extends GenericDataSoftDelete {
@Column(nullable = false)
public Long parentId;
@Column(nullable = false)

View File

@ -1,6 +1,6 @@
package org.kar.archidata.model;
public class Migration extends GenericTable {
public class Migration extends GenericDataSoftDelete {
public String migrationId;
}

View File

@ -30,7 +30,7 @@ import jakarta.persistence.Table;
@Table(name = "user")
@SQLIfNotExists
@JsonInclude(JsonInclude.Include.NON_NULL)
public class User extends GenericTable {
public class User extends GenericDataSoftDelete {
@Column(length = 128)
public String login = null;
@ -50,7 +50,7 @@ public class User extends GenericTable {
@Override
public String toString() {
return "User [login=" + this.login + ", last=" + this.lastConnection + ", admin=" + this.admin + "]";
return "User [login=" + login + ", last=" + lastConnection + ", admin=" + admin + "]";
}
}

View File

@ -4,6 +4,9 @@ import java.util.HashMap;
import java.util.Map;
public class QuerryOptions {
public static final String SQL_NOT_READ_DISABLE = "SQLNotRead_disable";
public static final String SQL_DELETED_DISABLE = "SQLDeleted_disable";
private final Map<String, Object> options = new HashMap<>();
public QuerryOptions() {
@ -11,25 +14,26 @@ public class QuerryOptions {
}
public QuerryOptions(String key, Object value) {
options.put(key, value);
this.options.put(key, value);
}
public QuerryOptions(String key, Object value, String key2, Object value2) {
options.put(key, value);
options.put(key2, value2);
this.options.put(key, value);
this.options.put(key2, value2);
}
public QuerryOptions(String key, Object value, String key2, Object value2, String key3, Object value3) {
options.put(key, value);
options.put(key2, value2);
options.put(key3, value3);
this.options.put(key, value);
this.options.put(key2, value2);
this.options.put(key3, value3);
}
public void put(String key, Object value) {
options.put(key, value);
this.options.put(key, value);
}
public Object get(String value) {
return options.get(value);
return this.options.get(value);
}
}

View File

@ -20,9 +20,7 @@ import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.annotation.CreationTimestamp;
import org.kar.archidata.annotation.DataAddOn;
import org.kar.archidata.annotation.SQLDefault;
import org.kar.archidata.annotation.SQLDeleted;
import org.kar.archidata.annotation.SQLIfNotExists;
import org.kar.archidata.annotation.SQLNotRead;
import org.kar.archidata.annotation.UpdateTimestamp;
import org.kar.archidata.db.DBEntry;
import org.kar.archidata.sqlWrapper.addOn.AddOnManyToMany;
@ -52,7 +50,7 @@ public class SqlWrapper {
public static void addAddOn(final SqlWrapperAddOn addOn) {
SqlWrapper.addOn.add(addOn);
};
}
public static class ExceptionDBInterface extends Exception {
private static final long serialVersionUID = 1L;
@ -69,7 +67,7 @@ public class SqlWrapper {
}
public static boolean isDBExist(final String name) throws InternalServerErrorException {
if (ConfigBaseVariable.getDBType().equals("sqlite")) {
if ("sqlite".equals(ConfigBaseVariable.getDBType())) {
// no base manage in sqLite ...
// TODO: check if the file exist or not ...
return true;
@ -111,18 +109,14 @@ public class SqlWrapper {
}
public static boolean createDB(final String name) {
if (ConfigBaseVariable.getDBType().equals("sqlite")) {
if ("sqlite".equals(ConfigBaseVariable.getDBType())) {
// no base manage in sqLite ...
// TODO: check if the file exist or not ...
return true;
}
try {
return 1 == SqlWrapper.executeSimpleQuerry("CREATE DATABASE `" + name + "`;", true);
} catch (final SQLException ex) {
ex.printStackTrace();
LOGGER.error("Can not check if the DB exist!!! {}", ex.getMessage());
return false;
} catch (final IOException ex) {
} catch (final SQLException | IOException ex) {
ex.printStackTrace();
LOGGER.error("Can not check if the DB exist!!! {}", ex.getMessage());
return false;
@ -132,7 +126,7 @@ public class SqlWrapper {
public static boolean isTableExist(final String name) throws InternalServerErrorException {
try {
String request = "";
if (ConfigBaseVariable.getDBType().equals("sqlite")) {
if ("sqlite".equals(ConfigBaseVariable.getDBType())) {
request = """
SELECT COUNT(*) AS total
FROM sqlite_master
@ -191,7 +185,7 @@ public class SqlWrapper {
}
public static String convertTypeInSQL(final Class<?> type) throws Exception {
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
if (type == Long.class || type == long.class) {
return "bigint";
}
@ -430,7 +424,7 @@ public class SqlWrapper {
public static boolean isAddOnField(final Field field) {
boolean ret = AnnotationTools.isAnnotationGroup(field, DataAddOn.class);
if (ret == true) {
if (ret) {
return true;
}
// The specific element of the JPA manage fy generic add-on system:
@ -728,9 +722,7 @@ public class SqlWrapper {
}
}
ps.setLong(iii++, id);
// execute the request
final int affectedRows = ps.executeUpdate();
return affectedRows;
return ps.executeUpdate();
} catch (final SQLException ex) {
ex.printStackTrace();
} finally {
@ -768,24 +760,27 @@ public class SqlWrapper {
}
}
public static void whereAppendQuery(final StringBuilder querry, final String tableName, final QuerryItem condition, final QuerryOptions options) throws ExceptionDBInterface {
public static void whereAppendQuery(final StringBuilder querry, final String tableName, final QuerryItem condition, final QuerryOptions options, String deletedFieldName)
throws ExceptionDBInterface {
boolean exclude_deleted = true;
if (options != null) {
Object data = options.get("SQLDeleted_disable");
Object data = options.get(QuerryOptions.SQL_DELETED_DISABLE);
if (data instanceof Boolean elem) {
exclude_deleted = !(elem == true);
exclude_deleted = !elem;
} else {
if (data != null) {
LOGGER.error("'SQLDeleted_disable' ==> has not a boolean value: {}", data);
LOGGER.error("'{}' ==> has not a boolean value: {}", QuerryOptions.SQL_DELETED_DISABLE, data);
}
}
}
// Check if we have a condition to generate
if (condition == null) {
if (exclude_deleted) {
if (exclude_deleted && deletedFieldName != null) {
querry.append(" WHERE ");
querry.append(tableName);
querry.append(".deleted = false ");
querry.append(".");
querry.append(deletedFieldName);
querry.append(" = false ");
}
return;
}
@ -793,10 +788,12 @@ public class SqlWrapper {
condition.generateQuerry(querry, tableName);
querry.append(") ");
if (exclude_deleted) {
if (exclude_deleted && deletedFieldName != null) {
querry.append("AND ");
querry.append(tableName);
querry.append(".deleted = false ");
querry.append(".");
querry.append(deletedFieldName);
querry.append(" = false ");
}
}
@ -859,12 +856,12 @@ public class SqlWrapper {
boolean readAllfields = false;
if (options != null) {
Object data = options.get("SQLNotRead_disable");
Object data = options.get(QuerryOptions.SQL_NOT_READ_DISABLE);
if (data instanceof Boolean elem) {
readAllfields = elem;
} else {
if (data != null) {
LOGGER.error("'SQLNotRead_disable' ==> has not a boolean value: {}", data);
LOGGER.error("'{}' ==> has not a boolean value: {}", QuerryOptions.SQL_NOT_READ_DISABLE, data);
}
}
}
@ -882,7 +879,7 @@ public class SqlWrapper {
boolean firstField = true;
int count = 0;
boolean hasDeleted = false;
final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
for (final Field elem : clazz.getFields()) {
// static field is only for internal global declaration ==> remove it ..
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
@ -893,13 +890,10 @@ public class SqlWrapper {
continue;
}
// TODO: Manage it with AddOn
final boolean notRead = elem.getDeclaredAnnotationsByType(SQLNotRead.class).length != 0;
final boolean notRead = AnnotationTools.isdefaultNotRead(elem);
if (!readAllfields && notRead) {
continue;
}
if (!hasDeleted) {
hasDeleted = elem.getDeclaredAnnotationsByType(SQLDeleted.class).length != 0;
}
final String name = AnnotationTools.getFieldName(elem);
count++;
if (firstField) {
@ -919,7 +913,7 @@ public class SqlWrapper {
querry.append(" FROM `");
querry.append(tableName);
querry.append("` ");
whereAppendQuery(querry, tableName, condition, options);
whereAppendQuery(querry, tableName, condition, options, deletedFieldName);
if (orderBy != null && orderBy.length() >= 1) {
querry.append(" ORDER BY ");
//querry.append(tableName);
@ -937,6 +931,7 @@ public class SqlWrapper {
// execute the request
final ResultSet rs = ps.executeQuery();
while (rs.next()) {
// TODO: manage class that is defined inside a class ==> Not manage for now...
final Object data = clazz.getConstructors()[0].newInstance();
count = 1;
for (final Field elem : clazz.getFields()) {
@ -949,7 +944,7 @@ public class SqlWrapper {
continue;
}
// TODO: Manage it with AddOn
final boolean notRead = elem.getDeclaredAnnotationsByType(SQLNotRead.class).length != 0;
final boolean notRead = AnnotationTools.isdefaultNotRead(elem);
if (!readAllfields && notRead) {
continue;
}
@ -979,6 +974,10 @@ public class SqlWrapper {
// TODO : detect the @Id
public static <T> T get(final Class<T> clazz, final long id) throws Exception {
return get(clazz, id, null);
}
public static <T> T get(final Class<T> clazz, final long id, final QuerryOptions options) throws Exception {
Field primaryKeyField = null;
for (final Field elem : clazz.getFields()) {
// static field is only for internal global declaration ==> remove it ..
@ -990,7 +989,7 @@ public class SqlWrapper {
}
}
if (primaryKeyField != null) {
return SqlWrapper.getWhere(clazz, new QuerryCondition(AnnotationTools.getFieldName(primaryKeyField), "=", id));
return SqlWrapper.getWhere(clazz, new QuerryCondition(AnnotationTools.getFieldName(primaryKeyField), "=", id), options);
}
throw new Exception("Missing primary Key...");
}
@ -1007,64 +1006,95 @@ public class SqlWrapper {
return getsWhere(clazz, null, options);
}
public static boolean hasDeletedField(final Class<?> clazz) throws Exception {
try {
boolean hasDeleted = false;
for (final Field elem : clazz.getFields()) {
// static field is only for internal global declaration ==> remove it ..
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
continue;
}
if (elem.getDeclaredAnnotationsByType(SQLDeleted.class).length != 0) {
return true;
}
}
} catch (final Exception ex) {
ex.printStackTrace();
}
return false;
}
// TODO : detect the @Id
public static void delete(final Class<?> clazz, final long id) throws Exception {
boolean hasDeleted = hasDeletedField(clazz);
if (hasDeleted == true) {
deleteSoft(clazz, id);
public static int delete(final Class<?> clazz, final long id) throws Exception {
String hasDeletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
if (hasDeletedFieldName != null) {
return deleteSoft(clazz, id);
} else {
deleteHard(clazz, id);
return deleteHard(clazz, id);
}
}
public static void deleteHard(final Class<?> clazz, final long id) throws Exception {
throw new Exception("Not implemented delete hard ...");
public static int delete(final Class<?> clazz, final QuerryItem condition) throws Exception {
String hasDeletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
if (hasDeletedFieldName != null) {
return deleteSoftWhere(clazz, condition);
} else {
return deleteHardWhere(clazz, condition);
}
}
public static int deleteHard(final Class<?> clazz, final long id) throws Exception {
return deleteHardWhere(clazz, new QuerryCondition("id", "=", id));
}
public static int deleteHardWhere(final Class<?> clazz, final QuerryItem condition) throws Exception {
final String tableName = AnnotationTools.getTableName(clazz);
final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
// find the deleted field
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
final StringBuilder querry = new StringBuilder();
querry.append("DELETE FROM `");
querry.append(tableName);
querry.append("` ");
whereAppendQuery(querry, tableName, condition, null, deletedFieldName);
try {
LOGGER.debug("APPLY: {}", querry.toString());
final PreparedStatement ps = entry.connection.prepareStatement(querry.toString());
whereInjectValue(ps, condition);
return ps.executeUpdate();
} finally {
entry.close();
entry = null;
}
}
private static int deleteSoft(final Class<?> clazz, final long id) throws Exception {
return setDeleteWhere(clazz, new QuerryCondition("id", "=", id));
return deleteSoftWhere(clazz, new QuerryCondition("id", "=", id));
}
public static String getDBNow() {
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
return "now(3)";
}
return "DATE()";
}
public static int setDeleteWhere(final Class<?> clazz, final QuerryItem condition) throws Exception {
public static int deleteSoftWhere(final Class<?> clazz, final QuerryItem condition) throws Exception {
final String tableName = AnnotationTools.getTableName(clazz);
final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
/*
String updateFieldName = null;
if ("sqlite".equalsIgnoreCase(ConfigBaseVariable.getDBType())) {
updateFieldName = AnnotationTools.getUpdatedFieldName(clazz);
}
*/
// find the deleted field
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
final StringBuilder querry = new StringBuilder();
querry.append("UPDATE `");
querry.append(tableName);
querry.append("` SET `modify_date`=");
querry.append(getDBNow());
querry.append(", `deleted`=true ");
whereAppendQuery(querry, tableName, condition, null);
querry.append("` SET `");
querry.append(deletedFieldName);
querry.append("`=true ");
/*
* The trigger work well, but the timestamp is store @ seconds...
if (updateFieldName != null) {
// done only in SQLite (the trigger does not work...
querry.append(", `");
querry.append(updateFieldName);
querry.append("`=DATE()");
}
*/
whereAppendQuery(querry, tableName, condition, null, deletedFieldName);
try {
LOGGER.debug("APPLY UPDATE: {}", querry.toString());
final PreparedStatement ps = entry.connection.prepareStatement(querry.toString());
whereInjectValue(ps, condition);
final int affectedRows = ps.executeUpdate();
return affectedRows;
return ps.executeUpdate();
} finally {
entry.close();
entry = null;
@ -1077,26 +1107,30 @@ public class SqlWrapper {
public static int unsetDeleteWhere(final Class<?> clazz, final QuerryItem condition) throws Exception {
final String tableName = AnnotationTools.getTableName(clazz);
final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
if (deletedFieldName == null) {
throw new Exception("The class " + clazz.getCanonicalName() + " has no deleted field");
}
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
final StringBuilder querry = new StringBuilder();
querry.append("UPDATE `");
querry.append(tableName);
querry.append("` SET ");
querry.append("` SET `");
querry.append(deletedFieldName);
querry.append("`=false ");
/*
* is is needed only for SQLite ???
querry.append("`modify_date`=");
querry.append(getDBNow());
querry.append(", ");
*/
querry.append("`deleted`=false ");
// need to disable the deleted false because the model must be unselected to be updated.
QuerryOptions options = new QuerryOptions("SQLDeleted_disable", true);
whereAppendQuery(querry, tableName, condition, options);
QuerryOptions options = new QuerryOptions(QuerryOptions.SQL_DELETED_DISABLE, true);
whereAppendQuery(querry, tableName, condition, options, deletedFieldName);
try {
final PreparedStatement ps = entry.connection.prepareStatement(querry.toString());
whereInjectValue(ps, condition);
final int affectedRows = ps.executeUpdate();
return affectedRows;
return ps.executeUpdate();
} finally {
entry.close();
entry = null;
@ -1107,6 +1141,26 @@ public class SqlWrapper {
return createTable(clazz, true);
}
private static boolean isFieldFromSuperClass(Class<?> model, String filedName) {
Class<?> superClass = model.getSuperclass();
if (superClass == null) {
return false;
}
for (Field field : superClass.getFields()) {
String name;
try {
name = AnnotationTools.getFieldName(field);
if (filedName.equals(name)) {
return true;
}
} catch (Exception e) {
// TODO Auto-generated catch block
LOGGER.trace("Catch error field name in parent create data table: {}", e.getMessage());
}
}
return false;
}
public static void createTablesSpecificType(final String tableName, final Field elem, final StringBuilder mainTableBuilder, final List<String> preOtherTables, final List<String> postOtherTables,
final boolean createIfNotExist, final boolean createDrop, final int fieldId, final Class<?> classModel) throws Exception {
final String name = AnnotationTools.getFieldName(elem);
@ -1130,14 +1184,14 @@ public class SqlWrapper {
mainTableBuilder.append("` ");
String typeValue = null;
typeValue = convertTypeInSQL(classModel);
if (typeValue.equals("text") && !ConfigBaseVariable.getDBType().equals("sqlite")) {
if ("text".equals(typeValue) && !"sqlite".equals(ConfigBaseVariable.getDBType())) {
if (limitSize != null) {
mainTableBuilder.append("varchar(");
mainTableBuilder.append(limitSize);
mainTableBuilder.append(")");
} else {
mainTableBuilder.append("text");
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
mainTableBuilder.append(" CHARACTER SET utf8");
}
}
@ -1146,19 +1200,19 @@ public class SqlWrapper {
}
mainTableBuilder.append(" ");
if (notNull) {
if (!primaryKey || !ConfigBaseVariable.getDBType().equals("sqlite")) {
if (!primaryKey || !"sqlite".equalsIgnoreCase(ConfigBaseVariable.getDBType())) {
mainTableBuilder.append("NOT NULL ");
}
if (defaultValue == null) {
if (updateTime || createTime) {
mainTableBuilder.append("DEFAULT CURRENT_TIMESTAMP");
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
mainTableBuilder.append("(3)");
}
mainTableBuilder.append(" ");
}
if (updateTime) {
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
mainTableBuilder.append("ON UPDATE CURRENT_TIMESTAMP");
mainTableBuilder.append("(3)");
} else {
@ -1188,14 +1242,14 @@ public class SqlWrapper {
}
} else {
mainTableBuilder.append("DEFAULT ");
if ("CURRENT_TIMESTAMP(3)".equals(defaultValue) && ConfigBaseVariable.getDBType().equals("sqlite")) {
if ("CURRENT_TIMESTAMP(3)".equals(defaultValue) && "sqlite".equals(ConfigBaseVariable.getDBType())) {
mainTableBuilder.append("CURRENT_TIMESTAMP");
} else {
mainTableBuilder.append(defaultValue);
}
mainTableBuilder.append(" ");
if (updateTime) {
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
mainTableBuilder.append("ON UPDATE CURRENT_TIMESTAMP");
mainTableBuilder.append("(3)");
}
@ -1204,7 +1258,7 @@ public class SqlWrapper {
}
} else if (defaultValue == null) {
if (updateTime || createTime) {
if (ConfigBaseVariable.getDBType().equals("sqlite")) {
if ("sqlite".equals(ConfigBaseVariable.getDBType())) {
mainTableBuilder.append("DEFAULT CURRENT_TIMESTAMP ");
} else {
mainTableBuilder.append("DEFAULT CURRENT_TIMESTAMP(3) ");
@ -1220,12 +1274,12 @@ public class SqlWrapper {
mainTableBuilder.append(" ");
}
if (primaryKey && ConfigBaseVariable.getDBType().equals("sqlite")) {
if (primaryKey && "sqlite".equals(ConfigBaseVariable.getDBType())) {
mainTableBuilder.append("PRIMARY KEY ");
}
if (strategy == GenerationType.IDENTITY) {
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
mainTableBuilder.append("AUTO_INCREMENT ");
} else {
mainTableBuilder.append("AUTOINCREMENT ");
@ -1234,7 +1288,7 @@ public class SqlWrapper {
throw new Exception("Can not generate a stategy different of IDENTITY");
}
if (comment != null && !ConfigBaseVariable.getDBType().equals("sqlite")) {
if (comment != null && !"sqlite".equals(ConfigBaseVariable.getDBType())) {
mainTableBuilder.append("COMMENT '");
mainTableBuilder.append(comment.replace('\'', '\''));
mainTableBuilder.append("' ");
@ -1269,27 +1323,62 @@ public class SqlWrapper {
primaryKeys.add(AnnotationTools.getFieldName(elem));
}
}
for (final Field elem : clazz.getFields()) {
// static field is only for internal global declaration ==> remove it ..
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
continue;
}
if (isAddOnField(elem)) {
final SqlWrapperAddOn addOn = findAddOnforField(elem);
LOGGER.info("Create type for: {} ==> {} (ADD-ON)", AnnotationTools.getFieldName(elem), elem.getType());
if (addOn != null) {
addOn.createTables(tableName, elem, out, preActionList, postActionList, createIfNotExist, createDrop, fieldId);
} else {
throw new Exception("Element matked as add-on but add-on does not loaded: table:" + tableName + " field name=" + AnnotationTools.getFieldName(elem) + " type=" + elem.getType());
// Here we insert the data in the reverse mode ==> the parent class add there parameter at the start (we reorder the field with the parenting).
StringBuilder tmpOut = new StringBuilder();
StringBuilder reverseOut = new StringBuilder();
List<String> alreadyAdded = new ArrayList<>();
Class<?> currentClazz = clazz;
while (currentClazz != null) {
fieldId = 0;
LOGGER.info("parse class: '{}'", currentClazz.getCanonicalName());
for (final Field elem : clazz.getFields()) {
// static field is only for internal global declaration ==> remove it ..
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
continue;
}
} else {
LOGGER.info("Create type for: {} ==> {}", AnnotationTools.getFieldName(elem), elem.getType());
SqlWrapper.createTablesSpecificType(tableName, elem, out, preActionList, postActionList, createIfNotExist, createDrop, fieldId, elem.getType());
final String dataName = AnnotationTools.getFieldName(elem);
if (isFieldFromSuperClass(currentClazz, dataName)) {
LOGGER.trace(" SKIP: '{}'", elem.getName());
continue;
}
if (alreadyAdded.contains(dataName)) {
LOGGER.trace(" SKIP2: '{}'", elem.getName());
continue;
}
alreadyAdded.add(dataName);
LOGGER.info(" + '{}'", elem.getName());
if (isAddOnField(elem)) {
final SqlWrapperAddOn addOn = findAddOnforField(elem);
LOGGER.info("Create type for: {} ==> {} (ADD-ON)", AnnotationTools.getFieldName(elem), elem.getType());
if (addOn != null) {
addOn.createTables(tableName, elem, tmpOut, preActionList, postActionList, createIfNotExist, createDrop, fieldId);
} else {
throw new Exception(
"Element matked as add-on but add-on does not loaded: table:" + tableName + " field name=" + AnnotationTools.getFieldName(elem) + " type=" + elem.getType());
}
} else {
LOGGER.info("Create type for: {} ==> {}", AnnotationTools.getFieldName(elem), elem.getType());
SqlWrapper.createTablesSpecificType(tableName, elem, tmpOut, preActionList, postActionList, createIfNotExist, createDrop, fieldId, elem.getType());
}
fieldId++;
}
boolean dataInThisObject = tmpOut.toString().length() > 0;
if (dataInThisObject) {
boolean dataInPreviousObject = reverseOut.toString().length() > 0;
if (dataInPreviousObject) {
tmpOut.append(", ");
tmpOut.append(reverseOut.toString());
}
reverseOut = tmpOut;
tmpOut = new StringBuilder();
}
currentClazz = currentClazz.getSuperclass();
if (currentClazz == Object.class) {
break;
}
fieldId++;
}
if (primaryKeys.size() != 0 && !ConfigBaseVariable.getDBType().equals("sqlite")) {
out.append(reverseOut.toString());
if (primaryKeys.size() != 0 && !"sqlite".equals(ConfigBaseVariable.getDBType())) {
out.append(",\n\tPRIMARY KEY (`");
for (int iii = 0; iii < primaryKeys.size(); iii++) {
if (iii != 0) {
@ -1300,7 +1389,7 @@ public class SqlWrapper {
out.append("`)");
}
out.append("\n\t)");
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
if (!"sqlite".equals(ConfigBaseVariable.getDBType())) {
out.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci");
}
out.append(";");

View File

@ -0,0 +1,35 @@
# SLF4J's SimpleLogger configuration file
# Simple implementation of Logger that sends all enabled log messages, for all defined loggers, to System.err.
# Default logging detail level for all instances of SimpleLogger.
# Must be one of ("trace", "debug", "info", "warn", or "error").
# If not specified, defaults to "info".
org.slf4j.simpleLogger.defaultLogLevel=debug
# Logging detail level for a SimpleLogger instance named "xxxxx".
# Must be one of ("trace", "debug", "info", "warn", or "error").
# If not specified, the default logging detail level is used.
#org.slf4j.simpleLogger.log.xxxxx=
# Set to true if you want the current date and time to be included in output messages.
# Default is false, and will output the number of milliseconds elapsed since startup.
#org.slf4j.simpleLogger.showDateTime=false
# The date and time format to be used in the output messages.
# The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat.
# If the format is not specified or is invalid, the default format is used.
# The default format is yyyy-MM-dd HH:mm:ss:SSS Z.
#org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z
# Set to true if you want to output the current thread name.
# Defaults to true.
org.slf4j.simpleLogger.showThreadName=true
# Set to true if you want the Logger instance name to be included in output messages.
# Defaults to true.
#org.slf4j.simpleLogger.showLogName=true
# Set to true if you want the last component of the name to be included in output messages.
# Defaults to false.
#org.slf4j.simpleLogger.showShortLogName=false

View File

@ -1,51 +0,0 @@
package test.kar.archidata;
import java.io.IOException;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.kar.archidata.db.DBEntry;
import org.kar.archidata.util.ConfigBaseVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TestBase {
final static private Logger LOGGER = LoggerFactory.getLogger(TestBase.class);
@BeforeAll
public static void configureWebServer() throws Exception {
/*LOGGER.info("Create DB");
final String dbName = "sdfsdfsdfsfsdfsfsfsfsdfsdfsd";
boolean data = SqlWrapper.isDBExist(dbName);
LOGGER.error("exist: {}", data);
data = SqlWrapper.createDB(dbName);
LOGGER.error("create: {}", data);
data = SqlWrapper.isDBExist(dbName);
LOGGER.error("exist: {}", data);
*/
ConfigBaseVariable.dbType = "sqlite";
ConfigBaseVariable.dbHost = "memory";
// for test we need to connect all time the DB
ConfigBaseVariable.dbKeepConnected = "true";
}
@AfterAll
public static void removeDataBase() throws IOException {
LOGGER.info("Remove the test db");
DBEntry.closeAllForceMode();
ConfigBaseVariable.clearAllValue();
}
@Order(1)
@Test
public void checkSimpleTestError() throws Exception {
Assertions.assertEquals("lkjlkjlkjlk", "alive and kicking");
}
}

View File

@ -0,0 +1,156 @@
package test.kar.archidata;
import java.io.IOException;
import java.sql.Timestamp;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.kar.archidata.GlobalConfiguration;
import org.kar.archidata.db.DBEntry;
import org.kar.archidata.sqlWrapper.QuerryOptions;
import org.kar.archidata.sqlWrapper.SqlWrapper;
import org.kar.archidata.util.ConfigBaseVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import test.kar.archidata.model.SimpleTable;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TestSimpleTable {
final static private Logger LOGGER = LoggerFactory.getLogger(TestSimpleTable.class);
private static final String DATA_INJECTED = "kjhlkjhlkjghlmkkjhlkjhlkjghlmkqsmlfuqùaẑjfQZLSKNEFDÙQMSLDKFJQÙLSNEKRFÙZQOSEdinkqùsldkfnqÙSDKFQJÙMSDKFLkjhlkjhlkjghlmkqsmlfuqùaẑjfQZLSKNEFDÙQMSLDKFJQÙLSNEKRFÙZQOSEdinkqùsldkfnqÙSDKFQJÙMSDKFLkjhlkjhlkjghlmkqsmlfuqùaẑjfQZLSKNEFDÙQMSLDKFJQÙLSNEKRFÙZQOSEdinkqùsldkfnqÙSDKFQJÙMSDKFLkjhlkjhlkjghlmkqsmlfuqùaẑjfQZLSKNEFDÙQMSLDKFJQÙLSNEKRFÙZQOSEdinkqùsldkfnqÙSDKFQJÙMSDKFLqsmlfuqùaẑjfQZLSKNEFDÙQMSLDKFJQÙLSNEKRFÙZQOSEdinkqùsldkfnqÙSDKFQJÙMSDKFL";
private static final String DATA_INJECTED_2 = "dsqfsdfqsdfsqdf";
private static Long idOfTheObject = null;
private static Timestamp startAction = null;
@BeforeAll
public static void configureWebServer() throws Exception {
ConfigBaseVariable.dbType = "sqlite";
ConfigBaseVariable.dbHost = "memory";
// for test we need to connect all time the DB
ConfigBaseVariable.dbKeepConnected = "true";
// Clear the static test:
idOfTheObject = null;
startAction = null;
// Connect the dataBase...
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
entry.connect();
}
@AfterAll
public static void removeDataBase() throws IOException {
LOGGER.info("Remove the test db");
DBEntry.closeAllForceMode();
ConfigBaseVariable.clearAllValue();
}
@Order(1)
@Test
public void testTableInsertAndRetrieve() throws Exception {
TestSimpleTable.startAction = Timestamp.from(Instant.now());
List<String> sqlCommand = SqlWrapper.createTable(SimpleTable.class);
for (String elem : sqlCommand) {
LOGGER.debug("request: '{}'", elem);
SqlWrapper.executeSimpleQuerry(elem, false);
}
SimpleTable test = new SimpleTable();
test.data = TestSimpleTable.DATA_INJECTED;
SimpleTable insertedData = SqlWrapper.insert(test);
Assertions.assertNotNull(insertedData);
Assertions.assertNotNull(insertedData.id);
Assertions.assertTrue(insertedData.id >= 0);
// Try to retrieve all the data:
SimpleTable retrieve = SqlWrapper.get(SimpleTable.class, insertedData.id);
Assertions.assertNotNull(retrieve);
Assertions.assertNotNull(retrieve.id);
Assertions.assertEquals(insertedData.id, retrieve.id);
Assertions.assertEquals(TestSimpleTable.DATA_INJECTED, retrieve.data);
Assertions.assertNull(retrieve.createdAt);
Assertions.assertNull(retrieve.updatedAt);
TestSimpleTable.idOfTheObject = retrieve.id;
}
@Order(2)
@Test
public void testReadAllValuesUnreadable() throws Exception {
// check the full values
SimpleTable retrieve = SqlWrapper.get(SimpleTable.class, TestSimpleTable.idOfTheObject, new QuerryOptions(QuerryOptions.SQL_NOT_READ_DISABLE, true));
Assertions.assertNotNull(retrieve);
Assertions.assertNotNull(retrieve.id);
Assertions.assertEquals(TestSimpleTable.idOfTheObject, retrieve.id);
Assertions.assertEquals(TestSimpleTable.DATA_INJECTED, retrieve.data);
Assertions.assertNotNull(retrieve.createdAt);
LOGGER.info("start @ {} create @ {}", retrieve.createdAt.toInstant(), TestSimpleTable.startAction.toInstant());
// Gros travail sur les timestamp a faire pour que ce soit correct ...
// Assertions.assertTrue(retrieve.createdAt.after(this.startAction));
Assertions.assertNotNull(retrieve.updatedAt);
// Assertions.assertTrue(retrieve.updatedAt.after(this.startAction));
Assertions.assertEquals(retrieve.createdAt, retrieve.updatedAt);
}
@Order(3)
@Test
public void testUpdateData() throws Exception {
if ("sqlite".equalsIgnoreCase(ConfigBaseVariable.getDBType())) {
Thread.sleep(Duration.ofMillis(1100));
} else {
Thread.sleep(Duration.ofMillis(15));
}
// Delete the entry:
SimpleTable test = new SimpleTable();
test.data = TestSimpleTable.DATA_INJECTED_2;
SqlWrapper.update(test, TestSimpleTable.idOfTheObject, List.of("data"));
SimpleTable retrieve = SqlWrapper.get(SimpleTable.class, TestSimpleTable.idOfTheObject, new QuerryOptions(QuerryOptions.SQL_NOT_READ_DISABLE, true));
Assertions.assertNotNull(retrieve);
Assertions.assertNotNull(retrieve.id);
Assertions.assertEquals(TestSimpleTable.idOfTheObject, retrieve.id);
Assertions.assertEquals(TestSimpleTable.DATA_INJECTED_2, retrieve.data);
Assertions.assertNotNull(retrieve.createdAt);
Assertions.assertNotNull(retrieve.updatedAt);
LOGGER.info("created @ {} updated @ {}", retrieve.createdAt, retrieve.updatedAt);
Assertions.assertTrue(retrieve.updatedAt.after(retrieve.createdAt));
}
@Order(4)
@Test
public void testDeleteTheObject() throws Exception {
// Delete the entry:
SqlWrapper.delete(SimpleTable.class, TestSimpleTable.idOfTheObject);
SimpleTable retrieve = SqlWrapper.get(SimpleTable.class, TestSimpleTable.idOfTheObject);
Assertions.assertNull(retrieve);
}
@Order(5)
@Test
public void testReadDeletedObject() throws Exception {
// check if we set get deleted element
SimpleTable retrieve = SqlWrapper.get(SimpleTable.class, TestSimpleTable.idOfTheObject, new QuerryOptions(QuerryOptions.SQL_DELETED_DISABLE, true));
Assertions.assertNull(retrieve);
}
@Order(6)
@Test
public void testReadAllValuesUnreadableOfDeletedObject() throws Exception {
// check if we set get deleted element with all data
SimpleTable retrieve = SqlWrapper.get(SimpleTable.class, TestSimpleTable.idOfTheObject, new QuerryOptions(QuerryOptions.SQL_DELETED_DISABLE, true, QuerryOptions.SQL_NOT_READ_DISABLE, true));
Assertions.assertNull(retrieve);
}
}

View File

@ -0,0 +1,183 @@
package test.kar.archidata;
import java.io.IOException;
import java.sql.Timestamp;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.kar.archidata.GlobalConfiguration;
import org.kar.archidata.db.DBEntry;
import org.kar.archidata.sqlWrapper.QuerryOptions;
import org.kar.archidata.sqlWrapper.SqlWrapper;
import org.kar.archidata.util.ConfigBaseVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import test.kar.archidata.model.SimpleTableSoftDelete;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TestSimpleTableSoftDelete {
final static private Logger LOGGER = LoggerFactory.getLogger(TestSimpleTableSoftDelete.class);
private static final String DATA_INJECTED = "kjhlkjhlkjghlmkkjhlkjhlkjghlmkqsmlfuqùaẑjfQZLSKNEFDÙQMSLDKFJQÙLSNEKRFÙZQOSEdinkqùsldkfnqÙSDKFQJÙMSDKFLkjhlkjhlkjghlmkqsmlfuqùaẑjfQZLSKNEFDÙQMSLDKFJQÙLSNEKRFÙZQOSEdinkqùsldkfnqÙSDKFQJÙMSDKFLkjhlkjhlkjghlmkqsmlfuqùaẑjfQZLSKNEFDÙQMSLDKFJQÙLSNEKRFÙZQOSEdinkqùsldkfnqÙSDKFQJÙMSDKFLkjhlkjhlkjghlmkqsmlfuqùaẑjfQZLSKNEFDÙQMSLDKFJQÙLSNEKRFÙZQOSEdinkqùsldkfnqÙSDKFQJÙMSDKFLqsmlfuqùaẑjfQZLSKNEFDÙQMSLDKFJQÙLSNEKRFÙZQOSEdinkqùsldkfnqÙSDKFQJÙMSDKFL";
private static final String DATA_INJECTED_2 = "qsdfqsdfqsdfsqdf";
private static Long idOfTheObject = null;
private static Timestamp startAction = null;
@BeforeAll
public static void configureWebServer() throws Exception {
ConfigBaseVariable.dbType = "sqlite";
ConfigBaseVariable.dbHost = "memory";
// for test we need to connect all time the DB
ConfigBaseVariable.dbKeepConnected = "true";
// Clear the static test:
idOfTheObject = null;
startAction = null;
// Connect the dataBase...
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
entry.connect();
}
@AfterAll
public static void removeDataBase() throws IOException {
LOGGER.info("Remove the test db");
DBEntry.closeAllForceMode();
ConfigBaseVariable.clearAllValue();
}
@Order(1)
@Test
public void testTableInsertAndRetrieve() throws Exception {
TestSimpleTableSoftDelete.startAction = Timestamp.from(Instant.now());
List<String> sqlCommand = SqlWrapper.createTable(SimpleTableSoftDelete.class);
for (String elem : sqlCommand) {
LOGGER.debug("request: '{}'", elem);
SqlWrapper.executeSimpleQuerry(elem, false);
}
SimpleTableSoftDelete test = new SimpleTableSoftDelete();
test.data = TestSimpleTableSoftDelete.DATA_INJECTED;
SimpleTableSoftDelete insertedData = SqlWrapper.insert(test);
Assertions.assertNotNull(insertedData);
Assertions.assertNotNull(insertedData.id);
Assertions.assertTrue(insertedData.id >= 0);
// Try to retrieve all the data:
SimpleTableSoftDelete retrieve = SqlWrapper.get(SimpleTableSoftDelete.class, insertedData.id);
Assertions.assertNotNull(retrieve);
Assertions.assertNotNull(retrieve.id);
Assertions.assertEquals(insertedData.id, retrieve.id);
Assertions.assertEquals(TestSimpleTableSoftDelete.DATA_INJECTED, retrieve.data);
Assertions.assertNull(retrieve.createdAt);
Assertions.assertNull(retrieve.updatedAt);
Assertions.assertNull(retrieve.deleted);
TestSimpleTableSoftDelete.idOfTheObject = retrieve.id;
}
@Order(2)
@Test
public void testReadAllValuesUnreadable() throws Exception {
// check the full values
SimpleTableSoftDelete retrieve = SqlWrapper.get(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject, new QuerryOptions(QuerryOptions.SQL_NOT_READ_DISABLE, true));
Assertions.assertNotNull(retrieve);
Assertions.assertNotNull(retrieve.id);
Assertions.assertEquals(TestSimpleTableSoftDelete.idOfTheObject, retrieve.id);
Assertions.assertEquals(TestSimpleTableSoftDelete.DATA_INJECTED, retrieve.data);
Assertions.assertNotNull(retrieve.createdAt);
LOGGER.info("start @ {} create @ {}", retrieve.createdAt.toInstant(), TestSimpleTableSoftDelete.startAction.toInstant());
// Gros travail sur les timestamp a faire pour que ce soit correct ...
// Assertions.assertTrue(retrieve.createdAt.after(this.startAction));
Assertions.assertNotNull(retrieve.updatedAt);
// Assertions.assertTrue(retrieve.updatedAt.after(this.startAction));
Assertions.assertEquals(retrieve.createdAt, retrieve.updatedAt);
Assertions.assertNotNull(retrieve.deleted);
Assertions.assertEquals(false, retrieve.deleted);
}
@Order(3)
@Test
public void testUpdateData() throws Exception {
if ("sqlite".equalsIgnoreCase(ConfigBaseVariable.getDBType())) {
Thread.sleep(Duration.ofMillis(1100));
} else {
Thread.sleep(Duration.ofMillis(15));
}
// Delete the entry:
SimpleTableSoftDelete test = new SimpleTableSoftDelete();
test.data = TestSimpleTableSoftDelete.DATA_INJECTED_2;
SqlWrapper.update(test, TestSimpleTableSoftDelete.idOfTheObject, List.of("data"));
SimpleTableSoftDelete retrieve = SqlWrapper.get(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject,
new QuerryOptions(QuerryOptions.SQL_DELETED_DISABLE, true, QuerryOptions.SQL_NOT_READ_DISABLE, true));
Assertions.assertNotNull(retrieve);
Assertions.assertNotNull(retrieve.id);
Assertions.assertEquals(TestSimpleTableSoftDelete.idOfTheObject, retrieve.id);
Assertions.assertEquals(TestSimpleTableSoftDelete.DATA_INJECTED_2, retrieve.data);
Assertions.assertNotNull(retrieve.createdAt);
Assertions.assertNotNull(retrieve.updatedAt);
LOGGER.info("created @ {} updated @ {}", retrieve.createdAt, retrieve.updatedAt);
Assertions.assertTrue(retrieve.updatedAt.after(retrieve.createdAt));
Assertions.assertNotNull(retrieve.deleted);
Assertions.assertEquals(false, retrieve.deleted);
}
@Order(4)
@Test
public void testSoftDeleteTheObject() throws Exception {
if ("sqlite".equalsIgnoreCase(ConfigBaseVariable.getDBType())) {
Thread.sleep(Duration.ofMillis(1100));
} else {
Thread.sleep(Duration.ofMillis(15));
}
// Delete the entry:
SqlWrapper.delete(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject);
SimpleTableSoftDelete retrieve = SqlWrapper.get(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject);
Assertions.assertNull(retrieve);
}
@Order(5)
@Test
public void testReadDeletedObject() throws Exception {
// check if we set get deleted element
SimpleTableSoftDelete retrieve = SqlWrapper.get(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject, new QuerryOptions(QuerryOptions.SQL_DELETED_DISABLE, true));
Assertions.assertNotNull(retrieve);
Assertions.assertNotNull(retrieve.id);
Assertions.assertEquals(TestSimpleTableSoftDelete.idOfTheObject, retrieve.id);
Assertions.assertEquals(TestSimpleTableSoftDelete.DATA_INJECTED_2, retrieve.data);
Assertions.assertNull(retrieve.createdAt);
Assertions.assertNull(retrieve.updatedAt);
Assertions.assertNull(retrieve.deleted);
}
@Order(6)
@Test
public void testReadAllValuesUnreadableOfDeletedObject() throws Exception {
// check if we set get deleted element with all data
SimpleTableSoftDelete retrieve = SqlWrapper.get(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject,
new QuerryOptions(QuerryOptions.SQL_DELETED_DISABLE, true, QuerryOptions.SQL_NOT_READ_DISABLE, true));
Assertions.assertNotNull(retrieve);
Assertions.assertNotNull(retrieve.id);
Assertions.assertEquals(TestSimpleTableSoftDelete.idOfTheObject, retrieve.id);
Assertions.assertEquals(TestSimpleTableSoftDelete.DATA_INJECTED_2, retrieve.data);
Assertions.assertNotNull(retrieve.createdAt);
Assertions.assertNotNull(retrieve.updatedAt);
LOGGER.info("created @ {} updated @ {}", retrieve.createdAt, retrieve.updatedAt);
Assertions.assertTrue(retrieve.updatedAt.after(retrieve.createdAt));
Assertions.assertNotNull(retrieve.deleted);
Assertions.assertEquals(true, retrieve.deleted);
}
}

View File

@ -0,0 +1,7 @@
package test.kar.archidata.model;
import org.kar.archidata.model.GenericData;
public class SimpleTable extends GenericData {
public String data;
}

View File

@ -0,0 +1,7 @@
package test.kar.archidata.model;
import org.kar.archidata.model.GenericDataSoftDelete;
public class SimpleTableSoftDelete extends GenericDataSoftDelete {
public String data;
}