├── .idea └── .name ├── .gitignore ├── src ├── main │ ├── resources │ │ └── component.marker │ └── java │ │ └── sirius │ │ └── db │ │ ├── text │ │ ├── ToLowercaseProcessor.java │ │ ├── PurgeProcessor.java │ │ ├── ReduceCharacterProcessor.java │ │ ├── TokenProcessor.java │ │ ├── BasicSearchTokenizer.java │ │ ├── DeduplicateProcessor.java │ │ ├── TokenLimitProcessor.java │ │ └── PatternReplaceProcessor.java │ │ ├── mongo │ │ ├── package-info.java │ │ ├── MongoEntityCache.java │ │ ├── IndexDescription.java │ │ ├── types │ │ │ ├── MultiPointLocation.java │ │ │ └── MongoRefList.java │ │ ├── constraints │ │ │ └── MongoConstraint.java │ │ └── facets │ │ │ └── MongoFacet.java │ │ ├── jdbc │ │ ├── schema │ │ │ ├── MariaDBDatabaseDialect.java │ │ │ └── SQLPropertyInfo.java │ │ ├── constraints │ │ │ ├── Or.java │ │ │ ├── And.java │ │ │ ├── SQLConstraint.java │ │ │ ├── Not.java │ │ │ ├── Filled.java │ │ │ ├── NotFilled.java │ │ │ └── FieldOperator.java │ │ ├── SQLEntityCache.java │ │ ├── Operator.java │ │ ├── MonitoredDataSource.java │ │ ├── batch │ │ │ └── BatchSQLQuery.java │ │ └── TranslationState.java │ │ ├── mixing │ │ ├── types │ │ │ ├── StringMap.java │ │ │ ├── StringIntMap.java │ │ │ ├── StringBooleanMap.java │ │ │ ├── StringLocalDateTimeMap.java │ │ │ ├── StringList.java │ │ │ ├── NestedList.java │ │ │ └── StringNestedMap.java │ │ ├── annotations │ │ │ ├── Lob.java │ │ │ ├── Versioned.java │ │ │ ├── NullAllowed.java │ │ │ ├── Trim.java │ │ │ ├── Transient.java │ │ │ ├── Ordinal.java │ │ │ ├── RemoveWhitespace.java │ │ │ ├── LowerCase.java │ │ │ ├── UpperCase.java │ │ │ ├── MaxValue.java │ │ │ ├── MinValue.java │ │ │ ├── DefaultValue.java │ │ │ ├── Realm.java │ │ │ ├── Positive.java │ │ │ ├── Engine.java │ │ │ ├── RelationName.java │ │ │ ├── Indices.java │ │ │ ├── AfterDelete.java │ │ │ ├── BeforeDelete.java │ │ │ ├── Length.java │ │ │ ├── Mixin.java │ │ │ ├── Numeric.java │ │ │ ├── BeforeSave.java │ │ │ ├── AfterSave.java │ │ │ ├── OnValidate.java │ │ │ ├── SkipDefaultValue.java │ │ │ ├── Unique.java │ │ │ ├── ComplexDelete.java │ │ │ ├── ValidatedBy.java │ │ │ └── TranslationSource.java │ │ ├── Composite.java │ │ ├── query │ │ │ ├── constraints │ │ │ │ └── Constraint.java │ │ │ └── QueryTagHandler.java │ │ ├── PropertyValidator.java │ │ ├── ContextInfo.java │ │ ├── InvalidFieldException.java │ │ ├── MixinLoadAction.java │ │ └── IntegrityConstraintFailedException.java │ │ ├── DB.java │ │ ├── es │ │ ├── annotations │ │ │ ├── RoutedBy.java │ │ │ ├── ESOption.java │ │ │ └── CustomSettings.java │ │ ├── IndexNaming.java │ │ ├── SettingsCustomizer.java │ │ └── types │ │ │ └── ElasticRefList.java │ │ ├── redis │ │ └── Subscriber.java │ │ └── KeyGenerator.java └── test │ ├── resources │ ├── component.marker │ ├── test_de.properties │ ├── docker-db.yml │ └── test.conf │ ├── java │ ├── sirius │ │ └── db │ │ │ ├── mongo │ │ │ ├── properties │ │ │ │ ├── MongoStringMapMixinEntity.java │ │ │ │ ├── MongoStringListMixinEntity.java │ │ │ │ ├── MongoStringMapEntity.java │ │ │ │ ├── MongoStringIntMapEntity.java │ │ │ │ ├── MongoStringListEntity.java │ │ │ │ ├── MongoStringListMapEntity.java │ │ │ │ ├── MongoStringBooleanMapEntity.java │ │ │ │ ├── MongoExistsEntity.java │ │ │ │ ├── MongoMultiPointEntity.java │ │ │ │ ├── MongoStringMapMixin.java │ │ │ │ ├── MongoStringListMixin.java │ │ │ │ ├── MongoFilledEntity.java │ │ │ │ ├── MongoAmountEntity.java │ │ │ │ ├── MongoNestedListEntity.java │ │ │ │ └── MongoStringNestedMapEntity.java │ │ │ ├── MangoListTestEntity.java │ │ │ ├── MangoAggregationsTestEntity.java │ │ │ ├── MongoLockedTestEntity.java │ │ │ ├── MongoUniqueTestEntity.java │ │ │ ├── PrefixTestEntity.java │ │ │ ├── MangoWasCreatedTestEntity.java │ │ │ └── validators │ │ │ │ └── StringTestPropertyValidator.java │ │ │ ├── mixing │ │ │ ├── WriteOnceParentEntity.java │ │ │ ├── MongoComposite.java │ │ │ ├── MongoMixable.java │ │ │ ├── RefListElasticEntity.java │ │ │ ├── RefMongoEntity.java │ │ │ ├── RefElasticEntity.java │ │ │ ├── RefListMongoEntity.java │ │ │ ├── WriteOnceChildEntity.java │ │ │ ├── fieldlookup │ │ │ │ ├── MongoSuperHeroTestMixin.java │ │ │ │ ├── NameFieldsTestComposite.java │ │ │ │ └── SQLSuperHeroTestMixin.java │ │ │ ├── RefEntity.java │ │ │ └── properties │ │ │ │ └── DateEntity.java │ │ │ ├── jdbc │ │ │ ├── TestCompositeWithComposite.java │ │ │ ├── TestClobEntity.java │ │ │ ├── ListTestEntity.java │ │ │ ├── TransformedQueryTestEntity.java │ │ │ ├── TestMixinMixin.java │ │ │ ├── SmartQueryTestMixinEntity.java │ │ │ ├── TestEntityWithComposite.java │ │ │ ├── SQLStringListNonNullAllowedPropertyEntity.java │ │ │ ├── SQLLockedTestEntity.java │ │ │ ├── SQLUniqueTestEntity.java │ │ │ ├── SmartQueryTestParentEntity.java │ │ │ ├── TestMixin.java │ │ │ ├── SmartQueryTestMixinEntityMixin.java │ │ │ ├── SmartQueryTestLargeTableEntity.java │ │ │ ├── LegacyEntity.java │ │ │ ├── TestComposite.java │ │ │ ├── SQLWasCreatedTestEntity.java │ │ │ ├── SQLStringListPropertyEntity.java │ │ │ ├── SmartQueryTestChildChildEntity.java │ │ │ ├── SmartQueryTestEntity.java │ │ │ ├── TestEntityWithNullRef.java │ │ │ ├── SmartQueryTestCountEntity.java │ │ │ ├── TestEntityWithMixin.java │ │ │ ├── GeneratedStatementTestEntity.java │ │ │ ├── SmartQueryTestSortingEntity.java │ │ │ └── SmartQueryTest.java │ │ │ └── es │ │ │ ├── ESListTestEntity.java │ │ │ ├── properties │ │ │ ├── ESStringMapEntity.java │ │ │ ├── ESStringListEntity.java │ │ │ ├── ESStringListMapEntity.java │ │ │ ├── ESStringBooleanMapEntity.java │ │ │ ├── ESFilledEntity.java │ │ │ ├── ESStringLocalDateTimeMapEntity.java │ │ │ ├── ESDenseVectorEntity.java │ │ │ └── ESNestedListEntity.java │ │ │ ├── LockedTestEntity.java │ │ │ ├── BatchTestEntity.java │ │ │ ├── ElasticWasCreatedTestEntity.java │ │ │ ├── RoutedBatchTestEntity.java │ │ │ ├── SuggestTestEntity.java │ │ │ ├── ElasticTestEntity.java │ │ │ ├── RoutedTestEntity.java │ │ │ └── SuppressedRoutedTestEntity.java │ └── TestSuite.java │ └── kotlin │ └── sirius │ └── db │ ├── text │ ├── PatternReplaceProcessorTest.kt │ ├── ToLowercaseProcessorTest.kt │ ├── PatternExtractProcessorTest.kt │ ├── TokenProcessorTest.kt │ ├── ReduceCharactersProcessorTest.kt │ ├── TokenLimitProcessorTest.kt │ ├── PatternSplitProcessorTest.kt │ ├── PipelineProcessorTest.kt │ └── BasicIndexTokenizerTest.kt │ ├── util │ └── TensorsTest.kt │ ├── testutil │ └── MongoMocks.kt │ ├── mixing │ ├── CompositeTest.kt │ └── properties │ │ ├── LocalDatePropertyTest.kt │ │ ├── LocalTimePropertyTest.kt │ │ └── LocalDateTimePropertyTest.kt │ ├── redis │ └── RedisTest.kt │ ├── jdbc │ └── SmartQueryNighlyTest.kt │ ├── mongo │ └── properties │ │ ├── MongoMultiPointTest.kt │ │ ├── MongoStringMapPropertyTest.kt │ │ └── MongoStringIntMapPropertyTest.kt │ └── es │ └── properties │ ├── ElasticStringMapPropertyTest.kt │ ├── ElasticStringListPropertyTest.kt │ ├── ElasticStringListMapPropertyTest.kt │ └── ElasticStringBooleanMapPropertyTest.kt ├── .github ├── workflows │ ├── main.yml │ ├── ga-releases.yml │ └── enforce-pr-label.yml ├── PULL_REQUEST_TEMPLATE.md └── ga-release-drafter.yml └── .run ├── local install.run.xml └── mvn clean test - without nightly.run.xml /.idea/.name: -------------------------------------------------------------------------------- 1 | sirius-db -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | *.iml 3 | .idea -------------------------------------------------------------------------------- /src/main/resources/component.marker: -------------------------------------------------------------------------------- 1 | This file is discovered by sirius.kernel.Classpath and marks a classpath root which will be scanned. -------------------------------------------------------------------------------- /src/test/resources/component.marker: -------------------------------------------------------------------------------- 1 | This file is discovered by sirius.kernel.Classpath and marks a classpath root which will be scanned. -------------------------------------------------------------------------------- /src/test/resources/test_de.properties: -------------------------------------------------------------------------------- 1 | ESDataTypesEntity.enumValue=Enum Value 2 | Model.firstname=Vorname 3 | Model.shortStringList=Model.shortStringList 4 | MongoIntEntity.testIntPositive=MongoIntEntity.testIntPositive 5 | MongoIntEntity.testIntMaxHundred=MongoIntEntity.testIntMaxHundred 6 | MongoIntEntity.testIntMinHundred=MongoIntEntity.testIntMinHundred 7 | ValidatedByTestEntity.stringTest=ValidatedByTestEntity.stringTest 8 | -------------------------------------------------------------------------------- /src/test/java/sirius/db/mongo/properties/MongoStringMapMixinEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Made with all the love in the world 3 | * by scireum in Remshalden, Germany 4 | * 5 | * Copyright by scireum GmbH 6 | * http://www.scireum.de - info@scireum.de 7 | */ 8 | 9 | package sirius.db.mongo.properties; 10 | 11 | import sirius.db.mongo.MongoEntity; 12 | 13 | public class MongoStringMapMixinEntity extends MongoEntity { 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/sirius/db/mongo/properties/MongoStringListMixinEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Made with all the love in the world 3 | * by scireum in Remshalden, Germany 4 | * 5 | * Copyright by scireum GmbH 6 | * http://www.scireum.de - info@scireum.de 7 | */ 8 | 9 | package sirius.db.mongo.properties; 10 | 11 | import sirius.db.mongo.MongoEntity; 12 | 13 | public class MongoStringListMixinEntity extends MongoEntity { 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/sirius/db/mixing/WriteOnceParentEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Made with all the love in the world 3 | * by scireum in Remshalden, Germany 4 | * 5 | * Copyright by scireum GmbH 6 | * http://www.scireum.de - info@scireum.de 7 | */ 8 | 9 | package sirius.db.mixing; 10 | 11 | import sirius.db.jdbc.SQLEntity; 12 | import sirius.db.mixing.annotations.ComplexDelete; 13 | 14 | @ComplexDelete(false) 15 | public class WriteOnceParentEntity extends SQLEntity { 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/TestSuite.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Made with all the love in the world 3 | * by scireum in Remshalden, Germany 4 | * 5 | * Copyright by scireum GmbH 6 | * http://www.scireum.de - info@scireum.de 7 | */ 8 | 9 | import com.googlecode.junittoolbox.SuiteClasses; 10 | import org.junit.runner.RunWith; 11 | import sirius.kernel.ScenarioSuite; 12 | 13 | @RunWith(ScenarioSuite.class) 14 | @SuiteClasses({"**/*Test.class", "**/*Spec.class"}) 15 | public class TestSuite { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/sirius/db/text/ToLowercaseProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Made with all the love in the world 3 | * by scireum in Remshalden, Germany 4 | * 5 | * Copyright by scireum GmbH 6 | * http://www.scireum.de - info@scireum.de 7 | */ 8 | 9 | package sirius.db.text; 10 | 11 | /** 12 | * Converts all tokens to lowercase. 13 | */ 14 | public class ToLowercaseProcessor extends ChainableTokenProcessor { 15 | 16 | @Override 17 | public void accept(String token) { 18 | emit(token.toLowerCase()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/sirius/db/jdbc/TestCompositeWithComposite.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Made with all the love in the world 3 | * by scireum in Remshalden, Germany 4 | * 5 | * Copyright by scireum GmbH 6 | * http://www.scireum.de - info@scireum.de 7 | */ 8 | 9 | package sirius.db.jdbc; 10 | 11 | import sirius.db.mixing.Composite; 12 | 13 | public class TestCompositeWithComposite extends Composite { 14 | 15 | private final TestComposite composite = new TestComposite(); 16 | 17 | public TestComposite getComposite() { 18 | return composite; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Automatic Releases 2 | 3 | on: 4 | push: 5 | branches: [ "develop" ] 6 | tags: 7 | - "dev-*.*.*" 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v3 16 | if: startsWith(github.ref, 'refs/tags/') 17 | 18 | - name: Release 19 | uses: softprops/action-gh-release@v0.1.14 20 | if: startsWith(github.ref, 'refs/tags/') 21 | with: 22 | prerelease: true 23 | generate_release_notes: true 24 | -------------------------------------------------------------------------------- /src/main/java/sirius/db/text/PurgeProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Made with all the love in the world 3 | * by scireum in Remshalden, Germany 4 | * 5 | * Copyright by scireum GmbH 6 | * http://www.scireum.de - info@scireum.de 7 | */ 8 | 9 | package sirius.db.text; 10 | 11 | /** 12 | * Invokes {@link #purge()} after each token which is simply forwarded to the downstream processor. 13 | */ 14 | public class PurgeProcessor extends ChainableTokenProcessor { 15 | 16 | @Override 17 | public void accept(String token) { 18 | emit(token); 19 | purge(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/sirius/db/mixing/MongoComposite.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Made with all the love in the world 3 | * by scireum in Remshalden, Germany 4 | * 5 | * Copyright by scireum GmbH 6 | * http://www.scireum.de - info@scireum.de 7 | */ 8 | 9 | package sirius.db.mixing; 10 | 11 | import sirius.db.mixing.types.StringMap; 12 | 13 | public class MongoComposite extends Composite { 14 | 15 | public static final Mapping MAP = Mapping.named("map"); 16 | private final StringMap map = new StringMap(); 17 | 18 | public StringMap getMap() { 19 | return map; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/sirius/db/mongo/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Made with all the love in the world 3 | * by scireum in Remshalden, Germany 4 | * 5 | * Copyright by scireum GmbH 6 | * http://www.scireum.de - info@scireum.de 7 | */ 8 | 9 | /** 10 | * Thin layer above Mongo DB. 11 | *
12 | * Basically this provides a connection pool which can be configured via the system configuration (namely 13 | * mongo.host and mongo.db). 14 | *
15 | * It also provides fluent query builders for CRUD operations. 16 | * 17 | * @see sirius.db.mongo.Mongo 18 | */ 19 | package sirius.db.mongo; -------------------------------------------------------------------------------- /src/test/java/sirius/db/jdbc/TestClobEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Made with all the love in the world 3 | * by scireum in Remshalden, Germany 4 | * 5 | * Copyright by scireum GmbH 6 | * http://www.scireum.de - info@scireum.de 7 | */ 8 | 9 | package sirius.db.jdbc; 10 | 11 | import sirius.db.mixing.annotations.Lob; 12 | 13 | public class TestClobEntity extends SQLEntity { 14 | 15 | @Lob 16 | private String largeValue; 17 | 18 | public String getLargeValue() { 19 | return largeValue; 20 | } 21 | 22 | public void setLargeValue(String largeValue) { 23 | this.largeValue = largeValue; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/sirius/db/jdbc/schema/MariaDBDatabaseDialect.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Made with all the love in the world 3 | * by scireum in Remshalden, Germany 4 | * 5 | * Copyright by scireum GmbH 6 | * http://www.scireum.de - info@scireum.de 7 | */ 8 | 9 | package sirius.db.jdbc.schema; 10 | 11 | import sirius.kernel.di.std.Register; 12 | 13 | /** 14 | * Defines the dialect used to sync the schema against a MariaDB database. 15 | *
16 | * This is for now equal to a MySQL database.
17 | */
18 | @Register(name = "mariadb", classes = DatabaseDialect.class)
19 | public class MariaDBDatabaseDialect extends MySQLDatabaseDialect {
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/types/StringMap.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.types;
10 |
11 | /**
12 | * Provides a simple string-string map as property value.
13 | */
14 | public class StringMap extends SafeMap
20 | * By default all columns are NON-NULL.
21 | */
22 | @Documented
23 | @Retention(RetentionPolicy.RUNTIME)
24 | @Target(ElementType.FIELD)
25 | public @interface NullAllowed {
26 | }
27 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/jdbc/SQLStringListNonNullAllowedPropertyEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.jdbc;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.annotations.Length;
13 | import sirius.db.mixing.types.StringList;
14 |
15 | public class SQLStringListNonNullAllowedPropertyEntity extends SQLEntity {
16 |
17 | public static final Mapping STRING_LIST = Mapping.named("stringList");
18 | @Length(4096)
19 | private final StringList stringList = new StringList();
20 |
21 |
22 | public StringList getStringList() {
23 | return stringList;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/jdbc/SQLLockedTestEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.jdbc;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.annotations.Length;
13 | import sirius.db.mixing.annotations.Versioned;
14 |
15 | @Versioned
16 | public class SQLLockedTestEntity extends SQLEntity {
17 |
18 | public static final Mapping VALUE = Mapping.named("value");
19 | @Length(50)
20 | private String value;
21 |
22 | public String getValue() {
23 | return value;
24 | }
25 |
26 | public void setValue(String value) {
27 | this.value = value;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/.github/workflows/ga-releases.yml:
--------------------------------------------------------------------------------
1 | name: Automatic GA Release Drafts
2 |
3 | on:
4 | push:
5 | # branches to consider in the event; optional, defaults to all
6 | branches:
7 | - master
8 |
9 | permissions:
10 | contents: read
11 |
12 | jobs:
13 | update_release_draft:
14 | permissions:
15 | # write permission is required to create a github release
16 | contents: write
17 | pull-requests: read
18 | runs-on: ubuntu-latest
19 | steps:
20 | # Drafts your next Release notes as Pull Requests are merged into "master"
21 | - uses: release-drafter/release-drafter@v5
22 | with:
23 | config-name: ga-release-drafter.yml
24 | disable-autolabeler: true
25 | env:
26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
27 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/Trim.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import java.lang.annotation.Documented;
12 | import java.lang.annotation.ElementType;
13 | import java.lang.annotation.Retention;
14 | import java.lang.annotation.RetentionPolicy;
15 | import java.lang.annotation.Target;
16 |
17 | /**
18 | * Marks a string property as auto trimmed.
19 | *
20 | * The value of this property will be trimmed before it is written to the database.
21 | */
22 | @Documented
23 | @Retention(RetentionPolicy.RUNTIME)
24 | @Target(ElementType.FIELD)
25 | public @interface Trim {
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/jdbc/SQLEntityCache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.jdbc;
10 |
11 | import sirius.db.util.BaseEntityCache;
12 | import sirius.kernel.di.std.Part;
13 |
14 | /**
15 | * Provides a template for caching JDBC/SQL entities in an on-heap cache.
16 | *
17 | * @param
17 | * Many characters like umlauts or ligatures are "down converted" by this processor into their ASCII representation.
18 | */
19 | public class ReduceCharacterProcessor extends ChainableTokenProcessor {
20 |
21 | @Override
22 | public void accept(String token) {
23 | emit(Strings.cleanup(token, StringCleanup::reduceCharacters));
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/mongo/MongoUniqueTestEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mongo;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.annotations.Index;
13 |
14 | @Index(name = "unique_test", columns = "value", columnSettings = Mango.INDEX_ASCENDING, unique = true)
15 | public class MongoUniqueTestEntity extends MongoEntity {
16 |
17 | public static final Mapping VALUE = Mapping.named("value");
18 | private String value;
19 |
20 | public String getValue() {
21 | return value;
22 | }
23 |
24 | public void setValue(String value) {
25 | this.value = value;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/mongo/properties/MongoStringMapMixin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mongo.properties;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.Mixable;
13 | import sirius.db.mixing.annotations.Mixin;
14 | import sirius.db.mixing.types.StringMap;
15 |
16 | @Mixin(MongoStringMapMixinEntity.class)
17 | public class MongoStringMapMixin extends Mixable {
18 |
19 | public static final Mapping MAP_IN_MIXIN = Mapping.named("mapInMixin");
20 | private final StringMap mapInMixin = new StringMap();
21 |
22 | public StringMap getMapInMixin() {
23 | return mapInMixin;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mongo/MongoEntityCache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mongo;
10 |
11 | import sirius.db.util.BaseEntityCache;
12 | import sirius.kernel.di.std.Part;
13 |
14 | /**
15 | * Provides a template for caching mongo entities in an on-heap cache.
16 | *
17 | * @param
20 | * Can be placed on local caches or other fields which must not be persisted.
21 | */
22 | @Documented
23 | @Retention(RetentionPolicy.RUNTIME)
24 | @Target(ElementType.FIELD)
25 | public @interface Transient {
26 | }
27 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/es/properties/ESStringLocalDateTimeMapEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.es.properties;
10 |
11 | import sirius.db.es.ElasticEntity;
12 | import sirius.db.mixing.Mapping;
13 | import sirius.db.mixing.annotations.NullAllowed;
14 | import sirius.db.mixing.types.StringLocalDateTimeMap;
15 |
16 | public class ESStringLocalDateTimeMapEntity extends ElasticEntity {
17 |
18 | public static final Mapping MAP = Mapping.named("map");
19 | @NullAllowed
20 | private final StringLocalDateTimeMap map = new StringLocalDateTimeMap();
21 |
22 | public StringLocalDateTimeMap getMap() {
23 | return map;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/jdbc/SQLUniqueTestEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.jdbc;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.annotations.Index;
13 | import sirius.db.mixing.annotations.Length;
14 |
15 | @Index(name = "unique_test", columns = "value", unique = true)
16 | public class SQLUniqueTestEntity extends SQLEntity {
17 |
18 | public static final Mapping VALUE = Mapping.named("value");
19 | @Length(50)
20 | private String value;
21 |
22 | public String getValue() {
23 | return value;
24 | }
25 |
26 | public void setValue(String value) {
27 | this.value = value;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/mixing/RefMongoEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing;
10 |
11 | import sirius.db.jdbc.SQLEntityRef;
12 | import sirius.db.mixing.annotations.ComplexDelete;
13 | import sirius.db.mixing.annotations.NullAllowed;
14 | import sirius.db.mixing.types.BaseEntityRef;
15 | import sirius.db.mongo.MongoEntity;
16 |
17 | @ComplexDelete(false)
18 | public class RefMongoEntity extends MongoEntity {
19 |
20 | @NullAllowed
21 | private final SQLEntityRef
20 | * Note that this shouldn't be null and also be an non analyzed field.
21 | */
22 | @Documented
23 | @Retention(RetentionPolicy.RUNTIME)
24 | @Target(ElementType.FIELD)
25 | public @interface RoutedBy {
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/RemoveWhitespace.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import java.lang.annotation.Documented;
12 | import java.lang.annotation.ElementType;
13 | import java.lang.annotation.Retention;
14 | import java.lang.annotation.RetentionPolicy;
15 | import java.lang.annotation.Target;
16 |
17 | /**
18 | * Marks a string property to remove any white-spaces.
19 | *
20 | * All white-spaces of the property's value will be removed before it is written to the database.
21 | */
22 | @Documented
23 | @Retention(RetentionPolicy.RUNTIME)
24 | @Target(ElementType.FIELD)
25 | public @interface RemoveWhitespace {
26 | }
27 |
--------------------------------------------------------------------------------
/src/test/kotlin/sirius/db/text/PatternReplaceProcessorTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.text
10 |
11 | import org.junit.jupiter.api.Test
12 | import java.util.regex.Pattern
13 |
14 | /**
15 | * Tests the [PatternReplaceProcessor].
16 | */
17 | class PatternReplaceProcessorTest : TokenProcessorTest() {
18 | @Test
19 | fun tokenizing() {
20 | assertExactTokenizing("a7b8\$c", PatternReplaceProcessor(Pattern.compile("[^a-z]"), " "), "a b c")
21 | assertExactTokenizing(
22 | "a7b\u00178\$c\u0008\n\t",
23 | PatternReplaceProcessor.createRemoveControlCharacters(),
24 | "a7b 8\$c "
25 | )
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/Composite.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing;
10 |
11 | /**
12 | * Base class for all composites.
13 | *
14 | * A composite can be embed in an {@link BaseEntity}. All fields declared here will be mapped to properties
15 | * (and therefore columns of the entity).
16 | *
17 | * As the field name containing the composite is prepended to all fields here, the same composite can be
18 | * used several times in one entity.
19 | *
20 | * As it derives from {@link Mixable} a composite can be extended using Mixins. Also a composite can contain
21 | * further composites.
22 | */
23 | public class Composite extends Mixable {
24 | }
25 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/jdbc/SmartQueryTestParentEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.jdbc;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.annotations.ComplexDelete;
13 | import sirius.db.mixing.annotations.Length;
14 |
15 | /**
16 | * Testentity for SmartQuerySpec
17 | */
18 | @ComplexDelete(false)
19 | public class SmartQueryTestParentEntity extends SQLEntity {
20 |
21 | @Length(50)
22 | private String name;
23 | public static final Mapping NAME = Mapping.named("name");
24 |
25 | public String getName() {
26 | return name;
27 | }
28 |
29 | public void setName(String name) {
30 | this.name = name;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/jdbc/TestMixin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.jdbc;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.Mixable;
13 | import sirius.db.mixing.annotations.Length;
14 | import sirius.db.mixing.annotations.Mixin;
15 |
16 | @Mixin(TestEntityWithMixin.class)
17 | public class TestMixin extends Mixable {
18 |
19 | public static final Mapping MIDDLE_NAME = Mapping.named("middleName");
20 | @Length(50)
21 | private String middleName;
22 |
23 | public String getMiddleName() {
24 | return middleName;
25 | }
26 |
27 | public void setMiddleName(String middleName) {
28 | this.middleName = middleName;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/test/kotlin/sirius/db/util/TensorsTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.util
10 |
11 | import org.junit.jupiter.api.Assertions
12 | import org.junit.jupiter.api.Test
13 |
14 | /**
15 | * Tests the {@link Tensors} class.
16 | */
17 | class TensorsTest {
18 | @Test
19 | fun `test string tools`() {
20 | val tensor = floatArrayOf(1f, 2f, 3f, 4f, 5f)
21 |
22 | Assertions.assertArrayEquals(Tensors.parse(Tensors.encode(tensor)), tensor)
23 | }
24 |
25 | @Test
26 | fun `test array tools`() {
27 | val tensor = floatArrayOf(1f, 2f, 3f, 4f, 5f)
28 |
29 | Assertions.assertArrayEquals(Tensors.fromList(tensor.asList()), tensor)
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/mongo/PrefixTestEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mongo;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.annotations.Index;
13 |
14 | @Index(name = "prefix", columns = "prefix", columnSettings = Mango.INDEX_ASCENDING)
15 | @Index(name = "text", columns = "prefix", columnSettings = Mango.INDEX_AS_FULLTEXT)
16 | public class PrefixTestEntity extends MongoEntity {
17 |
18 | public static final Mapping PREFIX = Mapping.named("prefix");
19 | private String prefix;
20 |
21 | public String getPrefix() {
22 | return prefix;
23 | }
24 |
25 | public void setPrefix(String prefix) {
26 | this.prefix = prefix;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/LowerCase.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import java.lang.annotation.Documented;
12 | import java.lang.annotation.ElementType;
13 | import java.lang.annotation.Retention;
14 | import java.lang.annotation.RetentionPolicy;
15 | import java.lang.annotation.Target;
16 |
17 | /**
18 | * Marks a string property as auto lower-cased.
19 | *
20 | * The value of this property will be lower-cased before it is written to the database. Also, it is used to optimize
21 | * some system generated queries.
22 | */
23 | @Documented
24 | @Retention(RetentionPolicy.RUNTIME)
25 | @Target(ElementType.FIELD)
26 | public @interface LowerCase {
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/UpperCase.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import java.lang.annotation.Documented;
12 | import java.lang.annotation.ElementType;
13 | import java.lang.annotation.Retention;
14 | import java.lang.annotation.RetentionPolicy;
15 | import java.lang.annotation.Target;
16 |
17 | /**
18 | * Marks a string property as auto upper-cased.
19 | *
20 | * The value of this property will be upper-cased before it is written to the database. Also, it is used to optimize
21 | * some system generated queries.
22 | */
23 | @Documented
24 | @Retention(RetentionPolicy.RUNTIME)
25 | @Target(ElementType.FIELD)
26 | public @interface UpperCase {
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/MaxValue.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import java.lang.annotation.Documented;
12 | import java.lang.annotation.ElementType;
13 | import java.lang.annotation.Retention;
14 | import java.lang.annotation.RetentionPolicy;
15 | import java.lang.annotation.Target;
16 |
17 | /**
18 | * Sets the maximal value for a {@link sirius.db.mixing.properties.NumberProperty}.
19 | */
20 | @Documented
21 | @Retention(RetentionPolicy.RUNTIME)
22 | @Target(ElementType.FIELD)
23 | public @interface MaxValue {
24 |
25 | /**
26 | * The maximal value of this property.
27 | *
28 | * @return the maximal value
29 | */
30 | long value();
31 | }
32 |
--------------------------------------------------------------------------------
/src/test/kotlin/sirius/db/text/ToLowercaseProcessorTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.text
10 |
11 | import org.junit.jupiter.api.Test
12 |
13 | /**
14 | * Tests the [ToLowercaseProcessor].
15 | */
16 | class ToLowercaseProcessorTest : TokenProcessorTest() {
17 | @Test
18 | fun tokenizing() {
19 | assertExactTokenizing("HelloWorld", ToLowercaseProcessor(), "helloworld")
20 | assertExactTokenizing("ÄÖÜOUKÁ", ToLowercaseProcessor(), "äöüouká")
21 | assertExactTokenizing("Hello World", ToLowercaseProcessor(), "hello world")
22 | assertExactTokenizing("123", ToLowercaseProcessor(), "123")
23 | assertExactTokenizing("--$--", ToLowercaseProcessor(), "--$--")
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/query/constraints/Constraint.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.query.constraints;
10 |
11 | /**
12 | * Represents a constraint which can be applied to a {@link sirius.db.mixing.query.Query}.
13 | */
14 | public abstract class Constraint {
15 |
16 | /**
17 | * Creates a string representation of this constraint.
18 | *
19 | * @param builder the target to write the string representation to
20 | */
21 | public abstract void asString(StringBuilder builder);
22 |
23 | @Override
24 | public String toString() {
25 | StringBuilder builder = new StringBuilder();
26 | asString(builder);
27 | return builder.toString();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/mixing/RefListMongoEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing;
10 |
11 | import sirius.db.es.types.ElasticRefList;
12 | import sirius.db.mixing.annotations.ComplexDelete;
13 | import sirius.db.mixing.annotations.NullAllowed;
14 | import sirius.db.mixing.types.BaseEntityRef;
15 | import sirius.db.mongo.MongoEntity;
16 |
17 | @ComplexDelete(false)
18 | public class RefListMongoEntity extends MongoEntity {
19 |
20 | @NullAllowed
21 | private final ElasticRefList
16 | * Note that almost all processors should and must be chainable and therefore be a subclass of
17 | * {@link ChainableTokenProcessor}.
18 | */
19 | public interface TokenProcessor extends Consumer
24 | * If this processor doesn't buffer any data internally, nothing will happen but any
25 | * subsequent processors must also be purged.
26 | */
27 | default void purge() {
28 |
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/DefaultValue.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import java.lang.annotation.Documented;
12 | import java.lang.annotation.ElementType;
13 | import java.lang.annotation.Retention;
14 | import java.lang.annotation.RetentionPolicy;
15 | import java.lang.annotation.Target;
16 |
17 | /**
18 | * Defines a default value which is added to the CREATE TABLE statement when generating the schema.
19 | */
20 | @Documented
21 | @Retention(RetentionPolicy.RUNTIME)
22 | @Target(ElementType.FIELD)
23 | public @interface DefaultValue {
24 | /**
25 | * Contains the string representation of the default value.
26 | *
27 | * @return the default value to use
28 | */
29 | String value();
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/Realm.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import java.lang.annotation.Documented;
12 | import java.lang.annotation.ElementType;
13 | import java.lang.annotation.Retention;
14 | import java.lang.annotation.RetentionPolicy;
15 | import java.lang.annotation.Target;
16 |
17 | /**
18 | * Specifies the realm to use for an entity.
19 | *
20 | * This can be used to determine which datasource is used to reprenset an entity class.
21 | */
22 | @Documented
23 | @Retention(RetentionPolicy.RUNTIME)
24 | @Target(ElementType.TYPE)
25 | public @interface Realm {
26 |
27 | /**
28 | * The name of the realm to use.
29 | *
30 | * @return the name of the realm
31 | */
32 | String value();
33 | }
34 |
--------------------------------------------------------------------------------
/src/test/kotlin/sirius/db/testutil/MongoMocks.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.testutil
10 |
11 | import io.mockk.spyk
12 | import sirius.db.mixing.types.BaseEntityRef
13 | import sirius.db.mongo.MongoEntity
14 | import sirius.db.mongo.types.MongoRef
15 |
16 | /**
17 | * Class contains functionality used for mocking Mongo parts in unit tests.
18 | */
19 | class MongoMocks {
20 | companion object {
21 | /**
22 | * Wrap an entity as a MongoRef
23 | * @param entity which is to be wrapped
24 | */
25 | fun
16 | * Once the first operation is triggered against Mongo DB, the framework finds all classes implementing this interface.
17 | * To be discovered, the class has to wear a {@link sirius.kernel.di.std.Register} annotation.
18 | */
19 | public interface IndexDescription {
20 |
21 | /**
22 | * Invoked once the Mongo DB is first accessed and permits to create required indices.
23 | *
24 | * @param database the name of the database (in the configuration) for which the indices are created
25 | * @param client can be used to create indices in the Mongo DB
26 | */
27 | void createIndices(String database, MongoDatabase client);
28 | }
29 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/mongo/MangoWasCreatedTestEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mongo;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.annotations.AfterSave;
13 | import sirius.db.mixing.annotations.Transient;
14 |
15 | public class MangoWasCreatedTestEntity extends MongoEntity {
16 |
17 | public static final Mapping VALUE = Mapping.named("value");
18 | private String value;
19 |
20 | @Transient
21 | private boolean wasCreatedIndicator;
22 |
23 | @AfterSave
24 | protected void checkIfCreated() {
25 | wasCreatedIndicator = wasCreated();
26 | }
27 |
28 | public String getValue() {
29 | return value;
30 | }
31 |
32 | public void setValue(String value) {
33 | this.value = value;
34 | }
35 |
36 | public boolean hasJustBeenCreated() {
37 | return wasCreatedIndicator;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/test/resources/docker-db.yml:
--------------------------------------------------------------------------------
1 | services:
2 | redis:
3 | image: redis:8.2.2-alpine
4 | ports:
5 | - "6379"
6 | hostname: redis
7 |
8 | mongo:
9 | image: mongo:8.0.8
10 | ports:
11 | - "27017"
12 | hostname: mongo
13 |
14 | mariadb:
15 | image: mariadb:11.8.3-noble
16 | ports:
17 | - "3306"
18 | environment:
19 | MYSQL_ROOT_PASSWORD: root
20 | hostname: mysql
21 | command: --collation-server=utf8mb4_bin --character-set-server=utf8mb4
22 |
23 | clickhouse:
24 | image: clickhouse/clickhouse-server:25.8.2.29-alpine
25 | ports:
26 | - "8123"
27 | - "9000"
28 | hostname: clickhouse
29 | environment:
30 | CLICKHOUSE_USER: default
31 | CLICKHOUSE_PASSWORD: secret
32 |
33 | elasticsearch:
34 | image: elasticsearch:8.19.3
35 | ports:
36 | - "9200"
37 | environment:
38 | - ES_JAVA_OPTS=-Xms128M -Xmx128M
39 | - discovery.type=single-node
40 | - ingest.geoip.downloader.enabled=false
41 | - xpack.security.enabled=false
42 | hostname: es
43 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/jdbc/TestComposite.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.jdbc;
10 |
11 | import sirius.db.mixing.Composite;
12 | import sirius.db.mixing.annotations.Length;
13 |
14 | public class TestComposite extends Composite {
15 |
16 | @Length(100)
17 | private String street;
18 |
19 | @Length(10)
20 | private String zip;
21 |
22 | @Length(100)
23 | private String city;
24 |
25 | public String getStreet() {
26 | return street;
27 | }
28 |
29 | public void setStreet(String street) {
30 | this.street = street;
31 | }
32 |
33 | public String getZip() {
34 | return zip;
35 | }
36 |
37 | public void setZip(String zip) {
38 | this.zip = zip;
39 | }
40 |
41 | public String getCity() {
42 | return city;
43 | }
44 |
45 | public void setCity(String city) {
46 | this.city = city;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/Engine.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import java.lang.annotation.Documented;
12 | import java.lang.annotation.ElementType;
13 | import java.lang.annotation.Retention;
14 | import java.lang.annotation.RetentionPolicy;
15 | import java.lang.annotation.Target;
16 |
17 | /**
18 | * Can be placed on a {@link sirius.db.jdbc.SQLEntity} to specify the database engine to use.
19 | *
20 | * Use e.g. InnoDB for MySQL or MergeTree(EventDate, (CounterID, EventDate), 8192)
21 | * for Clickhouse.
22 | */
23 | @Documented
24 | @Retention(RetentionPolicy.RUNTIME)
25 | @Target(ElementType.TYPE)
26 | public @interface Engine {
27 |
28 | /**
29 | * Contains the engine specification to apply on the generated table.
30 | *
31 | * @return the engine used for the annotated type
32 | */
33 | String value();
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/RelationName.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import java.lang.annotation.Documented;
12 | import java.lang.annotation.ElementType;
13 | import java.lang.annotation.Retention;
14 | import java.lang.annotation.RetentionPolicy;
15 | import java.lang.annotation.Target;
16 |
17 | /**
18 | * Specifies the relation name to used for an entity.
19 | *
20 | * By default the simple class name (all lowercase) is used as relation name. This annotation can be used to
21 | * provide a custom one.
22 | */
23 | @Documented
24 | @Retention(RetentionPolicy.RUNTIME)
25 | @Target(ElementType.TYPE)
26 | public @interface RelationName {
27 |
28 | /**
29 | * The relation name (table name / collection name / index name) to use.
30 | *
31 | * @return the name to use to represent an entity in the database
32 | */
33 | String value();
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/Indices.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import java.lang.annotation.Documented;
12 | import java.lang.annotation.ElementType;
13 | import java.lang.annotation.Retention;
14 | import java.lang.annotation.RetentionPolicy;
15 | import java.lang.annotation.Target;
16 |
17 | /**
18 | * Provides a container to make {@link Index} repeatable.
19 | *
20 | * As of Java 8 several Index annotation can be placed on an entity class, therefore this wrapper is only used
21 | * by the compiler and runtime to carry those annotations.
22 | */
23 | @Documented
24 | @Target(ElementType.TYPE)
25 | @Retention(RetentionPolicy.RUNTIME)
26 | public @interface Indices {
27 |
28 | /**
29 | * Contains all index annoations placed on an entity class.
30 | *
31 | * @return an array of all index annotations
32 | */
33 | Index[] value();
34 | }
35 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/mixing/fieldlookup/MongoSuperHeroTestMixin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.fieldlookup;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.Mixable;
13 | import sirius.db.mixing.annotations.Mixin;
14 | import sirius.db.mixing.types.StringList;
15 |
16 | @Mixin(MongoFieldLookUpTestEntity.class)
17 | public class MongoSuperHeroTestMixin extends Mixable {
18 |
19 | public static final Mapping HERO_NAMES = Mapping.named("heroNames");
20 | private final NameFieldsTestComposite heroNames = new NameFieldsTestComposite();
21 |
22 | public static final Mapping SUPER_POWERS = Mapping.named("superPowers");
23 | private final StringList superPowers = new StringList();
24 |
25 | public NameFieldsTestComposite getHeroNames() {
26 | return heroNames;
27 | }
28 |
29 | public StringList getSuperPowers() {
30 | return superPowers;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/es/ElasticWasCreatedTestEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.es;
10 |
11 | import sirius.db.es.ElasticEntity;
12 | import sirius.db.mixing.Mapping;
13 | import sirius.db.mixing.annotations.AfterSave;
14 | import sirius.db.mixing.annotations.Transient;
15 |
16 | public class ElasticWasCreatedTestEntity extends ElasticEntity {
17 |
18 | public static final Mapping VALUE = Mapping.named("value");
19 | private String value;
20 |
21 | @Transient
22 | private boolean wasCreatedIndicator;
23 |
24 | @AfterSave
25 | protected void checkIfCreated() {
26 | wasCreatedIndicator = wasCreated();
27 | }
28 |
29 | public String getValue() {
30 | return value;
31 | }
32 |
33 | public void setValue(String value) {
34 | this.value = value;
35 | }
36 |
37 | public boolean hasJustBeenCreated() {
38 | return wasCreatedIndicator;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/jdbc/SQLWasCreatedTestEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.jdbc;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.annotations.AfterSave;
13 | import sirius.db.mixing.annotations.Length;
14 | import sirius.db.mixing.annotations.Transient;
15 |
16 | public class SQLWasCreatedTestEntity extends SQLEntity {
17 | public static final Mapping VALUE = Mapping.named("value");
18 | @Length(255)
19 | private String value;
20 |
21 | @Transient
22 | private boolean wasCreatedIndicator;
23 |
24 | @AfterSave
25 | protected void checkIfCreated() {
26 | wasCreatedIndicator = wasCreated();
27 | }
28 |
29 | public String getValue() {
30 | return value;
31 | }
32 |
33 | public void setValue(String value) {
34 | this.value = value;
35 | }
36 |
37 | public boolean hasJustBeenCreated() {
38 | return wasCreatedIndicator;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/jdbc/SQLStringListPropertyEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.jdbc;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.annotations.Length;
13 | import sirius.db.mixing.annotations.NullAllowed;
14 | import sirius.db.mixing.types.StringList;
15 |
16 | public class SQLStringListPropertyEntity extends SQLEntity {
17 |
18 | public static final Mapping STRING_LIST = Mapping.named("stringList");
19 | @NullAllowed
20 | @Length(4096)
21 | private final StringList stringList = new StringList();
22 |
23 | public static final Mapping SHORT_STRING_LIST = Mapping.named("shortStringList");
24 | @NullAllowed
25 | @Length(20)
26 | private final StringList shortStringList = new StringList();
27 |
28 | public StringList getStringList() {
29 | return stringList;
30 | }
31 |
32 | public StringList getShortStringList() {
33 | return shortStringList;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/redis/Subscriber.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.redis;
10 |
11 | /**
12 | * Subscribes to a publish/subscribe topic which uses redis for one to many communication.
13 | *
14 | * A class implementing this interface must wear a {@link sirius.kernel.di.std.Register} annotation to be
15 | * discovered by {@link Redis}. Once a message is published via {@link Redis#publish(String, String)} all subscribers
16 | * on all connected nodes will be notified via {@link #onMessage(String)}.
17 | */
18 | public interface Subscriber {
19 |
20 | /**
21 | * Returns the name of the topic to subscribe to.
22 | *
23 | * @return the name of the topic in redis
24 | */
25 | String getTopic();
26 |
27 | /**
28 | * Invoked for each message received from redis for the subscribed topic.
29 | *
30 | * @param message the message that was published
31 | */
32 | void onMessage(String message);
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/es/annotations/ESOption.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.es.annotations;
10 |
11 | /**
12 | * Used to describe a tri-state property which is either true, false or default, which
13 | * will use the default value used by Elasticsearch.
14 | */
15 | public enum ESOption {
16 |
17 | /**
18 | * Specifies true to elasticsearch as the value for this option
19 | */
20 | TRUE("true"),
21 |
22 | /**
23 | * Specifies false to elasticsearch as the value for this option
24 | */
25 | FALSE("false"),
26 |
27 | /**
28 | * Specifies no value to elasticsearch, hence using the default value of elasticserach
29 | */
30 | ES_DEFAULT("");
31 |
32 | private final String value;
33 |
34 | ESOption(String value) {
35 | this.value = value;
36 | }
37 |
38 | @Override
39 | public String toString() {
40 | return value;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/es/RoutedBatchTestEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.es;
10 |
11 | import sirius.db.es.annotations.RoutedBy;
12 | import sirius.db.mixing.Mapping;
13 | import sirius.db.mixing.annotations.Versioned;
14 |
15 | @Versioned
16 | public class RoutedBatchTestEntity extends ElasticEntity {
17 |
18 | public static final Mapping VALUE = Mapping.named("value");
19 | private int value;
20 |
21 | public static final Mapping VALUE1 = Mapping.named("value1");
22 | @RoutedBy
23 | private int value1;
24 |
25 | public int getValue() {
26 | return value;
27 | }
28 |
29 | public RoutedBatchTestEntity withValue(int value) {
30 | this.value = value;
31 | return this;
32 | }
33 |
34 | public int getValue1() {
35 | return value1;
36 | }
37 |
38 | public RoutedBatchTestEntity withValue1(int value) {
39 | this.value1 = value;
40 | return this;
41 | }
42 |
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/mixing/RefEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing;
10 |
11 | import sirius.db.es.types.ElasticRef;
12 | import sirius.db.jdbc.SQLEntity;
13 | import sirius.db.mixing.annotations.ComplexDelete;
14 | import sirius.db.mixing.annotations.NullAllowed;
15 | import sirius.db.mixing.types.BaseEntityRef;
16 | import sirius.db.mongo.types.MongoRef;
17 |
18 | @ComplexDelete(false)
19 | public class RefEntity extends SQLEntity {
20 |
21 | @NullAllowed
22 | private final ElasticRef
21 | * This annotation needs to be placed on an entity class and will then invoke the given customizer during index
22 | * creation. This can be used to add additional settings when creating an index within Elasticsearh.
23 | */
24 | @Retention(RetentionPolicy.RUNTIME)
25 | @Target(ElementType.TYPE)
26 | public @interface CustomSettings {
27 |
28 | /**
29 | * Specifies the {@link SettingsCustomizer} to use.
30 | *
31 | * @return the type of customizer to use
32 | */
33 | Class extends SettingsCustomizer> value();
34 | }
35 |
--------------------------------------------------------------------------------
/.github/ga-release-drafter.yml:
--------------------------------------------------------------------------------
1 | name-template: 'GA Release $RESOLVED_VERSION'
2 | tag-template: 'ga-$RESOLVED_VERSION'
3 | categories:
4 | - title: 'Breaking Changes'
5 | label: '💣 BREAKING CHANGE'
6 | - title: 'New Features / Enhancements'
7 | collapse-after: 10
8 | label: '🧬 Enhancement'
9 | - title: 'Bugfixes'
10 | collapse-after: 5
11 | label: '🐛 Bugfix'
12 | - title: 'Maintenance'
13 | collapse-after: 5
14 | labels:
15 | - '🛠️ Maintenance'
16 | - '⬆️ Dependencies'
17 | - title: 'Uncategorized'
18 | exclude-labels:
19 | - '⎇ Sidebranch'
20 | change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
21 | filter-by-commitish: true
22 | version-resolver:
23 | major:
24 | labels:
25 | - '💣 BREAKING CHANGE'
26 | minor:
27 | labels:
28 | - '🧬 Enhancement'
29 | patch:
30 | labels:
31 | - '🐛 Bugfix'
32 | - '🛠️ Maintenance'
33 | default: patch
34 | template: |
35 | # Changelog
36 |
37 | $CHANGES
38 |
39 | **Full Changelog:** [$PREVIOUS_TAG...ga-$RESOLVED_VERSION](https://github.com/scireum/$REPOSITORY/compare/$PREVIOUS_TAG...ga-$RESOLVED_VERSION)
40 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/es/IndexNaming.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.es;
10 |
11 | import sirius.db.mixing.EntityDescriptor;
12 |
13 | /**
14 | * Can be supplied to enforce naming conventions for indices and mappings in ElasticSearch on a per product basis.
15 | *
16 | * Use {@link sirius.kernel.di.std.Register} to make a custom implementation visible to the framework.
17 | */
18 | public interface IndexNaming {
19 |
20 | /**
21 | * Determines the name of the index for the given entity.
22 | *
23 | * @param descriptor the descriptor of the entity to return the index name for
24 | * @return the index name
25 | */
26 | String determineIndexName(EntityDescriptor descriptor);
27 |
28 | /**
29 | * Determines the name of the mapping for the given entity.
30 | *
31 | * @param descriptor the descriptor of the entity to return the mapping name for
32 | * @return the mapping name
33 | */
34 | String determineMappingName(EntityDescriptor descriptor);
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/Length.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import java.lang.annotation.Documented;
12 | import java.lang.annotation.ElementType;
13 | import java.lang.annotation.Retention;
14 | import java.lang.annotation.RetentionPolicy;
15 | import java.lang.annotation.Target;
16 |
17 | /**
18 | * Specifies the column length, most probably of string (CHAR) columns.
19 | *
20 | * This annotation has no effect on properties other than a string, except the columns
21 | * definitions for Clickhouse, where the length is used also for other types, for example int,
22 | * to define the int size to use.
23 | *
24 | * @see sirius.db.jdbc.schema.ClickhouseDatabaseDialect
25 | */
26 | @Documented
27 | @Retention(RetentionPolicy.RUNTIME)
28 | @Target(ElementType.FIELD)
29 | public @interface Length {
30 |
31 | /**
32 | * The maximal length of the column.
33 | *
34 | * @return the maximal length of the column
35 | */
36 | int value();
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/query/QueryTagHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.query;
10 |
11 | import sirius.db.mixing.EntityDescriptor;
12 | import sirius.db.mixing.query.constraints.Constraint;
13 | import sirius.db.mixing.query.constraints.FilterFactory;
14 | import sirius.kernel.di.std.Named;
15 |
16 | /**
17 | * Compiles a tag value provided by a {@link QueryTag} into a {@link Constraint}.
18 | *
19 | * @param
22 | * A mixin can add properties to an entity or composite, which are not defined in the original class. This can be used
23 | * to defined customer extensions without modifying the standard classes.
24 | */
25 | @Documented
26 | @Retention(RetentionPolicy.RUNTIME)
27 | @Target(ElementType.TYPE)
28 | public @interface Mixin {
29 | /**
30 | * The target class which will inherit all properties defined by this mixing.
31 | *
32 | * @return the target class to extend
33 | */
34 | Class> value();
35 | }
36 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/es/ElasticTestEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.es;
10 |
11 | import sirius.db.mixing.Mapping;
12 |
13 | public class ElasticTestEntity extends ElasticEntity {
14 |
15 | public static final Mapping FIRSTNAME = Mapping.named("firstname");
16 | private String firstname;
17 |
18 | public static final Mapping LASTNAME = Mapping.named("lastname");
19 | private String lastname;
20 |
21 | public static final Mapping AGE = Mapping.named("age");
22 | private int age;
23 |
24 | public String getFirstname() {
25 | return firstname;
26 | }
27 |
28 | public void setFirstname(String firstname) {
29 | this.firstname = firstname;
30 | }
31 |
32 | public String getLastname() {
33 | return lastname;
34 | }
35 |
36 | public void setLastname(String lastname) {
37 | this.lastname = lastname;
38 | }
39 |
40 | public int getAge() {
41 | return age;
42 | }
43 |
44 | public void setAge(int age) {
45 | this.age = age;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/mixing/fieldlookup/SQLSuperHeroTestMixin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.fieldlookup;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.Mixable;
13 | import sirius.db.mixing.annotations.Length;
14 | import sirius.db.mixing.annotations.Mixin;
15 | import sirius.db.mixing.annotations.NullAllowed;
16 | import sirius.db.mixing.types.StringList;
17 |
18 | @Mixin(SQLFieldLookUpTestEntity.class)
19 | public class SQLSuperHeroTestMixin extends Mixable {
20 |
21 | public static final Mapping HERO_NAMES = Mapping.named("heroNames");
22 | private final NameFieldsTestComposite heroNames = new NameFieldsTestComposite();
23 |
24 | public static final Mapping SUPER_POWERS = Mapping.named("superPowers");
25 | @Length(100)
26 | @NullAllowed
27 | private final StringList superPowers = new StringList();
28 |
29 | public NameFieldsTestComposite getHeroNames() {
30 | return heroNames;
31 | }
32 |
33 | public StringList getSuperPowers() {
34 | return superPowers;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/.run/mvn clean test - without nightly.run.xml:
--------------------------------------------------------------------------------
1 |
33 | * Throwing any exception will abort the write operation.
34 | *
35 | * @param value the value to validate
36 | */
37 | void beforeSave(Property property, Object value);
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/ContextInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing;
10 |
11 | import sirius.kernel.commons.Value;
12 |
13 | /**
14 | * Represents a context info which can be supplied for {@link BaseMapper#find(Class, Object, ContextInfo...)}.
15 | */
16 | public class ContextInfo {
17 |
18 | private String key;
19 | private Value value;
20 |
21 | /**
22 | * Creates a new info object for the given key and value.
23 | *
24 | * @param key the key used to pass in
25 | * @param value the value to pass in
26 | */
27 | public ContextInfo(String key, Value value) {
28 | this.key = key;
29 | this.value = value;
30 | }
31 |
32 | /**
33 | * Returns the key of this info.
34 | *
35 | * @return the key of this info
36 | */
37 | public String getKey() {
38 | return key;
39 | }
40 |
41 | /**
42 | * Returns the value of this info.
43 | *
44 | * @return the value of this info
45 | */
46 | public Value getValue() {
47 | return value;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/jdbc/SmartQueryTestCountEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.jdbc;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.annotations.ComplexDelete;
13 | import sirius.db.mixing.annotations.Length;
14 |
15 | /**
16 | * Test entity for SmartQuerySpec concerning distinct and not distinct counts
17 | */
18 | @ComplexDelete(false)
19 | public class SmartQueryTestCountEntity extends SQLEntity {
20 |
21 | public static final Mapping FIELD_ONE = Mapping.named("fieldOne");
22 | @Length(50)
23 | private String fieldOne;
24 |
25 | public static final Mapping FIELD_TWO = Mapping.named("fieldTwo");
26 | @Length(50)
27 | private String fieldTwo;
28 |
29 | public String getFieldOne() {
30 | return fieldOne;
31 | }
32 |
33 | public void setFieldOne(String fieldOne) {
34 | this.fieldOne = fieldOne;
35 | }
36 |
37 | public String getFieldTwo() {
38 | return fieldTwo;
39 | }
40 |
41 | public void setFieldTwo(String fieldTwo) {
42 | this.fieldTwo = fieldTwo;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/jdbc/TestEntityWithMixin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.jdbc;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.annotations.Length;
13 |
14 | public class TestEntityWithMixin extends SQLEntity {
15 |
16 | public static final Mapping FIRSTNAME = Mapping.named("firstname");
17 | @Length(50)
18 | private String firstname;
19 |
20 | public static final Mapping LASTNAME = Mapping.named("lastname");
21 | @Length(50)
22 | private String lastname;
23 |
24 | private int age;
25 |
26 | public String getFirstname() {
27 | return firstname;
28 | }
29 |
30 | public void setFirstname(String firstname) {
31 | this.firstname = firstname;
32 | }
33 |
34 | public String getLastname() {
35 | return lastname;
36 | }
37 |
38 | public void setLastname(String lastname) {
39 | this.lastname = lastname;
40 | }
41 |
42 | public int getAge() {
43 | return age;
44 | }
45 |
46 | public void setAge(int age) {
47 | this.age = age;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/Numeric.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import java.lang.annotation.Documented;
12 | import java.lang.annotation.ElementType;
13 | import java.lang.annotation.Retention;
14 | import java.lang.annotation.RetentionPolicy;
15 | import java.lang.annotation.Target;
16 |
17 | /**
18 | * Specifies the numeric precision of a NUMBER column.
19 | *
20 | * If a column must store values with 12 digits and 3 decimal places, the precision would be 15 and scale
21 | * 3.
22 | */
23 | @Documented
24 | @Retention(RetentionPolicy.RUNTIME)
25 | @Target(ElementType.FIELD)
26 | public @interface Numeric {
27 |
28 | /**
29 | * The total number of digits which can be stored in that column without rounding.
30 | *
31 | * @return the total number of digits
32 | */
33 | int precision();
34 |
35 | /**
36 | * The number of decimal digits after the decimal separator.
37 | *
38 | * @return the number of digits after the decimal separator
39 | */
40 | int scale();
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/text/DeduplicateProcessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.text;
10 |
11 | import java.util.HashSet;
12 | import java.util.Set;
13 |
14 | /**
15 | * Filters duplicate tokens generated by upstream processors.
16 | */
17 | public class DeduplicateProcessor extends ChainableTokenProcessor {
18 |
19 | private final Set
18 | * This class needs to be {@link sirius.kernel.di.std.Register registered} and can then be referenced by placing
19 | * a {@link sirius.db.es.annotations.CustomSettings} annotation on the appropriate entity classes.
20 | */
21 | @AutoRegister
22 | public interface SettingsCustomizer {
23 |
24 | /**
25 | * Customizes the given settings object for the given entity (descriptor).
26 | *
27 | * @param descriptor the descriptor of the entity to customize
28 | * @param settingsObject the settings object which will be passed to Elasticsearch when creating a new
29 | * index.
30 | */
31 | void customizeSettings(EntityDescriptor descriptor, ObjectNode settingsObject);
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/jdbc/GeneratedStatementTestEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.jdbc;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.annotations.ComplexDelete;
13 | import sirius.db.mixing.annotations.Length;
14 | import sirius.db.mixing.types.BaseEntityRef;
15 |
16 | import javax.annotation.Nullable;
17 |
18 | /**
19 | * Testentity for UpdateStatementSpec
20 | */
21 | @ComplexDelete(false)
22 | public class GeneratedStatementTestEntity extends SQLEntity {
23 |
24 | public static final Mapping VALUE = Mapping.named("value");
25 | @Length(50)
26 | private String value;
27 |
28 | public static final Mapping TEST_NUMBER = Mapping.named("testNumber");
29 | private int testNumber;
30 |
31 | public String getValue() {
32 | return value;
33 | }
34 |
35 | public void setValue(String value) {
36 | this.value = value;
37 | }
38 |
39 | public int getTestNumber() {
40 | return testNumber;
41 | }
42 |
43 | public void setTestNumber(int testNumber) {
44 | this.testNumber = testNumber;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/es/RoutedTestEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.es;
10 |
11 | import sirius.db.es.annotations.RoutedBy;
12 | import sirius.db.mixing.Mapping;
13 |
14 | public class RoutedTestEntity extends ElasticEntity {
15 |
16 | public static final Mapping FIRSTNAME = Mapping.named("firstname");
17 | private String firstname;
18 |
19 | public static final Mapping LASTNAME = Mapping.named("lastname");
20 | @RoutedBy
21 | private String lastname;
22 |
23 | public static final Mapping AGE = Mapping.named("age");
24 | private int age;
25 |
26 | public String getFirstname() {
27 | return firstname;
28 | }
29 |
30 | public void setFirstname(String firstname) {
31 | this.firstname = firstname;
32 | }
33 |
34 | public String getLastname() {
35 | return lastname;
36 | }
37 |
38 | public void setLastname(String lastname) {
39 | this.lastname = lastname;
40 | }
41 |
42 | public int getAge() {
43 | return age;
44 | }
45 |
46 | public void setAge(int age) {
47 | this.age = age;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/InvalidFieldException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing;
10 |
11 | import java.io.Serial;
12 |
13 | /**
14 | * Marker exception to mark which field produced an error.
15 | *
16 | * This is used as "cause" for HandledExceptions that are generated by a failed field check.
17 | * This way, other frameworks can pick up this exception and extract the source field for an error message.
18 | *
19 | * This is used by sirius-biz to highlight the field which caused an error when trying to save an entity.
20 | */
21 | public class InvalidFieldException extends Exception {
22 |
23 | @Serial
24 | private static final long serialVersionUID = 4954813810676679158L;
25 | private final String field;
26 |
27 | /**
28 | * Creates a new exception for the given field.
29 | *
30 | * @param field the name of the field which produced the error message
31 | */
32 | public InvalidFieldException(String field) {
33 | super(field);
34 | this.field = field;
35 | }
36 |
37 | public String getField() {
38 | return field;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/MixinLoadAction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing;
10 |
11 | import sirius.db.mixing.annotations.Mixin;
12 | import sirius.kernel.Sirius;
13 | import sirius.kernel.di.ClassLoadAction;
14 | import sirius.kernel.di.MutableGlobalContext;
15 | import sirius.kernel.di.std.Framework;
16 |
17 | import java.lang.annotation.Annotation;
18 |
19 | /**
20 | * Loads all {@link Mixin}s so that they don't have to wear a {@link sirius.kernel.di.std.Register} annotation.
21 | */
22 | public class MixinLoadAction implements ClassLoadAction {
23 |
24 | @Override
25 | public Class extends Annotation> getTrigger() {
26 | return Mixin.class;
27 | }
28 |
29 | @Override
30 | public void handle(MutableGlobalContext ctx, Class> clazz) throws Exception {
31 | if (clazz.isAnnotationPresent(Framework.class)) {
32 | if (Sirius.isFrameworkEnabled(clazz.getAnnotation(Framework.class).value())) {
33 | ctx.registerPart(clazz, Mixin.class);
34 | }
35 | } else {
36 | ctx.registerPart(clazz, Mixin.class);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/text/TokenLimitProcessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.text;
10 |
11 | /**
12 | * Discards tokens which are either too long or to too short to be processed.
13 | */
14 | public class TokenLimitProcessor extends ChainableTokenProcessor {
15 |
16 | private final int tokenMinLength;
17 | private final int tokenMaxLength;
18 |
19 | /**
20 | * Creates a new processor with the given lengths.
21 | *
22 | * @param tokenMinLength the minimal length for a token to be accepted
23 | * @param tokenMaxLength the maximal length for a token to be accepted
24 | */
25 | public TokenLimitProcessor(int tokenMinLength, int tokenMaxLength) {
26 | this.tokenMinLength = tokenMinLength;
27 | this.tokenMaxLength = tokenMaxLength;
28 | }
29 |
30 | @Override
31 | public void accept(String value) {
32 | if (tokenMinLength > 0 && value.length() < tokenMinLength) {
33 | return;
34 | }
35 |
36 | if (tokenMaxLength > 0 && value.length() > tokenMaxLength) {
37 | return;
38 | }
39 |
40 | emit(value);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/es/SuppressedRoutedTestEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.es;
10 |
11 | import sirius.db.es.annotations.RoutedBy;
12 | import sirius.db.mixing.Mapping;
13 |
14 | public class SuppressedRoutedTestEntity extends ElasticEntity {
15 |
16 | public static final Mapping FIRSTNAME = Mapping.named("firstname");
17 | private String firstname;
18 |
19 | public static final Mapping LASTNAME = Mapping.named("lastname");
20 | @RoutedBy
21 | private String lastname;
22 |
23 | public static final Mapping AGE = Mapping.named("age");
24 | private int age;
25 |
26 | public String getFirstname() {
27 | return firstname;
28 | }
29 |
30 | public void setFirstname(String firstname) {
31 | this.firstname = firstname;
32 | }
33 |
34 | public String getLastname() {
35 | return lastname;
36 | }
37 |
38 | public void setLastname(String lastname) {
39 | this.lastname = lastname;
40 | }
41 |
42 | public int getAge() {
43 | return age;
44 | }
45 |
46 | public void setAge(int age) {
47 | this.age = age;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/test/kotlin/sirius/db/text/PatternSplitProcessorTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.text
10 |
11 | import org.junit.jupiter.api.Test
12 | import java.util.regex.Pattern
13 |
14 | /**
15 | * Tests the [PatternSplitProcessor].
16 | */
17 | class PatternSplitProcessorTest : TokenProcessorTest() {
18 |
19 | @Test
20 | fun tokenizing() {
21 | assertExactTokenizing(
22 | "a7b8\$c",
23 | PatternSplitProcessor(Pattern.compile("[^a-z]"), false, true),
24 | "a",
25 | "b",
26 | "c"
27 | )
28 | assertExactTokenizing(
29 | " A B-6:7C-",
30 | PatternSplitProcessor(Pattern.compile("[^a-zA-Z0-9]"), true, true),
31 | " A B-6:7C-",
32 | "A",
33 | "B",
34 | "6",
35 | "7C"
36 | )
37 | }
38 |
39 | @Test
40 | fun `tokenizing via hard boundary splitter preset`() {
41 | // Text including a plus or ampersand not surrounded by whitespace should not be split
42 | assertExactTokenizing("A+B&C", PatternSplitProcessor.createHardBoundarySplitter(), "A+B&C")
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/BeforeSave.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import sirius.db.mixing.BaseEntity;
12 | import sirius.db.mixing.Mixable;
13 | import sirius.kernel.di.std.Priorized;
14 |
15 | import java.lang.annotation.Documented;
16 | import java.lang.annotation.ElementType;
17 | import java.lang.annotation.Retention;
18 | import java.lang.annotation.RetentionPolicy;
19 | import java.lang.annotation.Target;
20 |
21 | /**
22 | * Used to mark methods in {@link Mixable}s which will be called before an entity is saved.
23 | *
24 | * If you need different logic for updated and newly created entities, use {@link BaseEntity#isNew()} in your method.
25 | */
26 | @Documented
27 | @Retention(RetentionPolicy.RUNTIME)
28 | @Target(ElementType.METHOD)
29 | public @interface BeforeSave {
30 |
31 | /**
32 | * Determines the execution order of all before save handlers.
33 | *
34 | * @return the execution priority. Handlers will be executed in ascending order, the one with the lowest value
35 | * will be executed first.
36 | */
37 | int priority() default Priorized.DEFAULT_PRIORITY;
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/types/StringList.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.types;
10 |
11 | /**
12 | * Provides a simple list of strings as property value.
13 | */
14 | public class StringList extends SafeList
21 | * Auto-parsing will expect a single string value and split at each occurrence of a ",".
22 | *
23 | * @return the list itself for fluent method calls
24 | */
25 | public StringList enableAutoparse() {
26 | this.autoparse = true;
27 | return this;
28 | }
29 |
30 | /**
31 | * Determines if auto-parsing is enabled.
32 | *
33 | * @return true if auto-parse is enabled, false otherwise
34 | */
35 | public boolean isAutoparse() {
36 | return autoparse;
37 | }
38 |
39 | @Override
40 | protected boolean valueNeedsCopy() {
41 | return false;
42 | }
43 |
44 | @Override
45 | protected String copyValue(String value) {
46 | return value;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/AfterSave.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import sirius.db.mixing.BaseEntity;
12 | import sirius.db.mixing.Mixable;
13 | import sirius.kernel.di.std.Priorized;
14 |
15 | import java.lang.annotation.Documented;
16 | import java.lang.annotation.ElementType;
17 | import java.lang.annotation.Retention;
18 | import java.lang.annotation.RetentionPolicy;
19 | import java.lang.annotation.Target;
20 |
21 | /**
22 | * Used to mark methods in {@link Mixable mixables} which will be called once an entity was saved.
23 | *
24 | * If you need different logic for updated and newly created entities, use {@link BaseEntity#wasCreated()} in your method.
25 | */
26 | @Documented
27 | @Retention(RetentionPolicy.RUNTIME)
28 | @Target(ElementType.METHOD)
29 | public @interface AfterSave {
30 |
31 | /**
32 | * Determines the execution order of all after save handlers.
33 | *
34 | * @return the execution priority. Handlers will be executed in ascending order, the one with the lowest value
35 | * will be executed first.
36 | */
37 | int priority() default Priorized.DEFAULT_PRIORITY;
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/OnValidate.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import sirius.db.mixing.Mixable;
12 | import sirius.kernel.di.std.Priorized;
13 |
14 | import java.lang.annotation.Documented;
15 | import java.lang.annotation.ElementType;
16 | import java.lang.annotation.Retention;
17 | import java.lang.annotation.RetentionPolicy;
18 | import java.lang.annotation.Target;
19 |
20 | /**
21 | * Used to mark methods in {@link Mixable}s which will be called once is validated.
22 | *
23 | * Note that such a method must accept a Consumer<String> as first parameter or the entity
24 | * itself and the consumer as second parameter, when called within a mixin.
25 | */
26 | @Documented
27 | @Retention(RetentionPolicy.RUNTIME)
28 | @Target(ElementType.METHOD)
29 | public @interface OnValidate {
30 |
31 | /**
32 | * Determines the execution order of all validate handlers.
33 | *
34 | * @return the execution priority. Handlers will be executed in ascending order, the one with the lowest value
35 | * will be executed first.
36 | */
37 | int priority() default Priorized.DEFAULT_PRIORITY;
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/annotations/SkipDefaultValue.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.annotations;
10 |
11 | import java.lang.annotation.ElementType;
12 | import java.lang.annotation.Retention;
13 | import java.lang.annotation.RetentionPolicy;
14 | import java.lang.annotation.Target;
15 |
16 | /**
17 | * Instructs the entity mapper to not store a value in the database if the current value is a default value.
18 | *
19 | * This can e.g. be used for MongoDB where we can simply skip fields which are null or false, as when
20 | * reading them back, the property will restore the default value anyway.
21 | *
22 | * Note that this is not enabled by default as it might lead to unexpected behavior in queries. For example using
23 | * {@code db.collection.find({"non_existent_flag", false})} will not return document which false has been
24 | * skipped by not storing a value at all.
25 | *
26 | * The bottom line is, that this can be used to "optimize away" sparse values which are not used in queries.
27 | */
28 | @Target(ElementType.FIELD)
29 | @Retention(RetentionPolicy.RUNTIME)
30 | public @interface SkipDefaultValue {
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/types/NestedList.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.types;
10 |
11 | import sirius.db.mixing.Nested;
12 |
13 | /**
14 | * Represents a list of {@link Nested} objects.
15 | *
16 | * @param
20 | * A value in this column must only occur once. If within is filled, the value must only occur once while
21 | * having the same values for the properties enumerated in within.
22 | */
23 | @Documented
24 | @Retention(RetentionPolicy.RUNTIME)
25 | @Target(ElementType.FIELD)
26 | public @interface Unique {
27 |
28 | /**
29 | * Names properties which must also match for two entities to trigger the unique check.
30 | *
31 | * @return the array of properties which determine the scope of the uniqueness
32 | */
33 | String[] within() default {};
34 |
35 | /**
36 | * Determines if the null also must be unique.
37 | *
38 | * @return true if null also must occur at most once, false (default) otherwise
39 | */
40 | boolean includingNull() default false;
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/types/StringNestedMap.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing.types;
10 |
11 | import sirius.db.mixing.Nested;
12 |
13 | /**
14 | * Represents map of String pointing to {@link Nested} values.
15 | *
16 | * @param
20 | * Even if connections are short-lived and not concurrently created, they could still drain the pool of local TCP ports
21 | * of the OS. Therefore we track the number of total created connections and warn if there are too many - this is
22 | * a strong indication that the connection pool is misconfigured and not working as expected anyway.
23 | */
24 | class MonitoredDataSource extends BasicDataSource {
25 |
26 | @Override
27 | protected ConnectionFactory createConnectionFactory() throws SQLException {
28 | ConnectionFactory actualFactory = super.createConnectionFactory();
29 |
30 | return new ConnectionFactory() {
31 | @Override
32 | public Connection createConnection() throws SQLException {
33 | Databases.numConnects.inc();
34 | return actualFactory.createConnection();
35 | }
36 | };
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/test/kotlin/sirius/db/mongo/properties/MongoMultiPointTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mongo.properties
10 |
11 | import org.junit.jupiter.api.Test
12 | import org.junit.jupiter.api.extension.ExtendWith
13 | import sirius.db.mongo.Mango
14 | import sirius.kernel.SiriusExtension
15 | import sirius.kernel.commons.Tuple
16 | import sirius.kernel.di.std.Part
17 | import kotlin.test.assertEquals
18 |
19 | @ExtendWith(SiriusExtension::class)
20 | class MongoMultiPointTest {
21 | @Test
22 | fun `read and write multipoint works`() {
23 | var mongoMultiPointEntity = MongoMultiPointEntity()
24 |
25 | mango.update(mongoMultiPointEntity)
26 |
27 | mongoMultiPointEntity.locations.isEmpty
28 |
29 | val coords = listOf(Tuple.create(48.81734, 9.376294), Tuple.create(48.823356, 9.424718))
30 | mongoMultiPointEntity.locations.addAll(coords)
31 | mango.update(mongoMultiPointEntity)
32 |
33 | assertEquals(2, mongoMultiPointEntity.locations.size())
34 |
35 | mongoMultiPointEntity = mango.refreshOrFail(mongoMultiPointEntity)
36 |
37 | assertEquals(2, mongoMultiPointEntity.locations.size())
38 | }
39 |
40 | companion object {
41 | @Part
42 | private lateinit var mango: Mango
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mixing/IntegrityConstraintFailedException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mixing;
10 |
11 | import java.io.Serial;
12 |
13 | /**
14 | * Wraps all database specific exceptions to signal that an integrity constraint was violated.
15 | *
16 | * Sometimes we use a constraint like "UNIQUE" to detect certain race conditions or other parallel behaviour
17 | * without the need for locking. The occurrence of such an error then needs to be handled properly
18 | * (i.e. by retrying an operation). Therefore some methods (e.g. {@link BaseMapper#tryUpdate(BaseEntity)}
19 | * throw this dedicated exception to permit the application code to handle this case properly.
20 | */
21 | public class IntegrityConstraintFailedException extends Exception {
22 |
23 | @Serial
24 | private static final long serialVersionUID = -3178562817868475776L;
25 |
26 | /**
27 | * Creates a new instance without any reference to another error.
28 | */
29 | public IntegrityConstraintFailedException() {
30 | }
31 |
32 | /**
33 | * Creates a new instance with a reference to the given cause.
34 | *
35 | * @param cause the cause of this error
36 | */
37 | public IntegrityConstraintFailedException(Throwable cause) {
38 | super(cause);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/java/sirius/db/mongo/properties/MongoStringNestedMapEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mongo.properties;
10 |
11 | import sirius.db.mixing.Mapping;
12 | import sirius.db.mixing.Nested;
13 | import sirius.db.mixing.types.StringNestedMap;
14 | import sirius.db.mongo.MongoEntity;
15 |
16 | import java.time.LocalDateTime;
17 |
18 | public class MongoStringNestedMapEntity extends MongoEntity {
19 |
20 | public static class NestedEntity extends Nested {
21 |
22 | private String value1;
23 | private LocalDateTime value2;
24 |
25 | public String getValue1() {
26 | return value1;
27 | }
28 |
29 | public LocalDateTime getValue2() {
30 | return value2;
31 | }
32 |
33 | public NestedEntity withValue1(String value) {
34 | this.value1 = value;
35 | return this;
36 | }
37 |
38 | public NestedEntity withValue2(LocalDateTime value) {
39 | this.value2 = value;
40 | return this;
41 | }
42 | }
43 |
44 | public static final Mapping MAP = Mapping.named("map");
45 | private final StringNestedMap
20 | * This can either be placed on the entity class or on any {@link BeforeDelete before delete handler} or
21 | * {@link AfterDelete after delete handler}.
22 | *
23 | * If the value is set to true (default), the entity is considered complex to delete. If false
24 | * is specified, it isn't considered complex to delete, even if there are cascadeing actions (setting fields in other
25 | * entities to null or deleting other entities).
26 | */
27 | @Documented
28 | @Target({ElementType.TYPE, ElementType.METHOD})
29 | @Retention(RetentionPolicy.RUNTIME)
30 | public @interface ComplexDelete {
31 |
32 | /**
33 | * Specifies if the entity is complex to delete.
34 | *
35 | * @return true to mark it as complex, false to mark it as non-complex even if there are cascade
36 | * delete actions. Note that this can only be specified on the entity class but not for cascade delete handlers
37 | */
38 | boolean value() default true;
39 | }
40 |
--------------------------------------------------------------------------------
/src/test/kotlin/sirius/db/mongo/properties/MongoStringMapPropertyTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mongo.properties
10 |
11 | import org.junit.jupiter.api.Test
12 | import org.junit.jupiter.api.extension.ExtendWith
13 | import sirius.db.mongo.Mango
14 | import sirius.db.mongo.Mongo
15 | import sirius.kernel.SiriusExtension
16 | import sirius.kernel.di.std.Part
17 | import kotlin.test.assertEquals
18 | import kotlin.test.assertFalse
19 |
20 | @ExtendWith(SiriusExtension::class)
21 | class MongoStringMapPropertyTest {
22 | @Test
23 | fun `reading and writing works`() {
24 | val test = MongoStringMapEntity()
25 | test.map.put("Test", "1").put("Foo", "2")
26 | mango.update(test)
27 | var resolved = mango.refreshOrFail(test)
28 |
29 | assertEquals(2, resolved.map.size())
30 | assertEquals("1", resolved.map.get("Test").get())
31 | assertEquals("2", resolved.map.get("Foo").get())
32 |
33 | resolved.map.modify().remove("Test")
34 | mango.update(resolved)
35 | resolved = mango.refreshOrFail(test)
36 |
37 | assertEquals(1, resolved.map.size())
38 | assertFalse { resolved.map.containsKey("Test") }
39 | assertEquals("2", resolved.map.get("Foo").get())
40 | }
41 |
42 | companion object {
43 | @Part
44 | private lateinit var mango: Mango
45 |
46 | @Part
47 | private lateinit var mongo: Mongo
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/test/kotlin/sirius/db/text/BasicIndexTokenizerTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.text
10 |
11 | import org.junit.jupiter.api.Test
12 | import sirius.kernel.commons.Strings
13 | import kotlin.test.assertEquals
14 |
15 | /**
16 | * Tests the [BasicIndexTokenizer].
17 | */
18 | class BasicIndexTokenizerTest : TokenProcessorTest() {
19 | @Test
20 | fun tokenizing() {
21 | assertExactTokenizing(
22 | "email:test@test.local",
23 | "[email:test@test.local, email, test, local, email:test, test.local]"
24 | )
25 | assertExactTokenizing(
26 | "max.mustermann@website.com",
27 | "[max.mustermann@website.com, max, mustermann, website, com, max.mustermann, website.com]"
28 | )
29 | assertExactTokenizing("test-foobar", "[test-foobar, test, foobar]")
30 | assertExactTokenizing("test123@bla-bar.foo", "[test123@bla-bar.foo, test123, bla, bar, foo, bla-bar.foo]")
31 | }
32 |
33 | private fun assertExactTokenizing(input: String?, vararg tokens: String?) {
34 | val tokenizer = BasicIndexTokenizer()
35 | val result: MutableList
39 | * Due to its length and secure generation pattern such IDs are suitable for auth tokens and the like.
40 | *
41 | * @return a newly generated secure unique id
42 | */
43 | public String generateSecureId() {
44 | byte[] input = new byte[256];
45 | ThreadLocalRandom.current().nextBytes(input);
46 | return Hasher.sha256().hash(seed).hashBytes(input).hashLong(System.nanoTime()).toHexString();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/kotlin/sirius/db/mongo/properties/MongoStringIntMapPropertyTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mongo.properties
10 |
11 | import org.junit.jupiter.api.Test
12 | import org.junit.jupiter.api.extension.ExtendWith
13 | import sirius.db.mongo.Mango
14 | import sirius.kernel.SiriusExtension
15 | import sirius.kernel.di.std.Part
16 | import kotlin.test.assertEquals
17 | import kotlin.test.assertFalse
18 |
19 | @ExtendWith(SiriusExtension::class)
20 | class MongoStringIntMapPropertyTe {
21 | @Test
22 | fun `read and write a string int map works`() {
23 | val mongoStringIntMapEntity = MongoStringIntMapEntity()
24 | mongoStringIntMapEntity.map.put("Test", 1).put("Foo", 2).put("Test", 3)
25 | mango.update(mongoStringIntMapEntity)
26 | var resolved = mango.refreshOrFail(mongoStringIntMapEntity)
27 |
28 | assertEquals(2, resolved.map.size())
29 | assertEquals(3, resolved.map.get("Test").get())
30 | assertEquals(2, resolved.map.get("Foo").get())
31 |
32 | resolved.map.modify().remove("Test")
33 | mango.update(resolved)
34 | resolved = mango.refreshOrFail(mongoStringIntMapEntity)
35 |
36 | assertEquals(1, resolved.map.size())
37 | assertFalse { resolved.map.containsKey("Test") }
38 | assertEquals(2, resolved.map.get("Foo").get())
39 | }
40 |
41 | companion object {
42 | @Part
43 | private lateinit var mango: Mango
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/mongo/types/MongoRefList.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.mongo.types;
10 |
11 | import sirius.db.mixing.ContextInfo;
12 | import sirius.db.mixing.types.BaseEntityRef;
13 | import sirius.db.mixing.types.BaseEntityRefList;
14 | import sirius.db.mongo.Mango;
15 | import sirius.db.mongo.MongoEntity;
16 | import sirius.kernel.di.std.Part;
17 |
18 | import java.util.Optional;
19 |
20 | /**
21 | * Represents a list of {@link MongoEntity entities} being referenced by id.
22 | *
23 | * @param
22 | * This validator will be invoked before the property is written to the database.
23 | * It can be used to perform custom validation that is the same for fields across multiple entities.
24 | */
25 | @Documented
26 | @Retention(RetentionPolicy.RUNTIME)
27 | @Target(ElementType.FIELD)
28 | public @interface ValidatedBy {
29 |
30 | /**
31 | * Specifies the validator to use.
32 | */
33 | Class extends PropertyValidator> value();
34 |
35 | /**
36 | * Specifies if the validator should be invoked in strict mode. Strict mode means that the validator gets
37 | * always executed. Non-strict mode means that the validator is only executed if the property value has changed.
38 | *
39 | * The non-strict mode might be useful e.g. for properties that have persisted legacy data which is not valid
40 | * and when validity is not mandatory.
41 | *
42 | * @return true for strict validation, false otherwise
43 | */
44 | boolean strictValidation() default true;
45 | }
46 |
--------------------------------------------------------------------------------
/src/test/kotlin/sirius/db/es/properties/ElasticStringListMapPropertyTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.es.properties
10 |
11 | import org.junit.jupiter.api.Test
12 | import org.junit.jupiter.api.extension.ExtendWith
13 | import sirius.db.es.Elastic
14 | import sirius.kernel.SiriusExtension
15 | import sirius.kernel.di.std.Part
16 | import kotlin.test.assertEquals
17 | import kotlin.test.assertFalse
18 | import kotlin.test.assertTrue
19 |
20 | @ExtendWith(SiriusExtension::class)
21 | class ElasticStringListMapPropertyTest {
22 | @Test
23 | fun `reading and writing works`() {
24 | val test = ESStringListMapEntity()
25 | test.map.add("Test", "1").add("Foo", "2").add("Test", "3")
26 | elastic.update(test)
27 | var resolved = elastic.refreshOrFail(test)
28 |
29 | assertEquals(2, resolved.map.size())
30 | assertTrue { resolved.map.contains("Test", "1") }
31 | assertTrue { resolved.map.contains("Test", "3") }
32 | assertTrue { resolved.map.contains("Foo", "2") }
33 |
34 | resolved.map.remove("Test", "1")
35 | elastic.update(resolved)
36 | resolved = elastic.refreshOrFail(test)
37 |
38 | assertEquals(2, resolved.map.size())
39 | assertFalse { resolved.map.contains("Test", "1") }
40 | assertTrue { resolved.map.contains("Test", "3") }
41 | assertTrue { resolved.map.contains("Foo", "2") }
42 | }
43 |
44 | companion object {
45 | @Part
46 | private lateinit var elastic: Elastic
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/jdbc/constraints/FieldOperator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.jdbc.constraints;
10 |
11 | import sirius.db.jdbc.SmartQuery;
12 | import sirius.kernel.commons.Strings;
13 | import sirius.kernel.commons.Tuple;
14 |
15 | import java.util.List;
16 |
17 | /**
18 | * Represents a simple field operator as constraint.
19 | */
20 | class FieldOperator extends SQLConstraint {
21 |
22 | private final CompoundValue leftHandSide;
23 | private final CompoundValue rightHandSide;
24 | private final String operator;
25 |
26 | protected FieldOperator(CompoundValue leftHandSide, String operator, CompoundValue rightHandSide) {
27 | this.leftHandSide = leftHandSide;
28 | this.operator = operator;
29 | this.rightHandSide = rightHandSide;
30 | }
31 |
32 | @Override
33 | public void appendSQL(SmartQuery.Compiler compiler) {
34 | Tuple
20 | * By default {@link sirius.db.mixing.EntityDescriptor} and {@link sirius.db.mixing.Property} use the class which
21 | * contains a field or the entity class itself when building property keys. Using this annotation, another class can
22 | * be used to provide the i18n keys.
23 | *
24 | * This is mostly used by database independent frameworks. These define a common interface with shared
25 | * {@link sirius.db.mixing.Mapping mappings} which is then implemented by subclasses of the respective entity types.
26 | * To also share the i18n keys, the database specific entities can delegate all i18n keys by using the interface
27 | * as translation source.
28 | */
29 | @Documented
30 | @Target(ElementType.TYPE)
31 | @Retention(RetentionPolicy.RUNTIME)
32 | public @interface TranslationSource {
33 |
34 | /**
35 | * Contains the class which is then used to compute the i18n keys of the annotated entity class.
36 | *
37 | * @return the class which is used to provide common names for i18n keys
38 | */
39 | Class> value();
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/kotlin/sirius/db/es/properties/ElasticStringBooleanMapPropertyTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.es.properties
10 |
11 | import org.junit.jupiter.api.Test
12 | import org.junit.jupiter.api.extension.ExtendWith
13 | import sirius.db.es.Elastic
14 | import sirius.kernel.SiriusExtension
15 | import sirius.kernel.di.std.Part
16 | import kotlin.test.assertEquals
17 | import kotlin.test.assertFalse
18 | import kotlin.test.assertTrue
19 |
20 | @ExtendWith(SiriusExtension::class)
21 | class ElasticStringBooleanMapPropertyTest {
22 | @Test
23 | fun `read and write a string boolean map works`() {
24 | val test = ESStringBooleanMapEntity()
25 | test.map.put("a", true).put("b", false).put("c", true).put("d", false)
26 | elastic.update(test)
27 | var resolved = elastic.refreshOrFail(test)
28 |
29 | assertEquals(4, resolved.map.size())
30 |
31 | assertTrue { resolved.map.get("a").get() }
32 | assertFalse { resolved.map.get("b").get() }
33 | assertTrue { resolved.map.get("c").get() }
34 | assertFalse { resolved.map.get("d").get() }
35 |
36 | resolved.map.modify().remove("a")
37 | elastic.update(resolved)
38 | resolved = elastic.refreshOrFail(test)
39 |
40 | assertEquals(3, resolved.map.size())
41 |
42 | assertFalse { resolved.map.containsKey("a") }
43 | assertTrue { resolved.map.get("c").get() }
44 | }
45 |
46 | companion object {
47 | @Part
48 | private lateinit var elastic: Elastic
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/sirius/db/jdbc/TranslationState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Made with all the love in the world
3 | * by scireum in Remshalden, Germany
4 | *
5 | * Copyright by scireum GmbH
6 | * http://www.scireum.de - info@scireum.de
7 | */
8 |
9 | package sirius.db.jdbc;
10 |
11 | import sirius.db.jdbc.constraints.Exists;
12 | import sirius.db.mixing.EntityDescriptor;
13 | import sirius.kernel.commons.Tuple;
14 |
15 | import java.util.Map;
16 |
17 | /**
18 | * Keeps track of the internal JOIN and column translation state of a {@link SmartQuery.Compiler}.
19 | *
20 | * This is mainly used by constraints which generate internal JOINS like {@link Exists}.
21 | */
22 | public class TranslationState {
23 |
24 | private final EntityDescriptor ed;
25 | private final String defaultAlias;
26 | private final StringBuilder joins;
27 | private final Map
13 |
17 |