Skip to content

Commit

Permalink
update with SQLDelight working ( except JS)
Browse files Browse the repository at this point in the history
  • Loading branch information
a187839 committed Dec 1, 2023
1 parent 041d865 commit 09e6919
Show file tree
Hide file tree
Showing 5 changed files with 336 additions and 2 deletions.
Binary file added docs/src/assets/images/diagramme_sql.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
180 changes: 178 additions & 2 deletions docs/src/database/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,189 @@ It generates typesafe code for any labeled SQL statements.

::: warning

This section is under construction
> Stay tuned for an update.
Be carefull with SQL Delight , the project and his dependancies just move from `com.squareup.sqldelight.*`
to `app.cash.sqldelight.*`

Pay attention also with beta, alpha version of Android studio that could produce bugs on gradle task management for code generation of SQL Delight databases.
:::




## 🧪 add and use your sqldelight database to your quizz to retrieve network only if you your quizz data are older than 5 minutes

> Refer to the multiplatform implementation of SQLDelight in official Github pages
> 👉 https://cashapp.github.io/sqldelight/2.0.0/multiplatform_sqlite/

#### Add the correct dependancies to the project
``` kotlin
plugins {
...
id("app.cash.sqldelight") version "2.0.0"
}
...
sourceSets {
val commonMain by getting {
dependencies {
...
implementation("app.cash.sqldelight:runtime:2.0.0")
implementation("app.cash.sqldelight:coroutines-extensions:2.0.0")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.1")

}
}
val androidMain by getting {
dependencies {
...
implementation("app.cash.sqldelight:android-driver:2.0.0")

}
}
...
val iosMain by creating {
...
dependencies {
...
implementation("app.cash.sqldelight:native-driver:2.0.0")
}
}
val desktopMain by getting {
dependencies {
...
implementation("app.cash.sqldelight:sqlite-driver:2.0.0")
}
}
...
```
#### Create the native SQL driver factory and use it for creating the DB with `actual`/`expect` kotlin keywords

#### Read carefully the modelisation UML below

![diagram SQL ](../assets/images/diagramme_sql.png)

#### Create you SQLDelight model 'QuizDatabase.sq'

::: details QuizDatabase.sq (ressources of commonMain)*

```sql
CREATE TABLE update_time (
timestamprequest INTEGER
);

INSERT INTO update_time(timestamprequest) VALUES (0);

CREATE TABLE questions (
id INTEGER PRIMARY KEY,
label TEXT NOT NULL,
correctAnswerId INTEGER NOT NULL
);

CREATE TABLE answers (
id INTEGER NOT NULL,
label TEXT NOT NULL,
question_id INTEGER NOT NULL,
PRIMARY KEY (id, question_id),
FOREIGN KEY (question_id)
REFERENCES questions (id)
ON UPDATE CASCADE
ON DELETE CASCADE
);

selectUpdateTimestamp:
SELECT *
FROM update_time;

insertTimeStamp:
INSERT INTO update_time(timestamprequest)
VALUES (:timestamp);

deleteTimeStamp:
DELETE FROM update_time;

deleteQuestions:
DELETE FROM questions;

deleteAnswers:
DELETE FROM answers;

selectAllQuestions:
SELECT *
FROM questions;

selectAllAnswersFromQuestion:
SELECT *
FROM answers
WHERE question_id = :questionId;

insertQuestion:
INSERT INTO questions(id, label,correctAnswerId)
VALUES (?, ?, ?);

insertAnswer:
INSERT INTO answers(id, label,question_id)
VALUES (?, ?, ?);
```
:::

#### Create your Database datasource by generating insert and update suspending functions

::: details network/QuizDB.kt (commonMain)
``` kotlin
package network

import app.cash.sqldelight.db.SqlDriver
import com.myapplication.common.cache.Database
import com.myapplication.common.cache.QuizDatabaseQueries
import network.data.Answer
import network.data.Question

class QuizDB(sqlDriver: SqlDriver) {

private val database = Database(sqlDriver)
private val quizQueries: QuizDatabaseQueries = database.quizDatabaseQueries

suspend fun getUpdateTimeStamp():Long = quizQueries.selectUpdateTimestamp().executeAsOneOrNull()?.timestamprequest ?: 0L

suspend fun setUpdateTimeStamp(timeStamp:Long) {
quizQueries.deleteTimeStamp()
quizQueries.insertTimeStamp(timeStamp)
}

suspend fun getAllQuestions() = quizQueries.selectAllQuestions(
mapper = { id, label, correctAnswer ->
Question(id,label,correctAnswer,getAnswersByQuestionId(id)
)
}).executeAsList()

private fun getAnswersByQuestionId(idQuestion:Long) = quizQueries.selectAllAnswersFromQuestion(
questionId = idQuestion,
mapper = { id, label, _ ->
Answer(id, label)
}).executeAsList()

suspend fun insertQuestions(questions:List<Question>) {
quizQueries.deleteQuestions();
quizQueries.deleteAnswers()
questions.forEach {question ->
quizQueries.insertQuestion(question.id, question.label, question.correctAnswerId)
question.answers.forEach {answer ->
quizQueries.insertAnswer(answer.id,answer.label,question.id)
}
}
}
}
```
:::

#### Update your repository by instanciating your database

Your repository handle the following cases :
* If there is no network and it's the first time launch of the app : handle and error
* if there is no network and you have db datas : return on the flow the db data
* if there is network and db data are younger than 5 min : return on the flow the db data
* if there is network and db data are older than 5 min : retourn on the flow the network data and reset db data
## 🎯 Solutions
::: tip
Expand Down
68 changes: 68 additions & 0 deletions others/KMP plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
Prerequisites : POO, Developper tools knowledges (Git, Linux Shell, IDE)

🚀 Presentation of Kotlin
Some features
History
Some numbers and facts
Why switch from Java to Kotlin
Prerequisites

Kotlin language features

Basic features
Basic constructs (variables, control flow)
Functions
Null safety
Enumerations

Intermediate features
Object oriented programming
Data class
Functional programming
Kotlin and Java interoperability

Let's start kotlin multiplatform
Prerequisites
IDE support overview
KMP roadmap
Hands-on Lab objectives
Functionnally
Technically
Design screens

Configure a KMP project
🧪 Plugins installation
🧪 Clone the KMP template provided by JetBrains
📚 A Guided tour of the sample project
🧪 Deploy your apps

User interface
📚 Reminder
Compose Multiplatform
How to create composables ?
Create composable for the Quiz
🧪 WelcomeScreen
🧪 ScoreScreen
🧪 QuestionScreen

Connectivity
📚 Reminder
Data layer for KMP
Kotlin flow
Coroutine
Connect my Quizz to the internet
🧪 Ktor as a multiplatform HTTP client
👷‍♂️ Ktor as a rest API server
🧪 Create a Ktor server module inside your actual

Database & Datastore preferences
🧪 add and use your sqldelight database to your quizz to retrieve network only if you your quizz data are older than 5 minutes

Let's go further
🧪 Create Navigation between composable screens
🎯 Solutions
👷‍♂️ Manage your ressources
👷‍♂️ Integrate a JS Web target



Binary file added others/Keys of quizzes with answers.docx
Binary file not shown.
90 changes: 90 additions & 0 deletions others/Quizz.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
Which components can be shared across platforms in Kotlin Multiplatform projects?
UI logic
Business logic
Data models
Networking code
Utility functions


Name some popular libraries/frameworks compatible with Kotlin Multiplatform.
Ktor
kotlinx.serialization
SQLDelight
kotlinx.coroutines


How does Kotlin Multiplatform handle platform-specific implementations?
Through expected and actual declarations
Expected declarations define an interface or contract
Actual declarations provide platform-specific implementations


What tools or IDE support is available for Kotlin Multiplatform development?
IntelliJ IDEA with Kotlin plugin
Android Studio
Visual Studio Code with Kotlin extension
jetbrain Fleet


What is the level of maturity or adoption of Kotlin Multiplatform in the development community?
Multiplatform is stable, ready for production
Multiplatform is not stable, not for production
Compose is not stable, not for production
Compose is stable, ready for production


1. **Which of the following best describes the primary advantage of using Ktor's HttpClient?**

a) Synchronous processing of HTTP requests
b) Integration only with Android platforms
c) Asynchronous and non-blocking by default <--
d) Exclusive support for RESTful APIs


**How do you typically perform a GET request using Ktor's HttpClient?**

a) `get()` <--
b) `sendRequest(HttpMethod.Get)`
c) `performGET()`
d) `executeRequest(Method.GET)`


**What is the purpose of `MutableState` in Jetpack Compose?**

a) To manage global application state
b) To retain state within a composable and trigger recomposition
c) To handle lifecycle events in composables
d) To store read-only state



**Which function is used to create and manage mutable state in Jetpack Compose?**

a) `stateOf()`
b) `mutableStateOf()` <--
c) `composeState()`
d) `createState()`



5. **What is Kotlin Flows
a) Flows is a multithreading framework library for kotlin
b) Flows are built on Kotlin coroutines, supporting sequential asynchronous processing <--
c) Flows are synchronous
d) Flows are limited to Android development only


6. **Which operator is commonly used to transform data emitted by a Kotlin Flow?**

a) `map()` <--
b) `switchMap()`
c) `flatMap()`
d) `transform()`


What role does `CoroutineScope` play in managing coroutines?**

a) It determines the Thread used for asynchronous execusion thanks to Dispatcher <--
c) It defines the lifecycle of the application
d) It specifies the UI thread for coroutine execution

0 comments on commit 09e6919

Please sign in to comment.