tinmegali
7/14/2017 - 7:19 PM

Android Room with Kotlin

Android Room with Kotlin

package com.tinmegali.daggerwithkotlin.room

import android.arch.persistence.room.Database
import android.arch.persistence.room.RoomDatabase
import android.arch.persistence.room.TypeConverters

import com.tinmegali.daggerwithkotlin.room.daos.NoteDAO
import com.tinmegali.daggerwithkotlin.room.daos.UserDAO
import com.tinmegali.daggerwithkotlin.room.entities.Note
import com.tinmegali.daggerwithkotlin.room.entities.User

/**
 * com.tinmegali.daggerwithkotlin.room | DaggerWithKotlin
 * __________________________________
 * Created by tinmegali
 * 13/07/17

 * @see [tinmegali.com](http://www.tinmegali.com)

 * @see [github](http://github.com/tinmegali)
 * ___________________________________
 */

@Database(entities = arrayOf(Note::class, User::class), version = 1)
@TypeConverters(Converters::class)
abstract class AppDatabse : RoomDatabase() {

    abstract fun userDAO(): UserDAO
    abstract fun noteDAO(): NoteDAO

}
package com.tinmegali.daggerwithkotlin.room

import android.arch.persistence.room.TypeConverter

import java.util.Date


class Converters {

    @TypeConverter
    fun fromTimestamp(value: Long?): Date? {
        return if (value == null) null else Date(value)
    }

    @TypeConverter
    fun dateToTimestamp(date: Date?): Long? {
        return date?.time
    }

}
        // definitive DB
        val db: AppDatabse = 
                Room.databaseBuilder(appContext, AppDatabse::class.java, "db")
                        .allowMainThreadQueries() // allow calls on UI
                        .build()
        
        
        // in Memory DB
        val db: AppDatabse = Room.inMemoryDatabaseBuilder(appContext, AppDatabse::class.java).build()
package com.tinmegali.daggerwithkotlin.room

import android.arch.lifecycle.LiveData
import android.arch.lifecycle.Observer
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit

// Extension to allow unit tests on LiveData
// discussion on: https://stackoverflow.com/questions/44270688/unit-testing-room-and-livedata

fun <T> LiveData<T>.blockingObserve(): T? {
    var value: T? = null
    val latch = CountDownLatch(1)
    val innerObserver = Observer<T> {
        value = it
        latch.countDown()
    }
    observeForever(innerObserver)
    latch.await(2, TimeUnit.SECONDS)
    return value
}
package com.tinmegali.daggerwithkotlin.room.entities

import android.arch.persistence.room.ColumnInfo
import android.arch.persistence.room.Entity
import android.arch.persistence.room.ForeignKey
import android.arch.persistence.room.Index
import android.arch.persistence.room.PrimaryKey

import java.util.Date

/**
 * com.tinmegali.daggerwithkotlin.models | DaggerWithKotlin
 * __________________________________
 * Created by tinmegali
 * 13/07/17

 * @see [tinmegali.com](http://www.tinmegali.com)

 * @see [github](http://github.com/tinmegali)
 * ___________________________________
 */

@Entity(indices = arrayOf(
        Index(value = *arrayOf("isDone", "updatedAt", "user_id"))),
        foreignKeys = arrayOf(
                ForeignKey(
                        entity = User::class,
                        parentColumns = arrayOf("id"),
                        childColumns = arrayOf("user_id"),
                        onDelete = ForeignKey.CASCADE,
                        onUpdate = ForeignKey.CASCADE
                )))
class Note {

    @PrimaryKey(autoGenerate = true)
    var id: Long? = null

    var text: String? = null

    var isDone: Boolean = false

    var createdAt: Date? = null

    var updatedAt: Date? = null

    @ColumnInfo(name = "user_id")
    var userId: Long? = null

    class Resumed {
        var id: Long? = null
        var text: String? = null
        var isDone: Boolean = false
    }
}
package com.tinmegali.daggerwithkotlin.room.daos

import android.arch.lifecycle.LiveData
import android.arch.persistence.room.Dao
import android.arch.persistence.room.Delete
import android.arch.persistence.room.Insert
import android.arch.persistence.room.OnConflictStrategy
import android.arch.persistence.room.Query
import android.arch.persistence.room.Update

import com.tinmegali.daggerwithkotlin.room.entities.Note

import java.util.Date

/**
 * com.tinmegali.daggerwithkotlin.room.daos | DaggerWithKotlin
 * __________________________________
 * Created by tinmegali
 * 13/07/17

 * @see [tinmegali.com](http://www.tinmegali.com)

 * @see [github](http://github.com/tinmegali)
 * ___________________________________
 */

@Dao
interface NoteDAO {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertNote(note: Note): Long?

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertNotes(vararg notes: Note): Array<Long>

    @Update(onConflict = OnConflictStrategy.REPLACE)
    fun updateNotes(vararg note: Note): Int

    @Delete
    fun deleteNotes(vararg notes: Note): Int

    @Query("SELECT * FROM note WHERE updatedAt >= :arg0")
    fun findNotesByDate(updatedAt: Date): List<Note>

    @Query("SELECT id, text, isDone FROM note ORDER BY updatedAt ASC")
    fun findAllResumedNotesFilteredByUpdateDate(): List<Note.Resumed>

    @Query("SELECT id, text, isDone FROM note WHERE isDone == 1 ORDER BY updatedAt ASC")
    fun findAllResumedNotesNotDoneFilteredByUpdateDate(): List<Note.Resumed>

    @Query("SELECT * FROM note ORDER BY isDone, updatedAt DESC")
    fun findAllNotesGroupedByDoneStatus(): List<Note>

    @Query("SELECT * FROM note WHERE id = :arg0 LIMIT 1")
    fun findById(id: Long?): Note

    @Query("SELECT * FROM note")
    fun findAllNotedObservable(): LiveData<List<Note>>

}
package com.tinmegali.daggerwithkotlin.room.entities

import android.arch.persistence.room.ColumnInfo
import android.arch.persistence.room.Entity
import android.arch.persistence.room.Index
import android.arch.persistence.room.PrimaryKey


@Entity(indices = arrayOf(
        Index(value = *arrayOf("first_name", "last_name"),
                unique = true
        )))
class User {

    @PrimaryKey
    var id: Long? = null

    var username: String? = null

    @ColumnInfo(name = "first_name")
    var firstName: String? = null

    @ColumnInfo(name = "last_name")
    var lastName: String? = null

    var email: String? = null

}
package com.tinmegali.daggerwithkotlin.room.daos

import android.arch.persistence.room.Dao
import android.arch.persistence.room.Delete
import android.arch.persistence.room.Insert
import android.arch.persistence.room.OnConflictStrategy
import android.arch.persistence.room.Query
import android.arch.persistence.room.Update

import com.tinmegali.daggerwithkotlin.room.entities.User


@Dao
interface UserDAO {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertUser(user: User): Long?

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun inserUsers(vararg users: User): List<Long>

    @Update
    fun updateUser(user: User): Int

    @Delete
    fun deleteUser(user: User): Int

    @Query("SELECT * FROM user WHERE username = :arg0 LIMIT 1")
    fun findUserByUsername(username: String): User

    @Query("SELECT * FROM user WHERE id = :arg0 LIMIT 1")
    fun findUserById(id: Long?): User

}