128 lines
3.9 KiB
Kotlin
128 lines
3.9 KiB
Kotlin
package app.boxmanifest.data
|
|
|
|
import android.content.Context
|
|
import androidx.room.Dao
|
|
import androidx.room.Database
|
|
import androidx.room.Entity
|
|
import androidx.room.Index
|
|
import androidx.room.Insert
|
|
import androidx.room.OnConflictStrategy
|
|
import androidx.room.PrimaryKey
|
|
import androidx.room.Query
|
|
import androidx.room.Room
|
|
import androidx.room.RoomDatabase
|
|
import androidx.room.Transaction
|
|
|
|
@Entity(tableName = "nodes", indices = [Index("parentId")])
|
|
data class LocalNode(
|
|
@PrimaryKey val id: String,
|
|
val lookupCode: String,
|
|
val parentId: String?,
|
|
val name: String,
|
|
val description: String?,
|
|
val quantity: Long?,
|
|
val typeId: String?,
|
|
val tagIdsJson: String,
|
|
val revision: Long,
|
|
val sortOrder: Int,
|
|
val pendingCreate: Boolean = false,
|
|
)
|
|
|
|
@Entity(tableName = "pending_operations", indices = [Index(value = ["nodeId"], unique = true)])
|
|
data class PendingOperation(
|
|
@PrimaryKey(autoGenerate = true) val operationId: Long = 0,
|
|
val kind: String,
|
|
val nodeId: String,
|
|
val parentId: String?,
|
|
val name: String,
|
|
val description: String?,
|
|
val quantity: Long?,
|
|
val baseRevision: Long?,
|
|
val status: String = STATUS_PENDING,
|
|
val error: String? = null,
|
|
) {
|
|
companion object {
|
|
const val CREATE = "CREATE"
|
|
const val UPDATE = "UPDATE"
|
|
const val STATUS_PENDING = "PENDING"
|
|
const val STATUS_CONFLICT = "CONFLICT"
|
|
}
|
|
}
|
|
|
|
@Dao
|
|
interface InventoryDao {
|
|
@Query("SELECT * FROM nodes ORDER BY sortOrder")
|
|
suspend fun nodes(): List<LocalNode>
|
|
|
|
@Query("SELECT * FROM nodes WHERE id = :id")
|
|
suspend fun node(id: String): LocalNode?
|
|
|
|
@Query("SELECT COALESCE(MAX(sortOrder), -1) + 1 FROM nodes")
|
|
suspend fun nextSortOrder(): Int
|
|
|
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
suspend fun putNode(node: LocalNode)
|
|
|
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
suspend fun putNodes(nodes: List<LocalNode>)
|
|
|
|
@Query("DELETE FROM nodes")
|
|
suspend fun deleteNodes()
|
|
|
|
@Transaction
|
|
suspend fun replaceNodes(nodes: List<LocalNode>) {
|
|
deleteNodes()
|
|
putNodes(nodes)
|
|
}
|
|
|
|
@Query("SELECT * FROM pending_operations ORDER BY operationId")
|
|
suspend fun operations(): List<PendingOperation>
|
|
|
|
@Query("SELECT * FROM pending_operations WHERE nodeId = :nodeId")
|
|
suspend fun operationFor(nodeId: String): PendingOperation?
|
|
|
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
|
suspend fun putOperation(operation: PendingOperation)
|
|
|
|
@Query("DELETE FROM pending_operations WHERE operationId = :id")
|
|
suspend fun deleteOperation(id: Long)
|
|
|
|
@Query("UPDATE pending_operations SET status = :status, error = :error WHERE operationId = :id")
|
|
suspend fun markOperation(id: Long, status: String, error: String?)
|
|
|
|
@Query("DELETE FROM pending_operations")
|
|
suspend fun deleteOperations()
|
|
|
|
@Query("SELECT COUNT(*) FROM pending_operations WHERE status = 'PENDING'")
|
|
suspend fun pendingCount(): Int
|
|
|
|
@Query("SELECT error FROM pending_operations WHERE status = 'CONFLICT' ORDER BY operationId LIMIT 1")
|
|
suspend fun firstConflict(): String?
|
|
|
|
@Query("SELECT * FROM pending_operations WHERE status = 'CONFLICT' ORDER BY operationId LIMIT 1")
|
|
suspend fun firstConflictOperation(): PendingOperation?
|
|
|
|
@Transaction
|
|
suspend fun clearAll() {
|
|
deleteOperations()
|
|
deleteNodes()
|
|
}
|
|
}
|
|
|
|
@Database(entities = [LocalNode::class, PendingOperation::class], version = 1, exportSchema = false)
|
|
abstract class LocalInventoryDatabase : RoomDatabase() {
|
|
abstract fun inventory(): InventoryDao
|
|
|
|
companion object {
|
|
@Volatile private var instance: LocalInventoryDatabase? = null
|
|
|
|
fun get(context: Context): LocalInventoryDatabase = instance ?: synchronized(this) {
|
|
instance ?: Room.databaseBuilder(
|
|
context.applicationContext,
|
|
LocalInventoryDatabase::class.java,
|
|
"box-manifest-local.db",
|
|
).build().also { instance = it }
|
|
}
|
|
}
|
|
}
|