main
Alexis Drai 3 years ago
parent bf4d530ac0
commit e064615a9d

@ -1,8 +1,10 @@
plugins { plugins {
id 'com.android.application' id 'com.android.application'
id 'org.jetbrains.kotlin.android' id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
} }
android { android {
namespace 'fr.uca.iut.urbandictionarylight' namespace 'fr.uca.iut.urbandictionarylight'
compileSdk 33 compileSdk 33
@ -39,7 +41,6 @@ android {
} }
dependencies { dependencies {
implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.6.0' implementation 'androidx.appcompat:appcompat:1.6.0'
implementation 'com.google.android.material:material:1.8.0' implementation 'com.google.android.material:material:1.8.0'
@ -47,4 +48,10 @@ dependencies {
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'
def room_version = "2.5.0"
def kotlin_version = "1.7.21"
def nav_version = "2.5.3"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
} }

@ -2,6 +2,7 @@ package fr.uca.iut.urbandictionarylight
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import fr.uca.iut.urbandictionarylight.data.UrbanDictionaryDatabase
import fr.uca.iut.urbandictionarylight.databinding.ActivityMainBinding import fr.uca.iut.urbandictionarylight.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {

@ -0,0 +1,22 @@
package fr.uca.iut.urbandictionarylight.data
import androidx.room.*
import fr.uca.iut.urbandictionarylight.model.Definition
@Dao
interface DefinitionDao {
@Query("SELECT * FROM definitions")
fun queryAll(): Set<Definition>
@Query("SELECT * FROM entries WHERE id == :id")
fun query(id: Int): Definition?
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(entry: Definition)
@Update
fun update(entry: Definition)
@Delete
fun delete(entry: Definition)
}

@ -0,0 +1,23 @@
package fr.uca.iut.urbandictionarylight.data
import androidx.room.*
import fr.uca.iut.urbandictionarylight.model.EntryWithDefinitions
@Dao
interface EntryDao {
@Query("SELECT * FROM entries")
fun queryAll(): List<EntryWithDefinitions>
@Query("SELECT * FROM entries WHERE id == :id")
fun query(id: Int): EntryWithDefinitions?
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(entry: EntryWithDefinitions)
@Update
fun update(entry: EntryWithDefinitions)
@Delete
fun delete(entry: EntryWithDefinitions)
}

@ -0,0 +1,96 @@
package fr.uca.iut.urbandictionarylight.data
import android.app.Application
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import fr.uca.iut.urbandictionarylight.model.Definition
import fr.uca.iut.urbandictionarylight.model.Entry
import fr.uca.iut.urbandictionarylight.model.EntryWithDefinitions
private const val DB_FILE = "u_d_light.db"
@Database(entities = [Entry::class, Definition::class], version = 1)
abstract class UrbanDictionaryDatabase : RoomDatabase() {
abstract fun entryDao(): EntryDao
abstract fun definitionDao(): DefinitionDao
companion object {
private lateinit var application: Application
@Volatile
private var instance: UrbanDictionaryDatabase? = null
fun getInstance(): UrbanDictionaryDatabase {
if (Companion::application.isInitialized) {
if (instance == null)
synchronized(this) {
if (instance == null) {
instance = Room.databaseBuilder(
application.applicationContext,
UrbanDictionaryDatabase::class.java,
DB_FILE
)
.allowMainThreadQueries()
.build()
instance?.entryDao()?.let {
if (it.queryAll().isEmpty()) emptyDatabaseStub(it)
}
}
}
return instance!!
} else
throw RuntimeException("the database must be initialized first")
}
//????
@Synchronized
fun initialize(app: Application) {
if (Companion::application.isInitialized)
throw RuntimeException("the database must not be initialized twice")
application = app
}
private fun emptyDatabaseStub(
entryDao: EntryDao,
definitionDao: DefinitionDao
): () -> Unit = {
val def1 = Definition("bleep", "bleep blap bloop", 1)
val def2 = Definition("blarp", "bleeeep blap bloop", 7)
val def3 = Definition("blep", "bleep blap blooop", 4)
val def4 = Definition("blupo", "bleep blaap bloop", 56)
with(definitionDao) {
insert(def1)
insert(def2)
insert(def3)
insert(def4)
}
with(entryDao) {
insert(
EntryWithDefinitions(
Entry("shrimping"),
listOf(def1, def4)
)
)
insert(
EntryWithDefinitions(
Entry("blunderkegel"),
listOf(def2)
)
)
insert(
EntryWithDefinitions(
Entry("something horrible and dumb"),
listOf(def3)
)
)
}
}
}
}

@ -1,11 +1,14 @@
package fr.uca.iut.urbandictionarylight.model package fr.uca.iut.urbandictionarylight.model
data class Definition(val content: String, val example: String) { import androidx.room.Entity
private var upvotes: UInt = 0u import androidx.room.PrimaryKey
fun getUpvotes() = upvotes const val NEW_DEFINITION_ID = 0L
fun upvote() { @Entity(tableName = "definitions")
upvotes++ data class Definition(
} val content: String,
} val example: String,
var upvotes: Int = 0,
@PrimaryKey(autoGenerate = true) val id: Long = NEW_DEFINITION_ID
)

@ -1,5 +1,9 @@
// UHM THIS WILL PROBABLY BE THE REPOSITORY ITSELF
/*
package fr.uca.iut.urbandictionarylight.model package fr.uca.iut.urbandictionarylight.model
@Entity
class Dictionary { class Dictionary {
private val entries: MutableSet<Entry> = mutableSetOf() private val entries: MutableSet<Entry> = mutableSetOf()
@ -38,4 +42,4 @@ class Dictionary {
} }
// TODO ? redefine equals and hashset ? // TODO ? redefine equals and hashset ?
} }*/

@ -1,61 +1,12 @@
package fr.uca.iut.urbandictionarylight.model package fr.uca.iut.urbandictionarylight.model
import fr.uca.iut.urbandictionarylight.utils.Sorting import androidx.room.Entity
import androidx.room.PrimaryKey
class Entry(val phrase: String) { const val NEW_ENTRY_ID = 0L
private val definitions: MutableSet<Definition> = mutableSetOf()
fun createDefinition(definition: Definition) { @Entity(tableName = "entries")
if (definition.content.isNotBlank() && definition.example.isNotBlank()) { data class Entry(
definitions.add(definition) val phrase: String,
} @PrimaryKey(autoGenerate = true) val id: Long = NEW_ENTRY_ID
} )
fun readDefinition(id: Int): Definition {
// TODO implement once ORM is in place
return Definition(
content = "poopy butt",
example = "Yeah, that's right -- poopy butt. This method hasn't been implemented yet."
)
}
fun readAllDefinitions() = definitions.toSet()
// TODO implement
fun readAllDefinitions(criterion: Sorting): Set<Definition> {
when (criterion) {
Sorting.ASC -> {
print("implement asc sorting!")
return readAllDefinitions()
}
Sorting.DESC -> {
print("implement desc sorting!")
return readAllDefinitions()
}
else -> return readAllDefinitions()
}
}
fun updateDefinition(definition: Definition) {
// TODO implement once ORM is in place
// removeDefinition(definition.id)
createDefinition(definition)
}
// TODO throw this away soon
fun updateDefinition(old: Definition, new: Definition) {
deleteDefinition(old)
createDefinition(new)
}
fun deleteDefinition(definition: Definition) {
definitions.remove(definition)
}
fun deleteDefinition(id: Int) {
// TODO implement once ORM is in place
// definitions.removeIf { def -> id == def.id }
}
// TODO redefine equals and hashset
}

@ -0,0 +1,12 @@
package fr.uca.iut.urbandictionarylight.model
import androidx.room.Embedded
import androidx.room.Relation
data class EntryWithDefinitions(
@Embedded val entry: Entry,
@Relation(
parentColumn = "id",
entityColumn = "entryId"
) val definitions: List<Definition>
)

@ -7,7 +7,7 @@
tools:context=".MainActivity"> tools:context=".MainActivity">
<SearchView <SearchView
android:id="@+id/searchView" android:id="@+id/search_view"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
@ -19,7 +19,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView" android:id="@+id/recycler_view"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
@ -29,10 +29,10 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/searchView" /> app:layout_constraintTop_toBottomOf="@+id/search_view" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/addDefinitionBtn" android:id="@+id/add_definition_btn"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
@ -42,11 +42,11 @@
android:focusable="true" android:focusable="true"
app:backgroundTint="#55752F" app:backgroundTint="#55752F"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/searchView" app:layout_constraintTop_toBottomOf="@+id/search_view"
app:srcCompat="@android:drawable/ic_input_add" /> app:srcCompat="@android:drawable/ic_input_add" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/addTermBtn" android:id="@+id/add_term_btn"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp" android:layout_marginStart="24dp"
@ -56,27 +56,27 @@
android:focusable="true" android:focusable="true"
app:backgroundTint="#3E4E83" app:backgroundTint="#3E4E83"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/searchView" app:layout_constraintTop_toBottomOf="@+id/search_view"
app:srcCompat="@android:drawable/ic_input_add" /> app:srcCompat="@android:drawable/ic_input_add" />
<TextView <TextView
android:id="@+id/textView" android:id="@+id/add_definition_btn_lbl"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/add_term_lbl" android:layout_marginEnd="16dp"
app:layout_constraintStart_toStartOf="parent" android:text="@string/add_def_lbl"
app:layout_constraintTop_toBottomOf="@+id/addTermBtn" /> app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/add_definition_btn" />
<TextView <TextView
android:id="@+id/textView2" android:id="@+id/add_term_btn_lbl"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:layout_marginEnd="16dp" android:text="@string/add_term_lbl"
android:text="@string/add_def_lbl" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/add_term_btn" />
app:layout_constraintTop_toBottomOf="@+id/addDefinitionBtn" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

@ -3,4 +3,4 @@ plugins {
id 'com.android.application' version '7.4.0' apply false id 'com.android.application' version '7.4.0' apply false
id 'com.android.library' version '7.4.0' apply false id 'com.android.library' version '7.4.0' apply false
id 'org.jetbrains.kotlin.android' version '1.7.10' apply false id 'org.jetbrains.kotlin.android' version '1.7.10' apply false
} }

Loading…
Cancel
Save