@@ -452,24 +452,6 @@ internal class DBAdapter(context: Context, config: CleverTapInstanceConfig) {
452452 cleanInternal(PUSH_NOTIFICATIONS , 0 )
453453 }
454454
455- /* *
456- * Removes sent events with an _id <= last_id from table
457- *
458- * @param lastId the last id to delete
459- * @param table the table to remove events
460- */
461- @WorkerThread
462- @Synchronized
463- fun cleanupEventsFromLastId (lastId : String , table : Table ) {
464- val tName = table.tableName
465- try {
466- dbHelper.writableDatabase.delete(tName, " ${Column .ID } <= ?" , arrayOf(lastId))
467- } catch (e: SQLiteException ) {
468- logger.verbose(" Error removing sent data from table $tName Recreating DB" )
469- deleteDB()
470- }
471- }
472-
473455 @Synchronized
474456 fun storePushNotificationId (id : String? , ttl : Long ) {
475457 if (id == null ) {
@@ -517,39 +499,146 @@ internal class DBAdapter(context: Context, config: CleverTapInstanceConfig) {
517499 * @return JSONObject containing the max row ID and a JSONArray of the JSONObject events or null
518500 */
519501 @Synchronized
520- fun fetchEvents (table : Table , limit : Int ): JSONObject ? {
502+ fun fetchEvents (table : Table , limit : Int ): QueueData {
503+ val queueData = QueueData ()
504+
521505 val tName = table.tableName
522- var lastId: String? = null
523- val events = JSONArray ()
524506 try {
525507 dbHelper.readableDatabase.query(
526- tName, null , null , null , null , null , " ${Column .CREATED_AT } ASC" , limit.toString()
508+ tName,
509+ arrayOf(Column .ID , Column .DATA , Column .CREATED_AT ),
510+ null , null , null , null ,
511+ " ${Column .CREATED_AT } ASC" ,
512+ (limit + 1 ).toString()
527513 )?.use { cursor ->
514+ val rowCount = cursor.count
515+ queueData.hasMore = rowCount > limit
516+
517+ var pos = 0
528518 while (cursor.moveToNext()) {
529- if (cursor.isLast ) {
530- lastId = cursor.getString(cursor.getColumnIndexOrThrow( Column . ID ))
519+ if (pos == limit ) {
520+ break
531521 }
522+ val id = cursor.getString(cursor.getColumnIndexOrThrow(Column .ID ))
523+ val eventData = cursor.getString(cursor.getColumnIndexOrThrow(Column .DATA ))
524+
532525 try {
533- val j = JSONObject (cursor.getString(cursor.getColumnIndexOrThrow(Column .DATA )))
534- events.put(j)
526+ val jsonEvent = JSONObject (eventData)
527+ queueData.data.put(jsonEvent)
528+
529+ if (table == Table .PROFILE_EVENTS ) {
530+ queueData.profileEventIds.add(id)
531+ } else {
532+ queueData.eventIds.add(id)
533+ }
534+
535535 } catch (e: JSONException ) {
536- // Ignore
536+ logger.verbose( " Error parsing event data for id: $id from table: $tName " , e)
537537 }
538+ pos++
538539 }
539540 }
540- } catch (e: Exception ) { // SQLiteException | IllegalArgumentException
541- logger.verbose(" Could not fetch records out of database $tName ." , e)
542- lastId = null
541+ } catch (e: Exception ) {
542+ logger.verbose(" Could not fetch records from table $tName " , e)
543543 }
544544
545- return lastId?.let {
546- try {
547- val ret = JSONObject ()
548- ret.put(it, events)
549- ret
550- } catch (e: JSONException ) {
551- null
545+ val size = if (table == Table .PROFILE_EVENTS ) {
546+ queueData.profileEventIds.size
547+ } else {
548+ queueData.eventIds.size
549+ }
550+ logger.verbose(" Fetched $size events from $tName " )
551+ return queueData
552+ }
553+
554+ /* *
555+ * Fetches a combined batch of events from both events and profileEvents tables
556+ * Prioritizes profileEvents table first, then fills remaining slots from events
557+ *
558+ * @param batchSize The maximum number of events to fetch (typically 50)
559+ * @return QueueData containing the events and their IDs for cleanup
560+ */
561+ @Synchronized
562+ fun fetchCombinedEvents (batchSize : Int ): QueueData {
563+ val combinedQueueData = QueueData ()
564+
565+ // First priority: Fetch from profileEvents table using the base fetchEvents method
566+ val profileData = fetchEvents(Table .PROFILE_EVENTS , batchSize)
567+
568+ // Add profile events to combined data
569+ for (i in 0 until profileData.data.length()) {
570+ combinedQueueData.data.put(profileData.data.getJSONObject(i))
571+ }
572+ combinedQueueData.profileEventIds.addAll(profileData.profileEventIds)
573+ combinedQueueData.hasMore = profileData.hasMore
574+
575+ // Calculate remaining slots for normal events
576+ val eventsNeeded = batchSize - combinedQueueData.profileEventIds.size
577+
578+ // Second priority: Fill remaining slots from events table
579+ if (eventsNeeded > 0 || combinedQueueData.hasMore.not ()) {
580+ val eventsData = fetchEvents(Table .EVENTS , eventsNeeded)
581+
582+ // Add events to combined data
583+ for (i in 0 until eventsData.data.length()) {
584+ combinedQueueData.data.put(eventsData.data.getJSONObject(i))
585+ }
586+ combinedQueueData.eventIds.addAll(eventsData.eventIds)
587+ combinedQueueData.hasMore = eventsData.hasMore
588+ }
589+
590+ logger.verbose(" Fetched combined batch: ${combinedQueueData.profileEventIds.size} profile events, ${combinedQueueData.eventIds.size} events" )
591+
592+ return combinedQueueData
593+ }
594+
595+ /* *
596+ * Removes sent events with an _id <= last_id from table
597+ *
598+ * @param lastId the last id to delete
599+ * @param table the table to remove events
600+ */
601+ @WorkerThread
602+ @Synchronized
603+ fun cleanupEventsFromLastId (lastId : String , table : Table ) {
604+ val tName = table.tableName
605+ try {
606+ dbHelper.writableDatabase.delete(tName, " ${Column .ID } <= ?" , arrayOf(lastId))
607+ } catch (e: SQLiteException ) {
608+ logger.verbose(" Error removing sent data from table $tName Recreating DB" )
609+ deleteDB()
610+ }
611+ }
612+
613+ /* *
614+ * Cleans up events from the profileEvents table by their IDs
615+ *
616+ * @param events List of profile event IDs to delete
617+ */
618+ @WorkerThread
619+ @Synchronized
620+ fun cleanupEventsByIds (table : Table , events : List <String >) {
621+ if (events.isEmpty()) {
622+ return
623+ }
624+
625+ val tName = table.tableName
626+
627+ try {
628+ // Process in chunks if the list is too large
629+ val chunkSize = 100
630+ events.chunked(chunkSize).forEach { chunk ->
631+ val placeholders = chunk.joinToString(" ," ) { " ?" }
632+ val deletedCount = dbHelper.writableDatabase.delete(
633+ tName,
634+ " ${Column .ID } IN ($placeholders )" ,
635+ chunk.toTypedArray()
636+ )
637+ logger.verbose(" Deleted $deletedCount events from $tName " )
552638 }
639+ } catch (e: SQLiteException ) {
640+ logger.verbose(" Error removing events from $tName " , e)
641+ deleteDB()
553642 }
554643 }
555644
0 commit comments