From 3f4ff4aba4f0e1dec915f81b1dbb5055d0e12fcc Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Tue, 10 Dec 2024 23:13:12 +0300 Subject: [PATCH] migrate realmMyCourse and course progress --- .../myplanet/model/RealmCourseProgress.kt | 203 +++--- .../planet/myplanet/model/RealmMyCourse.kt | 641 ++++++++++++------ 2 files changed, 559 insertions(+), 285 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseProgress.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseProgress.kt index a4f6884757..3c85633474 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseProgress.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmCourseProgress.kt @@ -2,9 +2,20 @@ package org.ole.planet.myplanet.model import com.google.gson.JsonObject import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmObject -import io.realm.annotations.PrimaryKey +import io.realm.kotlin.Realm +import io.realm.kotlin.RealmConfiguration +import io.realm.kotlin.ext.query +import io.realm.kotlin.ext.realmListOf +import io.realm.kotlin.query.Sort +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.toList import org.ole.planet.myplanet.MainApplication.Companion.context import org.ole.planet.myplanet.model.RealmMyCourse.Companion.getCourseSteps import org.ole.planet.myplanet.model.RealmMyCourse.Companion.getMyCourseByUserId @@ -14,124 +25,124 @@ import java.io.File import java.io.FileWriter import java.io.IOException -open class RealmCourseProgress : RealmObject() { +class RealmCourseProgress : RealmObject { @PrimaryKey - var id: String? = null - var _id: String? = null - var createdOn: String? = null + var id: String = "" + var _id: String = "" + var createdOn: String = "" var createdDate: Long = 0 var updatedDate: Long = 0 - var _rev: String? = null - var stepNum = 0 - var passed = false - var userId: String? = null - var courseId: String? = null - var parentCode: String? = null + var _rev: String = "" + var stepNum: Int = 0 + var passed: Boolean = false + var userId: String = "" + var courseId: String = "" + var parentCode: String = "" companion object { - val progressDataList: MutableList> = mutableListOf() - @JvmStatic + private val progressDataList = mutableListOf>() + fun serializeProgress(progress: RealmCourseProgress): JsonObject { - val `object` = JsonObject() - `object`.addProperty("userId", progress.userId) - `object`.addProperty("parentCode", progress.parentCode) - `object`.addProperty("courseId", progress.courseId) - `object`.addProperty("passed", progress.passed) - `object`.addProperty("stepNum", progress.stepNum) - `object`.addProperty("createdOn", progress.createdOn) - `object`.addProperty("createdDate", progress.createdDate) - `object`.addProperty("updatedDate", progress.updatedDate) - return `object` + return JsonObject().apply { + addProperty("userId", progress.userId) + addProperty("parentCode", progress.parentCode) + addProperty("courseId", progress.courseId) + addProperty("passed", progress.passed) + addProperty("stepNum", progress.stepNum) + addProperty("createdOn", progress.createdOn) + addProperty("createdDate", progress.createdDate) + addProperty("updatedDate", progress.updatedDate) + } } - @JvmStatic - fun getCourseProgress(mRealm: Realm, userId: String?): HashMap { - val r = getMyCourseByUserId(userId, mRealm.where(RealmMyCourse::class.java).findAll()) - val map = HashMap() - for (course in r) { - val `object` = JsonObject() - val steps = getCourseSteps(mRealm, course.courseId) - `object`.addProperty("max", steps.size) - `object`.addProperty("current", getCurrentProgress(steps, mRealm, userId, course.courseId)) - if (isMyCourse(userId, course.courseId, mRealm)) map[course.courseId] = `object` + suspend fun getCourseProgress(realm: Realm, userId: String): Flow> { + return getMyCourseByUserId(userId).map { courses -> + courses.map { course -> + getCourseSteps(course.courseId).first().let { steps -> + if (isMyCourse(userId, course.courseId)) { + course.courseId to JsonObject().apply { + addProperty("max", steps.size) + addProperty("current", getCurrentProgress(steps, realm, userId, course.courseId)) + } + } else null + } + }.filterNotNull().toMap() } - return map } -// @JvmStatic -// fun getPassedCourses(mRealm: Realm, userId: String?): List { -// val progresses = mRealm.where(RealmCourseProgress::class.java).equalTo("userId", userId).equalTo("passed", true).findAll() -// val list: MutableList = ArrayList() -// for (progress in progresses) { -// Utilities.log("Course id certified " + progress.courseId) -// val sub = progress.courseId?.let { -// mRealm.where(RealmSubmission::class.java) -// .contains("parentId", it).equalTo("userId", userId) -// .sort("lastUpdateTime", Sort.DESCENDING).findFirst() +// fun getPassedCourses(realm: Realm, userId: String): Flow> { +// return realm.query("userId == $0 AND passed == true", userId) +// .asFlow() +// .map { progresses -> +// progresses.list.mapNotNull { progress -> +// realm.query("parentId CONTAINS $0 AND userId == $1", +// progress.courseId, userId).sort("lastUpdateTime", Sort.DESCENDING) +// .first().find() +// } // } -// if (sub != null) list.add(sub) -// } -// return list // } - @JvmStatic - fun getCurrentProgress(steps: List?, mRealm: Realm, userId: String?, courseId: String?): Int { - var i = 0 - while (i < (steps?.size ?: 0)) { - mRealm.where(RealmCourseProgress::class.java).equalTo("stepNum", i + 1).equalTo("userId", userId).equalTo("courseId", courseId) - .findFirst() - ?: break - i++ + fun getCurrentProgress(steps: List, realm: Realm, userId: String, courseId: String): Int { + var currentStep = 0 + while (currentStep < steps.size) { + val progress = realm.query( + "stepNum == $0 AND userId == $1 AND courseId == $2", currentStep + 1, userId, courseId + ).first().find() ?: break + currentStep++ } - return i + return currentStep } - @JvmStatic - fun insert(mRealm: Realm, act: JsonObject?) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - var courseProgress = mRealm.where(RealmCourseProgress::class.java).equalTo("_id", JsonUtils.getString("_id", act)).findFirst() - if (courseProgress == null) { - courseProgress = mRealm.createObject(RealmCourseProgress::class.java, JsonUtils.getString("_id", act)) - } - courseProgress?._rev = JsonUtils.getString("_rev", act) - courseProgress?._id = JsonUtils.getString("_id", act) - courseProgress?.passed = JsonUtils.getBoolean("passed", act) - courseProgress?.stepNum = JsonUtils.getInt("stepNum", act) - courseProgress?.userId = JsonUtils.getString("userId", act) - courseProgress?.parentCode = JsonUtils.getString("parentCode", act) - courseProgress?.courseId = JsonUtils.getString("courseId", act) - courseProgress?.createdOn = JsonUtils.getString("createdOn", act) - courseProgress?.createdDate = JsonUtils.getLong("createdDate", act) - courseProgress?.updatedDate = JsonUtils.getLong("updatedDate", act) - mRealm.commitTransaction() + suspend fun insert(realm: Realm, act: JsonObject) { + realm.write { + val courseProgress = query("_id == $0", + JsonUtils.getString("_id", act)).first().find() + ?: RealmCourseProgress().apply { + id = JsonUtils.getString("_id", act) + } + + copyToRealm(courseProgress.apply { + _rev = JsonUtils.getString("_rev", act) + _id = JsonUtils.getString("_id", act) + passed = JsonUtils.getBoolean("passed", act) + stepNum = JsonUtils.getInt("stepNum", act) + userId = JsonUtils.getString("userId", act) + parentCode = JsonUtils.getString("parentCode", act) + courseId = JsonUtils.getString("courseId", act) + createdOn = JsonUtils.getString("createdOn", act) + createdDate = JsonUtils.getLong("createdDate", act) + updatedDate = JsonUtils.getLong("updatedDate", act) + }) - val csvRow = arrayOf( - JsonUtils.getString("_id", act), - JsonUtils.getString("_rev", act), - JsonUtils.getBoolean("passed", act).toString(), - JsonUtils.getInt("stepNum", act).toString(), - JsonUtils.getString("userId", act), - JsonUtils.getString("parentCode", act), - JsonUtils.getString("courseId", act), - JsonUtils.getString("createdOn", act), - JsonUtils.getLong("createdDate", act).toString(), - JsonUtils.getLong("updatedDate", act).toString() - ) - progressDataList.add(csvRow) + val csvRow = arrayOf( + JsonUtils.getString("_id", act), + JsonUtils.getString("_rev", act), + JsonUtils.getBoolean("passed", act).toString(), + JsonUtils.getInt("stepNum", act).toString(), + JsonUtils.getString("userId", act), + JsonUtils.getString("parentCode", act), + JsonUtils.getString("courseId", act), + JsonUtils.getString("createdOn", act), + JsonUtils.getLong("createdDate", act).toString(), + JsonUtils.getLong("updatedDate", act).toString() + ) + progressDataList.add(csvRow) + } } fun writeCsv(filePath: String, data: List>) { try { val file = File(filePath) file.parentFile?.mkdirs() - val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("progressId", "progress_rev", "passed", "stepNum", "userId", "parentCode", "courseId", "createdOn", "createdDate", "updatedDate")) - for (row in data) { - writer.writeNext(row) + CSVWriter(FileWriter(file)).use { writer -> + writer.writeNext(arrayOf( + "progressId", "progress_rev", "passed", "stepNum", "userId", "parentCode", + "courseId", "createdOn", "createdDate", "updatedDate" + )) + data.forEach { row -> + writer.writeNext(row) + } } - writer.close() } catch (e: IOException) { e.printStackTrace() } diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt index ca760df965..73a4df6de3 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyCourse.kt @@ -8,136 +8,118 @@ import com.google.gson.Gson import com.google.gson.JsonArray import com.google.gson.JsonObject import com.opencsv.CSVWriter -import io.realm.Realm -import io.realm.RealmList -import io.realm.RealmObject -import io.realm.RealmResults -import io.realm.annotations.PrimaryKey -import io.realm.kotlin.where +import io.realm.kotlin.Realm +import io.realm.kotlin.ext.query +import io.realm.kotlin.ext.realmListOf +import io.realm.kotlin.types.RealmList +import io.realm.kotlin.types.RealmObject +import io.realm.kotlin.types.annotations.PrimaryKey +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.ole.planet.myplanet.MainApplication.Companion.context import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.createStepResource import org.ole.planet.myplanet.model.RealmStepExam.Companion.insertCourseStepsExams import org.ole.planet.myplanet.utilities.Constants.PREFS_NAME -import org.ole.planet.myplanet.utilities.DownloadUtils.extractLinks import org.ole.planet.myplanet.utilities.JsonUtils -import org.ole.planet.myplanet.utilities.Utilities import java.io.File import java.io.FileWriter import java.io.IOException -open class RealmMyCourse : RealmObject() { +class RealmMyCourse : RealmObject { @PrimaryKey - var id: String? = null - var userId: RealmList? = null - private set - var courseId: String? = null - var courseRev: String? = null - var languageOfInstruction: String? = null - var courseTitle: String? = null - var memberLimit: Int? = null - var description: String? = null - var method: String? = null - var gradeLevel: String? = null - var subjectLevel: String? = null + var id: String = "" + var userId: RealmList = realmListOf() + var courseId: String = "" + var courseRev: String = "" + var languageOfInstruction: String = "" + var courseTitle: String = "" + var memberLimit: Int = 0 + var description: String = "" + var method: String = "" + var gradeLevel: String = "" + var subjectLevel: String = "" var createdDate: Long = 0 - private var numberOfSteps: Int? = null - var courseSteps: RealmList? = null + private var numberOfSteps: Int = 0 + var courseSteps: RealmList = realmListOf() + @Transient var isMyCourse: Boolean = false - fun setUserId(userId: String?) { - if (this.userId == null) { - this.userId = RealmList() - } - if (!this.userId?.contains(userId)!! && !TextUtils.isEmpty(userId)) { - this.userId?.add(userId) + + fun addUserId(userId: String) { + if (!TextUtils.isEmpty(userId) && !this.userId.contains(userId)) { + this.userId.add(userId) } } - fun removeUserId(userId: String?) { - this.userId?.remove(userId) + fun removeUserId(userId: String) { + this.userId.remove(userId) } - fun getNumberOfSteps(): Int { - return numberOfSteps ?: 0 - } + fun getNumberOfSteps(): Int = numberOfSteps - fun setNumberOfSteps(numberOfSteps: Int?) { - this.numberOfSteps = numberOfSteps + fun setNumberOfSteps(steps: Int) { + numberOfSteps = steps } - override fun toString(): String { - return courseTitle ?: "" - } + override fun toString(): String = courseTitle companion object { private val gson = Gson() private val concatenatedLinks = ArrayList() val courseDataList: MutableList> = mutableListOf() - @JvmStatic - fun insertMyCourses(userId: String?, myCoursesDoc: JsonObject?, mRealm: Realm) { - context.getSharedPreferences(PREFS_NAME, MODE_PRIVATE) - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() - } - val id = JsonUtils.getString("_id", myCoursesDoc) - var myMyCoursesDB = mRealm.where(RealmMyCourse::class.java).equalTo("id", id).findFirst() - if (myMyCoursesDB == null) { - myMyCoursesDB = mRealm.createObject(RealmMyCourse::class.java, id) - } - myMyCoursesDB?.setUserId(userId) - myMyCoursesDB?.courseId = JsonUtils.getString("_id", myCoursesDoc) - myMyCoursesDB?.courseRev = JsonUtils.getString("_rev", myCoursesDoc) - myMyCoursesDB?.languageOfInstruction = JsonUtils.getString("languageOfInstruction", myCoursesDoc) - myMyCoursesDB?.courseTitle = JsonUtils.getString("courseTitle", myCoursesDoc) - myMyCoursesDB?.memberLimit = JsonUtils.getInt("memberLimit", myCoursesDoc) - myMyCoursesDB?.description = JsonUtils.getString("description", myCoursesDoc) - val description = JsonUtils.getString("description", myCoursesDoc) - val links = extractLinks(description) - val baseUrl = Utilities.getUrl() - for (link in links) { - val concatenatedLink = "$baseUrl/$link" - concatenatedLinks.add(concatenatedLink) - } - myMyCoursesDB?.method = JsonUtils.getString("method", myCoursesDoc) - myMyCoursesDB?.gradeLevel = JsonUtils.getString("gradeLevel", myCoursesDoc) - myMyCoursesDB?.subjectLevel = JsonUtils.getString("subjectLevel", myCoursesDoc) - myMyCoursesDB?.createdDate = JsonUtils.getLong("createdDate", myCoursesDoc) - myMyCoursesDB?.setNumberOfSteps(JsonUtils.getJsonArray("steps", myCoursesDoc).size()) - val courseStepsJsonArray = JsonUtils.getJsonArray("steps", myCoursesDoc) - val courseStepsList = mutableListOf() - - for (i in 0 until courseStepsJsonArray.size()) { - val stepId = Base64.encodeToString(courseStepsJsonArray[i].toString().toByteArray(), Base64.NO_WRAP) - val stepJson = courseStepsJsonArray[i].asJsonObject - val step = RealmCourseStep() - step.id = stepId - step.stepTitle = JsonUtils.getString("stepTitle", stepJson) - step.description = JsonUtils.getString("description", stepJson) - val stepDescription = JsonUtils.getString("description", stepJson) - val stepLinks = extractLinks(stepDescription) - for (stepLink in stepLinks) { - val concatenatedLink = "$baseUrl/$stepLink" - concatenatedLinks.add(concatenatedLink) + fun insertMyCourses(userId: String, myCoursesDoc: JsonObject, realm: Realm) { + CoroutineScope(Dispatchers.IO).launch { + val ID = JsonUtils.getString("_id", myCoursesDoc) + realm.writeBlocking { + var myMyCourseDB = this.query("id == $0", ID).first().find() + + if (myMyCourseDB == null) { + myMyCourseDB = RealmMyCourse().apply { this.id = ID } + copyToRealm(myMyCourseDB) + } + + myMyCourseDB.apply { + addUserId(userId) + courseId = JsonUtils.getString("_id", myCoursesDoc) + courseRev = JsonUtils.getString("_rev", myCoursesDoc) + languageOfInstruction = JsonUtils.getString("languageOfInstruction", myCoursesDoc) + courseTitle = JsonUtils.getString("courseTitle", myCoursesDoc) + memberLimit = JsonUtils.getInt("memberLimit", myCoursesDoc) + description = JsonUtils.getString("description", myCoursesDoc) + method = JsonUtils.getString("method", myCoursesDoc) + gradeLevel = JsonUtils.getString("gradeLevel", myCoursesDoc) + subjectLevel = JsonUtils.getString("subjectLevel", myCoursesDoc) + createdDate = JsonUtils.getLong("createdDate", myCoursesDoc) + setNumberOfSteps(JsonUtils.getJsonArray("steps", myCoursesDoc).size()) + + courseSteps.clear() + } } - insertCourseStepsAttachments(myMyCoursesDB?.courseId, stepId, JsonUtils.getJsonArray("resources", stepJson), mRealm) - insertExam(stepJson, mRealm, stepId, i + 1, myMyCoursesDB?.courseId) - insertSurvey(stepJson, mRealm, stepId, i + 1, myMyCoursesDB?.courseId, myMyCoursesDB?.createdDate) - step.noOfResources = JsonUtils.getJsonArray("resources", stepJson).size() - step.courseId = myMyCoursesDB?.courseId - courseStepsList.add(step) - } - if (mRealm.isInTransaction) { - mRealm.commitTransaction() - } + val courseStepsJsonArray = JsonUtils.getJsonArray("steps", myCoursesDoc) + + for (i in 0 until courseStepsJsonArray.size()) { + val stepJson = courseStepsJsonArray[i].asJsonObject + val stepId = Base64.encodeToString(stepJson.toString().toByteArray(), Base64.NO_WRAP) - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() + realm.writeBlocking { + val step = RealmCourseStep().apply { + id = stepId + stepTitle = JsonUtils.getString("stepTitle", stepJson) + description = JsonUtils.getString("description", stepJson) + courseId = ID + noOfResources = JsonUtils.getJsonArray("resources", stepJson).size() + } + copyToRealm(step) + } + + // Safely call suspend functions + insertExam(stepJson, realm, stepId, i + 1, ID) + insertSurvey(stepJson, realm, stepId, i + 1, ID, JsonUtils.getLong("createdDate", myCoursesDoc)) + } } - myMyCoursesDB?.courseSteps = RealmList() - myMyCoursesDB?.courseSteps?.addAll(courseStepsList) - mRealm.commitTransaction() val csvRow = arrayOf( JsonUtils.getString("_id", myCoursesDoc), @@ -159,12 +141,14 @@ open class RealmMyCourse : RealmObject() { try { val file = File(filePath) file.parentFile?.mkdirs() - val writer = CSVWriter(FileWriter(file)) - writer.writeNext(arrayOf("courseId", "course_rev", "languageOfInstruction", "courseTitle", "memberLimit", "description", "method", "gradeLevel", "subjectLevel", "createdDate", "steps")) - for (row in data) { - writer.writeNext(row) + CSVWriter(FileWriter(file)).use { writer -> + writer.writeNext(arrayOf( + "courseId", "course_rev", "languageOfInstruction", + "courseTitle", "memberLimit", "description", "method", + "gradeLevel", "subjectLevel", "createdDate", "steps" + )) + data.forEach { writer.writeNext(it) } } - writer.close() } catch (e: IOException) { e.printStackTrace() } @@ -174,132 +158,411 @@ open class RealmMyCourse : RealmObject() { writeCsv("${context.getExternalFilesDir(null)}/ole/course.csv", courseDataList) } - @JvmStatic fun saveConcatenatedLinksToPrefs() { val settings: SharedPreferences = context.getSharedPreferences(PREFS_NAME, MODE_PRIVATE) val existingJsonLinks = settings.getString("concatenated_links", null) - val existingConcatenatedLinks = if (existingJsonLinks != null) { - gson.fromJson(existingJsonLinks, Array::class.java).toMutableList() - } else { - mutableListOf() - } - val linksToProcess: List + val existingConcatenatedLinks = existingJsonLinks?.let { + gson.fromJson(it, Array::class.java).toMutableList() + } ?: mutableListOf() + synchronized(concatenatedLinks) { - linksToProcess = concatenatedLinks.toList() - } - for (link in linksToProcess) { - if (!existingConcatenatedLinks.contains(link)) { - existingConcatenatedLinks.add(link) + concatenatedLinks.forEach { link -> + if (!existingConcatenatedLinks.contains(link)) { + existingConcatenatedLinks.add(link) + } } } - val jsonConcatenatedLinks = gson.toJson(existingConcatenatedLinks) - settings.edit().putString("concatenated_links", jsonConcatenatedLinks).apply() + + settings.edit().putString("concatenated_links", gson.toJson(existingConcatenatedLinks)).apply() } - fun getCourseSteps(mRealm: Realm, courseId: String?): List { - val myCourse = mRealm.where().equalTo("id", courseId).findFirst() - val courseSteps = myCourse?.courseSteps ?: emptyList() - return courseSteps + fun getCourseSteps(realm: Realm, courseId: String): List { + return realm.query("id == $0", courseId).first().find()?.courseSteps?.toList() + ?: emptyList() } - fun getCourseStepIds(mRealm: Realm, courseId: String?): Array { - val course = mRealm.where().equalTo("courseId", courseId).findFirst() - val stepIds = course?.courseSteps?.map { it.id }?.toTypedArray() ?: emptyArray() - return stepIds + fun getCourseStepIds(realm: Realm, courseId: String): Array { + return realm.query("courseId == $0", courseId).first().find()?.courseSteps?.map { it.id }?.toTypedArray() ?: emptyArray() } - private fun insertExam(stepContainer: JsonObject, mRealm: Realm, stepId: String, i: Int, myCoursesID: String?) { + private suspend fun insertExam(stepContainer: JsonObject, realm: Realm, stepId: String, stepNumber: Int, courseId: String) { if (stepContainer.has("exam")) { - val `object` = stepContainer.getAsJsonObject("exam") - `object`.addProperty("stepNumber", i) - insertCourseStepsExams(myCoursesID, stepId, `object`, mRealm) + val examObject = stepContainer.getAsJsonObject("exam").apply { + addProperty("stepNumber", stepNumber) + } + insertCourseStepsExams(courseId, stepId, examObject, realm) } } - private fun insertSurvey(stepContainer: JsonObject, mRealm: Realm, stepId: String, i: Int, myCoursesID: String?, createdDate: Long?) { + private suspend fun insertSurvey(stepContainer: JsonObject, realm: Realm, stepId: String, stepNumber: Int, courseId: String, createdDate: Long) { if (stepContainer.has("survey")) { - val `object` = stepContainer.getAsJsonObject("survey") - `object`.addProperty("stepNumber", i) - `object`.addProperty("createdDate", createdDate) - insertCourseStepsExams(myCoursesID, stepId, `object`, mRealm) + val surveyObject = stepContainer.getAsJsonObject("survey").apply { + addProperty("stepNumber", stepNumber) + addProperty("createdDate", createdDate) + } + insertCourseStepsExams(courseId, stepId, surveyObject, realm) } } - private fun insertCourseStepsAttachments(myCoursesID: String?, stepId: String?, resources: JsonArray, mRealm: Realm?) { + private fun insertCourseStepsAttachments(courseId: String, stepId: String, resources: JsonArray, realm: Realm) { resources.forEach { resource -> - if (mRealm != null) { - createStepResource(mRealm, resource.asJsonObject, myCoursesID, stepId) - } + createStepResource(realm, resource.asJsonObject, courseId, stepId) } } - @JvmStatic - fun getMyByUserId(mRealm: Realm, settings: SharedPreferences?): RealmResults { - val userId = settings?.getString("userId", "--") - return mRealm.where(RealmMyCourse::class.java) - .equalTo("userId", userId) - .findAll() + fun getMyByUserId(realm: Realm, settings: SharedPreferences?): List { + val userId = settings?.getString("userId", "--") ?: return emptyList() + return realm.query("userId == $0", userId).find() } - @JvmStatic - fun getMyCourseByUserId(userId: String?, libs: List?): List { - val libraries: MutableList = ArrayList() - for (item in libs ?: emptyList()) { - if (item.userId?.contains(userId) == true) { - libraries.add(item) - } - } - return libraries + fun getMyCourseByUserId(userId: String, courses: List): List { + return courses.filter { course -> course.userId.contains(userId) } } - @JvmStatic - fun getOurCourse(userId: String?, libs: List): List { - val libraries: MutableList = ArrayList() - for (item in libs) { - if (!item.userId?.contains(userId)!!) { - libraries.add(item) - } - } - return libraries + fun getOurCourse(userId: String, courses: List): List { + return courses.filter { course -> !course.userId.contains(userId) } } - @JvmStatic - fun isMyCourse(userId: String?, courseId: String?, realm: Realm): Boolean { - return getMyCourseByUserId(userId, realm.where(RealmMyCourse::class.java).equalTo("courseId", courseId).findAll()).isNotEmpty() + fun isMyCourse(userId: String, courseId: String, realm: Realm): Boolean { + val courses = realm.query("courseId == $0", courseId).find() + return getMyCourseByUserId(userId, courses).isNotEmpty() } - @JvmStatic - fun getCourseByCourseId(courseId: String, mRealm: Realm): RealmMyCourse? { - return mRealm.where(RealmMyCourse::class.java).equalTo("courseId", courseId).findFirst() + fun getCourseByCourseId(courseId: String, realm: Realm): RealmMyCourse? { + return realm.query("courseId == $0", courseId).first().find() } - @JvmStatic - fun insert(mRealm: Realm, myCoursesDoc: JsonObject?) { - insertMyCourses("", myCoursesDoc, mRealm) + fun insert(realm: Realm, myCoursesDoc: JsonObject) { + insertMyCourses("", myCoursesDoc, realm) } - @JvmStatic - fun getMyCourse(mRealm: Realm, id: String?): RealmMyCourse? { - return mRealm.where(RealmMyCourse::class.java).equalTo("courseId", id).findFirst() + fun getMyCourse(realm: Realm, id: String): RealmMyCourse? { + return realm.query("courseId == $0", id).first().find() } - @JvmStatic - fun createMyCourse(course: RealmMyCourse?, mRealm: Realm, id: String?) { - if (!mRealm.isInTransaction) { - mRealm.beginTransaction() + fun createMyCourse(course: RealmMyCourse?, realm: Realm, id: String) { + realm.writeBlocking { + course?.addUserId(id) } - course?.setUserId(id) - mRealm.commitTransaction() } - @JvmStatic - fun getMyCourseIds(realm: Realm?, userId: String?): JsonArray { - val myCourses = getMyCourseByUserId(userId, realm?.where(RealmMyCourse::class.java)?.findAll()) - val ids = JsonArray() - for (lib in myCourses) { - ids.add(lib.courseId) + fun getMyCourseIds(realm: Realm?, userId: String): JsonArray { + val myCourses = realm?.let { + getMyCourseByUserId(userId, it.query().find()) + } ?: emptyList() + + return JsonArray().apply { + myCourses.forEach { course -> + add(course.courseId) + } } - return ids } } -} \ No newline at end of file +} + + +//package org.ole.planet.myplanet.model +// +//import android.content.Context.MODE_PRIVATE +//import android.content.SharedPreferences +//import android.text.TextUtils +//import android.util.Base64 +//import com.google.gson.Gson +//import com.google.gson.JsonArray +//import com.google.gson.JsonObject +//import com.opencsv.CSVWriter +//import io.realm.Realm +//import io.realm.RealmList +//import io.realm.RealmObject +//import io.realm.RealmResults +//import io.realm.annotations.PrimaryKey +//import io.realm.kotlin.where +//import org.ole.planet.myplanet.MainApplication.Companion.context +//import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.createStepResource +//import org.ole.planet.myplanet.model.RealmStepExam.Companion.insertCourseStepsExams +//import org.ole.planet.myplanet.utilities.Constants.PREFS_NAME +//import org.ole.planet.myplanet.utilities.DownloadUtils.extractLinks +//import org.ole.planet.myplanet.utilities.JsonUtils +//import org.ole.planet.myplanet.utilities.Utilities +//import java.io.File +//import java.io.FileWriter +//import java.io.IOException +// +//open class RealmMyCourse : RealmObject() { +// @PrimaryKey +// var id: String? = null +// var userId: RealmList? = null +// private set +// var courseId: String? = null +// var courseRev: String? = null +// var languageOfInstruction: String? = null +// var courseTitle: String? = null +// var memberLimit: Int? = null +// var description: String? = null +// var method: String? = null +// var gradeLevel: String? = null +// var subjectLevel: String? = null +// var createdDate: Long = 0 +// private var numberOfSteps: Int? = null +// var courseSteps: RealmList? = null +// @Transient +// var isMyCourse: Boolean = false +// fun setUserId(userId: String?) { +// if (this.userId == null) { +// this.userId = RealmList() +// } +// if (!this.userId?.contains(userId)!! && !TextUtils.isEmpty(userId)) { +// this.userId?.add(userId) +// } +// } +// +// fun removeUserId(userId: String?) { +// this.userId?.remove(userId) +// } +// +// fun getNumberOfSteps(): Int { +// return numberOfSteps ?: 0 +// } +// +// fun setNumberOfSteps(numberOfSteps: Int?) { +// this.numberOfSteps = numberOfSteps +// } +// +// override fun toString(): String { +// return courseTitle ?: "" +// } +// +// companion object { +// private val gson = Gson() +// private val concatenatedLinks = ArrayList() +// val courseDataList: MutableList> = mutableListOf() +// +// @JvmStatic +// fun insertMyCourses(userId: String?, myCoursesDoc: JsonObject?, mRealm: Realm) { +// context.getSharedPreferences(PREFS_NAME, MODE_PRIVATE) +// if (!mRealm.isInTransaction) { +// mRealm.beginTransaction() +// } +// val id = JsonUtils.getString("_id", myCoursesDoc) +// var myMyCoursesDB = mRealm.where(RealmMyCourse::class.java).equalTo("id", id).findFirst() +// if (myMyCoursesDB == null) { +// myMyCoursesDB = mRealm.createObject(RealmMyCourse::class.java, id) +// } +// myMyCoursesDB?.setUserId(userId) +// myMyCoursesDB?.courseId = JsonUtils.getString("_id", myCoursesDoc) +// myMyCoursesDB?.courseRev = JsonUtils.getString("_rev", myCoursesDoc) +// myMyCoursesDB?.languageOfInstruction = JsonUtils.getString("languageOfInstruction", myCoursesDoc) +// myMyCoursesDB?.courseTitle = JsonUtils.getString("courseTitle", myCoursesDoc) +// myMyCoursesDB?.memberLimit = JsonUtils.getInt("memberLimit", myCoursesDoc) +// myMyCoursesDB?.description = JsonUtils.getString("description", myCoursesDoc) +// val description = JsonUtils.getString("description", myCoursesDoc) +// val links = extractLinks(description) +// val baseUrl = Utilities.getUrl() +// for (link in links) { +// val concatenatedLink = "$baseUrl/$link" +// concatenatedLinks.add(concatenatedLink) +// } +// myMyCoursesDB?.method = JsonUtils.getString("method", myCoursesDoc) +// myMyCoursesDB?.gradeLevel = JsonUtils.getString("gradeLevel", myCoursesDoc) +// myMyCoursesDB?.subjectLevel = JsonUtils.getString("subjectLevel", myCoursesDoc) +// myMyCoursesDB?.createdDate = JsonUtils.getLong("createdDate", myCoursesDoc) +// myMyCoursesDB?.setNumberOfSteps(JsonUtils.getJsonArray("steps", myCoursesDoc).size()) +// val courseStepsJsonArray = JsonUtils.getJsonArray("steps", myCoursesDoc) +// val courseStepsList = mutableListOf() +// +// for (i in 0 until courseStepsJsonArray.size()) { +// val stepId = Base64.encodeToString(courseStepsJsonArray[i].toString().toByteArray(), Base64.NO_WRAP) +// val stepJson = courseStepsJsonArray[i].asJsonObject +// val step = RealmCourseStep() +// step.id = stepId +// step.stepTitle = JsonUtils.getString("stepTitle", stepJson) +// step.description = JsonUtils.getString("description", stepJson) +// val stepDescription = JsonUtils.getString("description", stepJson) +// val stepLinks = extractLinks(stepDescription) +// for (stepLink in stepLinks) { +// val concatenatedLink = "$baseUrl/$stepLink" +// concatenatedLinks.add(concatenatedLink) +// } +// insertCourseStepsAttachments(myMyCoursesDB?.courseId, stepId, JsonUtils.getJsonArray("resources", stepJson), mRealm) +// insertExam(stepJson, mRealm, stepId, i + 1, myMyCoursesDB?.courseId) +// insertSurvey(stepJson, mRealm, stepId, i + 1, myMyCoursesDB?.courseId, myMyCoursesDB?.createdDate) +// step.noOfResources = JsonUtils.getJsonArray("resources", stepJson).size() +// step.courseId = myMyCoursesDB?.courseId +// courseStepsList.add(step) +// } +// +// if (mRealm.isInTransaction) { +// mRealm.commitTransaction() +// } +// +// if (!mRealm.isInTransaction) { +// mRealm.beginTransaction() +// } +// myMyCoursesDB?.courseSteps = RealmList() +// myMyCoursesDB?.courseSteps?.addAll(courseStepsList) +// mRealm.commitTransaction() +// +// val csvRow = arrayOf( +// JsonUtils.getString("_id", myCoursesDoc), +// JsonUtils.getString("_rev", myCoursesDoc), +// JsonUtils.getString("languageOfInstruction", myCoursesDoc), +// JsonUtils.getString("courseTitle", myCoursesDoc), +// JsonUtils.getInt("memberLimit", myCoursesDoc).toString(), +// JsonUtils.getString("description", myCoursesDoc), +// JsonUtils.getString("method", myCoursesDoc), +// JsonUtils.getString("gradeLevel", myCoursesDoc), +// JsonUtils.getString("subjectLevel", myCoursesDoc), +// JsonUtils.getLong("createdDate", myCoursesDoc).toString(), +// JsonUtils.getJsonArray("steps", myCoursesDoc).toString() +// ) +// courseDataList.add(csvRow) +// } +// +// fun writeCsv(filePath: String, data: List>) { +// try { +// val file = File(filePath) +// file.parentFile?.mkdirs() +// val writer = CSVWriter(FileWriter(file)) +// writer.writeNext(arrayOf("courseId", "course_rev", "languageOfInstruction", "courseTitle", "memberLimit", "description", "method", "gradeLevel", "subjectLevel", "createdDate", "steps")) +// for (row in data) { +// writer.writeNext(row) +// } +// writer.close() +// } catch (e: IOException) { +// e.printStackTrace() +// } +// } +// +// fun courseWriteCsv() { +// writeCsv("${context.getExternalFilesDir(null)}/ole/course.csv", courseDataList) +// } +// +// @JvmStatic +// fun saveConcatenatedLinksToPrefs() { +// val settings: SharedPreferences = context.getSharedPreferences(PREFS_NAME, MODE_PRIVATE) +// val existingJsonLinks = settings.getString("concatenated_links", null) +// val existingConcatenatedLinks = if (existingJsonLinks != null) { +// gson.fromJson(existingJsonLinks, Array::class.java).toMutableList() +// } else { +// mutableListOf() +// } +// val linksToProcess: List +// synchronized(concatenatedLinks) { +// linksToProcess = concatenatedLinks.toList() +// } +// for (link in linksToProcess) { +// if (!existingConcatenatedLinks.contains(link)) { +// existingConcatenatedLinks.add(link) +// } +// } +// val jsonConcatenatedLinks = gson.toJson(existingConcatenatedLinks) +// settings.edit().putString("concatenated_links", jsonConcatenatedLinks).apply() +// } +// +// fun getCourseSteps(mRealm: Realm, courseId: String?): List { +// val myCourse = mRealm.where().equalTo("id", courseId).findFirst() +// val courseSteps = myCourse?.courseSteps ?: emptyList() +// return courseSteps +// } +// +// fun getCourseStepIds(mRealm: Realm, courseId: String?): Array { +// val course = mRealm.where().equalTo("courseId", courseId).findFirst() +// val stepIds = course?.courseSteps?.map { it.id }?.toTypedArray() ?: emptyArray() +// return stepIds +// } +// +// private fun insertExam(stepContainer: JsonObject, mRealm: Realm, stepId: String, i: Int, myCoursesID: String?) { +// if (stepContainer.has("exam")) { +// val `object` = stepContainer.getAsJsonObject("exam") +// `object`.addProperty("stepNumber", i) +// insertCourseStepsExams(myCoursesID, stepId, `object`, mRealm) +// } +// } +// +// private fun insertSurvey(stepContainer: JsonObject, mRealm: Realm, stepId: String, i: Int, myCoursesID: String?, createdDate: Long?) { +// if (stepContainer.has("survey")) { +// val `object` = stepContainer.getAsJsonObject("survey") +// `object`.addProperty("stepNumber", i) +// `object`.addProperty("createdDate", createdDate) +// insertCourseStepsExams(myCoursesID, stepId, `object`, mRealm) +// } +// } +// +// private fun insertCourseStepsAttachments(myCoursesID: String?, stepId: String?, resources: JsonArray, mRealm: Realm?) { +// resources.forEach { resource -> +// if (mRealm != null) { +// createStepResource(mRealm, resource.asJsonObject, myCoursesID, stepId) +// } +// } +// } +// +// @JvmStatic +// fun getMyByUserId(mRealm: Realm, settings: SharedPreferences?): RealmResults { +// val userId = settings?.getString("userId", "--") +// return mRealm.where(RealmMyCourse::class.java) +// .equalTo("userId", userId) +// .findAll() +// } +// +// @JvmStatic +// fun getMyCourseByUserId(userId: String?, libs: List?): List { +// val libraries: MutableList = ArrayList() +// for (item in libs ?: emptyList()) { +// if (item.userId?.contains(userId) == true) { +// libraries.add(item) +// } +// } +// return libraries +// } +// +// @JvmStatic +// fun getOurCourse(userId: String?, libs: List): List { +// val libraries: MutableList = ArrayList() +// for (item in libs) { +// if (!item.userId?.contains(userId)!!) { +// libraries.add(item) +// } +// } +// return libraries +// } +// +// @JvmStatic +// fun isMyCourse(userId: String?, courseId: String?, realm: Realm): Boolean { +// return getMyCourseByUserId(userId, realm.where(RealmMyCourse::class.java).equalTo("courseId", courseId).findAll()).isNotEmpty() +// } +// +// @JvmStatic +// fun getCourseByCourseId(courseId: String, mRealm: Realm): RealmMyCourse? { +// return mRealm.where(RealmMyCourse::class.java).equalTo("courseId", courseId).findFirst() +// } +// +// @JvmStatic +// fun insert(mRealm: Realm, myCoursesDoc: JsonObject?) { +// insertMyCourses("", myCoursesDoc, mRealm) +// } +// +// @JvmStatic +// fun getMyCourse(mRealm: Realm, id: String?): RealmMyCourse? { +// return mRealm.where(RealmMyCourse::class.java).equalTo("courseId", id).findFirst() +// } +// +// @JvmStatic +// fun createMyCourse(course: RealmMyCourse?, mRealm: Realm, id: String?) { +// if (!mRealm.isInTransaction) { +// mRealm.beginTransaction() +// } +// course?.setUserId(id) +// mRealm.commitTransaction() +// } +// +// @JvmStatic +// fun getMyCourseIds(realm: Realm?, userId: String?): JsonArray { +// val myCourses = getMyCourseByUserId(userId, realm?.where(RealmMyCourse::class.java)?.findAll()) +// val ids = JsonArray() +// for (lib in myCourses) { +// ids.add(lib.courseId) +// } +// return ids +// } +// } +//} \ No newline at end of file