forked from Writand/writand
Merge branch 'backend/db-projects' into 'main'
feat: projects local database and repository made Closes #9 See merge request EmmaVandewalle/writand!24
This commit is contained in:
commit
8def0b92a8
14 changed files with 259 additions and 18 deletions
|
@ -1,16 +1,20 @@
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
id 'org.jetbrains.kotlin.android'
|
id 'org.jetbrains.kotlin.android'
|
||||||
|
id "com.google.dagger.hilt.android"
|
||||||
|
id 'kotlinx-serialization'
|
||||||
|
id "kotlin-kapt"
|
||||||
|
id 'com.google.protobuf' version '0.9.4'
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace 'be.re.writand'
|
namespace 'be.re.writand'
|
||||||
compileSdk 33
|
compileSdk 34
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "be.re.writand"
|
applicationId "be.re.writand"
|
||||||
minSdk 24
|
minSdk 26
|
||||||
targetSdk 33
|
targetSdk 34
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
|
|
||||||
|
@ -27,37 +31,92 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_17
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_17
|
||||||
}
|
}
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = '1.8'
|
jvmTarget = '17'
|
||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
compose true
|
compose true
|
||||||
}
|
}
|
||||||
composeOptions {
|
composeOptions {
|
||||||
kotlinCompilerExtensionVersion '1.2.0'
|
kotlinCompilerExtensionVersion '1.5.0'
|
||||||
}
|
}
|
||||||
packagingOptions {
|
packagingOptions {
|
||||||
resources {
|
resources {
|
||||||
excludes += '/META-INF/{AL2.0,LGPL2.1}'
|
excludes += '/META-INF/{AL2.0,LGPL2.1}'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
testOptions {
|
||||||
|
unitTests.all {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
unitTests.returnDefaultValues = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation 'androidx.core:core-ktx:1.13.1'
|
||||||
implementation 'androidx.core:core-ktx:1.7.0'
|
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.3'
|
||||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
|
implementation 'androidx.activity:activity-compose:1.9.0'
|
||||||
implementation 'androidx.activity:activity-compose:1.3.1'
|
|
||||||
implementation "androidx.compose.ui:ui:$compose_ui_version"
|
implementation "androidx.compose.ui:ui:$compose_ui_version"
|
||||||
implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version"
|
implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version"
|
||||||
implementation 'androidx.compose.material:material:1.2.0'
|
implementation 'androidx.compose.material:material:1.6.8'
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||||
|
|
||||||
|
// Testing
|
||||||
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
|
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
|
||||||
|
testImplementation "org.junit.jupiter:junit-jupiter-api:5.8.1"
|
||||||
|
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.8.1"
|
||||||
|
|
||||||
|
// Mockito testing
|
||||||
|
testImplementation "org.mockito.kotlin:mockito-kotlin:3.2.0"
|
||||||
|
testImplementation "org.robolectric:robolectric:3.4.2"
|
||||||
|
testImplementation 'org.powermock:powermock-api-mockito:1.4.12'
|
||||||
|
testImplementation 'org.powermock:powermock-module-junit4:1.6.2'
|
||||||
|
|
||||||
|
testImplementation "org.mockito:mockito-core:4.2.0"
|
||||||
|
testImplementation "org.mockito:mockito-inline:4.1.0"
|
||||||
|
testImplementation "org.mockito:mockito-android:4.1.0"
|
||||||
|
|
||||||
|
// Hilt
|
||||||
|
implementation "com.google.dagger:hilt-android:2.48"
|
||||||
|
kapt "com.google.dagger:hilt-compiler:2.48"
|
||||||
|
|
||||||
|
// Room
|
||||||
|
implementation 'androidx.room:room-runtime:2.6.1'
|
||||||
|
annotationProcessor 'androidx.room:room-compiler:2.6.1'
|
||||||
|
implementation 'androidx.room:room-ktx:2.6.1'
|
||||||
|
|
||||||
|
// Proto DataStore
|
||||||
|
implementation 'androidx.datastore:datastore:1.1.1'
|
||||||
|
implementation 'com.google.protobuf:protobuf-javalite:3.21.7'
|
||||||
|
|
||||||
debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
|
debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
|
||||||
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"
|
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kapt {
|
||||||
|
correctErrorTypes true
|
||||||
|
}
|
||||||
|
|
||||||
|
protobuf {
|
||||||
|
protoc {
|
||||||
|
artifact = "com.google.protobuf:protoc:3.21.7"
|
||||||
|
}
|
||||||
|
// Generates the java Protobuf-lite code for the Protobufs in this project.
|
||||||
|
// see https://github.com/google/protobuf-gradle-plugin#customizing-protobuf-compilation
|
||||||
|
// for more information.
|
||||||
|
generateProtoTasks {
|
||||||
|
all().each { task ->
|
||||||
|
task.builtins {
|
||||||
|
java {
|
||||||
|
option 'lite'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package be.re.writand.data.local.db
|
||||||
|
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import be.re.writand.data.local.models.OpenFilePath
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entity for recent projects to keep in memory, used in the ProjectsDAO.
|
||||||
|
* @param[id] the unique id of a project.
|
||||||
|
* @param[path] the absolute path to the directory/file.
|
||||||
|
* A file in case of a project consisting of 1 file only.
|
||||||
|
* @param[openedFiles] a list of objects to specify more about each last opened file.
|
||||||
|
*/
|
||||||
|
@Entity(tableName = "projects")
|
||||||
|
data class ProjectEntity (
|
||||||
|
@PrimaryKey val id: Int,
|
||||||
|
val path: String,
|
||||||
|
val openedFiles: List<OpenFilePath>
|
||||||
|
)
|
37
app/src/main/java/be/re/writand/data/local/db/ProjectsDao.kt
Normal file
37
app/src/main/java/be/re/writand/data/local/db/ProjectsDao.kt
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package be.re.writand.data.local.db
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.Query
|
||||||
|
import be.re.writand.data.local.models.Project
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A DAO to handle recent opened projects when the Project Picker is presented.
|
||||||
|
*/
|
||||||
|
@Dao
|
||||||
|
interface ProjectsDao {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all the recent files that were opened.
|
||||||
|
*/
|
||||||
|
@Query("SELECT * FROM projects")
|
||||||
|
fun getAllProjects(): Flow<List<Project>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a project into the database that was just opened.
|
||||||
|
* @param[project] the project to add in the database.
|
||||||
|
*/
|
||||||
|
@Insert(entity = ProjectEntity::class)
|
||||||
|
suspend fun insertProject(project: Project)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a project from the recent opened projects.
|
||||||
|
* Should be called when the limit of saving projects is reached.
|
||||||
|
* @param[project] the project to be deleted from the database.
|
||||||
|
*/
|
||||||
|
@Delete(entity = ProjectEntity::class)
|
||||||
|
suspend fun deleteProject(project: Project)
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package be.re.writand.data.local.db
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.room.Database
|
||||||
|
import androidx.room.Room
|
||||||
|
import androidx.room.RoomDatabase
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database for all the recent projects.
|
||||||
|
*/
|
||||||
|
@Database(entities = [ProjectEntity::class], version = 1)
|
||||||
|
abstract class ProjectsDatabase: RoomDatabase() {
|
||||||
|
|
||||||
|
abstract fun projectsDao(): ProjectsDao
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@Volatile private var instance: ProjectsDatabase? = null
|
||||||
|
|
||||||
|
fun getInstance(context: Context) = instance ?: synchronized(this) {
|
||||||
|
return Room.databaseBuilder(
|
||||||
|
context.applicationContext, ProjectsDatabase::class.java, "projects-db"
|
||||||
|
).build().also { instance = it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
app/src/main/java/be/re/writand/data/local/models/Project.kt
Normal file
16
app/src/main/java/be/re/writand/data/local/models/Project.kt
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package be.re.writand.data.local.models
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data class used in the ProjectsDAO to store information about a recent project.
|
||||||
|
* @param[id] a unique id for the project.
|
||||||
|
* @param[path] the absolute path to the directory/file location of the project.
|
||||||
|
*/
|
||||||
|
data class Project(val id: Int, val path: String)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data class used in ProjectEntity to store information about a recent file of a project.
|
||||||
|
* @param[projectId] the id of the project the file belongs to.
|
||||||
|
* @param[path] the relative path to the file starting from the root fo the project.
|
||||||
|
* @param[isSaved] info whether the file was saved before closing the app (for expansion of unsaved files).
|
||||||
|
*/
|
||||||
|
data class OpenFilePath(val projectId: Int, val path: String, var isSaved: Boolean)
|
|
@ -0,0 +1,29 @@
|
||||||
|
package be.re.writand.data.repos
|
||||||
|
|
||||||
|
import be.re.writand.data.local.models.Project
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repository that handles everything for the local ProjectsDatabase.
|
||||||
|
* @param[dao] the dao provides get/add/delete functionality of the recent projects.
|
||||||
|
*/
|
||||||
|
interface IProjectsRepository {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all the projects from the local storage.
|
||||||
|
*/
|
||||||
|
fun getAllProjects(): Flow<List<Project>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a project to the local storage of recent projects.
|
||||||
|
* @param[project] the project to be added to the database.
|
||||||
|
*/
|
||||||
|
suspend fun addProject(project: Project)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a project from the local storage of recent projects.
|
||||||
|
* @param[project] the project to be deleted from the database.
|
||||||
|
*/
|
||||||
|
suspend fun deleteProject(project: Project)
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package be.re.writand.data.repos
|
||||||
|
|
||||||
|
import be.re.writand.data.local.db.ProjectsDao
|
||||||
|
import be.re.writand.data.local.models.Project
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class ProjectsRepository @Inject constructor(private val dao: ProjectsDao): IProjectsRepository {
|
||||||
|
|
||||||
|
override fun getAllProjects(): Flow<List<Project>> {
|
||||||
|
return dao.getAllProjects()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun addProject(project: Project) {
|
||||||
|
dao.insertProject(project)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteProject(project: Project) {
|
||||||
|
dao.deleteProject(project)
|
||||||
|
}
|
||||||
|
}
|
29
app/src/main/java/be/re/writand/di/DatabaseModule.kt
Normal file
29
app/src/main/java/be/re/writand/di/DatabaseModule.kt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package be.re.writand.di
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import be.re.writand.data.local.db.ProjectsDao
|
||||||
|
import be.re.writand.data.local.db.ProjectsDatabase
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module necessary to enable dependency injection for databases and DAO's.
|
||||||
|
*/
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
@Module
|
||||||
|
class DatabaseModule {
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
fun provideProjectsDatabase(@ApplicationContext context: Context): ProjectsDatabase {
|
||||||
|
return ProjectsDatabase.getInstance(context)
|
||||||
|
}
|
||||||
|
@Provides
|
||||||
|
fun provideQuotesDao(projectsDatabase: ProjectsDatabase): ProjectsDao {
|
||||||
|
return projectsDatabase.projectsDao()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
build.gradle
11
build.gradle
|
@ -1,10 +1,13 @@
|
||||||
buildscript {
|
buildscript {
|
||||||
ext {
|
ext {
|
||||||
compose_ui_version = '1.2.0'
|
kotlin_version = '1.9.0'
|
||||||
|
compose_ui_version = '1.6.8'
|
||||||
}
|
}
|
||||||
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application' version '7.4.2' apply false
|
id 'com.android.application' version '8.5.1' apply false
|
||||||
id 'com.android.library' version '7.4.2' apply false
|
id 'com.android.library' version '8.5.1' apply false
|
||||||
id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
|
id 'org.jetbrains.kotlin.android' version '1.9.0' apply false
|
||||||
|
id 'com.google.dagger.hilt.android' version '2.44' apply false
|
||||||
|
id 'org.jetbrains.kotlin.plugin.serialization' version '1.6.21'
|
||||||
}
|
}
|
|
@ -21,3 +21,4 @@ kotlin.code.style=official
|
||||||
# resources declared in the library itself and none from the library's dependencies,
|
# resources declared in the library itself and none from the library's dependencies,
|
||||||
# thereby reducing the size of the R class for that library
|
# thereby reducing the size of the R class for that library
|
||||||
android.nonTransitiveRClass=true
|
android.nonTransitiveRClass=true
|
||||||
|
android.nonFinalResIds=false
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
||||||
#Tue Jul 16 09:37:51 CEST 2024
|
#Tue Jul 16 09:37:51 CEST 2024
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|
Loading…
Reference in a new issue