Skip to content

Commit 4709aeb

Browse files
authored
Feature/branch 46 (#53)
* Clean up API. * Unwrap templates before adding where clause.
1 parent 96c4da5 commit 4709aeb

File tree

6 files changed

+53
-46
lines changed

6 files changed

+53
-46
lines changed

storm-core/src/main/java/st/orm/core/template/impl/QueryBuilderImpl.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import st.orm.core.template.TemplateString;
3232
import st.orm.core.template.TypedJoinBuilder;
3333
import st.orm.core.template.WhereBuilder;
34+
import st.orm.core.template.impl.Elements.Expression;
3435
import st.orm.core.template.impl.Elements.ObjectExpression;
3536
import st.orm.core.template.impl.Elements.TableSource;
3637
import st.orm.core.template.impl.Elements.TableTarget;
@@ -41,6 +42,7 @@
4142

4243
import java.util.ArrayList;
4344
import java.util.List;
45+
import java.util.Optional;
4446
import java.util.function.Function;
4547
import java.util.function.Supplier;
4648

@@ -524,8 +526,22 @@ protected <V> PredicateBuilder<TX, RX, IDX> whereImpl(@Nonnull Metamodel<?, V> p
524526
}
525527
}
526528

529+
private Object unwrap(@Nonnull TemplateString template) {
530+
if (template.fragments().equals(List.of("", ""))) {
531+
return template.values().getFirst();
532+
}
533+
return null;
534+
}
535+
527536
private QueryBuilder<TX, RX, IDX> build(List<TemplateString> templates) {
528-
return queryBuilder.addWhere(new Where(new TemplateExpression(combine(templates)), null));
537+
var template = combine(templates);
538+
Where where;
539+
if (unwrap(template) instanceof Expression expression) {
540+
where = new Where(expression, null);
541+
} else {
542+
where = new Where(new TemplateExpression(template), null);
543+
}
544+
return queryBuilder.addWhere(where);
529545
}
530546
}
531547

storm-kotlin/src/main/kotlin/st/orm/repository/RepositoryLookup.kt

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,9 @@
1616
package st.orm.repository
1717

1818
import kotlinx.coroutines.flow.Flow
19-
import st.orm.Data
20-
import st.orm.Entity
21-
import st.orm.Metamodel
19+
import st.orm.*
2220
import st.orm.Operator.EQUALS
2321
import st.orm.Operator.IN
24-
import st.orm.Projection
25-
import st.orm.Ref
2622
import st.orm.template.PredicateBuilder
2723
import st.orm.template.QueryBuilder
2824
import st.orm.template.WhereBuilder
@@ -70,7 +66,7 @@ interface RepositoryLookup {
7066
* @param <ID> the type of the projection's primary key, or Void if the projection specifies no primary key.
7167
* @return the repository for the given projection type.
7268
*/
73-
fun <T, ID: Any> projection(type: KClass<T>): ProjectionRepository<T, ID> where T : Projection<ID>
69+
fun <T, ID : Any> projection(type: KClass<T>): ProjectionRepository<T, ID> where T : Projection<ID>
7470

7571
/**
7672
* Returns a proxy for the repository of the given type.
@@ -588,11 +584,11 @@ inline fun <reified T : Data> RepositoryLookup.findAll(
588584
* @return A [QueryBuilder] for selecting records of type [T].
589585
*/
590586
@Suppress("UNCHECKED_CAST")
591-
inline fun <reified T : Data> RepositoryLookup.findAll(predicate: PredicateBuilder<T, T, *>): List<T> =
587+
inline fun <reified T : Data> RepositoryLookup.findAll(predicate: PredicateBuilder<T, *, *>): List<T> =
592588
if (T::class.isSubclassOf(Entity::class))
593-
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).select().where(predicate as PredicateBuilder<Entity<*>, Entity<*>, *>).resultList as List<T>
589+
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).select().where(predicate as PredicateBuilder<Entity<*>, *, *>).resultList as List<T>
594590
else
595-
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).select().where(predicate as PredicateBuilder<Projection<*>, Projection<*>, *>).resultList as List<T>
591+
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).select().where(predicate as PredicateBuilder<Projection<*>, *, *>).resultList as List<T>
596592

597593
/**
598594
* Creates a query builder to select records of type [T].
@@ -618,11 +614,11 @@ inline fun <reified T : Data> RepositoryLookup.findAllRef(
618614
* @return A [QueryBuilder] for selecting records of type [T].
619615
*/
620616
@Suppress("UNCHECKED_CAST")
621-
inline fun <reified T : Data> RepositoryLookup.findAllRef(predicate: PredicateBuilder<T, T, *>): List<Ref<T>> =
617+
inline fun <reified T : Data> RepositoryLookup.findAllRef(predicate: PredicateBuilder<T, *, *>): List<Ref<T>> =
622618
if (T::class.isSubclassOf(Entity::class))
623-
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).selectRef().where(predicate as PredicateBuilder<Entity<*>, Entity<*>, *>).resultList as List<Ref<T>>
619+
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).selectRef().where(predicate as PredicateBuilder<Entity<*>, *, *>).resultList as List<Ref<T>>
624620
else
625-
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).selectRef().where(predicate as PredicateBuilder<Projection<*>, Projection<*>, *>).resultList as List<Ref<T>>
621+
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).selectRef().where(predicate as PredicateBuilder<Projection<*>, *, *>).resultList as List<Ref<T>>
626622

627623
/**
628624
* Creates a query builder to select records of type [T].
@@ -648,11 +644,11 @@ inline fun <reified T : Data> RepositoryLookup.find(
648644
* @return A [QueryBuilder] for selecting records of type [T].
649645
*/
650646
@Suppress("UNCHECKED_CAST")
651-
inline fun <reified T : Data> RepositoryLookup.find(predicate: PredicateBuilder<T, T, *>): T? =
647+
inline fun <reified T : Data> RepositoryLookup.find(predicate: PredicateBuilder<T, *, *>): T? =
652648
if (T::class.isSubclassOf(Entity::class))
653-
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).select().where(predicate as PredicateBuilder<Entity<*>, Entity<*>, *>).optionalResult as T?
649+
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).select().where(predicate as PredicateBuilder<Entity<*>, *, *>).optionalResult as T?
654650
else
655-
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).select().where(predicate as PredicateBuilder<Projection<*>, Projection<*>, *>).optionalResult as T?
651+
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).select().where(predicate as PredicateBuilder<Projection<*>, *, *>).optionalResult as T?
656652

657653
/**
658654
* Creates a query builder to select records of type [T].
@@ -678,11 +674,11 @@ inline fun <reified T : Data> RepositoryLookup.findRef(
678674
* @return A [QueryBuilder] for selecting records of type [T].
679675
*/
680676
@Suppress("UNCHECKED_CAST")
681-
inline fun <reified T : Data> RepositoryLookup.findRef(predicate: PredicateBuilder<T, T, *>): Ref<T> =
677+
inline fun <reified T : Data> RepositoryLookup.findRef(predicate: PredicateBuilder<T, *, *>): Ref<T>? =
682678
if (T::class.isSubclassOf(Entity::class))
683-
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).selectRef().where(predicate as PredicateBuilder<Entity<*>, Entity<*>, *>).singleResult as Ref<T>
679+
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).selectRef().where(predicate as PredicateBuilder<Entity<*>, *, *>).optionalResult as Ref<T>?
684680
else
685-
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).selectRef().where(predicate as PredicateBuilder<Projection<*>, Projection<*>, *>).singleResult as Ref<T>
681+
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).selectRef().where(predicate as PredicateBuilder<Projection<*>, *, *>).optionalResult as Ref<T>?
686682

687683
/**
688684
* Creates a query builder to select records of type [T].
@@ -708,11 +704,11 @@ inline fun <reified T : Data> RepositoryLookup.get(
708704
* @return A [QueryBuilder] for selecting records of type [T].
709705
*/
710706
@Suppress("UNCHECKED_CAST")
711-
inline fun <reified T : Data> RepositoryLookup.get(predicate: PredicateBuilder<T, T, *>): T =
707+
inline fun <reified T : Data> RepositoryLookup.get(predicate: PredicateBuilder<T, *, *>): T =
712708
if (T::class.isSubclassOf(Entity::class))
713-
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).select().where(predicate as PredicateBuilder<Entity<*>, Entity<*>, *>).singleResult as T
709+
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).select().where(predicate as PredicateBuilder<Entity<*>, *, *>).singleResult as T
714710
else
715-
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).select().where(predicate as PredicateBuilder<Projection<*>, Projection<*>, *>).singleResult as T
711+
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).select().where(predicate as PredicateBuilder<Projection<*>, *, *>).singleResult as T
716712

717713
/**
718714
* Creates a query builder to select records of type [T].
@@ -738,11 +734,11 @@ inline fun <reified T : Data> RepositoryLookup.getRef(
738734
* @return A [QueryBuilder] for selecting records of type [T].
739735
*/
740736
@Suppress("UNCHECKED_CAST")
741-
inline fun <reified T : Data> RepositoryLookup.getRef(predicate: PredicateBuilder<T, Ref<T>, *>): Ref<T> =
737+
inline fun <reified T : Data> RepositoryLookup.getRef(predicate: PredicateBuilder<T, *, *>): Ref<T> =
742738
if (T::class.isSubclassOf(Entity::class))
743-
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).selectRef().where(predicate as PredicateBuilder<Entity<*>, Ref<Entity<*>>, *>).singleResult as Ref<T>
739+
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).selectRef().where(predicate as PredicateBuilder<Entity<*>, *, *>).singleResult as Ref<T>
744740
else
745-
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).selectRef().where(predicate as PredicateBuilder<Projection<*>, Ref<Projection<*>>, *>).singleResult as Ref<T>
741+
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).selectRef().where(predicate as PredicateBuilder<Projection<*>, *, *>).singleResult as Ref<T>
746742

747743
/**
748744
* Creates a query builder to select records of type [T].
@@ -768,11 +764,11 @@ inline fun <reified T : Data> RepositoryLookup.select(
768764
* @return A [QueryBuilder] for selecting records of type [T].
769765
*/
770766
@Suppress("UNCHECKED_CAST")
771-
inline fun <reified T : Data> RepositoryLookup.select(predicate: PredicateBuilder<T, T, *>): Flow<T> =
767+
inline fun <reified T : Data> RepositoryLookup.select(predicate: PredicateBuilder<T, *, *>): Flow<T> =
772768
if (T::class.isSubclassOf(Entity::class))
773-
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).select().where(predicate as PredicateBuilder<Entity<*>, Entity<*>, *>).resultFlow as Flow<T>
769+
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).select().where(predicate as PredicateBuilder<Entity<*>, *, *>).resultFlow as Flow<T>
774770
else
775-
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).select().where(predicate as PredicateBuilder<Projection<*>, Projection<*>, *>).resultFlow as Flow<T>
771+
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).select().where(predicate as PredicateBuilder<Projection<*>, *, *>).resultFlow as Flow<T>
776772

777773
/**
778774
* Creates a query builder to select records of type [T].
@@ -798,11 +794,11 @@ inline fun <reified T : Data> RepositoryLookup.selectRef(
798794
* @return A [QueryBuilder] for selecting records of type [T].
799795
*/
800796
@Suppress("UNCHECKED_CAST")
801-
inline fun <reified T : Data> RepositoryLookup.selectRef(predicate: PredicateBuilder<T, Ref<T>, *>): Flow<Ref<T>> =
797+
inline fun <reified T : Data> RepositoryLookup.selectRef(predicate: PredicateBuilder<T, *, *>): Flow<Ref<T>> =
802798
if (T::class.isSubclassOf(Entity::class))
803-
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).selectRef().where(predicate as PredicateBuilder<Entity<*>, Ref<Entity<*>>, *>).resultFlow as Flow<Ref<T>>
799+
(entity(T::class as KClass<Entity<Any>>) as EntityRepository<Entity<*>, *>).selectRef().where(predicate as PredicateBuilder<Entity<*>, *, *>).resultFlow as Flow<Ref<T>>
804800
else
805-
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).selectRef().where(predicate as PredicateBuilder<Projection<*>, Ref<Projection<*>>, *>).resultFlow as Flow<Ref<T>>
801+
(projection(T::class as KClass<Projection<Any>>) as ProjectionRepository<Projection<*>, *>).selectRef().where(predicate as PredicateBuilder<Projection<*>, *, *>).resultFlow as Flow<Ref<T>>
806802

807803
/**
808804
* Creates a query builder to select records of type [T].
@@ -1121,7 +1117,7 @@ inline fun <reified T : Entity<*>> RepositoryLookup.deleteAll() =
11211117
* @param value the ID value to match against.
11221118
* @return the number of entities deleted (0 or 1).
11231119
*/
1124-
inline fun <reified T : Entity<ID>, ID> RepositoryLookup.deleteBy(field: Metamodel<T, ID>, value: ID): Int =
1120+
inline fun <reified T : Entity<ID>, ID : Any> RepositoryLookup.deleteBy(field: Metamodel<T, ID>, value: ID): Int =
11251121
entity<T>().delete().where(field, EQUALS, value).executeUpdate()
11261122

11271123
/**

storm-kotlin/src/main/kotlin/st/orm/template/PredicateBuilder.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ interface PredicateBuilder<T : Data, R, ID> {
5454
* This method combines the specified predicate with existing predicates using an AND operation, ensuring
5555
* that all added conditions must be true.
5656
*
57-
* @param builder the predicate builder to add.
57+
* @param template the predicate builder to add.
5858
* @return the predicate builder.
5959
*/
60-
fun and(builder: TemplateBuilder) : PredicateBuilder<T, R, ID> {
61-
return and(builder.build())
60+
fun and(template: TemplateBuilder) : PredicateBuilder<T, R, ID> {
61+
return and(template.build())
6262
}
6363

6464
/**
@@ -102,11 +102,11 @@ interface PredicateBuilder<T : Data, R, ID> {
102102
* This method combines the specified predicate with existing predicates using an OR operation, ensuring
103103
* that all added conditions must be true.
104104
*
105-
* @param builder the predicate builder to add.
105+
* @param template the predicate builder to add.
106106
* @return the predicate builder.
107107
*/
108-
fun or(builder: TemplateBuilder) : PredicateBuilder<T, R, ID> {
109-
return or(builder.build())
108+
fun or(template: TemplateBuilder) : PredicateBuilder<T, R, ID> {
109+
return or(template.build())
110110
}
111111

112112
/**

storm-kotlin/src/main/kotlin/st/orm/template/Query.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616
package st.orm.template
1717

18-
import jakarta.annotation.Nonnull
1918
import kotlinx.coroutines.flow.Flow
2019
import kotlinx.coroutines.stream.consumeAsFlow
2120
import st.orm.Data
@@ -326,7 +325,7 @@ interface Query {
326325
* @param <T> the type of the result.
327326
* @throws NonUniqueResultException if more than one result.
328327
*/
329-
private fun <T> optionalResult(@Nonnull stream: Stream<T>): T? {
328+
private fun <T> optionalResult(stream: Stream<T>): T? {
330329
stream.use {
331330
return stream
332331
.reduce { _, _ ->

storm-kotlin/src/main/kotlin/st/orm/template/SubqueryTemplate.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ interface SubqueryTemplate {
6262
* @return the subquery builder.
6363
* @param <T> the table type to select from.
6464
*/
65-
fun <T : Data> subquery(fromType: KClass<T>, builder: TemplateBuilder): QueryBuilder<T, *, *> {
66-
return subquery(fromType, builder.build())
65+
fun <T : Data> subquery(fromType: KClass<T>, template: TemplateBuilder): QueryBuilder<T, *, *> {
66+
return subquery(fromType, template.build())
6767
}
6868

6969
/**

storm-kotlin/src/main/kotlin/st/orm/template/TemplateString.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,20 @@ sealed interface TemplateString {
2424
/**
2525
* Create a new template string from the given [TemplateBuilder].
2626
*/
27-
@JvmStatic
2827
fun raw(builder: TemplateBuilder): TemplateString = builder.build()
2928

3029
/**
3130
* Create a new template string from the given [TemplateBuilder].
3231
*/
33-
@JvmStatic
3432
fun raw(str: String): TemplateString =
3533
TemplateStringHolder(st.orm.core.template.TemplateString.of(str))
3634

3735
/**
3836
* Create a new template string from the given [TemplateBuilder].
3937
*/
40-
@JvmStatic
4138
fun wrap(value: Any?): TemplateString =
4239
TemplateStringHolder(st.orm.core.template.TemplateString.wrap(value))
4340

44-
@JvmStatic
4541
fun combine(vararg templates: TemplateString): TemplateString =
4642
TemplateStringHolder(st.orm.core.template.TemplateString.combine(*templates.map { it.unwrap }.toTypedArray()))
4743
}

0 commit comments

Comments
 (0)