main

square/leakcanary

Last updated at: 29/12/2023 09:39

Cursors.kt

TLDR

This file contains Kotlin extension functions for working with Cursors and SQLiteDatabase objects in the LeakCanary library. The functions provide convenient utilities for managing Cursors and executing transactions on SQLiteDatabase objects.

Methods

use

This method is an extension function for the Cursor class. It allows you to safely work with a Cursor by automatically closing it after the block of code executes. It ensures that the Cursor is closed even if an exception is thrown. This method is similar to the use function for Closeable objects.

inTransaction

This method is an extension function for the SQLiteDatabase class. It allows you to execute a transaction on a SQLiteDatabase object. It automatically handles beginning and ending the transaction, as well as setting the transaction as successful. If a transaction is already in progress, the block of code is executed outside of the transaction.

package leakcanary.internal.activity.db

import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import kotlin.concurrent.getOrSet

/**
 * Similar to the more generic use() for Closable.
 * Cursor started implementing Closable in API 16.
 */
internal inline fun <R> Cursor.use(block: (Cursor) -> R): R {
  var exception: Throwable? = null
  try {
    return block(this)
  } catch (e: Throwable) {
    exception = e
    throw e
  } finally {
    when (exception) {
      null -> close()
      else -> try {
        close()
      } catch (_: Throwable) {
      }
    }
  }
}

private val inTransaction = ThreadLocal<Boolean>()

internal inline fun <T> SQLiteDatabase.inTransaction(block: SQLiteDatabase.() -> T): T {
  if (inTransaction.getOrSet { false }) {
    return block()
  }
  try {
    inTransaction.set(true)
    beginTransaction()
    val result = block()
    setTransactionSuccessful()
    return result
  } finally {
    endTransaction()
    inTransaction.set(false)
  }
}