Skip to content

Commit fbe165c

Browse files
PropertyQuery: add avgLong, also update avg docs to advertise it, add tests.
1 parent cea1f1b commit fbe165c

File tree

2 files changed

+92
-1
lines changed

2 files changed

+92
-1
lines changed

objectbox-java/src/main/java/io/objectbox/query/PropertyQuery.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ native String nativeFindString(long handle, long cursorHandle, int propertyId, b
9494

9595
native double nativeAvg(long handle, long cursorHandle, int propertyId);
9696

97+
native long nativeAvgLong(long handle, long cursorHandle, int propertyId);
98+
9799
native long nativeCount(long handle, long cursorHandle, int propertyId, boolean distinct);
98100

99101
/** Clears all values (e.g. distinct and null value). */
@@ -448,7 +450,11 @@ public Double call() {
448450
});
449451
}
450452

451-
/** Calculates the average of all values for the given property over all Objects matching the query. */
453+
/**
454+
* Calculates the average of all values for the given number property over all Objects matching the query.
455+
* <p>
456+
* For integer properties you can also use {@link #avgLong()}.
457+
*/
452458
public double avg() {
453459
return (Double) query.callInReadTx(new Callable<Double>() {
454460
@Override
@@ -458,6 +464,20 @@ public Double call() {
458464
});
459465
}
460466

467+
/**
468+
* Calculates the average of all values for the given integer property over all Objects matching the query.
469+
* <p>
470+
* For floating-point properties use {@link #avg()}.
471+
*/
472+
public long avgLong() {
473+
return (Long) query.callInReadTx(new Callable<Long>() {
474+
@Override
475+
public Long call() {
476+
return nativeAvgLong(queryHandle, query.cursorHandle(), propertyId);
477+
}
478+
});
479+
}
480+
461481
public long count() {
462482
return (Long) query.callInReadTx(new Callable<Long>() {
463483
@Override

tests/objectbox-java-test/src/test/java/io/objectbox/query/PropertyQueryTest.java

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ private void putTestEntityInteger(byte vByte, short vShort, int vInt, long vLong
4242
entity.setSimpleShort(vShort);
4343
entity.setSimpleInt(vInt);
4444
entity.setSimpleLong(vLong);
45+
entity.setSimpleShortU(vShort);
46+
entity.setSimpleIntU(vInt);
47+
entity.setSimpleLongU(vLong);
4548
box.put(entity);
4649
}
4750

@@ -479,6 +482,18 @@ public void avg_notSupported() {
479482
assertUnsupported(() -> query.property(simpleString).avg(), exceptionMessage);
480483
}
481484

485+
@Test
486+
public void avgLong_notSupported() {
487+
Query<TestEntity> query = box.query().build();
488+
String exceptionMessage = "Cannot calculate sum. This function is for integer types only. This operation is not supported for Property ";
489+
assertUnsupported(() -> query.property(simpleByteArray).avgLong(), exceptionMessage);
490+
assertUnsupported(() -> query.property(simpleString).avgLong(), exceptionMessage);
491+
492+
String exceptionMessage2 = "Please use the double based average instead. This operation is not supported for Property ";
493+
assertUnsupported(() -> query.property(simpleFloat).avgLong(), exceptionMessage2);
494+
assertUnsupported(() -> query.property(simpleDouble).avgLong(), exceptionMessage2);
495+
}
496+
482497
@Test
483498
public void min_notSupported() {
484499
Query<TestEntity> query = box.query().build();
@@ -568,6 +583,20 @@ public void avg_noData() {
568583
assertEquals(Double.NaN, baseQuery.property(simpleDouble).avg(), 0.0);
569584
}
570585

586+
@Test
587+
public void avgLong_noData() {
588+
Query<TestEntity> baseQuery = box.query().build();
589+
// Integer.
590+
assertEquals(0, baseQuery.property(simpleByte).avgLong());
591+
assertEquals(0, baseQuery.property(simpleShort).avgLong());
592+
assertEquals(0, baseQuery.property(simpleInt).avgLong());
593+
assertEquals(0, baseQuery.property(simpleLong).avgLong());
594+
// Integer treated as unsigned.
595+
assertEquals(0, baseQuery.property(simpleShortU).avgLong());
596+
assertEquals(0, baseQuery.property(simpleIntU).avgLong());
597+
assertEquals(0, baseQuery.property(simpleLongU).avgLong());
598+
}
599+
571600
@Test
572601
public void min_noData() {
573602
Query<TestEntity> baseQuery = box.query().build();
@@ -668,6 +697,39 @@ public void avg_NaN() {
668697
assertEquals(Double.NaN, baseQuery.property(simpleDouble).avg(), 0.001);
669698
}
670699

700+
@Test
701+
public void avgLong_positiveOverflow() {
702+
putTestEntityInteger((byte) 0, (short) 0, 0, Long.MAX_VALUE);
703+
putTestEntityInteger((byte) 0, (short) 0, 0, 1);
704+
705+
Query<TestEntity> baseQuery = box.query().build();
706+
assertEquals(Long.MAX_VALUE / 2 + 1, baseQuery.property(simpleLong).avgLong());
707+
// Should not change if treated as unsigned.
708+
assertEquals(Long.MAX_VALUE / 2 + 1, baseQuery.property(simpleLongU).avgLong());
709+
}
710+
711+
@Test
712+
public void avgLong_negativeOverflow() {
713+
putTestEntityInteger((byte) 0, (short) 0, 0, Long.MIN_VALUE);
714+
putTestEntityInteger((byte) 0, (short) 0, 0, -1);
715+
716+
Query<TestEntity> baseQuery = box.query().build();
717+
assertEquals(Long.MIN_VALUE / 2, baseQuery.property(simpleLong).avgLong());
718+
// Should not change if treated as unsigned.
719+
assertEquals(Long.MIN_VALUE / 2, baseQuery.property(simpleLongU).avgLong());
720+
}
721+
722+
@Test
723+
public void avgLong_unsignedOverflow() {
724+
putTestEntityInteger((byte) 0, (short) 0, 0, -1);
725+
putTestEntityInteger((byte) 0, (short) 0, 0, 1);
726+
727+
Query<TestEntity> baseQuery = box.query().build();
728+
assertEquals(Long.MIN_VALUE, baseQuery.property(simpleLongU).avgLong());
729+
// Should be different if treated as signed.
730+
assertEquals(0, baseQuery.property(simpleLong).avgLong());
731+
}
732+
671733
@Test
672734
public void sum_byteShortIntOverflow() {
673735
putTestEntityInteger(Byte.MAX_VALUE, Short.MAX_VALUE, Integer.MAX_VALUE, 0);
@@ -777,6 +839,15 @@ public void testAggregates() {
777839
assertEquals(2100.5, shortUQuery.avg(), 0.0001);
778840
assertEquals(2000.5, intUQuery.avg(), 0.0001);
779841
assertEquals(3000.5, longUQuery.avg(), 0.0001);
842+
// avgLong
843+
assertEquals(1, booleanQuery.avgLong());
844+
assertEquals(-38, byteQuery.avgLong());
845+
assertEquals(2101, shortQuery.avgLong());
846+
assertEquals(2001, intQuery.avgLong());
847+
assertEquals(3001, longQuery.avgLong());
848+
assertEquals(2101, shortUQuery.avgLong());
849+
assertEquals(2001, intUQuery.avgLong());
850+
assertEquals(3001, longUQuery.avgLong());
780851
// min
781852
assertEquals(-38, byteQuery.min());
782853
assertEquals(2100, shortQuery.min());

0 commit comments

Comments
 (0)