Skip to content

Commit 61ca464

Browse files
TS426TS426
authored andcommitted
style: fix ktlint errors in bot-storage-mongo
- Rename MongoAggregationDSL.kt to MongoAgg.kt (single top-level declaration) - Rename Agg object to MongoAgg - Replace wildcard imports with explicit imports in UserTimelineMongoDAO - Replace wildcard imports and merge consecutive KDocs in UserTimelineMongoDAOTest - Apply ktlint auto-format fixes
1 parent a9d60ba commit 61ca464

File tree

4 files changed

+645
-556
lines changed

4 files changed

+645
-556
lines changed

bot/storage-mongo/src/main/kotlin/MongoAggregationDSL.kt renamed to bot/storage-mongo/src/main/kotlin/MongoAgg.kt

Lines changed: 111 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -18,120 +18,139 @@ package ai.tock.bot.mongo
1818

1919
import org.bson.Document
2020
import org.bson.conversions.Bson
21-
import java.time.Instant
2221
import java.time.ZonedDateTime
2322

2423
/**
2524
* Lightweight DSL for building MongoDB aggregation expressions.
26-
*
25+
*
2726
* This DSL provides simple functions to construct MongoDB aggregation operators
2827
* in a more readable way than using raw strings, while producing identical BSON output.
29-
*
28+
*
3029
* **Type Design**: Parameters are intentionally typed `Any` to support:
3130
* - BSON expressions (Document, Bson)
3231
* - MongoDB field paths ("$field")
3332
* - Aggregation variables ("$$value", "$$this")
3433
* - Primitive values (String, Int, null, etc.)
35-
*
34+
*
3635
* Usage example:
3736
* ```
38-
* val minDate = Agg.min(Agg.reduce(
39-
* input = Agg.field("stories"),
37+
* val minDate = MongoAgg.min(MongoAgg.reduce(
38+
* input = MongoAgg.field("stories"),
4039
* initialValue = null,
41-
* `in` = Agg.cond(
42-
* Agg.eq(Agg.value(), null),
43-
* Agg.ifNull(Agg.min("${Agg.thisVar()}.actions.date"), null),
44-
* Agg.min(listOf(Agg.value(), Agg.ifNull(Agg.min("${Agg.thisVar()}.actions.date"), Agg.value())))
40+
* `in` = MongoAgg.cond(
41+
* MongoAgg.eq(MongoAgg.value(), null),
42+
* MongoAgg.ifNull(MongoAgg.min("${MongoAgg.thisVar()}.actions.date"), null),
43+
* MongoAgg.min(listOf(MongoAgg.value(), MongoAgg.ifNull(MongoAgg.min("${MongoAgg.thisVar()}.actions.date"), MongoAgg.value())))
4544
* )
4645
* ))
4746
* ```
4847
*/
49-
object Agg {
48+
object MongoAgg {
5049
/**
5150
* Creates a $min aggregation expression.
52-
*
51+
*
5352
* @param expr the expression to find the minimum of (can be null)
5453
* @return Document representing $min operator
5554
*/
5655
fun min(expr: Any?): Document = Document("\$min", expr)
5756

5857
/**
5958
* Creates a $max aggregation expression.
60-
*
59+
*
6160
* @param expr the expression to find the maximum of (can be null)
6261
* @return Document representing $max operator
6362
*/
6463
fun max(expr: Any?): Document = Document("\$max", expr)
6564

6665
/**
6766
* Creates an $eq (equals) aggregation expression.
68-
*
67+
*
6968
* @param a first operand
7069
* @param b second operand (can be null)
7170
* @return Document representing $eq operator
7271
*/
73-
fun eq(a: Any, b: Any?): Document = Document("\$eq", listOf(a, b))
72+
fun eq(
73+
a: Any,
74+
b: Any?,
75+
): Document = Document("\$eq", listOf(a, b))
7476

7577
/**
7678
* Creates a $gte (greater than or equal) aggregation expression.
77-
*
79+
*
7880
* @param a first operand
7981
* @param b second operand (can be null)
8082
* @return Document representing $gte operator
8183
*/
82-
fun gte(a: Any, b: Any?): Document = Document("\$gte", listOf(a, b))
84+
fun gte(
85+
a: Any,
86+
b: Any?,
87+
): Document = Document("\$gte", listOf(a, b))
8388

8489
/**
8590
* Creates a $lte (less than or equal) aggregation expression.
86-
*
91+
*
8792
* @param a first operand
8893
* @param b second operand (can be null)
8994
* @return Document representing $lte operator
9095
*/
91-
fun lte(a: Any, b: Any?): Document = Document("\$lte", listOf(a, b))
96+
fun lte(
97+
a: Any,
98+
b: Any?,
99+
): Document = Document("\$lte", listOf(a, b))
92100

93101
/**
94102
* Creates a $gt (greater than) aggregation expression.
95-
*
103+
*
96104
* @param a first operand
97105
* @param b second operand (can be null)
98106
* @return Document representing $gt operator
99107
*/
100-
fun gt(a: Any, b: Any?): Document = Document("\$gt", listOf(a, b))
108+
fun gt(
109+
a: Any,
110+
b: Any?,
111+
): Document = Document("\$gt", listOf(a, b))
101112

102113
/**
103114
* Creates a $lt (less than) aggregation expression.
104-
*
115+
*
105116
* @param a first operand
106117
* @param b second operand (can be null)
107118
* @return Document representing $lt operator
108119
*/
109-
fun lt(a: Any, b: Any?): Document = Document("\$lt", listOf(a, b))
120+
fun lt(
121+
a: Any,
122+
b: Any?,
123+
): Document = Document("\$lt", listOf(a, b))
110124

111125
/**
112126
* Creates a $cond (conditional) aggregation expression.
113-
*
127+
*
114128
* @param ifExpr the condition expression
115129
* @param thenExpr the expression to evaluate if condition is true (can be null)
116130
* @param elseExpr the expression to evaluate if condition is false (can be null)
117131
* @return Document representing $cond operator
118132
*/
119-
fun cond(ifExpr: Any, thenExpr: Any?, elseExpr: Any?): Document =
120-
Document("\$cond", listOf(ifExpr, thenExpr, elseExpr))
133+
fun cond(
134+
ifExpr: Any,
135+
thenExpr: Any?,
136+
elseExpr: Any?,
137+
): Document = Document("\$cond", listOf(ifExpr, thenExpr, elseExpr))
121138

122139
/**
123140
* Creates an $ifNull aggregation expression.
124-
*
141+
*
125142
* @param expr the expression to evaluate
126143
* @param replacement the replacement value if expr is null (can be null)
127144
* @return Document representing $ifNull operator
128145
*/
129-
fun ifNull(expr: Any, replacement: Any?): Document =
130-
Document("\$ifNull", listOf(expr, replacement))
146+
fun ifNull(
147+
expr: Any,
148+
replacement: Any?,
149+
): Document = Document("\$ifNull", listOf(expr, replacement))
131150

132151
/**
133152
* Creates a $reduce aggregation expression.
134-
*
153+
*
135154
* @param input the array to reduce
136155
* @param initialValue the initial value for the accumulator (often null)
137156
* @param `in` the expression to apply to each element
@@ -140,24 +159,26 @@ object Agg {
140159
fun reduce(
141160
input: Any,
142161
initialValue: Any?,
143-
`in`: Any
144-
): Document = Document("\$reduce",
145-
Document("input", input)
146-
.append("initialValue", initialValue)
147-
.append("in", `in`)
148-
)
162+
`in`: Any,
163+
): Document =
164+
Document(
165+
"\$reduce",
166+
Document("input", input)
167+
.append("initialValue", initialValue)
168+
.append("in", `in`),
169+
)
149170

150171
/**
151172
* Creates an $expr aggregation expression for use in queries.
152-
*
173+
*
153174
* @param expr the expression to evaluate (can be Document, Bson, or any BSON-compatible value, can be null)
154175
* @return Bson representing $expr operator
155176
*/
156177
fun expr(expr: Any?): Bson = Document("\$expr", expr)
157178

158179
/**
159180
* Creates a MongoDB field path reference.
160-
*
181+
*
161182
* @param path the field path (e.g., "stories" becomes "$stories")
162183
* @return String representing the MongoDB field path
163184
*/
@@ -180,15 +201,15 @@ object Agg {
180201

181202
/**
182203
* Creates a $and aggregation expression.
183-
*
204+
*
184205
* @param exprs the expressions to combine with AND logic
185206
* @return Document representing $and operator
186207
*/
187208
fun and(vararg exprs: Any): Document = Document("\$and", exprs.toList())
188209

189210
/**
190211
* Creates an $or aggregation expression.
191-
*
212+
*
192213
* @param exprs the expressions to combine with OR logic
193214
* @return Document representing $or operator
194215
*/
@@ -197,30 +218,36 @@ object Agg {
197218
/**
198219
* Builds a MongoDB aggregation expression to calculate the oldest (earliest) date from a nested array field.
199220
* Uses $reduce with $min to find the minimum date across all elements.
200-
*
221+
*
201222
* @param inputField the input array field (e.g., "stories")
202223
* @param datePath the path to the date field within each element (e.g., "actions.date")
203224
* @return Document representing the min(date) expression
204225
*/
205-
private fun oldestDateInArray(inputField: String, datePath: String): Document {
226+
private fun oldestDateInArray(
227+
inputField: String,
228+
datePath: String,
229+
): Document {
206230
return dateInArray(inputField, datePath, ::min)
207231
}
208232

209233
/**
210234
* Builds a MongoDB aggregation expression to calculate the youngest (latest) date from a nested array field.
211235
* Uses $reduce with $max to find the maximum date across all elements.
212-
*
236+
*
213237
* @param inputField the input array field (e.g., "stories")
214238
* @param datePath the path to the date field within each element (e.g., "actions.date")
215239
* @return Document representing the max(date) expression
216240
*/
217-
private fun youngestDateInArray(inputField: String, datePath: String): Document {
241+
private fun youngestDateInArray(
242+
inputField: String,
243+
datePath: String,
244+
): Document {
218245
return dateInArray(inputField, datePath, ::max)
219246
}
220247

221248
/**
222249
* Generic function to build a MongoDB aggregation expression for date aggregation in nested arrays.
223-
*
250+
*
224251
* @param inputField the input array field (e.g., "stories")
225252
* @param datePath the path to the date field within each element (e.g., "actions.date")
226253
* @param aggregationFn the aggregation function to use (min for oldest, max for youngest)
@@ -229,34 +256,36 @@ object Agg {
229256
private fun dateInArray(
230257
inputField: String,
231258
datePath: String,
232-
aggregationFn: (Any?) -> Document
259+
aggregationFn: (Any?) -> Document,
233260
): Document {
234261
return aggregationFn(
235262
reduce(
236263
input = field(inputField),
237264
initialValue = null,
238-
`in` = cond(
239-
ifExpr = eq(value(), null),
240-
thenExpr = ifNull(aggregationFn("${thisVar()}.$datePath"), null),
241-
elseExpr = aggregationFn(
242-
listOf(
243-
value(),
244-
ifNull(aggregationFn("${thisVar()}.$datePath"), value())
245-
)
246-
)
247-
)
248-
)
265+
`in` =
266+
cond(
267+
ifExpr = eq(value(), null),
268+
thenExpr = ifNull(aggregationFn("${thisVar()}.$datePath"), null),
269+
elseExpr =
270+
aggregationFn(
271+
listOf(
272+
value(),
273+
ifNull(aggregationFn("${thisVar()}.$datePath"), value()),
274+
),
275+
),
276+
),
277+
),
249278
)
250279
}
251280

252281
/**
253282
* Filters documents where the oldest date (from array) is within a period.
254-
*
283+
*
255284
* Condition: fromDate <= oldestDate <= toDate
256-
*
285+
*
257286
* This is typically used for filtering by creation date, where we want to check
258287
* if the first action date falls within the specified period.
259-
*
288+
*
260289
* @param inputField the input array field (e.g., "stories")
261290
* @param datePath the path to the date field within each element (e.g., "actions.date")
262291
* @param fromDate optional start date filter (inclusive)
@@ -267,19 +296,20 @@ object Agg {
267296
inputField: String,
268297
datePath: String,
269298
fromDate: ZonedDateTime?,
270-
toDate: ZonedDateTime?
299+
toDate: ZonedDateTime?,
271300
): Bson? {
272301
val oldestDateExpr = oldestDateInArray(inputField, datePath)
273-
val conditionBuilders = listOfNotNull(
274-
fromDate?.let { { gte(oldestDateExpr, it.toInstant()) } },
275-
toDate?.let { { lte(oldestDateExpr, it.toInstant()) } }
276-
)
302+
val conditionBuilders =
303+
listOfNotNull(
304+
fromDate?.let { { gte(oldestDateExpr, it.toInstant()) } },
305+
toDate?.let { { lte(oldestDateExpr, it.toInstant()) } },
306+
)
277307
return buildExprFromConditionBuilders(conditionBuilders)
278308
}
279309

280310
/**
281311
* Builds a MongoDB $expr expression from a list of condition builders.
282-
*
312+
*
283313
* @param conditionBuilders list of functions that build condition documents
284314
* @return Bson expression wrapping the conditions, or null if empty
285315
*/
@@ -296,12 +326,12 @@ object Agg {
296326

297327
/**
298328
* Filters documents where the activity period overlaps with the filter period.
299-
*
329+
*
300330
* Condition: fromDate <= youngestDate AND oldestDate < toDate
301-
*
331+
*
302332
* A document is included if its activity period (from oldest to youngest date)
303333
* overlaps the filter range. This implements period overlap logic.
304-
*
334+
*
305335
* @param inputField the input array field (e.g., "stories")
306336
* @param datePath the path to the date field within each element (e.g., "actions.date")
307337
* @param fromDate optional start date filter (inclusive)
@@ -312,20 +342,19 @@ object Agg {
312342
inputField: String,
313343
datePath: String,
314344
fromDate: ZonedDateTime?,
315-
toDate: ZonedDateTime?
345+
toDate: ZonedDateTime?,
316346
): Bson? {
317-
val conditionBuilders = listOfNotNull(
318-
// fromDate <= youngestDate (need youngest only if fromDate is set)
319-
fromDate?.let {
320-
{ gte(youngestDateInArray(inputField, datePath), it.toInstant()) }
321-
},
322-
// oldestDate < toDate (need oldest only if toDate is set)
323-
toDate?.let {
324-
{ lt(oldestDateInArray(inputField, datePath), it.toInstant()) }
325-
}
326-
)
347+
val conditionBuilders =
348+
listOfNotNull(
349+
// fromDate <= youngestDate (need youngest only if fromDate is set)
350+
fromDate?.let {
351+
{ gte(youngestDateInArray(inputField, datePath), it.toInstant()) }
352+
},
353+
// oldestDate < toDate (need oldest only if toDate is set)
354+
toDate?.let {
355+
{ lt(oldestDateInArray(inputField, datePath), it.toInstant()) }
356+
},
357+
)
327358
return buildExprFromConditionBuilders(conditionBuilders)
328359
}
329-
330360
}
331-

0 commit comments

Comments
 (0)