Skip to content

Commit a798304

Browse files
committed
Merge remote-tracking branch 'origin/dev' into dev
2 parents a954e80 + a6880f7 commit a798304

File tree

4 files changed

+145
-27
lines changed

4 files changed

+145
-27
lines changed

pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@
3232
<organization>JavaWebStack</organization>
3333
<organizationUrl>https://javawebstack.org</organizationUrl>
3434
</developer>
35+
<developer>
36+
<name>Timothy Gillespie</name>
37+
<email>timothy@gillespie.eu</email>
38+
<organization>JavaWebStack</organization>
39+
<organizationUrl>https://javawebstack.org</organizationUrl>
40+
</developer>
41+
<developer>
42+
<name>Julian Gojani</name>
43+
<email>julian@gojani.xyz</email>
44+
<organization>JavaWebStack</organization>
45+
<organizationUrl>https://javawebstack.org</organizationUrl>
46+
</developer>
3547
</developers>
3648

3749
<scm>

src/main/java/org/javawebstack/orm/TableInfo.java

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class TableInfo {
2929
private final Class<? extends Model> modelClass;
3030
private String primaryKey;
3131
private final List<String> uniqueKeys = new ArrayList<>();
32-
private final Constructor<?> constructor;
32+
private Constructor<?> constructor;
3333
private String relationField;
3434
private final Map<String, String> filterable = new HashMap<>();
3535
private final List<String> searchable = new ArrayList<>();
@@ -42,6 +42,36 @@ public class TableInfo {
4242
public TableInfo(Class<? extends Model> model, ORMConfig config) throws ORMConfigurationException {
4343
this.config = config;
4444
this.modelClass = model;
45+
46+
Stack<Class<?>> superClasses = Helper.getSuperClassesTill(model, Model.class);
47+
while (!superClasses.isEmpty()) {
48+
Class<? extends Model> superClass = (Class<? extends Model>) superClasses.pop();
49+
if (Modifier.isAbstract(superClass.getModifiers())) {
50+
analyzeColumns(superClass);
51+
} else {
52+
throw new ORMConfigurationException("The parent model has to be abstract!");
53+
}
54+
}
55+
56+
constructInfo(model);
57+
}
58+
59+
private void constructInfo (Class<? extends Model> model) throws ORMConfigurationException {
60+
analyzeColumns(model);
61+
analyzeTable(model);
62+
63+
if (!fields.containsKey(idField))
64+
idField = "uuid";
65+
if (!fields.containsKey(idField))
66+
throw new ORMConfigurationException("No id field found!");
67+
68+
if (config.isIdPrimaryKey()) {
69+
if (primaryKey == null)
70+
primaryKey = idField;
71+
}
72+
}
73+
74+
private void analyzeTable(Class<? extends Model> model) throws ORMConfigurationException {
4575
if (model.isAnnotationPresent(Table.class)) {
4676
Table table = model.getDeclaredAnnotationsByType(Table.class)[0];
4777
tableName = table.value();
@@ -59,6 +89,26 @@ public TableInfo(Class<? extends Model> model, ORMConfig config) throws ORMConfi
5989
} catch (NoSuchMethodException e) {
6090
throw new ORMConfigurationException("The model class has no empty constructor!");
6191
}
92+
if (model.isAnnotationPresent(RelationField.class)) {
93+
relationField = model.getDeclaredAnnotationsByType(RelationField.class)[0].value();
94+
} else {
95+
relationField = Helper.pascalToCamelCase(model.getSimpleName()) + ((getIdType().equals(UUID.class) && !idField.equalsIgnoreCase("id")) ? "UUID" : "Id");
96+
}
97+
if (model.isAnnotationPresent(SoftDelete.class)) {
98+
softDelete = model.getDeclaredAnnotationsByType(SoftDelete.class)[0];
99+
if (!fields.containsKey(softDelete.value()))
100+
throw new ORMConfigurationException("Missing soft-delete field '" + softDelete.value() + "'");
101+
}
102+
if (model.isAnnotationPresent(Dates.class)) {
103+
dates = model.getDeclaredAnnotationsByType(Dates.class)[0];
104+
if (!fields.containsKey(dates.create()))
105+
throw new ORMConfigurationException("Missing dates field '" + dates.create() + "'");
106+
if (!fields.containsKey(dates.update()))
107+
throw new ORMConfigurationException("Missing dates field '" + dates.update() + "'");
108+
}
109+
}
110+
111+
private void analyzeColumns(Class<? extends Model> model) throws ORMConfigurationException {
62112
for (Field field : model.getDeclaredFields()) {
63113
if (Modifier.isStatic(field.getModifiers()))
64114
continue;
@@ -82,7 +132,7 @@ public TableInfo(Class<? extends Model> model, ORMConfig config) throws ORMConfi
82132
else
83133
fieldSize = fieldConfig.size();
84134

85-
SQLType sqlType = config.getType(field.getType(), fieldSize);
135+
SQLType sqlType = config.getType(field.getType(), fieldSize);
86136
if (sqlType != null) {
87137
sqlTypes.put(fieldName, sqlType);
88138
sqlTypeParameters.put(fieldName, config.getTypeParameters(field.getType(), fieldSize));
@@ -106,31 +156,6 @@ public TableInfo(Class<? extends Model> model, ORMConfig config) throws ORMConfi
106156
if (field.isAnnotationPresent(Searchable.class))
107157
this.searchable.add(fieldName);
108158
}
109-
if (!fields.containsKey(idField))
110-
idField = "uuid";
111-
if (!fields.containsKey(idField))
112-
throw new ORMConfigurationException("No id field found!");
113-
if (model.isAnnotationPresent(RelationField.class)) {
114-
relationField = model.getDeclaredAnnotationsByType(RelationField.class)[0].value();
115-
} else {
116-
relationField = Helper.pascalToCamelCase(model.getSimpleName()) + ((getIdType().equals(UUID.class) && !idField.equalsIgnoreCase("id")) ? "UUID" : "Id");
117-
}
118-
if (config.isIdPrimaryKey()) {
119-
if (primaryKey == null)
120-
primaryKey = idField;
121-
}
122-
if (model.isAnnotationPresent(SoftDelete.class)) {
123-
softDelete = model.getDeclaredAnnotationsByType(SoftDelete.class)[0];
124-
if (!fields.containsKey(softDelete.value()))
125-
throw new ORMConfigurationException("Missing soft-delete field '" + softDelete.value() + "'");
126-
}
127-
if (model.isAnnotationPresent(Dates.class)) {
128-
dates = model.getDeclaredAnnotationsByType(Dates.class)[0];
129-
if (!fields.containsKey(dates.create()))
130-
throw new ORMConfigurationException("Missing dates field '" + dates.create() + "'");
131-
if (!fields.containsKey(dates.update()))
132-
throw new ORMConfigurationException("Missing dates field '" + dates.update() + "'");
133-
}
134159
}
135160

136161
public boolean isSoftDelete() {

src/main/java/org/javawebstack/orm/util/Helper.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.javawebstack.orm.util;
22

3+
import java.util.Stack;
4+
35
public class Helper {
46

57
public static String toSnakeCase(String source) {
@@ -41,4 +43,15 @@ public static String toCamelCase(String source) {
4143
return sb.toString();
4244
}
4345

46+
public static Stack<Class<?>> getSuperClassesTill(Class<?> clazz, Class<?> target) {
47+
Stack<Class<?>> stack = new Stack<>();
48+
Class<?> superClass = clazz.getSuperclass();
49+
50+
while (superClass != null && superClass != target) {
51+
stack.push(superClass);
52+
superClass = superClass.getSuperclass();
53+
}
54+
55+
return stack;
56+
}
4457
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package org.javawebstack.orm.test;
2+
3+
import org.javawebstack.orm.Model;
4+
import org.javawebstack.orm.ORM;
5+
import org.javawebstack.orm.ORMConfig;
6+
import org.javawebstack.orm.Repo;
7+
import org.javawebstack.orm.annotation.Column;
8+
import org.javawebstack.orm.exception.ORMConfigurationException;
9+
import org.javawebstack.orm.util.KeyType;
10+
import org.junit.jupiter.api.Test;
11+
12+
import static org.junit.jupiter.api.Assertions.*;
13+
14+
public class TableInfoTest extends ORMTestCase {
15+
@Test
16+
public void testParentTableInfo () throws ORMConfigurationException {
17+
ORMConfig config = new ORMConfig()
18+
.setDefaultSize(255);
19+
ORM.register(Child.class, sql(), config);
20+
21+
assertEquals(Repo.get(Child.class).getInfo().getFields().size(), 2);
22+
}
23+
24+
@Test
25+
public void testParentTableMigration () throws ORMConfigurationException {
26+
ORMConfig config = new ORMConfig()
27+
.setDefaultSize(255);
28+
ORM.register(Child.class, sql(), config);
29+
ORM.autoMigrate(true);
30+
31+
Child child = new Child();
32+
child.id = 1337;
33+
child.content = "Hello World!";
34+
child.save();
35+
36+
Child fetchedChild = Repo.get(Child.class).get(1337);
37+
assertEquals(fetchedChild.id, child.id);
38+
assertEquals(fetchedChild.content, child.content);
39+
}
40+
41+
@Test
42+
public void testNonAbstractParent () throws ORMConfigurationException {
43+
ORMConfig config = new ORMConfig()
44+
.setDefaultSize(255);
45+
46+
assertThrows(ORMConfigurationException.class, () -> ORM.register(SecondChild.class, sql(), config), "The parent model has to be abstract!");
47+
}
48+
49+
public static abstract class Parent extends Model {
50+
@Column(ai = true, key = KeyType.PRIMARY)
51+
public int id;
52+
}
53+
54+
public static class Child extends Parent {
55+
@Column
56+
public String content;
57+
}
58+
59+
public static class NonAbstractParent extends Model {
60+
@Column(ai = true, key = KeyType.PRIMARY)
61+
public int id;
62+
}
63+
64+
public static class SecondChild extends NonAbstractParent {
65+
@Column
66+
public String content;
67+
}
68+
}

0 commit comments

Comments
 (0)