diff --git a/compose/.gradle/kotlin/errors/errors-1699722328394.log b/compose/.gradle/kotlin/errors/errors-1699722328394.log deleted file mode 100644 index 9d102ef..0000000 --- a/compose/.gradle/kotlin/errors/errors-1699722328394.log +++ /dev/null @@ -1,42 +0,0 @@ -kotlin version: 1.8.20 -error message: java.lang.NoSuchMethodError: 'kotlin.sequences.Sequence com.google.devtools.ksp.processing.Resolver.getPackagesWithAnnotation(java.lang.String)' - at androidx.room.compiler.processing.ksp.KspRoundEnv.getElementsAnnotatedWith(KspRoundEnv.kt:107) - at androidx.room.compiler.processing.CommonProcessorDelegate.processRound(XBasicAnnotationProcessor.kt:100) - at androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor.process(KspBasicAnnotationProcessor.kt:62) - at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$6$1.invoke(KotlinSymbolProcessingExtension.kt:291) - at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$6$1.invoke(KotlinSymbolProcessingExtension.kt:289) - at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.handleException(KotlinSymbolProcessingExtension.kt:394) - at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.doAnalysis(KotlinSymbolProcessingExtension.kt:289) - at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:123) - at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:99) - at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:257) - at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:42) - at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:115) - at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:248) - at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:88) - at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli$default(KotlinToJVMBytecodeCompiler.kt:47) - at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:168) - at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:53) - at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:100) - at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:46) - at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101) - at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1486) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) - at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.base/java.lang.reflect.Method.invoke(Method.java:568) - at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360) - at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200) - at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197) - at java.base/java.security.AccessController.doPrivileged(AccessController.java:712) - at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196) - at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587) - at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828) - at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705) - at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) - at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704) - at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) - at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) - at java.base/java.lang.Thread.run(Thread.java:833) - - diff --git a/compose/.idea/misc.xml b/compose/.idea/misc.xml index 0ad17cb..8978d23 100644 --- a/compose/.idea/misc.xml +++ b/compose/.idea/misc.xml @@ -1,4 +1,3 @@ - diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/dao/UserDao.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/dao/UserDao.kt index b60da16..5e4b411 100644 --- a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/dao/UserDao.kt +++ b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/dao/UserDao.kt @@ -27,9 +27,12 @@ interface UserDao { @Query("select * from users where users.userId = :uid") suspend fun getUserUid(uid: Long): UserWithTanks + @Query("select * from users where users.userId = :uid") + suspend fun getSimpleUserUid(uid: Long): User + //добавить танк в ангар пользователя @Insert - suspend fun insert(userWithTanks: UserWithTanks) : Long + suspend fun insert(userTankCrossRef: UserTankCrossRef) : Long @Insert suspend fun insert(user: User) diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/database/AppDatabase.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/database/AppDatabase.kt index 50bf177..794fd31 100644 --- a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/database/AppDatabase.kt +++ b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/database/AppDatabase.kt @@ -29,7 +29,7 @@ abstract class AppDatabase : RoomDatabase() { abstract fun userDao() : UserDao companion object { - private const val DB_NAME: String = "first-db" + private const val DB_NAME: String = "third-db" @Volatile private var INSTANCE: AppDatabase? = null @@ -112,11 +112,15 @@ abstract class AppDatabase : RoomDatabase() { //Users val userDao = database.userDao() - val user = User("3tankista73", "egor@mail.ru", "12032003", 10000000) - val newObj1 = UserWithTanks(user, listOf(tank1, tank3, tank5, tank7, tank9)) + val user = User(100L,"3tankista73", "egor@mail.ru", "12032003", 10000000) userDao.insert(user) - userDao.insert(newObj1) + + userDao.insert(UserTankCrossRef(user.userId ?: 0, tank1.tankId ?: 0)) + userDao.insert(UserTankCrossRef(user.userId ?: 0, tank3.tankId ?: 0)) + userDao.insert(UserTankCrossRef(user.userId ?: 0, tank5.tankId ?: 0)) + userDao.insert(UserTankCrossRef(user.userId ?: 0, tank7.tankId ?: 0)) + userDao.insert(UserTankCrossRef(user.userId ?: 0, tank9.tankId ?: 0)) } } diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/User.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/User.kt index 3ca6034..914c867 100644 --- a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/User.kt +++ b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/User.kt @@ -9,8 +9,8 @@ import androidx.room.PrimaryKey tableName = "users" ) data class User ( - @PrimaryKey(autoGenerate = true) - val userId: Long?, + @PrimaryKey(autoGenerate = false) + val userId: Long, @ColumnInfo(name = "nickname") val nickname: String, @ColumnInfo(name = "email") @@ -26,7 +26,7 @@ data class User ( email: String, password: String, balance: Int - ) : this(null, nickname, email, password, balance) + ) : this(100L, nickname, email, password, balance) override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/UserTankCrossRef.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/UserTankCrossRef.kt index 4df39de..ccbfc97 100644 --- a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/UserTankCrossRef.kt +++ b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/UserTankCrossRef.kt @@ -2,29 +2,31 @@ package ru.ulstu.`is`.pmu.tank.model import androidx.room.Entity import androidx.room.ForeignKey +import androidx.room.Index import androidx.room.PrimaryKey import org.jetbrains.annotations.NotNull //many to many for user and tank -@Entity(primaryKeys = ["userId", "tankId"], +@Entity(primaryKeys = ["memberUserId", "memberTankId"], + indices = [Index(value = ["memberTankId"], unique = false)], foreignKeys = [ ForeignKey( entity = User::class, parentColumns = ["userId"], - childColumns = ["userId"], - onDelete = ForeignKey.RESTRICT, - onUpdate = ForeignKey.RESTRICT + childColumns = ["memberUserId"], + onDelete = ForeignKey.CASCADE, + onUpdate = ForeignKey.CASCADE ), ForeignKey( entity = Tank::class, parentColumns = ["tankId"], - childColumns = ["tankId"], - onDelete = ForeignKey.RESTRICT, - onUpdate = ForeignKey.RESTRICT + childColumns = ["memberTankId"], + onDelete = ForeignKey.CASCADE, + onUpdate = ForeignKey.CASCADE ) ] ) data class UserTankCrossRef( - val userId: Long, - val tankId: Long + var memberUserId: Long, + var memberTankId: Long ) diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/UserWithTanks.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/UserWithTanks.kt index 8aa1cc2..483e7a3 100644 --- a/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/UserWithTanks.kt +++ b/compose/app/src/main/java/ru/ulstu/is/pmu/tank/model/UserWithTanks.kt @@ -1,17 +1,23 @@ package ru.ulstu.`is`.pmu.tank.model import androidx.room.Embedded +import androidx.room.Entity import androidx.room.Junction import androidx.room.Relation //для работы many to many для получения списка танков для пользователя data class UserWithTanks( - @Embedded val user: User, + @Embedded var user: User, @Relation( + entity = Tank::class, parentColumn = "userId", entityColumn = "tankId", - associateBy = Junction(UserTankCrossRef::class) + associateBy = Junction( + UserTankCrossRef::class, + parentColumn = "memberTankId", + entityColumn = "memberUserId" + ) ) - val tanks: List + var tanks: List ) diff --git a/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Account.kt b/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Account.kt index cac000a..036fe0a 100644 --- a/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Account.kt +++ b/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Account.kt @@ -28,6 +28,7 @@ import androidx.compose.material3.TextButton import androidx.compose.material3.TextField import androidx.compose.material3.TextFieldDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -39,6 +40,7 @@ import androidx.compose.ui.graphics.StrokeJoin import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.modifier.modifierLocalConsumer +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.ExperimentalTextApi @@ -51,28 +53,40 @@ import androidx.compose.ui.unit.sp import androidx.navigation.NavController import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import ru.ulstu.`is`.pmu.R import ru.ulstu.`is`.pmu.composeui.navigation.Screen -import ru.ulstu.`is`.pmu.ui.theme.CustomBackground +import ru.ulstu.`is`.pmu.tank.database.AppDatabase +import ru.ulstu.`is`.pmu.tank.model.User import ru.ulstu.`is`.pmu.ui.theme.CustomDark import ru.ulstu.`is`.pmu.ui.theme.CustomOrange import ru.ulstu.`is`.pmu.ui.theme.CustomRed import ru.ulstu.`is`.pmu.ui.theme.CustomYellow import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme -@OptIn(ExperimentalMaterial3Api::class, ExperimentalTextApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun Account(navController: NavController) { val navBackStackEntry by navController.currentBackStackEntryAsState() val currentDestination = navBackStackEntry?.destination val currentScreen = currentDestination?.route?.let { Screen.getItem(it) } + //работа с БД + val context = LocalContext.current + val (userWithTanks, setUserWithTanks) = remember { mutableStateOf(null) } + LaunchedEffect(Unit) { + withContext(Dispatchers.IO) { + setUserWithTanks(AppDatabase.getInstance(context).userDao().getSimpleUserUid(100L)) + } + } + //для работы текстовых полей - var nickname by remember { mutableStateOf("") } + var nickname by remember { mutableStateOf(userWithTanks?.nickname) } - var password by remember { mutableStateOf("") } + var password by remember { mutableStateOf(userWithTanks?.password) } - var balance by remember { mutableStateOf("") } + var balance by remember { mutableStateOf(userWithTanks?.balance.toString()) } Column( verticalArrangement = Arrangement.spacedBy(35.dp), @@ -109,24 +123,21 @@ fun Account(navController: NavController) { } Column { TextField( - value = nickname, - placeholder = { Text(text = "Логин", color = CustomDark) }, + value = userWithTanks?.nickname ?: "", onValueChange = { nickname = it }, modifier = Modifier .width(200.dp), ) Spacer(Modifier.height(10.dp)) TextField( - value = password, - placeholder = { Text(text = "Пароль", color = CustomDark) }, + value = userWithTanks?.password ?: "", onValueChange = { password = it }, modifier = Modifier .width(200.dp), ) Spacer(Modifier.height(10.dp)) TextField( - value = balance, - placeholder = { Text(text = "Баланс", color = CustomDark) }, + value = userWithTanks?.balance.toString(), onValueChange = { balance = it }, modifier = Modifier .width(200.dp),