Extended database model.
This commit is contained in:
@@ -2,11 +2,11 @@
|
|||||||
"formatVersion": 1,
|
"formatVersion": 1,
|
||||||
"database": {
|
"database": {
|
||||||
"version": 2,
|
"version": 2,
|
||||||
"identityHash": "4f4222f215c1724a7401aa8d181012a4",
|
"identityHash": "e86f0253ec49cbc67a601f90d5169a8a",
|
||||||
"entities": [
|
"entities": [
|
||||||
{
|
{
|
||||||
"tableName": "charges",
|
"tableName": "charges",
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `charge` REAL NOT NULL, `battery_id` TEXT NOT NULL, `date` TEXT NOT NULL, `createdTime` TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY(`id`))",
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `charge` REAL NOT NULL, `battery_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `comment` TEXT NOT NULL DEFAULT '', `created_at` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP, `synced` INTEGER NOT NULL DEFAULT false, FOREIGN KEY(`battery_id`) REFERENCES `batteries`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"fieldPath": "id",
|
"fieldPath": "id",
|
||||||
@@ -23,20 +23,110 @@
|
|||||||
{
|
{
|
||||||
"fieldPath": "batteryId",
|
"fieldPath": "batteryId",
|
||||||
"columnName": "battery_id",
|
"columnName": "battery_id",
|
||||||
"affinity": "TEXT",
|
"affinity": "INTEGER",
|
||||||
"notNull": true
|
"notNull": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldPath": "date",
|
"fieldPath": "date",
|
||||||
"columnName": "date",
|
"columnName": "date",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "comment",
|
||||||
|
"columnName": "comment",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true,
|
||||||
|
"defaultValue": "''"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "createdAt",
|
||||||
|
"columnName": "created_at",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true,
|
||||||
|
"defaultValue": "CURRENT_TIMESTAMP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "synced",
|
||||||
|
"columnName": "synced",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true,
|
||||||
|
"defaultValue": "false"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"autoGenerate": true
|
||||||
|
},
|
||||||
|
"indices": [
|
||||||
|
{
|
||||||
|
"name": "index_charges_battery_id",
|
||||||
|
"unique": false,
|
||||||
|
"columnNames": [
|
||||||
|
"battery_id"
|
||||||
|
],
|
||||||
|
"orders": [],
|
||||||
|
"createSql": "CREATE INDEX IF NOT EXISTS `index_charges_battery_id` ON `${TABLE_NAME}` (`battery_id`)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"foreignKeys": [
|
||||||
|
{
|
||||||
|
"table": "batteries",
|
||||||
|
"onDelete": "CASCADE",
|
||||||
|
"onUpdate": "NO ACTION",
|
||||||
|
"columns": [
|
||||||
|
"battery_id"
|
||||||
|
],
|
||||||
|
"referencedColumns": [
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tableName": "batteries",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `declared_capacity` REAL DEFAULT NULL, `comment` TEXT NOT NULL DEFAULT '', `synced` INTEGER NOT NULL DEFAULT false, `created_at` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP)",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "id",
|
||||||
|
"columnName": "id",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "name",
|
||||||
|
"columnName": "name",
|
||||||
"affinity": "TEXT",
|
"affinity": "TEXT",
|
||||||
"notNull": true
|
"notNull": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldPath": "createdTime",
|
"fieldPath": "declaredCapacity",
|
||||||
"columnName": "createdTime",
|
"columnName": "declared_capacity",
|
||||||
|
"affinity": "REAL",
|
||||||
|
"notNull": false,
|
||||||
|
"defaultValue": "NULL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "comment",
|
||||||
|
"columnName": "comment",
|
||||||
"affinity": "TEXT",
|
"affinity": "TEXT",
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
|
"defaultValue": "''"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "synced",
|
||||||
|
"columnName": "synced",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true,
|
||||||
|
"defaultValue": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "createdAt",
|
||||||
|
"columnName": "created_at",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true,
|
||||||
"defaultValue": "CURRENT_TIMESTAMP"
|
"defaultValue": "CURRENT_TIMESTAMP"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -44,33 +134,7 @@
|
|||||||
"columnNames": [
|
"columnNames": [
|
||||||
"id"
|
"id"
|
||||||
],
|
],
|
||||||
"autoGenerate": false
|
"autoGenerate": true
|
||||||
},
|
|
||||||
"indices": [],
|
|
||||||
"foreignKeys": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"tableName": "batteries",
|
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `declared_charge` REAL, PRIMARY KEY(`id`))",
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldPath": "id",
|
|
||||||
"columnName": "id",
|
|
||||||
"affinity": "TEXT",
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldPath": "declaredCharge",
|
|
||||||
"columnName": "declared_charge",
|
|
||||||
"affinity": "REAL",
|
|
||||||
"notNull": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"primaryKey": {
|
|
||||||
"columnNames": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"autoGenerate": false
|
|
||||||
},
|
},
|
||||||
"indices": [],
|
"indices": [],
|
||||||
"foreignKeys": []
|
"foreignKeys": []
|
||||||
@@ -79,7 +143,7 @@
|
|||||||
"views": [],
|
"views": [],
|
||||||
"setupQueries": [
|
"setupQueries": [
|
||||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '4f4222f215c1724a7401aa8d181012a4')"
|
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e86f0253ec49cbc67a601f90d5169a8a')"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
{
|
||||||
|
"formatVersion": 1,
|
||||||
|
"database": {
|
||||||
|
"version": 3,
|
||||||
|
"identityHash": "e86f0253ec49cbc67a601f90d5169a8a",
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"tableName": "charges",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `charge` REAL NOT NULL, `battery_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `comment` TEXT NOT NULL DEFAULT '', `created_at` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP, `synced` INTEGER NOT NULL DEFAULT false, FOREIGN KEY(`battery_id`) REFERENCES `batteries`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "id",
|
||||||
|
"columnName": "id",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "charge",
|
||||||
|
"columnName": "charge",
|
||||||
|
"affinity": "REAL",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "batteryId",
|
||||||
|
"columnName": "battery_id",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "date",
|
||||||
|
"columnName": "date",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "comment",
|
||||||
|
"columnName": "comment",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true,
|
||||||
|
"defaultValue": "''"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "createdAt",
|
||||||
|
"columnName": "created_at",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true,
|
||||||
|
"defaultValue": "CURRENT_TIMESTAMP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "synced",
|
||||||
|
"columnName": "synced",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true,
|
||||||
|
"defaultValue": "false"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"autoGenerate": true
|
||||||
|
},
|
||||||
|
"indices": [
|
||||||
|
{
|
||||||
|
"name": "index_charges_battery_id",
|
||||||
|
"unique": false,
|
||||||
|
"columnNames": [
|
||||||
|
"battery_id"
|
||||||
|
],
|
||||||
|
"orders": [],
|
||||||
|
"createSql": "CREATE INDEX IF NOT EXISTS `index_charges_battery_id` ON `${TABLE_NAME}` (`battery_id`)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"foreignKeys": [
|
||||||
|
{
|
||||||
|
"table": "batteries",
|
||||||
|
"onDelete": "CASCADE",
|
||||||
|
"onUpdate": "NO ACTION",
|
||||||
|
"columns": [
|
||||||
|
"battery_id"
|
||||||
|
],
|
||||||
|
"referencedColumns": [
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tableName": "batteries",
|
||||||
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `declared_capacity` REAL DEFAULT NULL, `comment` TEXT NOT NULL DEFAULT '', `synced` INTEGER NOT NULL DEFAULT false, `created_at` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP)",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldPath": "id",
|
||||||
|
"columnName": "id",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "name",
|
||||||
|
"columnName": "name",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "declaredCapacity",
|
||||||
|
"columnName": "declared_capacity",
|
||||||
|
"affinity": "REAL",
|
||||||
|
"notNull": false,
|
||||||
|
"defaultValue": "NULL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "comment",
|
||||||
|
"columnName": "comment",
|
||||||
|
"affinity": "TEXT",
|
||||||
|
"notNull": true,
|
||||||
|
"defaultValue": "''"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "synced",
|
||||||
|
"columnName": "synced",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true,
|
||||||
|
"defaultValue": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "createdAt",
|
||||||
|
"columnName": "created_at",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true,
|
||||||
|
"defaultValue": "CURRENT_TIMESTAMP"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"primaryKey": {
|
||||||
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"autoGenerate": true
|
||||||
|
},
|
||||||
|
"indices": [],
|
||||||
|
"foreignKeys": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"views": [],
|
||||||
|
"setupQueries": [
|
||||||
|
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||||
|
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e86f0253ec49cbc67a601f90d5169a8a')"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ import com.sockenklaus.batterytracker.room.entities.Charge
|
|||||||
|
|
||||||
@Database(
|
@Database(
|
||||||
entities = [Charge::class, Battery::class],
|
entities = [Charge::class, Battery::class],
|
||||||
version = 2
|
version = 3
|
||||||
)
|
)
|
||||||
@TypeConverters(Converters::class)
|
@TypeConverters(Converters::class)
|
||||||
abstract class BatteryTrackerDB : RoomDatabase() {
|
abstract class BatteryTrackerDB : RoomDatabase() {
|
||||||
|
|||||||
@@ -2,13 +2,11 @@ package com.sockenklaus.batterytracker.room.dao
|
|||||||
|
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
import com.sockenklaus.batterytracker.room.entities.Battery
|
import com.sockenklaus.batterytracker.room.entities.Battery
|
||||||
|
import com.sockenklaus.batterytracker.room.entities.BatteryAndCharges
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface BatteryDao {
|
interface BatteryDao {
|
||||||
@Insert
|
|
||||||
fun insertAll(vararg batteries: Battery)
|
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
fun insert(battery: Battery)
|
fun insert(battery: Battery)
|
||||||
|
|
||||||
@@ -16,11 +14,19 @@ interface BatteryDao {
|
|||||||
fun delete(battery: Battery)
|
fun delete(battery: Battery)
|
||||||
|
|
||||||
@Update
|
@Update
|
||||||
fun updateBatteries(vararg batteries: Battery): Int
|
fun updateBattery(battery: Battery): Int
|
||||||
|
|
||||||
@Query("Select * FROM batteries")
|
@Query("Select * FROM batteries")
|
||||||
fun getBatteries(): Flow<List<Battery>>
|
fun getBatteries(): Flow<List<Battery>>
|
||||||
|
|
||||||
@Query("Select * FROM batteries WHERE id = :id")
|
@Query("Select * FROM batteries WHERE id = :id")
|
||||||
fun getBatteryById(id: String): Flow<Battery>
|
fun getBatteryById(id: Int): Flow<Battery>
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
@Query("SELECT * FROM batteries")
|
||||||
|
fun getBatteriesAndCharges(): Flow<List<BatteryAndCharges>>
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
@Query("SELECT * FROM batteries WHERE id = :id")
|
||||||
|
fun getBatteryAndCharges(id: Int): Flow<BatteryAndCharges>
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
package com.sockenklaus.batterytracker.room.dao
|
package com.sockenklaus.batterytracker.room.dao
|
||||||
|
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
|
import com.sockenklaus.batterytracker.room.entities.BatteryAndCharges
|
||||||
import com.sockenklaus.batterytracker.room.entities.Charge
|
import com.sockenklaus.batterytracker.room.entities.Charge
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface ChargeDao {
|
interface ChargeDao {
|
||||||
@Insert
|
|
||||||
fun insertAll(vararg charges: Charge)
|
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
fun insert(charge: Charge)
|
fun insert(charge: Charge)
|
||||||
|
|
||||||
@@ -16,11 +14,15 @@ interface ChargeDao {
|
|||||||
fun delete(charge: Charge): Int
|
fun delete(charge: Charge): Int
|
||||||
|
|
||||||
@Update
|
@Update
|
||||||
fun updateCharges(vararg charges: Charge): Int
|
fun updateCharge(charge: Charge): Int
|
||||||
|
|
||||||
@Query("Select * FROM charges")
|
@Query("Select * FROM charges")
|
||||||
fun getCharges(): Flow<List<Charge>>
|
fun getCharges(): Flow<List<Charge>>
|
||||||
|
|
||||||
@Query("Select * FROM charges WHERE id = :id")
|
@Query("Select * FROM charges WHERE id = :id")
|
||||||
fun getChargeById(id: Int): Flow<Charge>
|
fun getChargeById(id: Int): Flow<Charge>
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
@Query("SELECT * FROM batteries WHERE id = :id")
|
||||||
|
fun getBatteryAndCharges(id: Int): Flow<BatteryAndCharges>
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,29 @@
|
|||||||
package com.sockenklaus.batterytracker.room.entities
|
package com.sockenklaus.batterytracker.room.entities
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
@Entity(tableName = "batteries")
|
@Entity(tableName = "batteries")
|
||||||
data class Battery(
|
data class Battery(
|
||||||
@PrimaryKey
|
|
||||||
val id: String,
|
|
||||||
|
|
||||||
@ColumnInfo(name = "declared_charge")
|
@PrimaryKey(autoGenerate = true)
|
||||||
val declaredCharge: Double?,
|
@NonNull
|
||||||
|
val id: Int = 0,
|
||||||
|
|
||||||
|
val name: String,
|
||||||
|
|
||||||
|
@ColumnInfo(name = "declared_capacity", defaultValue = "NULL")
|
||||||
|
val declaredCapacity: Double? = null,
|
||||||
|
|
||||||
|
@ColumnInfo(defaultValue = "")
|
||||||
|
val comment: String = "",
|
||||||
|
|
||||||
|
@ColumnInfo(defaultValue = "false")
|
||||||
|
val synced: Boolean = false,
|
||||||
|
|
||||||
|
@ColumnInfo(name = "created_at", defaultValue = "CURRENT_TIMESTAMP")
|
||||||
|
val createdAt: LocalDateTime = LocalDateTime.now()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.sockenklaus.batterytracker.room.entities
|
||||||
|
|
||||||
|
import androidx.room.Embedded
|
||||||
|
import androidx.room.Relation
|
||||||
|
|
||||||
|
data class BatteryAndCharges(
|
||||||
|
@Embedded
|
||||||
|
val battery: Battery,
|
||||||
|
|
||||||
|
@Relation(
|
||||||
|
parentColumn = "id",
|
||||||
|
entityColumn = "battery_id"
|
||||||
|
)
|
||||||
|
val charges: List<Charge>
|
||||||
|
)
|
||||||
@@ -1,23 +1,40 @@
|
|||||||
package com.sockenklaus.batterytracker.room.entities
|
package com.sockenklaus.batterytracker.room.entities
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.*
|
||||||
import androidx.room.Entity
|
|
||||||
import androidx.room.PrimaryKey
|
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
@Entity(tableName = "charges")
|
@Entity(
|
||||||
|
tableName = "charges",
|
||||||
|
foreignKeys = [
|
||||||
|
ForeignKey(
|
||||||
|
entity = Battery::class,
|
||||||
|
parentColumns = arrayOf("id"),
|
||||||
|
childColumns = arrayOf("battery_id"),
|
||||||
|
onDelete = ForeignKey.CASCADE
|
||||||
|
)],
|
||||||
|
indices = [Index(value = ["battery_id"])]
|
||||||
|
)
|
||||||
data class Charge(
|
data class Charge(
|
||||||
|
|
||||||
@PrimaryKey
|
@PrimaryKey(autoGenerate = true)
|
||||||
val id: Int,
|
val id: Int = 0,
|
||||||
|
|
||||||
val charge: Double,
|
val charge: Double,
|
||||||
|
|
||||||
@ColumnInfo(name = "battery_id")
|
@ColumnInfo(name = "battery_id")
|
||||||
val batteryId: String,
|
val batteryId: Int,
|
||||||
|
|
||||||
val date: String,
|
val date: LocalDateTime,
|
||||||
|
|
||||||
@ColumnInfo(defaultValue = "CURRENT_TIMESTAMP")
|
@ColumnInfo(defaultValue = "")
|
||||||
val createdTime: String
|
val comment: String = "",
|
||||||
|
|
||||||
|
@ColumnInfo(
|
||||||
|
name = "created_at",
|
||||||
|
defaultValue = "CURRENT_TIMESTAMP"
|
||||||
|
)
|
||||||
|
val createdAt: LocalDateTime = LocalDateTime.now(),
|
||||||
|
|
||||||
|
@ColumnInfo(defaultValue = "false")
|
||||||
|
val synced: Boolean = false
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -16,17 +16,13 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.asLiveData
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import com.sockenklaus.batterytracker.R
|
import com.sockenklaus.batterytracker.R
|
||||||
import com.sockenklaus.batterytracker.databinding.FragmentAddBatteryBinding
|
import com.sockenklaus.batterytracker.databinding.FragmentAddBatteryBinding
|
||||||
import com.sockenklaus.batterytracker.room.BatteryTrackerDB
|
|
||||||
import com.sockenklaus.batterytracker.room.entities.Battery
|
import com.sockenklaus.batterytracker.room.entities.Battery
|
||||||
import com.sockenklaus.batterytracker.ui.theme.BatteryTrackerTheme
|
import com.sockenklaus.batterytracker.ui.theme.BatteryTrackerTheme
|
||||||
import com.sockenklaus.batterytracker.ui.theme.Gray500
|
import com.sockenklaus.batterytracker.ui.theme.Gray500
|
||||||
import com.sockenklaus.batterytracker.util.validateDecimal
|
import com.sockenklaus.batterytracker.util.validateDecimal
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple [Fragment] subclass.
|
* A simple [Fragment] subclass.
|
||||||
@@ -43,28 +39,17 @@ class AddBatteryFragment : Fragment() {
|
|||||||
): View {
|
): View {
|
||||||
|
|
||||||
_binding = FragmentAddBatteryBinding.inflate(inflater, container, false)
|
_binding = FragmentAddBatteryBinding.inflate(inflater, container, false)
|
||||||
val db = BatteryTrackerDB.getInstance(requireContext())
|
val model = ViewModelProvider(this)[AddBatteryViewModel::class.java]
|
||||||
val view = binding.root
|
val view = binding.root
|
||||||
|
|
||||||
/**
|
var batteries = emptyList<Battery>()
|
||||||
* TODO: Move database interactions to ViewModel!
|
|
||||||
*/
|
|
||||||
val batteries = db.batteryDao().getBatteries().asLiveData()
|
|
||||||
var listBatteries = emptyList<Battery>()
|
|
||||||
|
|
||||||
batteries.observe(viewLifecycleOwner) {
|
model.batteries.observe(viewLifecycleOwner) {
|
||||||
listBatteries = it
|
batteries = it
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.root.setContent {
|
binding.root.setContent {
|
||||||
BatteryTrackerTheme {
|
BatteryTrackerTheme {
|
||||||
var batteryId by remember { mutableStateOf("") }
|
|
||||||
var batteryHasError by remember { mutableStateOf(false) }
|
|
||||||
var batteryHelperId: Int? by remember { mutableStateOf(null) }
|
|
||||||
|
|
||||||
var declaredCapacity by remember { mutableStateOf("")}
|
|
||||||
var capacityHasError by remember { mutableStateOf(false) }
|
|
||||||
var capacityHelperId: Int? by remember { mutableStateOf(null) }
|
|
||||||
|
|
||||||
val outerPadding = 24.dp
|
val outerPadding = 24.dp
|
||||||
val innerPadding = 16.dp
|
val innerPadding = 16.dp
|
||||||
@@ -73,47 +58,47 @@ class AddBatteryFragment : Fragment() {
|
|||||||
Modifier.padding(outerPadding)
|
Modifier.padding(outerPadding)
|
||||||
) {
|
) {
|
||||||
MyOutlinedTextField(
|
MyOutlinedTextField(
|
||||||
value = batteryId,
|
value = model.batteryName,
|
||||||
onValueChange = { value ->
|
onValueChange = { value ->
|
||||||
batteryId = value
|
model.batteryName = value
|
||||||
batteryHasError = false
|
model.batteryHasError = false
|
||||||
batteryHelperId = null
|
model.batteryHelperId = null
|
||||||
if(listBatteries.any{ it.id.lowercase() == value.lowercase() }){
|
if(batteries.any{ it.name.lowercase() == value.lowercase() }){
|
||||||
batteryHasError = true
|
model.batteryHasError = true
|
||||||
batteryHelperId = R.string.helper_battery_not_unique
|
model.batteryHelperId = R.string.helper_battery_not_unique
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
labelId = R.string.hint_enter_battery_id,
|
labelId = R.string.hint_enter_battery_name,
|
||||||
leadingIcon = { Icon(Icons.Default.Tag, "Icon Tag") },
|
leadingIcon = { Icon(Icons.Default.Tag, "Icon Tag") },
|
||||||
isError = batteryHasError,
|
isError = model.batteryHasError,
|
||||||
helperTextId = batteryHelperId
|
helperTextId = model.batteryHelperId
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(Modifier.size(innerPadding))
|
Spacer(Modifier.size(innerPadding))
|
||||||
|
|
||||||
MyOutlinedTextField(
|
MyOutlinedTextField(
|
||||||
value = declaredCapacity,
|
value = model.declaredCapacity,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
declaredCapacity = validateDecimal(it, declaredCapacity)
|
model.declaredCapacity = validateDecimal(it, model.declaredCapacity)
|
||||||
capacityHasError = false
|
model.capacityHasError = false
|
||||||
capacityHelperId = null
|
model.capacityHelperId = null
|
||||||
},
|
},
|
||||||
labelId = R.string.hint_enter_declared_capacity,
|
labelId = R.string.hint_enter_declared_capacity,
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
|
||||||
leadingIcon = { Icon(Icons.Default.BatteryFull, "Icon Battery Full") },
|
leadingIcon = { Icon(Icons.Default.BatteryFull, "Icon Battery Full") },
|
||||||
isError = capacityHasError,
|
isError = model.capacityHasError,
|
||||||
helperTextId = capacityHelperId
|
helperTextId = model.capacityHelperId
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(Modifier.size(outerPadding))
|
Spacer(Modifier.size(outerPadding))
|
||||||
|
|
||||||
ExtendedFloatingActionButton(
|
ExtendedFloatingActionButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
if(batteryId.isBlank()) batteryHasError = true
|
if(model.batteryName.isBlank()) model.batteryHasError = true
|
||||||
if(declaredCapacity.isBlank()) capacityHasError = true
|
if(model.declaredCapacity.isBlank()) model.capacityHasError = true
|
||||||
|
|
||||||
if(!batteryHasError && !capacityHasError){
|
if(!model.batteryHasError && !model.capacityHasError){
|
||||||
saveBattery(batteryId, declaredCapacity)
|
model.saveBattery(model.batteryName, model.declaredCapacity)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon = { Icon(Icons.Default.Save, "Icon Save") },
|
icon = { Icon(Icons.Default.Save, "Icon Save") },
|
||||||
@@ -161,17 +146,6 @@ class AddBatteryFragment : Fragment() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveBattery(
|
|
||||||
id: String,
|
|
||||||
declaredCapacity: String
|
|
||||||
) {
|
|
||||||
val db = BatteryTrackerDB.getInstance(requireContext())
|
|
||||||
|
|
||||||
lifecycleScope.launch(Dispatchers.IO){
|
|
||||||
db.batteryDao().insert(Battery(id, declaredCapacity.toDouble()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*companion object {
|
/*companion object {
|
||||||
|
|
||||||
* Use this factory method to create a new instance of
|
* Use this factory method to create a new instance of
|
||||||
|
|||||||
@@ -1,13 +1,42 @@
|
|||||||
package com.sockenklaus.batterytracker.ui.fragments.add_battery
|
package com.sockenklaus.batterytracker.ui.fragments.add_battery
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.asLiveData
|
import androidx.lifecycle.asLiveData
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.sockenklaus.batterytracker.room.BatteryTrackerDB
|
import com.sockenklaus.batterytracker.room.BatteryTrackerDB
|
||||||
|
import com.sockenklaus.batterytracker.room.entities.Battery
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class AddBatteryViewModel(application: Application): AndroidViewModel(application) {
|
class AddBatteryViewModel(application: Application): AndroidViewModel(application) {
|
||||||
|
|
||||||
private val db = BatteryTrackerDB.getInstance(application)
|
private val db = BatteryTrackerDB.getInstance(application)
|
||||||
private val batteries = db.batteryDao().getBatteries().asLiveData()
|
val batteries = db.batteryDao().getBatteries().asLiveData()
|
||||||
|
|
||||||
|
var batteryName by mutableStateOf("")
|
||||||
|
var batteryHasError by mutableStateOf(false)
|
||||||
|
var batteryHelperId: Int? by mutableStateOf(null)
|
||||||
|
|
||||||
|
var declaredCapacity by mutableStateOf("")
|
||||||
|
var capacityHasError by mutableStateOf(false)
|
||||||
|
var capacityHelperId: Int? by mutableStateOf(null)
|
||||||
|
|
||||||
|
fun saveBattery(
|
||||||
|
name: String,
|
||||||
|
declaredCapacity: String? = null,
|
||||||
|
){
|
||||||
|
val battery = Battery(
|
||||||
|
name = name,
|
||||||
|
declaredCapacity = declaredCapacity?.toDouble()
|
||||||
|
)
|
||||||
|
|
||||||
|
viewModelScope.launch(Dispatchers.IO){
|
||||||
|
db.batteryDao().insert(battery)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ class AddChargeFragment : Fragment() {
|
|||||||
viewModel = ViewModelProvider(this)[AddChargeViewModel::class.java]
|
viewModel = ViewModelProvider(this)[AddChargeViewModel::class.java]
|
||||||
var items = emptyList<Battery>()
|
var items = emptyList<Battery>()
|
||||||
|
|
||||||
viewModel.allBatteryIds.observe(this.viewLifecycleOwner){
|
viewModel.batteries.observe(this.viewLifecycleOwner){
|
||||||
items = it
|
items = it
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ class AddChargeFragment : Fragment() {
|
|||||||
colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(),
|
colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(),
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
val filteringOptions = items.filter { it.id.contains(viewModel.batteryId.text, ignoreCase = true)}
|
val filteringOptions = items.filter { it.name.contains(viewModel.batteryId.text, ignoreCase = true)}
|
||||||
if(filteringOptions.size > 1 && viewModel.batteryId.text.isNotBlank()) bIdExpanded = true
|
if(filteringOptions.size > 1 && viewModel.batteryId.text.isNotBlank()) bIdExpanded = true
|
||||||
if(filteringOptions.isNotEmpty()) {
|
if(filteringOptions.isNotEmpty()) {
|
||||||
ExposedDropdownMenu(
|
ExposedDropdownMenu(
|
||||||
@@ -90,13 +90,13 @@ class AddChargeFragment : Fragment() {
|
|||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
onClick = {
|
onClick = {
|
||||||
viewModel.batteryId = TextFieldValue(
|
viewModel.batteryId = TextFieldValue(
|
||||||
text = filteringOption.id,
|
text = filteringOption.name,
|
||||||
selection = TextRange(filteringOption.id.length)
|
selection = TextRange(filteringOption.name.length)
|
||||||
)
|
)
|
||||||
bIdExpanded = false
|
bIdExpanded = false
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
Text(filteringOption.id)
|
Text(filteringOption.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import java.time.LocalDateTime
|
|||||||
class AddChargeViewModel(application: Application) : AndroidViewModel(application) {
|
class AddChargeViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
|
|
||||||
private val db = BatteryTrackerDB.getInstance(application)
|
private val db = BatteryTrackerDB.getInstance(application)
|
||||||
var allBatteryIds: LiveData<List<Battery>> = db.batteryDao().getBatteries().asLiveData()
|
var batteries: LiveData<List<Battery>> = db.batteryDao().getBatteries().asLiveData()
|
||||||
|
|
||||||
var batteryId: TextFieldValue by mutableStateOf(TextFieldValue(""))
|
var batteryId: TextFieldValue by mutableStateOf(TextFieldValue(""))
|
||||||
var date: LocalDateTime by mutableStateOf(LocalDateTime.now())
|
var date: LocalDateTime by mutableStateOf(LocalDateTime.now())
|
||||||
|
|||||||
@@ -22,11 +22,11 @@
|
|||||||
<string name="charge">Charge</string>
|
<string name="charge">Charge</string>
|
||||||
<string name="hint_charge">Enter Charge in Ah</string>
|
<string name="hint_charge">Enter Charge in Ah</string>
|
||||||
<string name="select_battery_id">Select Battery ID</string>
|
<string name="select_battery_id">Select Battery ID</string>
|
||||||
<string name="hint_enter_battery_id">Enter Battery ID</string>
|
<string name="hint_enter_battery_name">Enter Battery Name</string>
|
||||||
<string name="hint_enter_declared_capacity">Enter declared capacity</string>
|
<string name="hint_enter_declared_capacity">Enter declared capacity</string>
|
||||||
<string name="declared_capacity">Declared Capacity</string>
|
<string name="declared_capacity">Declared Capacity</string>
|
||||||
<string name="button_save_battery">Save Battery</string>
|
<string name="button_save_battery">Save Battery</string>
|
||||||
<string name="title_activity_add_battery">AddBattery</string>
|
<string name="title_activity_add_battery">AddBattery</string>
|
||||||
<string name="helper_required">* Required</string>
|
<string name="helper_required">* Required</string>
|
||||||
<string name="helper_battery_not_unique">Battery-ID not unique!</string>
|
<string name="helper_battery_not_unique">Battery-Name not unique!</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user