Skip to content

Commit 5994167

Browse files
committed
Started working on a tool that simplifies supporting both SQL and NoSQL
0 parents  commit 5994167

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2740
-0
lines changed

.gitignore

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Ignore everything by default
2+
*
3+
4+
!.gitignore
5+
!README.md
6+
!LICENSE
7+
!license_header.txt
8+
9+
# Don't ignore specific gradle files and folders
10+
!gradle
11+
!gradle/**
12+
!*.gradle.kts
13+
!gradle.properties
14+
!gradlew*
15+
16+
# Don't ignore the modules and its contents
17+
!ap
18+
!ap/src
19+
!ap/src/**
20+
!core
21+
!core/src
22+
!core/src/**
23+
!database
24+
!database/common
25+
!database/common/src
26+
!database/common/src/**
27+
!database/mongo
28+
!database/mongo/src
29+
!database/mongo/src/**
30+
!database/sql
31+
!database/sql/src
32+
!database/sql/src/**

ap/build.gradle.kts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
dependencies {
2+
implementation(projects.core)
3+
4+
implementation(projects.databaseSql)
5+
implementation(libs.sqlbuilder)
6+
7+
implementation(projects.databaseMongo)
8+
9+
implementation(libs.javapoet)
10+
implementation(libs.auto.service)
11+
annotationProcessor(libs.auto.service)
12+
13+
testImplementation(libs.compile.testing)
14+
testImplementation(platform("org.junit:junit-bom:5.9.1"))
15+
testImplementation("org.junit.jupiter:junit-jupiter")
16+
}
17+
18+
tasks.withType<Test>().configureEach {
19+
doFirst {
20+
// See: https://github.com/google/compile-testing/issues/222
21+
if (javaLauncher.get().metadata.languageVersion >= JavaLanguageVersion.of(9)) {
22+
jvmArgs(
23+
"--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
24+
"--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
25+
"--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED"
26+
)
27+
}
28+
}
29+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/*
2+
* Copyright (c) 2024 GeyserMC <https://geysermc.org>
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+
* THE SOFTWARE.
21+
*
22+
* @author GeyserMC
23+
* @link https://github.com/GeyserMC/DatabaseUtils
24+
*/
25+
package org.geysermc.databaseutils.processor;
26+
27+
import static org.geysermc.databaseutils.processor.util.AnnotationUtils.hasAnnotation;
28+
import static org.geysermc.databaseutils.processor.util.TypeUtils.toBoxedTypeElement;
29+
30+
import java.util.ArrayList;
31+
import java.util.Arrays;
32+
import java.util.Collection;
33+
import java.util.HashMap;
34+
import java.util.Map;
35+
import java.util.Objects;
36+
import javax.lang.model.element.Element;
37+
import javax.lang.model.element.ElementKind;
38+
import javax.lang.model.element.ExecutableElement;
39+
import javax.lang.model.element.Modifier;
40+
import javax.lang.model.element.TypeElement;
41+
import javax.lang.model.element.VariableElement;
42+
import javax.lang.model.util.Types;
43+
import org.geysermc.databaseutils.meta.Entity;
44+
import org.geysermc.databaseutils.meta.Key;
45+
import org.geysermc.databaseutils.processor.info.ColumnInfo;
46+
import org.geysermc.databaseutils.processor.info.EntityInfo;
47+
import org.geysermc.databaseutils.processor.info.IndexInfo;
48+
49+
final class EntityManager {
50+
private final Map<CharSequence, EntityInfo> entityInfoByClassName = new HashMap<>();
51+
private final Types typeUtils;
52+
53+
EntityManager(final Types typeUtils) {
54+
this.typeUtils = Objects.requireNonNull(typeUtils);
55+
}
56+
57+
Collection<EntityInfo> processedEntities() {
58+
return entityInfoByClassName.values();
59+
}
60+
61+
EntityInfo processEntity(TypeElement type) {
62+
var cached = entityInfoByClassName.get(type.getQualifiedName());
63+
if (cached != null) {
64+
return cached;
65+
}
66+
67+
Entity entity = type.getAnnotation(Entity.class);
68+
if (entity == null) {
69+
throw new IllegalStateException("Tried to process entity without an Entity annotation");
70+
}
71+
String tableName = entity.value();
72+
73+
var constructors = new ArrayList<ExecutableElement>();
74+
var keys = new ArrayList<CharSequence>();
75+
76+
var indexes = new ArrayList<IndexInfo>();
77+
var columns = new ArrayList<ColumnInfo>();
78+
79+
Arrays.stream(type.getAnnotationsByType(org.geysermc.databaseutils.meta.Index.class))
80+
.map(index -> new IndexInfo(index.name(), index.columns(), index.unique()))
81+
.forEach(indexes::add);
82+
83+
for (Element element : type.getEnclosedElements()) {
84+
if (element.getKind() == ElementKind.CONSTRUCTOR) {
85+
var constructor = (ExecutableElement) element;
86+
if (!constructor.getParameters().isEmpty()) {
87+
constructors.add(constructor);
88+
}
89+
continue;
90+
}
91+
if (element.getKind() != ElementKind.FIELD) {
92+
continue;
93+
}
94+
95+
var field = (VariableElement) element;
96+
if (field.getModifiers().contains(Modifier.STATIC)) {
97+
continue;
98+
}
99+
100+
TypeElement typeElement = toBoxedTypeElement(field.asType(), typeUtils);
101+
columns.add(new ColumnInfo(field.getSimpleName(), typeElement.getQualifiedName()));
102+
103+
if (hasAnnotation(field, Key.class)) {
104+
keys.add(field.getSimpleName());
105+
}
106+
var index = field.getAnnotation(org.geysermc.databaseutils.meta.Index.class);
107+
if (index != null) {
108+
indexes.add(new IndexInfo(index.name(), index.columns(), index.unique()));
109+
}
110+
}
111+
112+
boolean validConstructorFound = false;
113+
114+
constructors:
115+
for (ExecutableElement element : constructors) {
116+
var parameters = element.getParameters();
117+
if (parameters.size() != columns.size()) {
118+
continue;
119+
}
120+
121+
for (int i = 0; i < parameters.size(); i++) {
122+
var parameterType = toBoxedTypeElement(parameters.get(i).asType(), typeUtils)
123+
.getQualifiedName();
124+
if (!columns.get(i).typeName().equals(parameterType)) {
125+
continue constructors;
126+
}
127+
}
128+
validConstructorFound = true;
129+
break;
130+
}
131+
132+
if (!validConstructorFound) {
133+
throw new IllegalStateException("No valid all-arg constructor found or invalid parameter order");
134+
}
135+
136+
if (!keys.isEmpty()) {
137+
indexes.add(new IndexInfo("", keys.toArray(new CharSequence[0]), true));
138+
}
139+
140+
var entityInfo = new EntityInfo(tableName, type.getQualifiedName(), columns, indexes, keys.size() >= 2);
141+
entityInfoByClassName.put(type.getQualifiedName(), entityInfo);
142+
return entityInfo;
143+
}
144+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) 2024 GeyserMC <https://geysermc.org>
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+
* THE SOFTWARE.
21+
*
22+
* @author GeyserMC
23+
* @link https://github.com/GeyserMC/DatabaseUtils
24+
*/
25+
package org.geysermc.databaseutils.processor;
26+
27+
import java.util.Map;
28+
import org.geysermc.databaseutils.processor.query.QuerySection;
29+
import org.geysermc.databaseutils.processor.query.selector.AndSelector;
30+
import org.geysermc.databaseutils.processor.query.selector.OrSelector;
31+
32+
final class RegisteredActions {
33+
private static final Map<String, QuerySection> SELECTORS =
34+
Map.of("And", AndSelector.INSTANCE, "Or", OrSelector.INSTANCE);
35+
36+
private RegisteredActions() {}
37+
38+
public static QuerySection selectorFor(String name) {
39+
return SELECTORS.get(name);
40+
}
41+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (c) 2024 GeyserMC <https://geysermc.org>
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+
* THE SOFTWARE.
21+
*
22+
* @author GeyserMC
23+
* @link https://github.com/GeyserMC/DatabaseUtils
24+
*/
25+
package org.geysermc.databaseutils.processor;
26+
27+
import java.util.List;
28+
import java.util.function.Supplier;
29+
import java.util.stream.Collectors;
30+
import org.geysermc.databaseutils.processor.type.DatabaseGenerator;
31+
import org.geysermc.databaseutils.processor.type.RepositoryGenerator;
32+
import org.geysermc.databaseutils.processor.type.SqlDatabaseGenerator;
33+
import org.geysermc.databaseutils.processor.type.SqlRepositoryGenerator;
34+
35+
final class RegisteredGenerators {
36+
// both the database and the repository generators have to be on the same indexes
37+
38+
private static final List<Supplier<DatabaseGenerator>> DATABASE_GENERATORS = List.of(SqlDatabaseGenerator::new);
39+
private static final List<Supplier<RepositoryGenerator>> REPOSITORY_GENERATORS =
40+
List.of(SqlRepositoryGenerator::new);
41+
42+
private RegisteredGenerators() {}
43+
44+
public static List<DatabaseGenerator> databaseGenerators() {
45+
return DATABASE_GENERATORS.stream().map(Supplier::get).collect(Collectors.toList());
46+
}
47+
48+
public static List<RepositoryGenerator> repositoryGenerators() {
49+
return REPOSITORY_GENERATORS.stream().map(Supplier::get).collect(Collectors.toList());
50+
}
51+
52+
public static int generatorCount() {
53+
return DATABASE_GENERATORS.size();
54+
}
55+
}

0 commit comments

Comments
 (0)