From a5f488b1b67c5cc060e8b4944534795d48282442 Mon Sep 17 00:00:00 2001 From: JanHolger Date: Sat, 6 Nov 2021 03:03:55 +0100 Subject: [PATCH 01/19] Incremented version to 1.0.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ea75398..3c4303b 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ 8 8 - 1.0.1-SNAPSHOT + 1.0.2-SNAPSHOT org.javawebstack From e3167235c0a2776ac0cc127a822c4f199cb799ac Mon Sep 17 00:00:00 2001 From: Julian Gojani Date: Mon, 8 Nov 2021 18:00:36 +0100 Subject: [PATCH 02/19] Update pom.xml --- pom.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pom.xml b/pom.xml index 3c4303b..91fc662 100644 --- a/pom.xml +++ b/pom.xml @@ -32,6 +32,18 @@ JavaWebStack https://javawebstack.org + + Timothy Gillespie + timothy@gillespie.eu + JavaWebStack + https://javawebstack.org + + + Julian Gojani + julian@gojani.xyz + JavaWebStack + https://javawebstack.org + From b2290a5f648ce32fedc0820f1abd405b5656fe75 Mon Sep 17 00:00:00 2001 From: x7airworker Date: Mon, 29 Nov 2021 15:54:56 +0100 Subject: [PATCH 03/19] Added parent class support for models. --- pom.xml | 2 +- .../java/org/javawebstack/orm/TableInfo.java | 16 +++++- .../javawebstack/orm/test/TableInfoTest.java | 51 +++++++++++++++++++ 3 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 src/test/java/org/javawebstack/orm/test/TableInfoTest.java diff --git a/pom.xml b/pom.xml index 91fc662..0f0278e 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ 8 8 - 1.0.2-SNAPSHOT + 1.0.3-SNAPSHOT org.javawebstack diff --git a/src/main/java/org/javawebstack/orm/TableInfo.java b/src/main/java/org/javawebstack/orm/TableInfo.java index d91750d..8fe4778 100644 --- a/src/main/java/org/javawebstack/orm/TableInfo.java +++ b/src/main/java/org/javawebstack/orm/TableInfo.java @@ -29,7 +29,7 @@ public class TableInfo { private final Class modelClass; private String primaryKey; private final List uniqueKeys = new ArrayList<>(); - private final Constructor constructor; + private Constructor constructor; private String relationField; private final Map filterable = new HashMap<>(); private final List searchable = new ArrayList<>(); @@ -42,6 +42,18 @@ public class TableInfo { public TableInfo(Class model, ORMConfig config) throws ORMConfigurationException { this.config = config; this.modelClass = model; + if (model.getSuperclass() != Model.class) { + Class superModel = (Class) model.getSuperclass(); + if (Modifier.isAbstract(superModel.getModifiers())) { + constructInfo(superModel); + } else { + throw new ORMConfigurationException("The parent model has to be abstract!"); + } + } + constructInfo(model); + } + + private void constructInfo (Class model) throws ORMConfigurationException { if (model.isAnnotationPresent(Table.class)) { Table table = model.getDeclaredAnnotationsByType(Table.class)[0]; tableName = table.value(); @@ -82,7 +94,7 @@ public TableInfo(Class model, ORMConfig config) throws ORMConfi else fieldSize = fieldConfig.size(); - SQLType sqlType = config.getType(field.getType(), fieldSize); + SQLType sqlType = config.getType(field.getType(), fieldSize); if (sqlType != null) { sqlTypes.put(fieldName, sqlType); sqlTypeParameters.put(fieldName, config.getTypeParameters(field.getType(), fieldSize)); diff --git a/src/test/java/org/javawebstack/orm/test/TableInfoTest.java b/src/test/java/org/javawebstack/orm/test/TableInfoTest.java new file mode 100644 index 0000000..9ef8ee3 --- /dev/null +++ b/src/test/java/org/javawebstack/orm/test/TableInfoTest.java @@ -0,0 +1,51 @@ +package org.javawebstack.orm.test; + +import org.javawebstack.orm.Model; +import org.javawebstack.orm.ORM; +import org.javawebstack.orm.ORMConfig; +import org.javawebstack.orm.Repo; +import org.javawebstack.orm.annotation.Column; +import org.javawebstack.orm.exception.ORMConfigurationException; +import org.javawebstack.orm.util.KeyType; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class TableInfoTest extends ORMTestCase { + @Test + public void testParentTableInfo () throws ORMConfigurationException { + ORMConfig config = new ORMConfig() + .setDefaultSize(255); + ORM.register(Child.class, sql(), config); + + assertEquals(Repo.get(Child.class).getInfo().getFields().size(), 2); + } + + @Test + public void testParentTableMigration () throws ORMConfigurationException { + ORMConfig config = new ORMConfig() + .setDefaultSize(255); + ORM.register(Child.class, sql(), config); + ORM.autoMigrate(true); + + Child child = new Child(); + child.id = 1337; + child.content = "Hello World!"; + child.save(); + + Child fetchedChild = Repo.get(Child.class).get(1337); + assertEquals(fetchedChild.id, child.id); + assertEquals(fetchedChild.content, child.content); + } + + + public static abstract class Parent extends Model { + @Column(ai = true, key = KeyType.PRIMARY) + public int id; + } + + public static class Child extends Parent { + @Column + public String content; + } +} From 1aabe508dc2c5035b2c766a4babe42464b756a6f Mon Sep 17 00:00:00 2001 From: x7airworker Date: Mon, 29 Nov 2021 20:52:00 +0100 Subject: [PATCH 04/19] Added test case for non-abstract parent --- .../javawebstack/orm/test/TableInfoTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/java/org/javawebstack/orm/test/TableInfoTest.java b/src/test/java/org/javawebstack/orm/test/TableInfoTest.java index 9ef8ee3..7ed94d2 100644 --- a/src/test/java/org/javawebstack/orm/test/TableInfoTest.java +++ b/src/test/java/org/javawebstack/orm/test/TableInfoTest.java @@ -38,6 +38,13 @@ public void testParentTableMigration () throws ORMConfigurationException { assertEquals(fetchedChild.content, child.content); } + @Test + public void testNonAbstractParent () throws ORMConfigurationException { + ORMConfig config = new ORMConfig() + .setDefaultSize(255); + + assertThrows(ORMConfigurationException.class, () -> ORM.register(SecondChild.class, sql(), config), "The parent model has to be abstract!"); + } public static abstract class Parent extends Model { @Column(ai = true, key = KeyType.PRIMARY) @@ -48,4 +55,14 @@ public static class Child extends Parent { @Column public String content; } + + public static class NonAbstractParent extends Model { + @Column(ai = true, key = KeyType.PRIMARY) + public int id; + } + + public static class SecondChild extends NonAbstractParent { + @Column + public String content; + } } From d9c3c2e962ebaf68a4d3253e4c655f209de46211 Mon Sep 17 00:00:00 2001 From: x7airworker Date: Tue, 30 Nov 2021 14:44:58 +0100 Subject: [PATCH 05/19] Added support for n amount of super classes --- pom.xml | 2 +- src/main/java/org/javawebstack/orm/TableInfo.java | 11 +++++++---- src/main/java/org/javawebstack/orm/util/Helper.java | 13 +++++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 0f0278e..91fc662 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ 8 8 - 1.0.3-SNAPSHOT + 1.0.2-SNAPSHOT org.javawebstack diff --git a/src/main/java/org/javawebstack/orm/TableInfo.java b/src/main/java/org/javawebstack/orm/TableInfo.java index 8fe4778..2924ae2 100644 --- a/src/main/java/org/javawebstack/orm/TableInfo.java +++ b/src/main/java/org/javawebstack/orm/TableInfo.java @@ -42,14 +42,17 @@ public class TableInfo { public TableInfo(Class model, ORMConfig config) throws ORMConfigurationException { this.config = config; this.modelClass = model; - if (model.getSuperclass() != Model.class) { - Class superModel = (Class) model.getSuperclass(); - if (Modifier.isAbstract(superModel.getModifiers())) { - constructInfo(superModel); + + Stack> superClasses = Helper.getSuperClassesTill(model, Model.class); + while (!superClasses.isEmpty()) { + Class superClass = (Class) superClasses.pop(); + if (Modifier.isAbstract(superClass.getModifiers())) { + constructInfo(superClass); } else { throw new ORMConfigurationException("The parent model has to be abstract!"); } } + constructInfo(model); } diff --git a/src/main/java/org/javawebstack/orm/util/Helper.java b/src/main/java/org/javawebstack/orm/util/Helper.java index 2aaa23c..7a4ee85 100644 --- a/src/main/java/org/javawebstack/orm/util/Helper.java +++ b/src/main/java/org/javawebstack/orm/util/Helper.java @@ -1,5 +1,7 @@ package org.javawebstack.orm.util; +import java.util.Stack; + public class Helper { public static String toSnakeCase(String source) { @@ -41,4 +43,15 @@ public static String toCamelCase(String source) { return sb.toString(); } + public static Stack> getSuperClassesTill(Class clazz, Class target) { + Stack> stack = new Stack<>(); + Class superClass = clazz.getSuperclass(); + + while (superClass != null && superClass != target) { + stack.push(superClass); + superClass = superClass.getSuperclass(); + } + + return stack; + } } From 1cace0b30cbb5c601870fafb553de987bf1a4b12 Mon Sep 17 00:00:00 2001 From: x7airworker Date: Thu, 2 Dec 2021 17:53:58 +0100 Subject: [PATCH 06/19] Splitted table and column analysis into two methods --- .../java/org/javawebstack/orm/TableInfo.java | 62 +++++++++++-------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/javawebstack/orm/TableInfo.java b/src/main/java/org/javawebstack/orm/TableInfo.java index 2924ae2..230233a 100644 --- a/src/main/java/org/javawebstack/orm/TableInfo.java +++ b/src/main/java/org/javawebstack/orm/TableInfo.java @@ -47,7 +47,7 @@ public TableInfo(Class model, ORMConfig config) throws ORMConfi while (!superClasses.isEmpty()) { Class superClass = (Class) superClasses.pop(); if (Modifier.isAbstract(superClass.getModifiers())) { - constructInfo(superClass); + analyzeColumns(superClass); } else { throw new ORMConfigurationException("The parent model has to be abstract!"); } @@ -57,6 +57,21 @@ public TableInfo(Class model, ORMConfig config) throws ORMConfi } private void constructInfo (Class model) throws ORMConfigurationException { + analyzeTable(model); + analyzeColumns(model); + + if (!fields.containsKey(idField)) + idField = "uuid"; + if (!fields.containsKey(idField)) + throw new ORMConfigurationException("No id field found!"); + + if (config.isIdPrimaryKey()) { + if (primaryKey == null) + primaryKey = idField; + } + } + + private void analyzeTable(Class model) throws ORMConfigurationException { if (model.isAnnotationPresent(Table.class)) { Table table = model.getDeclaredAnnotationsByType(Table.class)[0]; tableName = table.value(); @@ -74,6 +89,26 @@ private void constructInfo (Class model) throws ORMConfiguratio } catch (NoSuchMethodException e) { throw new ORMConfigurationException("The model class has no empty constructor!"); } + if (model.isAnnotationPresent(RelationField.class)) { + relationField = model.getDeclaredAnnotationsByType(RelationField.class)[0].value(); + } else { + relationField = Helper.pascalToCamelCase(model.getSimpleName()) + ((getIdType().equals(UUID.class) && !idField.equalsIgnoreCase("id")) ? "UUID" : "Id"); + } + if (model.isAnnotationPresent(SoftDelete.class)) { + softDelete = model.getDeclaredAnnotationsByType(SoftDelete.class)[0]; + if (!fields.containsKey(softDelete.value())) + throw new ORMConfigurationException("Missing soft-delete field '" + softDelete.value() + "'"); + } + if (model.isAnnotationPresent(Dates.class)) { + dates = model.getDeclaredAnnotationsByType(Dates.class)[0]; + if (!fields.containsKey(dates.create())) + throw new ORMConfigurationException("Missing dates field '" + dates.create() + "'"); + if (!fields.containsKey(dates.update())) + throw new ORMConfigurationException("Missing dates field '" + dates.update() + "'"); + } + } + + private void analyzeColumns(Class model) throws ORMConfigurationException { for (Field field : model.getDeclaredFields()) { if (Modifier.isStatic(field.getModifiers())) continue; @@ -121,31 +156,6 @@ private void constructInfo (Class model) throws ORMConfiguratio if (field.isAnnotationPresent(Searchable.class)) this.searchable.add(fieldName); } - if (!fields.containsKey(idField)) - idField = "uuid"; - if (!fields.containsKey(idField)) - throw new ORMConfigurationException("No id field found!"); - if (model.isAnnotationPresent(RelationField.class)) { - relationField = model.getDeclaredAnnotationsByType(RelationField.class)[0].value(); - } else { - relationField = Helper.pascalToCamelCase(model.getSimpleName()) + ((getIdType().equals(UUID.class) && !idField.equalsIgnoreCase("id")) ? "UUID" : "Id"); - } - if (config.isIdPrimaryKey()) { - if (primaryKey == null) - primaryKey = idField; - } - if (model.isAnnotationPresent(SoftDelete.class)) { - softDelete = model.getDeclaredAnnotationsByType(SoftDelete.class)[0]; - if (!fields.containsKey(softDelete.value())) - throw new ORMConfigurationException("Missing soft-delete field '" + softDelete.value() + "'"); - } - if (model.isAnnotationPresent(Dates.class)) { - dates = model.getDeclaredAnnotationsByType(Dates.class)[0]; - if (!fields.containsKey(dates.create())) - throw new ORMConfigurationException("Missing dates field '" + dates.create() + "'"); - if (!fields.containsKey(dates.update())) - throw new ORMConfigurationException("Missing dates field '" + dates.update() + "'"); - } } public boolean isSoftDelete() { From d46558ddb696ca209cff0ed36551bef3a4e2494e Mon Sep 17 00:00:00 2001 From: x7airworker Date: Thu, 2 Dec 2021 18:32:46 +0100 Subject: [PATCH 07/19] Order of analyzeColumns and analyzeTable was wrong --- src/main/java/org/javawebstack/orm/TableInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/javawebstack/orm/TableInfo.java b/src/main/java/org/javawebstack/orm/TableInfo.java index 230233a..d24b21f 100644 --- a/src/main/java/org/javawebstack/orm/TableInfo.java +++ b/src/main/java/org/javawebstack/orm/TableInfo.java @@ -57,8 +57,8 @@ public TableInfo(Class model, ORMConfig config) throws ORMConfi } private void constructInfo (Class model) throws ORMConfigurationException { - analyzeTable(model); analyzeColumns(model); + analyzeTable(model); if (!fields.containsKey(idField)) idField = "uuid"; From a954e800ab3a3b709dd4948acc4b9c7d3de171b0 Mon Sep 17 00:00:00 2001 From: JanHolger Date: Mon, 14 Feb 2022 13:26:02 +0100 Subject: [PATCH 08/19] Added a fork() method to the SQL interface and implemented a thread local session helper to locally allow overwriting certain settings (currently only the connection used) --- .../java/org/javawebstack/orm/Session.java | 46 +++++++++++++++++++ .../org/javawebstack/orm/query/Query.java | 38 +++++++++------ .../org/javawebstack/orm/wrapper/MySQL.java | 4 ++ .../org/javawebstack/orm/wrapper/SQL.java | 2 + .../org/javawebstack/orm/wrapper/SQLite.java | 4 ++ 5 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 src/main/java/org/javawebstack/orm/Session.java diff --git a/src/main/java/org/javawebstack/orm/Session.java b/src/main/java/org/javawebstack/orm/Session.java new file mode 100644 index 0000000..2204d22 --- /dev/null +++ b/src/main/java/org/javawebstack/orm/Session.java @@ -0,0 +1,46 @@ +package org.javawebstack.orm; + +import org.javawebstack.orm.wrapper.SQL; + +import java.util.function.Consumer; + +public class Session { + + private static ThreadLocal sessions = new ThreadLocal<>(); + + public static Session current() { + return sessions.get(); + } + + private SQL connection; + + private Session() { + + } + + public Session via(SQL connection) { + this.connection = connection; + return this; + } + + public SQL getConnection() { + return connection; + } + + public static void session(Consumer consumer) { + Session session = begin(); + consumer.accept(session); + end(); + } + + public static Session begin() { + Session session = new Session(); + sessions.set(session); + return session; + } + + public static void end() { + sessions.remove(); + } + +} diff --git a/src/main/java/org/javawebstack/orm/query/Query.java b/src/main/java/org/javawebstack/orm/query/Query.java index e651363..da18324 100644 --- a/src/main/java/org/javawebstack/orm/query/Query.java +++ b/src/main/java/org/javawebstack/orm/query/Query.java @@ -3,7 +3,9 @@ import org.javawebstack.orm.Model; import org.javawebstack.orm.Repo; import org.javawebstack.orm.SQLMapper; +import org.javawebstack.orm.Session; import org.javawebstack.orm.exception.ORMQueryException; +import org.javawebstack.orm.wrapper.SQL; import org.javawebstack.orm.wrapper.builder.SQLQueryString; import java.sql.ResultSet; @@ -19,6 +21,7 @@ public class Query { private final Repo repo; private final Class model; + private SQL connection; private List select = new ArrayList<>(); private final QueryGroup where = new QueryGroup<>(); private Integer offset; @@ -35,6 +38,15 @@ public Query(Class model) { public Query(Repo repo, Class model) { this.repo = repo; this.model = model; + Session session = Session.current(); + this.connection = repo.getConnection(); + if(session != null && session.getConnection() != null) + this.connection = session.getConnection(); + } + + public Query via(SQL connection) { + this.connection = connection; + return this; } public boolean isWithDeleted() { @@ -356,9 +368,9 @@ public Query withDeleted() { } public void finalDelete() { - SQLQueryString qs = repo.getConnection().builder().buildDelete(this); + SQLQueryString qs = connection.builder().buildDelete(this); try { - repo.getConnection().write(qs.getQuery(), qs.getParameters().toArray()); + connection.write(qs.getQuery(), qs.getParameters().toArray()); } catch (SQLException throwables) { throw new ORMQueryException(throwables); } @@ -385,11 +397,11 @@ public void restore() { } public T refresh(T entity) { - SQLQueryString qs = repo.getConnection().builder().buildQuery(this); + SQLQueryString qs = connection.builder().buildQuery(this); try { - ResultSet rs = repo.getConnection().read(qs.getQuery(), qs.getParameters().toArray()); + ResultSet rs = connection.read(qs.getQuery(), qs.getParameters().toArray()); SQLMapper.mapBack(repo, rs, entity); - repo.getConnection().close(rs); + connection.close(rs); return entity; } catch (SQLException throwables) { throw new ORMQueryException(throwables); @@ -401,20 +413,20 @@ public void update(T entity) { } public void update(Map values) { - SQLQueryString queryString = repo.getConnection().builder().buildUpdate(this, values); + SQLQueryString queryString = connection.builder().buildUpdate(this, values); try { - repo.getConnection().write(queryString.getQuery(), queryString.getParameters().toArray()); + connection.write(queryString.getQuery(), queryString.getParameters().toArray()); } catch (SQLException throwables) { throw new ORMQueryException(throwables); } } public List all() { - SQLQueryString qs = repo.getConnection().builder().buildQuery(this); + SQLQueryString qs = connection.builder().buildQuery(this); try { - ResultSet rs = repo.getConnection().read(qs.getQuery(), qs.getParameters().toArray()); + ResultSet rs = connection.read(qs.getQuery(), qs.getParameters().toArray()); List list = SQLMapper.map(repo, rs, new ArrayList<>()); - repo.getConnection().close(rs); + connection.close(rs); return list; } catch (SQLException throwables) { throw new ORMQueryException(throwables); @@ -437,13 +449,13 @@ public Stream stream() { } public int count() { - SQLQueryString qs = repo.getConnection().builder().buildQuery(this.select("count(*)")); + SQLQueryString qs = connection.builder().buildQuery(this.select("count(*)")); try { - ResultSet rs = repo.getConnection().read(qs.getQuery(), qs.getParameters().toArray()); + ResultSet rs = connection.read(qs.getQuery(), qs.getParameters().toArray()); int c = 0; if (rs.next()) c = rs.getInt(1); - repo.getConnection().close(rs); + connection.close(rs); return c; } catch (SQLException throwables) { throw new ORMQueryException(throwables); diff --git a/src/main/java/org/javawebstack/orm/wrapper/MySQL.java b/src/main/java/org/javawebstack/orm/wrapper/MySQL.java index 21dda73..3d71818 100644 --- a/src/main/java/org/javawebstack/orm/wrapper/MySQL.java +++ b/src/main/java/org/javawebstack/orm/wrapper/MySQL.java @@ -32,6 +32,10 @@ public MySQL(String host, int port, String database, String username, String pas this.timeout = timeout * 1000L; } + public SQL fork() { + return new MySQL(host, port, database, username, password, (int) (timeout / 1000L)); + } + public Connection getConnection() { long now = System.currentTimeMillis(); if (now > lastQuery + timeout) { diff --git a/src/main/java/org/javawebstack/orm/wrapper/SQL.java b/src/main/java/org/javawebstack/orm/wrapper/SQL.java index 04b37ad..35a0a3b 100644 --- a/src/main/java/org/javawebstack/orm/wrapper/SQL.java +++ b/src/main/java/org/javawebstack/orm/wrapper/SQL.java @@ -22,4 +22,6 @@ public interface SQL { void removeQueryLogger(QueryLogger logger); + SQL fork(); + } diff --git a/src/main/java/org/javawebstack/orm/wrapper/SQLite.java b/src/main/java/org/javawebstack/orm/wrapper/SQLite.java index 1ae7a40..c07c4d4 100644 --- a/src/main/java/org/javawebstack/orm/wrapper/SQLite.java +++ b/src/main/java/org/javawebstack/orm/wrapper/SQLite.java @@ -17,6 +17,10 @@ public SQLite(String file) { this.file = file; } + public SQL fork() { + return new SQLite(file); + } + public Connection getConnection() { try { if (c == null || c.isClosed()) { From 75d8596202b61eddbab174bebc40afc04436dab9 Mon Sep 17 00:00:00 2001 From: "j.bebendorf" Date: Mon, 21 Mar 2022 16:35:38 +0100 Subject: [PATCH 09/19] Added grouping for the Accessible in order to improve security. --- .../java/org/javawebstack/orm/Accessible.java | 3 +- src/main/java/org/javawebstack/orm/Repo.java | 6 ++-- .../org/javawebstack/orm/query/Query.java | 14 ++++++++- .../builder/MySQLQueryStringBuilder.java | 30 +++++++++++++++++-- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/javawebstack/orm/Accessible.java b/src/main/java/org/javawebstack/orm/Accessible.java index 3b164bb..794aac6 100644 --- a/src/main/java/org/javawebstack/orm/Accessible.java +++ b/src/main/java/org/javawebstack/orm/Accessible.java @@ -1,7 +1,8 @@ package org.javawebstack.orm; import org.javawebstack.orm.query.Query; +import org.javawebstack.orm.query.QueryGroup; public interface Accessible { - Query access(Query query, Object accessor); + QueryGroup access(Query query, QueryGroup accessChecks, Object accessor); } diff --git a/src/main/java/org/javawebstack/orm/Repo.java b/src/main/java/org/javawebstack/orm/Repo.java index cb3241c..f40dea2 100644 --- a/src/main/java/org/javawebstack/orm/Repo.java +++ b/src/main/java/org/javawebstack/orm/Repo.java @@ -73,11 +73,11 @@ public Query whereId(Object right) { } public Query accessible(Object accessor) { - return accessible(query(), accessor); + return query().accessible(accessor); } - public Query accessible(Query query, Object accessor) { - return accessible == null ? query : accessible.access(query, accessor); + public Accessible getAccessible() { + return accessible; } public void save(T entry) { diff --git a/src/main/java/org/javawebstack/orm/query/Query.java b/src/main/java/org/javawebstack/orm/query/Query.java index da18324..5e102e8 100644 --- a/src/main/java/org/javawebstack/orm/query/Query.java +++ b/src/main/java/org/javawebstack/orm/query/Query.java @@ -30,6 +30,8 @@ public class Query { private boolean withDeleted = false; private final List groupBy = new ArrayList<>(); private QueryGroup having; + private boolean applyAccessible = false; + private Object accessor; public Query(Class model) { this(Repo.get(model), model); @@ -53,6 +55,14 @@ public boolean isWithDeleted() { return withDeleted; } + public boolean shouldApplyAccessible() { + return applyAccessible; + } + + public Object getAccessor() { + return accessor; + } + public QueryGroup getWhereGroup() { return where; } @@ -318,7 +328,9 @@ public Query has(Query relation) { } public Query accessible(Object accessor) { - return repo.accessible(this, accessor); + this.applyAccessible = true; + this.accessor = accessor; + return this; } public Query filter(Map filter) { diff --git a/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java b/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java index 3f3a372..e125933 100644 --- a/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java +++ b/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java @@ -1,10 +1,12 @@ package org.javawebstack.orm.wrapper.builder; -import org.javawebstack.orm.Repo; -import org.javawebstack.orm.SQLMapper; -import org.javawebstack.orm.TableInfo; +import org.javawebstack.orm.*; +import org.javawebstack.orm.exception.ORMQueryException; import org.javawebstack.orm.query.*; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.sql.Timestamp; import java.time.Instant; import java.util.*; @@ -15,6 +17,16 @@ public class MySQLQueryStringBuilder implements QueryStringBuilder { public static final MySQLQueryStringBuilder INSTANCE = new MySQLQueryStringBuilder(); + private static Method accessibleAccessMethod; + + static { + try { + accessibleAccessMethod = Accessible.class.getDeclaredMethod("access", Query.class, QueryGroup.class, Object.class); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + } + public SQLQueryString buildInsert(TableInfo info, Map values) { List params = new ArrayList<>(); StringBuilder sb = new StringBuilder("INSERT INTO `"); @@ -48,6 +60,18 @@ public SQLQueryString buildQuery(Query query) { .append('`'); QueryGroup where = query.getWhereGroup(); checkWithDeleted(repo, query.isWithDeleted(), where); + if(query.shouldApplyAccessible()) { + QueryGroup actualWhere = where; + where = new QueryGroup<>() + .and(q -> (QueryGroup) actualWhere) + .and(q -> { + try { + return (QueryGroup) accessibleAccessMethod.invoke(repo.getAccessible(), query, q, query.getAccessor()); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new ORMQueryException(e); + } + }); + } if (!where.getQueryElements().isEmpty()) { SQLQueryString qs = convertGroup(repo.getInfo(), where); sb.append(" WHERE ").append(qs.getQuery()); From 804d8aa30d6f3ab169218bd204aaaec9e3a26a1b Mon Sep 17 00:00:00 2001 From: "j.bebendorf" Date: Mon, 21 Mar 2022 17:05:37 +0100 Subject: [PATCH 10/19] Fixed issue with empty where in combination with the accessible --- .../orm/wrapper/builder/MySQLQueryStringBuilder.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java b/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java index e125933..4586146 100644 --- a/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java +++ b/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java @@ -61,6 +61,13 @@ public SQLQueryString buildQuery(Query query) { QueryGroup where = query.getWhereGroup(); checkWithDeleted(repo, query.isWithDeleted(), where); if(query.shouldApplyAccessible()) { + if(where.getQueryElements().isEmpty()) { + try { + where = (QueryGroup) accessibleAccessMethod.invoke(repo.getAccessible(), query, where, query.getAccessor()); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new ORMQueryException(e); + } + } QueryGroup actualWhere = where; where = new QueryGroup<>() .and(q -> (QueryGroup) actualWhere) @@ -71,6 +78,7 @@ public SQLQueryString buildQuery(Query query) { throw new ORMQueryException(e); } }); + } if (!where.getQueryElements().isEmpty()) { SQLQueryString qs = convertGroup(repo.getInfo(), where); From abe4f8b8dfe973c14eb69c5fc5b272ce1f2a3808 Mon Sep 17 00:00:00 2001 From: "j.bebendorf" Date: Mon, 21 Mar 2022 17:21:40 +0100 Subject: [PATCH 11/19] Fixed issue with empty where in combination with the accessible --- .../builder/MySQLQueryStringBuilder.java | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java b/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java index 4586146..2037bae 100644 --- a/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java +++ b/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java @@ -58,27 +58,21 @@ public SQLQueryString buildQuery(Query query) { .append(" FROM `") .append(repo.getInfo().getTableName()) .append('`'); - QueryGroup where = query.getWhereGroup(); + QueryGroup where = (QueryGroup) query.getWhereGroup(); checkWithDeleted(repo, query.isWithDeleted(), where); if(query.shouldApplyAccessible()) { - if(where.getQueryElements().isEmpty()) { - try { - where = (QueryGroup) accessibleAccessMethod.invoke(repo.getAccessible(), query, where, query.getAccessor()); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new ORMQueryException(e); - } + QueryGroup accessChecks; + try { + accessChecks = (QueryGroup) accessibleAccessMethod.invoke(repo.getAccessible(), query, new QueryGroup<>(), query.getAccessor()); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new ORMQueryException(e); } - QueryGroup actualWhere = where; - where = new QueryGroup<>() - .and(q -> (QueryGroup) actualWhere) - .and(q -> { - try { - return (QueryGroup) accessibleAccessMethod.invoke(repo.getAccessible(), query, q, query.getAccessor()); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new ORMQueryException(e); - } - }); - + QueryGroup actualWhere = where; + where = new QueryGroup<>(); + if(!actualWhere.getQueryElements().isEmpty()) + where.and(q -> actualWhere); + if(!accessChecks.getQueryElements().isEmpty()) + where.and(q -> accessChecks); } if (!where.getQueryElements().isEmpty()) { SQLQueryString qs = convertGroup(repo.getInfo(), where); From 4ea3b036211b8df261c55484c8aa867a59f95159 Mon Sep 17 00:00:00 2001 From: JanHolger Date: Sun, 1 May 2022 18:50:15 +0200 Subject: [PATCH 12/19] Fixed #34 (refresh throwing exception) and optimized imports --- pom.xml | 8 ++++---- src/main/java/org/javawebstack/orm/Repo.java | 2 -- src/main/java/org/javawebstack/orm/TableInfo.java | 1 - src/main/java/org/javawebstack/orm/query/Query.java | 12 ++++++++---- .../java/org/javawebstack/orm/query/QueryExists.java | 2 -- .../java/org/javawebstack/orm/query/QueryGroup.java | 3 --- .../java/org/javawebstack/orm/wrapper/BaseSQL.java | 2 +- .../orm/wrapper/builder/MySQLQueryStringBuilder.java | 5 ++++- .../orm/wrapper/builder/QueryStringBuilder.java | 2 +- 9 files changed, 18 insertions(+), 19 deletions(-) diff --git a/pom.xml b/pom.xml index 91fc662..21cee00 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ org.javawebstack abstract-data - 1.0.0 + 1.0.1 org.atteo @@ -71,7 +71,7 @@ org.junit.jupiter junit-jupiter-engine - 5.8.1 + 5.8.2 test @@ -83,13 +83,13 @@ org.projectlombok lombok - 1.18.22 + 1.18.24 test mysql mysql-connector-java - 8.0.27 + 8.0.28 test diff --git a/src/main/java/org/javawebstack/orm/Repo.java b/src/main/java/org/javawebstack/orm/Repo.java index cb3241c..b55c697 100644 --- a/src/main/java/org/javawebstack/orm/Repo.java +++ b/src/main/java/org/javawebstack/orm/Repo.java @@ -17,8 +17,6 @@ import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.function.Function; -import java.util.stream.Stream; public class Repo { diff --git a/src/main/java/org/javawebstack/orm/TableInfo.java b/src/main/java/org/javawebstack/orm/TableInfo.java index d24b21f..e144417 100644 --- a/src/main/java/org/javawebstack/orm/TableInfo.java +++ b/src/main/java/org/javawebstack/orm/TableInfo.java @@ -6,7 +6,6 @@ import org.javawebstack.orm.util.Helper; import org.javawebstack.orm.util.KeyType; -import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Modifier; diff --git a/src/main/java/org/javawebstack/orm/query/Query.java b/src/main/java/org/javawebstack/orm/query/Query.java index da18324..0766b53 100644 --- a/src/main/java/org/javawebstack/orm/query/Query.java +++ b/src/main/java/org/javawebstack/orm/query/Query.java @@ -26,7 +26,7 @@ public class Query { private final QueryGroup where = new QueryGroup<>(); private Integer offset; private Integer limit; - private List order = new ArrayList<>(); + private final List order = new ArrayList<>(); private boolean withDeleted = false; private final List groupBy = new ArrayList<>(); private QueryGroup having; @@ -400,9 +400,13 @@ public T refresh(T entity) { SQLQueryString qs = connection.builder().buildQuery(this); try { ResultSet rs = connection.read(qs.getQuery(), qs.getParameters().toArray()); - SQLMapper.mapBack(repo, rs, entity); - connection.close(rs); - return entity; + if(rs.next()) { + SQLMapper.mapBack(repo, rs, entity); + connection.close(rs); + return entity; + } else { + return null; + } } catch (SQLException throwables) { throw new ORMQueryException(throwables); } diff --git a/src/main/java/org/javawebstack/orm/query/QueryExists.java b/src/main/java/org/javawebstack/orm/query/QueryExists.java index a175f51..3b4044d 100644 --- a/src/main/java/org/javawebstack/orm/query/QueryExists.java +++ b/src/main/java/org/javawebstack/orm/query/QueryExists.java @@ -1,8 +1,6 @@ package org.javawebstack.orm.query; import org.javawebstack.orm.Model; -import org.javawebstack.orm.TableInfo; -import org.javawebstack.orm.wrapper.builder.SQLQueryString; public class QueryExists implements QueryElement { diff --git a/src/main/java/org/javawebstack/orm/query/QueryGroup.java b/src/main/java/org/javawebstack/orm/query/QueryGroup.java index 9b71f51..9f459a9 100644 --- a/src/main/java/org/javawebstack/orm/query/QueryGroup.java +++ b/src/main/java/org/javawebstack/orm/query/QueryGroup.java @@ -2,13 +2,10 @@ import org.javawebstack.orm.Model; import org.javawebstack.orm.Repo; -import org.javawebstack.orm.TableInfo; -import org.javawebstack.orm.wrapper.builder.SQLQueryString; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.function.Consumer; import java.util.function.Function; /** diff --git a/src/main/java/org/javawebstack/orm/wrapper/BaseSQL.java b/src/main/java/org/javawebstack/orm/wrapper/BaseSQL.java index 472aedd..ad0e0b5 100644 --- a/src/main/java/org/javawebstack/orm/wrapper/BaseSQL.java +++ b/src/main/java/org/javawebstack/orm/wrapper/BaseSQL.java @@ -2,8 +2,8 @@ import org.javawebstack.orm.exception.ORMQueryException; -import java.sql.*; import java.sql.Date; +import java.sql.*; import java.util.*; public abstract class BaseSQL implements SQL { diff --git a/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java b/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java index 3f3a372..ea1280f 100644 --- a/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java +++ b/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java @@ -7,7 +7,10 @@ import java.sql.Timestamp; import java.time.Instant; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import java.util.stream.IntStream; diff --git a/src/main/java/org/javawebstack/orm/wrapper/builder/QueryStringBuilder.java b/src/main/java/org/javawebstack/orm/wrapper/builder/QueryStringBuilder.java index 88cad14..0b48378 100644 --- a/src/main/java/org/javawebstack/orm/wrapper/builder/QueryStringBuilder.java +++ b/src/main/java/org/javawebstack/orm/wrapper/builder/QueryStringBuilder.java @@ -1,7 +1,7 @@ package org.javawebstack.orm.wrapper.builder; import org.javawebstack.orm.TableInfo; -import org.javawebstack.orm.query.*; +import org.javawebstack.orm.query.Query; import java.util.Map; From 1b1a25c2d141183a3adf7ce1fa915e02dc43112a Mon Sep 17 00:00:00 2001 From: JanHolger Date: Sun, 1 May 2022 20:09:17 +0200 Subject: [PATCH 13/19] Implemented #36 (don't render empty groups) --- .../org/javawebstack/orm/query/Query.java | 38 ++++--------- .../javawebstack/orm/query/QueryGroup.java | 54 +++++++++---------- 2 files changed, 36 insertions(+), 56 deletions(-) diff --git a/src/main/java/org/javawebstack/orm/query/Query.java b/src/main/java/org/javawebstack/orm/query/Query.java index c883c35..24ba5c8 100644 --- a/src/main/java/org/javawebstack/orm/query/Query.java +++ b/src/main/java/org/javawebstack/orm/query/Query.java @@ -144,18 +144,6 @@ public Query orLike(String left, Object right) { return orWhere(left, "LIKE", right); } - public QueryGroup whereMorph(String name, Class type) { - return where.whereMorph(name, type); - } - - public QueryGroup whereMorph(String name, Class type, Object id) { - return where.whereMorph(name, type, id); - } - - public QueryGroup whereMorph(String name, Model entity) { - return where.whereMorph(name, entity); - } - public Query orWhere(Class leftTable, String left, String operator, Class rightTable, String right) { if (rightTable != null) right = Repo.get(rightTable).getInfo().getTableName() + "." + Repo.get(rightTable).getInfo().getColumnName(right); @@ -212,33 +200,25 @@ public Query orWhereId(String operator, Class other, String return orWhereId(operator, new QueryColumn(Repo.get(other).getInfo().getTableName() + "." + Repo.get(other).getInfo().getColumnName(field))); } + @Deprecated public Query isNull(Object left) { where.isNull(left); return this; } + @Deprecated public Query notNull(Object left) { where.notNull(left); return this; } public Query whereNull(Object left) { - where.isNull(left); + where.whereNull(left); return this; } public Query whereNotNull(Object left) { - where.notNull(left); - return this; - } - - public Query lessThan(Object left, Object right) { - where.lessThan(left, right); - return this; - } - - public Query greaterThan(Object left, Object right) { - where.greaterThan(left, right); + where.whereNotNull(left); return this; } @@ -252,23 +232,25 @@ public Query orWhere(Object left, Object right) { return this; } + @Deprecated public Query orIsNull(Object left) { where.orIsNull(left); return this; } + @Deprecated public Query orNotNull(Object left) { where.orNotNull(left); return this; } - public Query orLessThan(Object left, Object right) { - where.orLessThan(left, right); + public Query orWhereNull(Object left) { + where.orWhereNull(left); return this; } - public Query orGreaterThan(Object left, Object right) { - where.orGreaterThan(left, right); + public Query orWhereNotNull(Object left) { + where.orWhereNotNull(left); return this; } diff --git a/src/main/java/org/javawebstack/orm/query/QueryGroup.java b/src/main/java/org/javawebstack/orm/query/QueryGroup.java index 9f459a9..34b3019 100644 --- a/src/main/java/org/javawebstack/orm/query/QueryGroup.java +++ b/src/main/java/org/javawebstack/orm/query/QueryGroup.java @@ -29,16 +29,30 @@ public List getQueryElements() { return queryElements; } + @Deprecated public QueryGroup and(Function, QueryGroup> group) { + return where(group); + } + + public QueryGroup where(Function, QueryGroup> group) { QueryGroup innerGroup = group.apply(new QueryGroup<>()); + if(innerGroup.queryElements.size() == 0) + return this; if (queryElements.size() > 0) queryElements.add(QueryConjunction.AND); queryElements.add(innerGroup); return this; } + @Deprecated public QueryGroup or(Function, QueryGroup> group) { + return orWhere(group); + } + + public QueryGroup orWhere(Function, QueryGroup> group) { QueryGroup innerGroup = group.apply(new QueryGroup<>()); + if(innerGroup.queryElements.size() == 0) + return this; if (queryElements.size() > 0) queryElements.add(QueryConjunction.OR); queryElements.add(innerGroup); @@ -68,28 +82,18 @@ public QueryGroup where(Class leftTable, String left, String return where(left, operator, right); } - public QueryGroup whereMorph(String name, Class type) { - return where(name + "Type", Repo.get(type).getInfo().getMorphType()); - } - - public QueryGroup whereMorph(String name, Class type, Object id) { - return whereMorph(name, type).where(name + "Id", id); - } - - public QueryGroup whereMorph(String name, Model entity) { - return whereMorph(name, entity.getClass(), Repo.get(entity.getClass()).getId(entity)); - } - public QueryGroup where(Object left, Object right) { return where(left, "=", right); } + @Deprecated public QueryGroup isNull(Object left) { - return where(left, "IS NULL", null); + return whereNull(left); } + @Deprecated public QueryGroup notNull(Object left) { - return where(left, "IS NOT NULL", null); + return whereNotNull(left); } public QueryGroup whereNull(Object left) { @@ -100,14 +104,6 @@ public QueryGroup whereNotNull(Object left) { return where(left, "IS NOT NULL", null); } - public QueryGroup lessThan(Object left, Object right) { - return where(left, "<", right); - } - - public QueryGroup greaterThan(Object left, Object right) { - return where(left, ">", right); - } - public QueryGroup orWhere(Object left, String condition, Object right) { if(condition.equalsIgnoreCase("=") && right == null) return orIsNull(left); @@ -147,20 +143,22 @@ public QueryGroup orWhereMorph(String name, Model entity) { return orWhereMorph(name, entity.getClass(), Repo.get(entity.getClass()).getId(entity)); } + @Deprecated public QueryGroup orIsNull(Object left) { - return orWhere(left, "IS NULL", null); + return orWhereNull(left); } + @Deprecated public QueryGroup orNotNull(Object left) { - return orWhere(left, "IS NOT NULL", null); + return orWhereNotNull(left); } - public QueryGroup orLessThan(Object left, Object right) { - return orWhere(left, "<", right); + public QueryGroup orWhereNull(Object left) { + return orWhere(left, "IS NULL", null); } - public QueryGroup orGreaterThan(Object left, Object right) { - return orWhere(left, ">", right); + public QueryGroup orWhereNotNull(Object left) { + return orWhere(left, "IS NOT NULL", null); } public QueryGroup whereExists(Class model, Function, Query> consumer) { From 9d146e8de02aa648d92045b1d698788c191f9de8 Mon Sep 17 00:00:00 2001 From: JanHolger Date: Sun, 1 May 2022 20:26:46 +0200 Subject: [PATCH 14/19] Implemented #35 (render empty IN as 1=2) --- .../java/org/javawebstack/orm/query/QueryGroup.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/org/javawebstack/orm/query/QueryGroup.java b/src/main/java/org/javawebstack/orm/query/QueryGroup.java index 34b3019..446b6f1 100644 --- a/src/main/java/org/javawebstack/orm/query/QueryGroup.java +++ b/src/main/java/org/javawebstack/orm/query/QueryGroup.java @@ -3,6 +3,7 @@ import org.javawebstack.orm.Model; import org.javawebstack.orm.Repo; +import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -64,6 +65,11 @@ public QueryGroup where(Object left, String condition, Object right) { return whereNull(left); if(condition.equalsIgnoreCase("!=") && right == null) return whereNotNull(left); + if((condition.equalsIgnoreCase("IN") || condition.equalsIgnoreCase("NOT IN")) && (right == null || Array.getLength(right) == 0)) { + left = 1; + condition = "="; + right = 2; + } if (queryElements.size() > 0) queryElements.add(QueryConjunction.AND); queryElements.add(new QueryCondition(left instanceof String ? new QueryColumn((String) left) : left, condition, right)); @@ -109,6 +115,11 @@ public QueryGroup orWhere(Object left, String condition, Object right) { return orIsNull(left); if(condition.equalsIgnoreCase("!=") && right == null) return orNotNull(left); + if((condition.equalsIgnoreCase("IN") || condition.equalsIgnoreCase("NOT IN")) && (right == null || Array.getLength(right) == 0)) { + left = 1; + condition = "="; + right = 2; + } if (queryElements.size() > 0) queryElements.add(QueryConjunction.OR); queryElements.add(new QueryCondition(left instanceof String ? new QueryColumn((String) left) : left, condition, right)); From ce66dbebafdaeccbd54a61f0c3ec1223a9a480d0 Mon Sep 17 00:00:00 2001 From: JanHolger Date: Sun, 1 May 2022 23:06:24 +0200 Subject: [PATCH 15/19] Updated abstract-data to 1.0.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 21cee00..446d119 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ org.javawebstack abstract-data - 1.0.1 + 1.0.2 org.atteo From cf52c50a172e7aebbb5d69427eb9138ba293665f Mon Sep 17 00:00:00 2001 From: "j.bebendorf" Date: Wed, 18 May 2022 11:06:07 +0200 Subject: [PATCH 16/19] Fixed create not using the session system --- src/main/java/org/javawebstack/orm/Repo.java | 1 + .../orm/wrapper/builder/MySQLQueryStringBuilder.java | 1 - src/test/java/org/javawebstack/orm/test/DatesTest.java | 4 ++-- .../java/org/javawebstack/orm/test/ExampleTest.java | 4 +++- .../javawebstack/orm/test/SQLDriverFactoryTest.java | 5 +++-- .../java/org/javawebstack/orm/test/TableInfoTest.java | 3 ++- .../javawebstack/orm/test/UpdateOnlyIfIsDirtyTest.java | 3 ++- .../org/javawebstack/orm/test/other/QueryUtilTest.java | 4 +++- .../orm/test/querybuilding/OrderByClauseTest.java | 10 +++++++--- .../orm/test/queryexecution/OrderByTest.java | 3 ++- 10 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/javawebstack/orm/Repo.java b/src/main/java/org/javawebstack/orm/Repo.java index 4da9cb6..f831184 100644 --- a/src/main/java/org/javawebstack/orm/Repo.java +++ b/src/main/java/org/javawebstack/orm/Repo.java @@ -120,6 +120,7 @@ private void executeCreate(T entry) { map.remove(idCol); } SQLQueryString qs = getConnection().builder().buildInsert(info, map); + SQL connection = Session.current() != null ? Session.current().getConnection() : this.connection; int id = connection.write(qs.getQuery(), qs.getParameters().toArray()); if (info.isAutoIncrement()) info.getField(info.getIdField()).set(entry, id); diff --git a/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java b/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java index 8a73ade..3c706e1 100644 --- a/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java +++ b/src/main/java/org/javawebstack/orm/wrapper/builder/MySQLQueryStringBuilder.java @@ -4,7 +4,6 @@ import org.javawebstack.orm.exception.ORMQueryException; import org.javawebstack.orm.query.*; -import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Timestamp; diff --git a/src/test/java/org/javawebstack/orm/test/DatesTest.java b/src/test/java/org/javawebstack/orm/test/DatesTest.java index d69afc0..9bd337e 100644 --- a/src/test/java/org/javawebstack/orm/test/DatesTest.java +++ b/src/test/java/org/javawebstack/orm/test/DatesTest.java @@ -10,10 +10,10 @@ import org.javawebstack.orm.exception.ORMConfigurationException; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - import java.sql.Timestamp; +import static org.junit.jupiter.api.Assertions.assertNotNull; + public class DatesTest extends ORMTestCase { @Test public void testTimes() throws ORMConfigurationException { diff --git a/src/test/java/org/javawebstack/orm/test/ExampleTest.java b/src/test/java/org/javawebstack/orm/test/ExampleTest.java index 5cc83ab..a83b405 100644 --- a/src/test/java/org/javawebstack/orm/test/ExampleTest.java +++ b/src/test/java/org/javawebstack/orm/test/ExampleTest.java @@ -7,7 +7,9 @@ import org.javawebstack.orm.annotation.Column; import org.javawebstack.orm.exception.ORMConfigurationException; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; public class ExampleTest extends ORMTestCase { diff --git a/src/test/java/org/javawebstack/orm/test/SQLDriverFactoryTest.java b/src/test/java/org/javawebstack/orm/test/SQLDriverFactoryTest.java index f367938..d6b1299 100644 --- a/src/test/java/org/javawebstack/orm/test/SQLDriverFactoryTest.java +++ b/src/test/java/org/javawebstack/orm/test/SQLDriverFactoryTest.java @@ -1,7 +1,5 @@ package org.javawebstack.orm.test; -import static org.junit.jupiter.api.Assertions.*; - import org.javawebstack.orm.wrapper.MySQL; import org.javawebstack.orm.wrapper.SQLDriverFactory; import org.javawebstack.orm.wrapper.SQLDriverNotFoundException; @@ -11,6 +9,9 @@ import java.util.HashMap; import java.util.Map; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + class SQLDriverFactoryTest { private SQLDriverFactory factory; diff --git a/src/test/java/org/javawebstack/orm/test/TableInfoTest.java b/src/test/java/org/javawebstack/orm/test/TableInfoTest.java index 7ed94d2..69aa577 100644 --- a/src/test/java/org/javawebstack/orm/test/TableInfoTest.java +++ b/src/test/java/org/javawebstack/orm/test/TableInfoTest.java @@ -9,7 +9,8 @@ import org.javawebstack.orm.util.KeyType; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; public class TableInfoTest extends ORMTestCase { @Test diff --git a/src/test/java/org/javawebstack/orm/test/UpdateOnlyIfIsDirtyTest.java b/src/test/java/org/javawebstack/orm/test/UpdateOnlyIfIsDirtyTest.java index fe176e9..44076f2 100644 --- a/src/test/java/org/javawebstack/orm/test/UpdateOnlyIfIsDirtyTest.java +++ b/src/test/java/org/javawebstack/orm/test/UpdateOnlyIfIsDirtyTest.java @@ -7,7 +7,8 @@ import org.javawebstack.orm.wrapper.QueryLogger; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; public class UpdateOnlyIfIsDirtyTest extends ORMTestCase { diff --git a/src/test/java/org/javawebstack/orm/test/other/QueryUtilTest.java b/src/test/java/org/javawebstack/orm/test/other/QueryUtilTest.java index f6d17d8..157b5b4 100644 --- a/src/test/java/org/javawebstack/orm/test/other/QueryUtilTest.java +++ b/src/test/java/org/javawebstack/orm/test/other/QueryUtilTest.java @@ -6,7 +6,9 @@ import org.javawebstack.orm.test.shared.util.QueryStringUtil; import org.junit.jupiter.api.Test; -import java.util.*; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/org/javawebstack/orm/test/querybuilding/OrderByClauseTest.java b/src/test/java/org/javawebstack/orm/test/querybuilding/OrderByClauseTest.java index bf884f3..9354c64 100644 --- a/src/test/java/org/javawebstack/orm/test/querybuilding/OrderByClauseTest.java +++ b/src/test/java/org/javawebstack/orm/test/querybuilding/OrderByClauseTest.java @@ -1,15 +1,19 @@ package org.javawebstack.orm.test.querybuilding; -import org.javawebstack.orm.exception.ORMQueryException; import org.javawebstack.orm.query.Query; import org.javawebstack.orm.test.exception.SectionIndexOutOfBoundException; import org.javawebstack.orm.test.shared.models.Datatype; import org.javawebstack.orm.test.shared.models.columnnames.OverwrittenColumnName; import org.javawebstack.orm.test.shared.verification.QueryVerification; import org.junit.jupiter.api.Test; -import java.util.*; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.Random; + import static org.javawebstack.orm.test.shared.setup.ModelSetup.setUpModel; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; // This class tests the query generation for order by statements an MySQL class OrderByClauseTest { diff --git a/src/test/java/org/javawebstack/orm/test/queryexecution/OrderByTest.java b/src/test/java/org/javawebstack/orm/test/queryexecution/OrderByTest.java index cdc223a..2c7e11a 100644 --- a/src/test/java/org/javawebstack/orm/test/queryexecution/OrderByTest.java +++ b/src/test/java/org/javawebstack/orm/test/queryexecution/OrderByTest.java @@ -9,7 +9,8 @@ import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; class OrderByTest extends ORMTestCase { From 9f73d833a818162cb3a9929082679ddb78a5c05a Mon Sep 17 00:00:00 2001 From: "j.bebendorf" Date: Sat, 13 Aug 2022 20:08:15 +0200 Subject: [PATCH 17/19] Added hotfix for missing braces in DefaultMapper and added support for varchar enums using size > 0 --- .../orm/mapper/DefaultMapper.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/javawebstack/orm/mapper/DefaultMapper.java b/src/main/java/org/javawebstack/orm/mapper/DefaultMapper.java index f95f0e6..b1d2fdb 100644 --- a/src/main/java/org/javawebstack/orm/mapper/DefaultMapper.java +++ b/src/main/java/org/javawebstack/orm/mapper/DefaultMapper.java @@ -109,7 +109,7 @@ public Object mapToJava(Object source, Class type) { } public SQLType getType(Class type, int size) { - if (type.equals(String.class) || type.equals(char[].class)) + if (type.equals(String.class) || type.equals(char[].class)) { // Upper limit of 4294967295 exceeds the int boundaries if (size > MAX_SIZE_MEDIUMTEXT) return SQLType.LONGTEXT; @@ -119,12 +119,18 @@ public SQLType getType(Class type, int size) { return SQLType.VARCHAR; if (size == 1) return SQLType.CHAR; + } if (type.equals(UUID.class)) return SQLType.VARCHAR; if (type.equals(char.class)) return SQLType.CHAR; - if (type.isEnum()) - return SQLType.ENUM; + if (type.isEnum()) { + if(size < 1) { + return SQLType.ENUM; + } else { + return SQLType.VARCHAR; + } + } if (type.equals(boolean.class) || type.equals(Boolean.class) || type.equals(byte.class) || type.equals(Byte.class)) return SQLType.TINYINT; if (type.equals(short.class) || type.equals(Short.class)) @@ -147,8 +153,13 @@ public SQLType getType(Class type, int size) { } public String getTypeParameters(Class type, int size) { - if (type.isEnum()) - return Arrays.stream(((Class>) type).getEnumConstants()).map(c -> "'" + c.name() + "'").collect(Collectors.joining(",")); + if (type.isEnum()) { + if(size < 1) { + return Arrays.stream(((Class>) type).getEnumConstants()).map(c -> "'" + c.name() + "'").collect(Collectors.joining(",")); + } else { + return String.valueOf(size); + } + } if (type.equals(String.class) || type.equals(char[].class)) return size > MAX_SIZE_VARCHAR || size < 1 ? null : String.valueOf(size); if (type.equals(byte[].class)) From 309e612c732ceee640ea90d3edb33c8998736ccd Mon Sep 17 00:00:00 2001 From: "j.bebendorf" Date: Fri, 19 Aug 2022 12:14:46 +0200 Subject: [PATCH 18/19] Fixed data type for abstract data json mapper --- .../orm/mapper/AbstractDataTypeMapper.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/javawebstack/orm/mapper/AbstractDataTypeMapper.java b/src/main/java/org/javawebstack/orm/mapper/AbstractDataTypeMapper.java index 0355576..96eeb34 100644 --- a/src/main/java/org/javawebstack/orm/mapper/AbstractDataTypeMapper.java +++ b/src/main/java/org/javawebstack/orm/mapper/AbstractDataTypeMapper.java @@ -4,6 +4,15 @@ import org.javawebstack.orm.SQLType; public class AbstractDataTypeMapper implements TypeMapper { + + private static final int BYTES_OVERHEAD_TEXT = 2; + private static final int BYTES_OVERHEAD_MEDIUMTEXT = 3; + private static final int BYTES_OVERHEAD_LONGTEXT = 4; + + private static final long MAX_SIZE_TEXT = (long) Math.floor((65535 - BYTES_OVERHEAD_TEXT) / 4); + private static final long MAX_SIZE_MEDIUMTEXT = (long) Math.floor((16777215 - BYTES_OVERHEAD_MEDIUMTEXT) / 4); + private static final long MAX_SIZE_LONGTEXT = (long) Math.floor((4294967295L - BYTES_OVERHEAD_LONGTEXT) / 4); + public Object mapToSQL(Object source, Class type) { if (source == null) return null; @@ -21,8 +30,13 @@ public Object mapToJava(Object source, Class type) { } public SQLType getType(Class type, int size) { - if (AbstractElement.class.isAssignableFrom(type)) + if (AbstractElement.class.isAssignableFrom(type)) { + if (size > MAX_SIZE_MEDIUMTEXT) + return SQLType.LONGTEXT; + if (size > MAX_SIZE_TEXT) + return SQLType.MEDIUMTEXT; return SQLType.TEXT; + } return null; } From a0a15483536f2e4d8f0f95eba7fe826b1a1909ba Mon Sep 17 00:00:00 2001 From: "j.bebendorf" Date: Fri, 7 Oct 2022 21:53:48 +0200 Subject: [PATCH 19/19] Upgraded abstract-data --- pom.xml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 446d119..d102ba0 100644 --- a/pom.xml +++ b/pom.xml @@ -56,8 +56,15 @@ org.javawebstack abstract-data - 1.0.2 + 1.0.4 + + + org.yaml + snakeyaml + 1.33 + + org.atteo evo-inflector @@ -71,7 +78,7 @@ org.junit.jupiter junit-jupiter-engine - 5.8.2 + 5.9.0 test @@ -89,7 +96,7 @@ mysql mysql-connector-java - 8.0.28 + 8.0.30 test