Skip to content

Commit

Permalink
migrated to room from realm, missing the delete use case and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Zeyad-37 committed Nov 15, 2018
1 parent a5133af commit 2476f12
Show file tree
Hide file tree
Showing 50 changed files with 1,555 additions and 1,415 deletions.
2 changes: 0 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ buildscript {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
// classpath 'com.google.gms:google-services:3.1.0'
classpath 'io.realm:realm-gradle-plugin:4.2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
Expand Down
6 changes: 5 additions & 1 deletion sampleApp/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'realm-android'
apply plugin: 'kotlin-kapt'

android {
compileSdkVersion 28
Expand Down Expand Up @@ -97,6 +97,10 @@ dependencies {
implementation "org.koin:koin-android-architecture:0.9.3"
implementation "android.arch.lifecycle:reactivestreams:1.1.1"

implementation "android.arch.persistence.room:runtime:$room_version"
implementation "android.arch.persistence.room:rxjava2:$room_version"
kapt "android.arch.persistence.room:compiler:$room_version"

// Support
implementation "com.android.support:appcompat-v7:$supportLibrary"
implementation "com.android.support:support-v4:$supportLibrary"
Expand Down
41 changes: 41 additions & 0 deletions sampleApp/src/main/java/com/zeyad/usecases/app/AppDatabase.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.zeyad.usecases.app

import android.arch.persistence.room.Database
import android.arch.persistence.room.Room
import android.arch.persistence.room.RoomDatabase
import android.content.Context
import com.zeyad.usecases.app.screens.user.User
import com.zeyad.usecases.app.screens.user.detail.Repository

@Database(entities = [User::class, Repository::class], version = 1)
abstract class AppDatabase : RoomDatabase() {

abstract fun userDao(): UserDao
abstract fun repoDao(): RepoDao

companion object {

@Volatile
private var instance: AppDatabase? = null

fun getInstance(context: Context): AppDatabase {
return instance ?: synchronized(this) {
instance ?: buildDatabase(context).also { instance = it }
}
}

// Create and pre-populate the database. See this article for more details:
// https://medium.com/google-developers/7-pro-tips-for-room-fbadea4bfbd1#4785
private fun buildDatabase(context: Context): AppDatabase {
return Room.databaseBuilder(context, AppDatabase::class.java, "app.room")
// .addCallback(object : RoomDatabase.Callback() {
// override fun onCreate(db: SupportSQLiteDatabase) {
// super.onCreate(db)
// val request = OneTimeWorkRequestBuilder<SeedDatabaseWorker>().build()
// WorkManager.getInstance().enqueue(request)
// }
// })
.build()
}
}
}
12 changes: 12 additions & 0 deletions sampleApp/src/main/java/com/zeyad/usecases/app/Daos.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.zeyad.usecases.app

import android.arch.persistence.room.Dao
import com.zeyad.usecases.app.screens.user.User
import com.zeyad.usecases.app.screens.user.detail.Repository
import com.zeyad.usecases.db.BaseDao

@Dao
interface UserDao : BaseDao<User>

@Dao
interface RepoDao : BaseDao<Repository>
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ import io.reactivex.disposables.Disposable
import io.reactivex.functions.Action
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import io.realm.Realm
import io.realm.RealmConfiguration
import io.realm.rx.RealmObservableFactory
import okhttp3.CertificatePinner
import okhttp3.ConnectionSpec
import okhttp3.OkHttpClient
Expand Down Expand Up @@ -124,13 +121,13 @@ open class GenericApplication : Application() {
}

private fun initializeRealm() {
Realm.init(this)
Realm.setDefaultConfiguration(RealmConfiguration.Builder()
.name("app.realm")
.modules(Realm.getDefaultModule(), LibraryModule())
.rxFactory(RealmObservableFactory())
.deleteRealmIfMigrationNeeded()
.build())
// Realm.init(this)
// Realm.setDefaultConfiguration(RealmConfiguration.Builder()
// .name("app.realm")
// .modules(Realm.getDefaultModule(), LibraryModule())
// .rxFactory(RealmObservableFactory())
// .deleteRealmIfMigrationNeeded()
// .build())
}

private fun checkAppTampering(context: Context): Boolean {
Expand Down

This file was deleted.

35 changes: 29 additions & 6 deletions sampleApp/src/main/java/com/zeyad/usecases/app/di/myModule.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package com.zeyad.usecases.app.di

import android.content.Context
import android.os.HandlerThread
import android.util.Log
import com.zeyad.usecases.api.DataServiceConfig
import com.zeyad.usecases.api.DataServiceFactory
import com.zeyad.usecases.api.IDataService
import com.zeyad.usecases.app.AppDatabase
import com.zeyad.usecases.app.BuildConfig
import com.zeyad.usecases.app.screens.user.User
import com.zeyad.usecases.app.screens.user.detail.Repository
import com.zeyad.usecases.app.screens.user.detail.UserDetailVM
import com.zeyad.usecases.app.screens.user.list.UserListVM
import com.zeyad.usecases.app.utils.Constants.URLS.API_BASE_URL
import com.zeyad.usecases.db.BaseDao
import com.zeyad.usecases.db.DaoResolver
import com.zeyad.usecases.db.DataBaseManager
import com.zeyad.usecases.db.RoomManager
import com.zeyad.usecases.utils.DataBaseManagerUtil
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import org.koin.android.architecture.ext.viewModel
Expand All @@ -21,16 +28,32 @@ val myModule: Module = applicationContext {
viewModel { UserListVM(get()) }
viewModel { UserDetailVM(get()) }

bean { createDataService(get()) }
bean { createDataService(get(), get()) }

bean { createDataBase(get()) }
}

fun createDataService(context: Context): IDataService {
DataServiceFactory(DataServiceConfig.Builder(context)
fun createDataBase(context: Context): AppDatabase = AppDatabase.getInstance(context)

fun createDataService(context: Context, db: AppDatabase): IDataService {
return DataServiceFactory(DataServiceConfig.Builder(context)
.baseUrl(API_BASE_URL)
.okHttpBuilder(getOkHttpBuilder())
.withRealm(HandlerThread("BackgroundHandlerThread"))
.withSQLite(object : DataBaseManagerUtil {
override fun getDataBaseManager(dataClass: Class<*>): DataBaseManager? {
return RoomManager(db, object : DaoResolver {
override fun <E> getDao(dataClass: Class<E>): BaseDao<E> {
return when (dataClass) {
User::class.java -> db.userDao() as BaseDao<E>
Repository::class.java -> db.repoDao() as BaseDao<E>
else -> throw IllegalArgumentException("")
}
}
})
}
})
.build())
return DataServiceFactory.dataService!!
.getInstance()
}

fun getOkHttpBuilder(): OkHttpClient.Builder {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
package com.zeyad.usecases.app.screens.user

import android.arch.persistence.room.ColumnInfo
import android.arch.persistence.room.Entity
import android.arch.persistence.room.PrimaryKey
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import com.zeyad.usecases.app.R.id.id
import kotlinx.android.parcel.Parcelize

/**
* @author zeyad on 1/10/17.
*/
@Entity
@Parcelize
open class User(@PrimaryKey
@SerializedName(LOGIN)
open class User(@SerializedName(LOGIN)
var login: String = "",
@SerializedName(ID)
var id: Int = 0,
@PrimaryKey var id: Int = 0,
@SerializedName(AVATAR_URL)
var avatarUrl: String = "") : RealmObject(), Parcelable {
@ColumnInfo(name = AVATAR_URL)
var avatarUrl: String = "") : Parcelable {

companion object {
const val LOGIN = "login"
private const val ID = "id"
private const val AVATAR_URL = "avatar_url"

fun isEmpty(user: User): Boolean {
return user.login.isEmpty() && id <= 0 && user.avatarUrl.isEmpty()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
package com.zeyad.usecases.app.screens.user.detail

import android.arch.persistence.room.ColumnInfo
import android.arch.persistence.room.Entity
import android.arch.persistence.room.PrimaryKey
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import com.zeyad.usecases.app.screens.user.User
import io.realm.RealmObject
import kotlinx.android.parcel.Parcelize

/**
* @author zeyad on 1/25/17.
*/
@Entity
@Parcelize
open class Repository(@SerializedName("id")
var id: Int = 0,
@PrimaryKey var id: Int = 0,
@SerializedName("name")
var name: String? = null,
var name: String = "",
@SerializedName("full_name")
var fullName: String? = null,
@SerializedName("owner")
internal var owner: User? = null) : RealmObject(), Parcelable {

companion object {

fun isEmpty(repository: Repository?): Boolean {
return repository == null || repository.name == null && repository.fullName == null && repository.owner == null
}
}
}
@ColumnInfo(name = "full_name")
var fullName: String = ""
// ,
// @SerializedName("owner")
// var owner: User = User()) : Parcelable
) : Parcelable
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class UserListVM(private var dataUseCase: IDataService) : BaseViewModel<UserList
override fun reduce(newResult: Any, event: BaseEvent<*>, currentStateBundle: UserListState?): UserListState {
var users: MutableList<User>
users = if (currentStateBundle?.users == null)
ArrayList<User>()
ArrayList()
else
Observable.fromIterable(currentStateBundle.users)
.map<User> { it.getData() }
Expand All @@ -49,8 +49,6 @@ class UserListVM(private var dataUseCase: IDataService) : BaseViewModel<UserList
is DeleteUsersEvent -> users = Observable.fromIterable(users)
.filter { user -> !(newResult as List<*>).contains(user.login) }
.distinct().toList().blockingGet()
else -> {
}
}
return UserListState.builder()
.users(users)
Expand Down Expand Up @@ -98,5 +96,6 @@ class UserListVM(private var dataUseCase: IDataService) : BaseViewModel<UserList
.cache()
.build())
.map { selectedItemsIds }
.toFlowable()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import android.content.Context;
import android.icu.util.Calendar;
import android.os.Build;
import android.preference.PreferenceManager;
import android.security.KeyPairGeneratorSpec;
import android.support.annotation.RequiresApi;
import android.util.Base64;
Expand All @@ -19,7 +18,6 @@
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.UnrecoverableEntryException;
import java.security.cert.CertificateException;
import java.util.Locale;
Expand All @@ -30,8 +28,6 @@
import javax.crypto.NoSuchPaddingException;
import javax.security.auth.x500.X500Principal;

import io.realm.RealmConfiguration;

import static java.nio.charset.StandardCharsets.UTF_8;

/**
Expand Down Expand Up @@ -124,26 +120,26 @@ public static byte[] cipherUsingKey(PublicKey publicKey, PrivateKey privateKey,
return inCipher.doFinal(bytes);
}

@RequiresApi(api = Build.VERSION_CODES.N)
public static String createSecureRealmKey(Context context)
throws IOException, CertificateException, NoSuchAlgorithmException, InvalidKeyException,
UnrecoverableEntryException, InvalidAlgorithmParameterException, IllegalBlockSizeException,
NoSuchProviderException, BadPaddingException, NoSuchPaddingException, KeyStoreException {
byte[] realmkey = new byte[RealmConfiguration.KEY_LENGTH];
new SecureRandom().nextBytes(realmkey);
return encrypt(context, realmkey);
}

// disable in manifest allowBackUp = true for encryption
@RequiresApi(api = Build.VERSION_CODES.N)
public static byte[] getRealmKey(Context context)
throws IOException, CertificateException, NoSuchAlgorithmException, InvalidKeyException,
UnrecoverableEntryException, InvalidAlgorithmParameterException, IllegalBlockSizeException,
BadPaddingException, NoSuchPaddingException, KeyStoreException, NoSuchProviderException {
String loadedKey = PreferenceManager.getDefaultSharedPreferences(context).getString("realmKey", "");
if (loadedKey.isEmpty()) {
loadedKey = createSecureRealmKey(context);
}
return decryptToByteArray(loadedKey);
}
// @RequiresApi(api = Build.VERSION_CODES.N)
// public static String createSecureRealmKey(Context context)
// throws IOException, CertificateException, NoSuchAlgorithmException, InvalidKeyException,
// UnrecoverableEntryException, InvalidAlgorithmParameterException, IllegalBlockSizeException,
// NoSuchProviderException, BadPaddingException, NoSuchPaddingException, KeyStoreException {
// byte[] realmkey = new byte[RealmConfiguration.KEY_LENGTH];
// new SecureRandom().nextBytes(realmkey);
// return encrypt(context, realmkey);
// }
//
// // disable in manifest allowBackUp = true for encryption
// @RequiresApi(api = Build.VERSION_CODES.N)
// public static byte[] getRealmKey(Context context)
// throws IOException, CertificateException, NoSuchAlgorithmException, InvalidKeyException,
// UnrecoverableEntryException, InvalidAlgorithmParameterException, IllegalBlockSizeException,
// BadPaddingException, NoSuchPaddingException, KeyStoreException, NoSuchProviderException {
// String loadedKey = PreferenceManager.getDefaultSharedPreferences(context).getString("realmKey", "");
// if (loadedKey.isEmpty()) {
// loadedKey = createSecureRealmKey(context);
// }
// return decryptToByteArray(loadedKey);
// }
}
6 changes: 0 additions & 6 deletions usecases/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-allopen'
apply plugin: 'realm-android'
apply plugin: "net.ltgt.errorprone"

android {
Expand Down Expand Up @@ -67,8 +66,6 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
//Job Dispatcher
implementation 'com.firebase:firebase-jobdispatcher:0.7.0'
// Network
implementation "com.squareup.retrofit2:retrofit:$retrofit"
implementation "com.squareup.retrofit2:converter-gson:$retrofit"
Expand All @@ -78,9 +75,6 @@ dependencies {
implementation "com.android.support:support-annotations:$supportLibrary"

implementation "android.arch.persistence.room:runtime:$room_version"
annotationProcessor "android.arch.persistence.room:compiler:$room_version"
implementation "android.arch.persistence.room:rxjava2:$room_version"
testImplementation "android.arch.persistence.room:testing:$room_version"

// Rx
api 'io.reactivex.rxjava2:rxandroid:2.1.0'
Expand Down
Loading

0 comments on commit 2476f12

Please sign in to comment.