diff --git a/junit4/junit4-sql-test/src/test/java/org/quickperf/sql/DisableQuickPerfFeaturesJUnit4Test.java b/junit4/junit4-sql-test/src/test/java/org/quickperf/sql/DisableQuickPerfFeaturesJUnit4Test.java
index af2e9297..b0202bed 100644
--- a/junit4/junit4-sql-test/src/test/java/org/quickperf/sql/DisableQuickPerfFeaturesJUnit4Test.java
+++ b/junit4/junit4-sql-test/src/test/java/org/quickperf/sql/DisableQuickPerfFeaturesJUnit4Test.java
@@ -19,6 +19,7 @@
import org.quickperf.annotation.FunctionalIteration;
import org.quickperf.junit4.QuickPerfJUnitRunner;
import org.quickperf.sql.annotation.ExpectSelect;
+import org.quickperf.sql.annotation.ExpectSelects;
import javax.persistence.EntityManager;
import javax.persistence.Query;
@@ -39,6 +40,18 @@ public void execute_one_select_but_five_select_expected() {
query.getResultList();
}
+ @DisableQuickPerf
+ @ExpectSelects({
+ @ExpectSelect(comment = "Select books"),
+ @ExpectSelect(comment = "Select related entities", value = 4)
+ })
+ @Test
+ public void execute_one_select_but_five_select_expected_with_repeated_annotations() {
+ EntityManager em = emf.createEntityManager();
+ Query query = em.createQuery("FROM " + Book.class.getCanonicalName());
+ query.getResultList();
+ }
+
}
@Test public void
@@ -67,6 +80,18 @@ public void execute_one_select_but_five_select_expected() {
query.getResultList();
}
+ @FunctionalIteration
+ @ExpectSelects({
+ @ExpectSelect(comment = "Select books"),
+ @ExpectSelect(comment = "Select related entities", value = 4)
+ })
+ @Test
+ public void execute_one_select_but_five_select_expected_with_repeated_annotations() {
+ EntityManager em = emf.createEntityManager();
+ Query query = em.createQuery("FROM " + Book.class.getCanonicalName());
+ query.getResultList();
+ }
+
}
@Test public void
diff --git a/junit4/junit4-sql-test/src/test/java/org/quickperf/sql/SqlConcurrencyJUnit4Test.java b/junit4/junit4-sql-test/src/test/java/org/quickperf/sql/SqlConcurrencyJUnit4Test.java
index e9431219..58ecb077 100644
--- a/junit4/junit4-sql-test/src/test/java/org/quickperf/sql/SqlConcurrencyJUnit4Test.java
+++ b/junit4/junit4-sql-test/src/test/java/org/quickperf/sql/SqlConcurrencyJUnit4Test.java
@@ -19,6 +19,7 @@
import org.junit.runner.RunWith;
import org.quickperf.junit4.QuickPerfJUnitRunner;
import org.quickperf.sql.annotation.ExpectSelect;
+import org.quickperf.sql.annotation.ExpectSelects;
import javax.persistence.EntityManager;
import javax.persistence.Query;
@@ -39,9 +40,21 @@ public void execute_one_select() {
query.getResultList();
}
+ @ExpectSelects({
+ @ExpectSelect(comment = "Select books.")
+ })
+ @Test
+ public void execute_one_select_with_repeatable_annotation() {
+ EntityManager em = emf.createEntityManager();
+ Query query = em.createQuery("FROM " + Book.class.getCanonicalName());
+ query.getResultList();
+ }
+
}
-
- @ThreadCount(100) @Test public void
+
+ @ThreadCount(100)
+ @Test
+ public void
sql_performance_property_is_ok() {
Class> testClass = AClassHavingAMethodWithoutSqlPerformanceIssue.class;
diff --git a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectDelete.java b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectDelete.java
index 08b9df7c..fc89d00c 100644
--- a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectDelete.java
+++ b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectDelete.java
@@ -40,4 +40,10 @@
*/
int value() default 1;
+ /**
+ * To comment on the reason why we expect the specified amount of queries of this type.
+ * @return comment message
+ */
+ String comment() default "";
+
}
diff --git a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectDeletes.java b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectDeletes.java
new file mode 100644
index 00000000..765ecfa6
--- /dev/null
+++ b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectDeletes.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2019-2022 the original author or authors.
+ */
+package org.quickperf.sql.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The ExpectDeletes
annotation verifies the number of executed delete statements corresponds to the
+ * specified values.
+ *
+ *
+ *
+ * @ExpectDeletes({
+ * @ExpectDelete(comment="Delete user"),
+ * @ExpectDelete(comment="Delete posts",value=2)
+ * })
+ * public void execute_three_delete() {
+ * ..
+ * }
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface ExpectDeletes {
+
+ /**
+ * Specifies an array of expected queries.
+ */
+ ExpectDelete[] value();
+
+}
diff --git a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectInsert.java b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectInsert.java
index 4e457b42..03377b1a 100644
--- a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectInsert.java
+++ b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectInsert.java
@@ -41,4 +41,10 @@
int value() default 1;
+ /**
+ * To comment on the reason why we expect the specified amount of queries of this type.
+ * @return comment message
+ */
+ String comment() default "";
+
}
diff --git a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectInserts.java b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectInserts.java
new file mode 100644
index 00000000..ada6416b
--- /dev/null
+++ b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectInserts.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2019-2022 the original author or authors.
+ */
+package org.quickperf.sql.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The ExpectInserts
annotation verifies the number of executed insert statements corresponds to the
+ * specified values.
+ *
+ *
+ * @ExpectInserts({
+ * @ExpectInsert(comment="Insert user"),
+ * @ExpectInsert(comment="Insert posts",value=2),
+ * @ExpectInsert(comment="Insert comments",value=3)
+ * })
+ * public void execute_six_insert() {
+ * ..
+ * }
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface ExpectInserts {
+
+ /**
+ * Specifies an array of expected queries.
+ */
+ ExpectInsert[] value();
+
+}
diff --git a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectJdbcQueryExecution.java b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectJdbcQueryExecution.java
index b7799842..16f8f6a5 100644
--- a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectJdbcQueryExecution.java
+++ b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectJdbcQueryExecution.java
@@ -40,4 +40,10 @@
*/
int value() default 1;
+ /**
+ * To comment on the reason why we expect the specified amount of queries of this type.
+ * @return comment message
+ */
+ String comment() default "";
+
}
diff --git a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectSelect.java b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectSelect.java
index 571795ed..cf3b78b7 100644
--- a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectSelect.java
+++ b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectSelect.java
@@ -40,4 +40,10 @@
*/
int value() default 1;
+ /**
+ * To comment on the reason why we expect the specified amount of queries of this type.
+ * @return comment message
+ */
+ String comment() default "";
+
}
diff --git a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectSelects.java b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectSelects.java
new file mode 100644
index 00000000..11b81b06
--- /dev/null
+++ b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectSelects.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2019-2022 the original author or authors.
+ */
+package org.quickperf.sql.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The ExpectSelects
annotation verifies the number of executed select statements corresponds to the
+ * specified values.
+ *
+ *
+ * @ExpectSelects({
+ * @ExpectSelect(comment="Load post"),
+ * @ExpectSelect(comment="Load comments",value=2)
+ * })
+ * public void execute_three_selects() {
+ * ..
+ * }
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface ExpectSelects {
+
+ /**
+ * Specifies an array of expected queries.
+ */
+ ExpectSelect[] value();
+
+}
diff --git a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectUpdate.java b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectUpdate.java
index 6aeb70fc..0c0c7a48 100644
--- a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectUpdate.java
+++ b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectUpdate.java
@@ -40,4 +40,10 @@
*/
int value() default 1;
+ /**
+ * To comment on the reason why we expect the specified amount of queries of this type.
+ * @return comment message
+ */
+ String comment() default "";
+
}
diff --git a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectUpdates.java b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectUpdates.java
new file mode 100644
index 00000000..d3945e44
--- /dev/null
+++ b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/ExpectUpdates.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ * Copyright 2019-2022 the original author or authors.
+ */
+package org.quickperf.sql.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The ExpectUpdates
annotation verifies the number of executed update statements corresponds to the
+ * specified values.
+ *
+ *
+ * @ExpectUpdates({
+ * @ExpectUpdate(comment="Update post"),
+ * @ExpectUpdate(comment="Update comments",value=2)
+ * })
+ * public void execute_three_update() {
+ * ..
+ * }
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface ExpectUpdates {
+
+ /**
+ * Specifies an array of expected queries.
+ */
+ ExpectUpdate[] value();
+
+}
diff --git a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/SqlAnnotationBuilder.java b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/SqlAnnotationBuilder.java
index 3a7a9575..0857c18f 100644
--- a/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/SqlAnnotationBuilder.java
+++ b/sql/sql-annotations/src/main/java/org/quickperf/sql/annotation/SqlAnnotationBuilder.java
@@ -134,6 +134,10 @@ public Class extends Annotation> annotationType() {
public int value() {
return value;
}
+ @Override
+ public String comment() {
+ return "";
+ }
};
}
@@ -231,6 +235,10 @@ public Class extends Annotation> annotationType() {
public int value() {
return value;
}
+ @Override
+ public String comment() {
+ return "";
+ }
};
}
@@ -247,6 +255,10 @@ public Class extends Annotation> annotationType() {
public int value() {
return value;
}
+ @Override
+ public String comment() {
+ return "";
+ }
};
}
@@ -263,6 +275,10 @@ public Class extends Annotation> annotationType() {
public int value() {
return value;
}
+ @Override
+ public String comment() {
+ return "";
+ }
};
}
@@ -279,6 +295,74 @@ public Class extends Annotation> annotationType() {
public int value() {
return value;
}
+ @Override
+ public String comment() {
+ return "";
+ }
+ };
+ }
+
+ /**
+ *Allows to build {@link org.quickperf.sql.annotation.ExpectDeletes} annotation.
+ */
+ public static ExpectDeletes expectDeletes(final ExpectDelete... value) {
+ return new ExpectDeletes() {
+ @Override
+ public Class extends Annotation> annotationType() {
+ return ExpectDeletes.class;
+ }
+ @Override
+ public ExpectDelete[] value() {
+ return value;
+ }
+ };
+ }
+
+ /**
+ *Allows to build {@link org.quickperf.sql.annotation.ExpectInserts} annotation.
+ */
+ public static ExpectInserts expectInserts(final ExpectInsert... value) {
+ return new ExpectInserts() {
+ @Override
+ public Class extends Annotation> annotationType() {
+ return ExpectInserts.class;
+ }
+ @Override
+ public ExpectInsert[] value() {
+ return value;
+ }
+ };
+ }
+
+ /**
+ *Allows to build {@link org.quickperf.sql.annotation.ExpectSelects} annotation.
+ */
+ public static ExpectSelects expectSelects(final ExpectSelect... value) {
+ return new ExpectSelects() {
+ @Override
+ public Class extends Annotation> annotationType() {
+ return ExpectSelects.class;
+ }
+ @Override
+ public ExpectSelect[] value() {
+ return value;
+ }
+ };
+ }
+
+ /**
+ *Allows to build {@link org.quickperf.sql.annotation.ExpectUpdates} annotation.
+ */
+ public static ExpectUpdates expectUpdates(final ExpectUpdate... value) {
+ return new ExpectUpdates() {
+ @Override
+ public Class extends Annotation> annotationType() {
+ return ExpectUpdates.class;
+ }
+ @Override
+ public ExpectUpdate[] value() {
+ return value;
+ }
};
}
diff --git a/sql/sql-annotations/src/main/java/org/quickperf/sql/config/library/SqlAnnotationsConfigs.java b/sql/sql-annotations/src/main/java/org/quickperf/sql/config/library/SqlAnnotationsConfigs.java
index 6772a457..28317a0f 100644
--- a/sql/sql-annotations/src/main/java/org/quickperf/sql/config/library/SqlAnnotationsConfigs.java
+++ b/sql/sql-annotations/src/main/java/org/quickperf/sql/config/library/SqlAnnotationsConfigs.java
@@ -27,18 +27,17 @@
import org.quickperf.sql.delete.DeleteCountMeasureExtractor;
import org.quickperf.sql.delete.MaxOfDeletesPerfIssueVerifier;
import org.quickperf.sql.delete.NumberOfSqlDeletePerfIssueVerifier;
+import org.quickperf.sql.delete.NumberOfSqlDeletesPerfIssueVerifier;
import org.quickperf.sql.display.DisplaySqlOfTestMethodBodyRecorder;
import org.quickperf.sql.display.DisplaySqlRecorder;
import org.quickperf.sql.execution.*;
import org.quickperf.sql.insert.InsertCountMeasureExtractor;
import org.quickperf.sql.insert.InsertNumberPerfIssueVerifier;
import org.quickperf.sql.insert.MaxOfInsertsPerfIssueVerifier;
+import org.quickperf.sql.insert.NumberOfSqlInsertsPerfIssueVerifier;
import org.quickperf.sql.like.ContainsLikeWithLeadingWildcardExtractor;
import org.quickperf.sql.like.HasLikeWithLeadingWildcardVerifier;
-import org.quickperf.sql.select.HasExactlySameSelectVerifier;
-import org.quickperf.sql.select.HasSameSelectTypesWithDiffParamValuesVerifier;
-import org.quickperf.sql.select.MaxOfSelectsPerfIssueVerifier;
-import org.quickperf.sql.select.SelectNumberPerfIssueVerifier;
+import org.quickperf.sql.select.*;
import org.quickperf.sql.select.analysis.SelectAnalysisExtractor;
import org.quickperf.sql.select.columns.MaxSelectedColumnsPerMeasureExtractor;
import org.quickperf.sql.select.columns.MaxSelectedColumnsPerfIssueVerifier;
@@ -49,6 +48,7 @@
import org.quickperf.sql.time.SqlQueryExecutionTimeExtractor;
import org.quickperf.sql.time.SqlQueryMaxExecutionTimeVerifier;
import org.quickperf.sql.update.MaxOfUpdatesPerfIssueVerifier;
+import org.quickperf.sql.update.NumberOfSqlUpdatesPerfIssueVerifier;
import org.quickperf.sql.update.UpdateCountMeasureExtractor;
import org.quickperf.sql.update.UpdateNumberPerfIssueVerifier;
import org.quickperf.sql.update.columns.MaxUpdatedColumnsPerMeasureExtractor;
@@ -88,6 +88,12 @@ private SqlAnnotationsConfigs() { }
.perfIssueVerifier(SelectNumberPerfIssueVerifier.INSTANCE)
.build(ExpectSelect.class);
+ static final AnnotationConfig NUMBER_OF_SQL_SELECTS = new AnnotationConfig.Builder()
+ .perfRecorderClass(PersistenceSqlRecorder.class)
+ .perfMeasureExtractor(SelectAnalysisExtractor.INSTANCE)
+ .perfIssueVerifier(NumberOfSqlSelectsPerfIssueVerifier.INSTANCE)
+ .build(ExpectSelects.class);
+
static final AnnotationConfig MAX_SQL_SELECT = new AnnotationConfig.Builder()
.perfRecorderClass(PersistenceSqlRecorder.class)
.perfMeasureExtractor(SelectAnalysisExtractor.INSTANCE)
@@ -134,6 +140,12 @@ private SqlAnnotationsConfigs() { }
.perfIssueVerifier(InsertNumberPerfIssueVerifier.INSTANCE)
.build(ExpectInsert.class);
+ static final AnnotationConfig NUMBER_OF_SQL_INSERTS = new AnnotationConfig.Builder()
+ .perfRecorderClass(PersistenceSqlRecorder.class)
+ .perfMeasureExtractor(InsertCountMeasureExtractor.INSTANCE)
+ .perfIssueVerifier(NumberOfSqlInsertsPerfIssueVerifier.INSTANCE)
+ .build(ExpectInserts.class);
+
static final AnnotationConfig SQL_STATEMENTS_BATCHED = new AnnotationConfig.Builder()
.perfRecorderClass(SqlStatementBatchRecorder.class)
.perfIssueVerifier(SqlStatementBatchVerifier.INSTANCE)
@@ -145,12 +157,24 @@ private SqlAnnotationsConfigs() { }
.perfIssueVerifier(NumberOfSqlDeletePerfIssueVerifier.INSTANCE)
.build(ExpectDelete.class);
+ static final AnnotationConfig NUMBER_OF_SQL_DELETES = new AnnotationConfig.Builder()
+ .perfRecorderClass(PersistenceSqlRecorder.class)
+ .perfMeasureExtractor(DeleteCountMeasureExtractor.INSTANCE)
+ .perfIssueVerifier(NumberOfSqlDeletesPerfIssueVerifier.INSTANCE)
+ .build(ExpectDeletes.class);
+
static final AnnotationConfig NUMBER_OF_SQL_UPDATE = new AnnotationConfig.Builder()
.perfRecorderClass(PersistenceSqlRecorder.class)
.perfMeasureExtractor(UpdateCountMeasureExtractor.INSTANCE)
.perfIssueVerifier(UpdateNumberPerfIssueVerifier.INSTANCE)
.build(ExpectUpdate.class);
+ static final AnnotationConfig NUMBER_OF_SQL_UPDATES = new AnnotationConfig.Builder()
+ .perfRecorderClass(PersistenceSqlRecorder.class)
+ .perfMeasureExtractor(UpdateCountMeasureExtractor.INSTANCE)
+ .perfIssueVerifier(NumberOfSqlUpdatesPerfIssueVerifier.INSTANCE)
+ .build(ExpectUpdates.class);
+
static final AnnotationConfig MAX_SQL_UPDATE = new AnnotationConfig.Builder()
.perfRecorderClass(PersistenceSqlRecorder.class)
.perfMeasureExtractor(UpdateCountMeasureExtractor.INSTANCE)
diff --git a/sql/sql-annotations/src/main/java/org/quickperf/sql/config/library/SqlConfigLoader.java b/sql/sql-annotations/src/main/java/org/quickperf/sql/config/library/SqlConfigLoader.java
index 7e1c466b..b5c73fd4 100644
--- a/sql/sql-annotations/src/main/java/org/quickperf/sql/config/library/SqlConfigLoader.java
+++ b/sql/sql-annotations/src/main/java/org/quickperf/sql/config/library/SqlConfigLoader.java
@@ -33,9 +33,13 @@ public Collection