diff --git a/AppMobile/app/build.gradle b/AppMobile/app/build.gradle index 605d18c..f33ddd8 100644 --- a/AppMobile/app/build.gradle +++ b/AppMobile/app/build.gradle @@ -34,14 +34,26 @@ android { dependencies { implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0")) implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'com.google.android.material:material:1.9.0' + implementation 'com.google.android.material:material:1.10.0' implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'com.google.android.material:material:1.9.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' - implementation 'androidx.navigation:navigation-fragment:2.7.3' - implementation 'androidx.navigation:navigation-ui:2.7.3' + implementation 'androidx.navigation:navigation-fragment:2.7.4' + implementation 'androidx.navigation:navigation-ui:2.7.4' + + // Room + def room_version = "2.5.0" + implementation "androidx.room:room-runtime:$room_version" + annotationProcessor "androidx.room:room-compiler:$room_version" + // optional - Paging 3 Integration + implementation "androidx.room:room-paging:$room_version" + // optional - RxJava3 support for Room + implementation "androidx.room:room-rxjava3:$room_version" + implementation 'io.reactivex.rxjava3:rxandroid:3.0.2' + // optional - Test helpers + testImplementation "androidx.room:room-testing:$room_version" + testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' diff --git a/AppMobile/app/src/main/java/com/example/appmobile/models/AppDatabase.java b/AppMobile/app/src/main/java/com/example/appmobile/models/AppDatabase.java new file mode 100644 index 0000000..a8ff2ad --- /dev/null +++ b/AppMobile/app/src/main/java/com/example/appmobile/models/AppDatabase.java @@ -0,0 +1,19 @@ +package com.example.appmobile.models; + +import androidx.room.Database; +import androidx.room.RoomDatabase; + +import com.example.appmobile.models.Category.Category; +import com.example.appmobile.models.Category.CategoryDao; +import com.example.appmobile.models.Task.Task; +import com.example.appmobile.models.Task.TaskDao; +import com.example.appmobile.models.User.User; +import com.example.appmobile.models.User.UserDao; + +@Database(entities = {User.class, Task.class, Category.class}, version = 1, exportSchema = false) +public abstract class AppDatabase extends RoomDatabase { + public abstract UserDao userDao (); + + public abstract TaskDao taskDao (); + public abstract CategoryDao categoryDao (); +} \ No newline at end of file diff --git a/AppMobile/app/src/main/java/com/example/appmobile/models/Category/Category.java b/AppMobile/app/src/main/java/com/example/appmobile/models/Category/Category.java new file mode 100644 index 0000000..6d33346 --- /dev/null +++ b/AppMobile/app/src/main/java/com/example/appmobile/models/Category/Category.java @@ -0,0 +1,37 @@ +package com.example.appmobile.models.Category; + +import androidx.annotation.NonNull; +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +@Entity(tableName = "categories") +public class Category { + @NonNull + @PrimaryKey(autoGenerate = true) + public Long id; + @NonNull + public String name; + + public Category(@NonNull Long id, @NonNull String name) { + this.id = id; + this.name = name; + } + + public Category(@NonNull String name) { + this.name = name; + } + + @NonNull + public Long getId() { + return id; + } + + @NonNull + public String getName() { + return name; + } + + public void setName(@NonNull String name) { + this.name = name; + } +} diff --git a/AppMobile/app/src/main/java/com/example/appmobile/models/Category/CategoryDao.java b/AppMobile/app/src/main/java/com/example/appmobile/models/Category/CategoryDao.java new file mode 100644 index 0000000..33473bf --- /dev/null +++ b/AppMobile/app/src/main/java/com/example/appmobile/models/Category/CategoryDao.java @@ -0,0 +1,33 @@ +package com.example.appmobile.models.Category; + +import androidx.room.Dao; +import androidx.room.Delete; +import androidx.room.Insert; +import androidx.room.Query; +import androidx.room.Update; + +import java.util.List; + +import io.reactivex.rxjava3.core.Completable; +import io.reactivex.rxjava3.core.Single; + +@Dao +public interface CategoryDao { + @Query("select * from categories") + Single> getAll(); + + @Query("select * from categories where categories.id = :id") + Single get(Long id); + + @Insert + Completable insert(Category category); + + @Insert + Completable insertAll(Category... categories); + + @Update + Completable update(Category categories); + + @Delete + Completable delete(Category categories); +} diff --git a/AppMobile/app/src/main/java/com/example/appmobile/models/Category/CategoryWithTasks.java b/AppMobile/app/src/main/java/com/example/appmobile/models/Category/CategoryWithTasks.java new file mode 100644 index 0000000..7335c24 --- /dev/null +++ b/AppMobile/app/src/main/java/com/example/appmobile/models/Category/CategoryWithTasks.java @@ -0,0 +1,19 @@ +package com.example.appmobile.models.Category; + +import androidx.room.Embedded; +import androidx.room.Relation; + +import com.example.appmobile.models.Task.Task; +import com.example.appmobile.models.User.User; + +import java.util.List; + +public class CategoryWithTasks { + @Embedded + public User user; + @Relation( + parentColumn = "id", + entityColumn = "categoryId" + ) + public List tasks; +} diff --git a/AppMobile/app/src/main/java/com/example/appmobile/models/Database.java b/AppMobile/app/src/main/java/com/example/appmobile/models/Database.java new file mode 100644 index 0000000..a2513eb --- /dev/null +++ b/AppMobile/app/src/main/java/com/example/appmobile/models/Database.java @@ -0,0 +1,63 @@ +package com.example.appmobile.models; + +import android.content.Context; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.room.Room; +import androidx.room.RoomDatabase; +import androidx.sqlite.db.SupportSQLiteDatabase; + +import com.example.appmobile.models.Category.Category; +import com.example.appmobile.models.Task.Task; +import com.example.appmobile.models.User.User; + +import java.util.concurrent.Executors; + +public final class Database { + private static final String DB_NAME = "TODOKA"; + private static volatile AppDatabase database; + + private Database() { + } + + private static void populateDatabase(Context applicationContext) { + User user = new User("Ino", "ino@gmail.com", "qw"); + Category category1 = new Category("Учеба"); + Category category2 = new Category("Дом"); + + Task t1 = new Task("Лабы", "сделать лабы по всем предметам", false, user, category1); + Task t2 = new Task("Уборка", "генеральная уборка в квартире", true, user, category2); + Task t3 = new Task("Продукты", "купить молоко и хлеб", false, user, category2); + Task t4 = new Task("Отчеты", "сделать все нужные отчеты по лабам", false, user, category1); + Task t5 = new Task("Бег", "3 км", true, user, category2); + Task t6 = new Task("Белочки", "пойти покормить белочек", false, user, category2); + + getDatabase(applicationContext).userDao().insert(user).subscribe().dispose(); + getDatabase(applicationContext).categoryDao().insertAll(category1, category2).subscribe().dispose(); + getDatabase(applicationContext).taskDao().insertAll(t1, t2, t3, t4, t5, t6).subscribe().dispose(); + + Log.d(Database.class.getSimpleName(), "Populated"); + } + + public static AppDatabase getDatabase(Context applicationContext) { + if (database == null) { + synchronized (Database.class) { + if (database == null) { + RoomDatabase.Callback populateCallback = new RoomDatabase.Callback() { + public void onCreate(@NonNull SupportSQLiteDatabase db) { + super.onCreate(db); + Executors.newSingleThreadScheduledExecutor() + .execute(() -> populateDatabase(applicationContext)); + } + }; + database = Room + .databaseBuilder(applicationContext, AppDatabase.class, DB_NAME) + .addCallback(populateCallback) + .build(); + } + } + } + return database; + } +} diff --git a/AppMobile/app/src/main/java/com/example/appmobile/models/Task/Task.java b/AppMobile/app/src/main/java/com/example/appmobile/models/Task/Task.java new file mode 100644 index 0000000..7b0d587 --- /dev/null +++ b/AppMobile/app/src/main/java/com/example/appmobile/models/Task/Task.java @@ -0,0 +1,119 @@ +package com.example.appmobile.models.Task; + +import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.ForeignKey; +import androidx.room.PrimaryKey; + +import com.example.appmobile.models.Category.Category; +import com.example.appmobile.models.User.User; + +@Entity(tableName = "tasks", foreignKeys = { + @ForeignKey( + entity = User.class, + parentColumns = {"id"}, + childColumns = {"group_id"}, + onDelete = ForeignKey.CASCADE, + onUpdate = ForeignKey.CASCADE + ), + @ForeignKey( + entity = Category.class, + parentColumns = {"id"}, + childColumns = {"category_id"}, + onDelete = ForeignKey.CASCADE, + onUpdate = ForeignKey.CASCADE + ) +}) +public class Task { + @NonNull + @PrimaryKey(autoGenerate = true) + public Long id; + @NonNull + public String title; + @NonNull + public String description; + @NonNull + public boolean close; + @NonNull + @ColumnInfo(name = "user_id", index = true) + public Long userId; + @NonNull + @ColumnInfo(name = "category_id", index = true) + public Long categoryId; + + public Task(@NonNull Long id, + @NonNull String title, + @NonNull String description, + boolean close, + @NonNull Long userId, + @NonNull Long categoryId) { + this.id = id; + this.title = title; + this.description = description; + this.close = close; + this.userId = userId; + this.categoryId = categoryId; + } + + public Task(@NonNull String title, + @NonNull String description, + boolean close, + @NonNull User user, + @NonNull Category category) { + this.title = title; + this.description = description; + this.close = close; + this.userId = user.getId(); + this.categoryId = category.getId(); + } + + @NonNull + public Long getId() { + return id; + } + + @NonNull + public String getTitle() { + return title; + } + + public void setTitle(@NonNull String title) { + this.title = title; + } + + @NonNull + public String getDescription() { + return description; + } + + public void setDescription(@NonNull String description) { + this.description = description; + } + + public boolean isClose() { + return close; + } + + public void setClose(boolean close) { + this.close = close; + } + + @NonNull + public Long getUserId() { + return userId; + } + + public void setUserId(@NonNull Long userId) { + this.userId = userId; + } + + @NonNull + public Long getCategoryId() { + return categoryId; + } + + public void setCategoryId(@NonNull Long categoryId) { + this.categoryId = categoryId; + } +} diff --git a/AppMobile/app/src/main/java/com/example/appmobile/models/Task/TaskDao.java b/AppMobile/app/src/main/java/com/example/appmobile/models/Task/TaskDao.java new file mode 100644 index 0000000..05a97fe --- /dev/null +++ b/AppMobile/app/src/main/java/com/example/appmobile/models/Task/TaskDao.java @@ -0,0 +1,33 @@ +package com.example.appmobile.models.Task; + +import androidx.room.Dao; +import androidx.room.Delete; +import androidx.room.Insert; +import androidx.room.Query; +import androidx.room.Update; + +import java.util.List; + +import io.reactivex.rxjava3.core.Completable; +import io.reactivex.rxjava3.core.Single; + +@Dao +public interface TaskDao { + @Query("select * from tasks") + Single> getAll(); + + @Query("select * from tasks where tasks.id = :id") + Single get(Long id); + + @Insert + Completable insert(Task task); + + @Insert + Completable insertAll(Task... tasks); + + @Update + Completable update(Task task); + + @Delete + Completable delete(Task task); +} diff --git a/AppMobile/app/src/main/java/com/example/appmobile/models/User/User.java b/AppMobile/app/src/main/java/com/example/appmobile/models/User/User.java new file mode 100644 index 0000000..f1db4af --- /dev/null +++ b/AppMobile/app/src/main/java/com/example/appmobile/models/User/User.java @@ -0,0 +1,70 @@ +package com.example.appmobile.models.User; + +import androidx.annotation.NonNull; +import androidx.room.Entity; +import androidx.room.PrimaryKey; + + +@Entity(tableName = "users") +public class User { + @NonNull + @PrimaryKey(autoGenerate = true) + public Long id; + + @NonNull + public String name; + @NonNull + public String email; + @NonNull + public String password; + + public User(@NonNull Long id, + @NonNull String name, + @NonNull String email, + @NonNull String password) { + this.id = id; + this.name = name; + this.email = email; + this.password = password; + } + + public User(@NonNull String name, + @NonNull String email, + @NonNull String password) { + this.name = name; + this.email = email; + this.password = password; + } + + @NonNull + public Long getId() { + return id; + } + + @NonNull + public String getName() { + return name; + } + + public void setName(@NonNull String name) { + this.name = name; + } + + @NonNull + public String getEmail() { + return email; + } + + public void setEmail(@NonNull String email) { + this.email = email; + } + + @NonNull + public String getPassword() { + return password; + } + + public void setPassword(@NonNull String password) { + this.password = password; + } +} diff --git a/AppMobile/app/src/main/java/com/example/appmobile/models/User/UserDao.java b/AppMobile/app/src/main/java/com/example/appmobile/models/User/UserDao.java new file mode 100644 index 0000000..cd7575b --- /dev/null +++ b/AppMobile/app/src/main/java/com/example/appmobile/models/User/UserDao.java @@ -0,0 +1,33 @@ +package com.example.appmobile.models.User; + +import androidx.room.Dao; +import androidx.room.Delete; +import androidx.room.Insert; +import androidx.room.Query; +import androidx.room.Update; + +import java.util.List; + +import io.reactivex.rxjava3.core.Completable; +import io.reactivex.rxjava3.core.Single; + +@Dao +public interface UserDao { + @Query("select * from users") + Single> getAll(); + + @Query("select * from users where users.id = :id") + Single get(Long id); + + @Insert + Completable insert(User user); + + @Insert + Completable insertAll(User... users); + + @Update + Completable update(User user); + + @Delete + Completable delete(User user); +} diff --git a/AppMobile/app/src/main/java/com/example/appmobile/models/User/UserWithTasks.java b/AppMobile/app/src/main/java/com/example/appmobile/models/User/UserWithTasks.java new file mode 100644 index 0000000..fd4fbe5 --- /dev/null +++ b/AppMobile/app/src/main/java/com/example/appmobile/models/User/UserWithTasks.java @@ -0,0 +1,17 @@ +package com.example.appmobile.models.User; + +import androidx.room.Embedded; +import androidx.room.Relation; + +import com.example.appmobile.models.Task.Task; + +import java.util.List; + +public class UserWithTasks { + @Embedded public User user; + @Relation( + parentColumn = "id", + entityColumn = "userId" + ) + public List tasks; +}