1
0
Fork 1

Compare commits

..

No commits in common. "2.5.5" and "1.9.0" have entirely different histories.
2.5.5 ... 1.9.0

545 changed files with 7349 additions and 34652 deletions

4
.github/FUNDING.yml vendored
View file

@ -1,4 +0,0 @@
# These are supported funding model platforms
github: wulkanowy
custom: https://www.paypal.com/paypalme/wulkanowy

View file

@ -13,10 +13,10 @@ jobs:
environment: google-play environment: google-play
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/setup-java@v3 - uses: actions/setup-java@v2
with: with:
distribution: 'zulu' distribution: 'zulu'
java-version: 17 java-version: 11
- uses: actions/cache@v3 - uses: actions/cache@v3
with: with:
path: | path: |
@ -49,10 +49,10 @@ jobs:
environment: app-gallery environment: app-gallery
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/setup-java@v3 - uses: actions/setup-java@v2
with: with:
distribution: 'zulu' distribution: 'zulu'
java-version: 17 java-version: 11
- uses: actions/cache@v3 - uses: actions/cache@v3
with: with:
path: | path: |

View file

@ -19,10 +19,10 @@ jobs:
environment: app-center environment: app-center
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/setup-java@v3 - uses: actions/setup-java@v2
with: with:
distribution: 'zulu' distribution: 'zulu'
java-version: 17 java-version: 11
- uses: actions/cache@v3 - uses: actions/cache@v3
with: with:
path: | path: |
@ -89,10 +89,10 @@ jobs:
if: github.event_name != 'pull_request_target' if: github.event_name != 'pull_request_target'
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/setup-java@v3 - uses: actions/setup-java@v2
with: with:
distribution: 'zulu' distribution: 'zulu'
java-version: 17 java-version: 11
- uses: actions/cache@v3 - uses: actions/cache@v3
with: with:
path: | path: |

View file

@ -19,10 +19,10 @@ jobs:
- uses: fkirc/skip-duplicate-actions@master - uses: fkirc/skip-duplicate-actions@master
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@v1 - uses: gradle/wrapper-validation-action@v1
- uses: actions/setup-java@v3 - uses: actions/setup-java@v2
with: with:
distribution: 'zulu' distribution: 'zulu'
java-version: 17 java-version: 11
- uses: actions/cache@v3 - uses: actions/cache@v3
with: with:
path: | path: |
@ -45,10 +45,10 @@ jobs:
- uses: fkirc/skip-duplicate-actions@master - uses: fkirc/skip-duplicate-actions@master
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@v1 - uses: gradle/wrapper-validation-action@v1
- uses: actions/setup-java@v3 - uses: actions/setup-java@v2
with: with:
distribution: 'zulu' distribution: 'zulu'
java-version: 17 java-version: 11
- uses: actions/cache@v3 - uses: actions/cache@v3
with: with:
path: | path: |
@ -71,10 +71,10 @@ jobs:
- uses: fkirc/skip-duplicate-actions@master - uses: fkirc/skip-duplicate-actions@master
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@v1 - uses: gradle/wrapper-validation-action@v1
- uses: actions/setup-java@v3 - uses: actions/setup-java@v2
with: with:
distribution: 'zulu' distribution: 'zulu'
java-version: 17 java-version: 11
- uses: actions/cache@v3 - uses: actions/cache@v3
with: with:
path: | path: |

7
.gitignore vendored
View file

@ -65,12 +65,6 @@ captures/
.idea/uiDesigner.xml .idea/uiDesigner.xml
.idea/runConfigurations.xml .idea/runConfigurations.xml
.idea/discord.xml .idea/discord.xml
.idea/migrations.xml
.idea/androidTestResultsUserPreferences.xml
.idea/copilot
.idea/deploymentTargetDropDown.xml
.idea/deploymentTargetSelector.xml
.idea/kotlinc.xml
# Keystore files # Keystore files
*.jks *.jks
@ -125,4 +119,3 @@ Thumbs.db
app/src/release/agconnect-services.json app/src/release/agconnect-services.json
app/src/release/agconnect-credentials.json app/src/release/agconnect-credentials.json
.idea/deploymentTargetDropDown.xml .idea/deploymentTargetDropDown.xml
.idea/kotlinc.xml

View file

@ -1,11 +1,8 @@
import com.github.triplet.gradle.androidpublisher.ReleaseStatus
import ru.cian.huawei.publish.ReleaseNote
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlinx-serialization' apply plugin: 'kotlinx-serialization'
apply plugin: 'kotlin-parcelize' apply plugin: 'kotlin-parcelize'
apply plugin: 'com.google.devtools.ksp' apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin' apply plugin: 'dagger.hilt.android.plugin'
apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics' apply plugin: 'com.google.firebase.crashlytics'
@ -13,29 +10,37 @@ apply plugin: 'com.github.triplet.play'
apply plugin: 'ru.cian.huawei-publish' apply plugin: 'ru.cian.huawei-publish'
apply plugin: 'com.mikepenz.aboutlibraries.plugin' apply plugin: 'com.mikepenz.aboutlibraries.plugin'
apply plugin: 'com.huawei.agconnect' apply plugin: 'com.huawei.agconnect'
apply plugin: 'kotlin-kapt'
apply from: 'jacoco.gradle' apply from: 'jacoco.gradle'
apply from: 'sonarqube.gradle' apply from: 'sonarqube.gradle'
apply from: 'hooks.gradle' apply from: 'hooks.gradle'
android { android {
namespace 'io.github.wulkanowy' namespace 'io.github.wulkanowy'
compileSdk 34 compileSdkVersion 33
defaultConfig { defaultConfig {
applicationId "io.github.wulkanowy" applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy" testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 34 targetSdkVersion 33
versionCode 154 versionCode 119
versionName "2.5.5" versionName "1.9.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resValue "string", "app_name", "Wulkanowy" resValue "string", "app_name", "Wulkanowy"
manifestPlaceholders = [ manifestPlaceholders = [
firebase_enabled: project.hasProperty("enableFirebase"), firebase_enabled: project.hasProperty("enableFirebase"),
admob_project_id: "" admob_project_id: ""
] ]
javaCompileOptions {
annotationProcessorOptions {
arguments += [
"room.schemaLocation": "$projectDir/schemas".toString(),
"room.incremental" : "true"
]
}
}
buildConfigField "String", "SINGLE_SUPPORT_AD_ID", "null" buildConfigField "String", "SINGLE_SUPPORT_AD_ID", "null"
buildConfigField "String", "DASHBOARD_TILE_AD_ID", "null" buildConfigField "String", "DASHBOARD_TILE_AD_ID", "null"
@ -68,7 +73,6 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release signingConfig signingConfigs.release
buildConfigField "String", "MESSAGES_BASE_URL", "\"https://messages.wulkanowy.net.pl\"" buildConfigField "String", "MESSAGES_BASE_URL", "\"https://messages.wulkanowy.net.pl\""
buildConfigField "String", "SCHOOLS_BASE_URL", '"https://schools.wulkanowy.net.pl"'
} }
debug { debug {
minifyEnabled false minifyEnabled false
@ -78,11 +82,10 @@ android {
versionNameSuffix "-dev" versionNameSuffix "-dev"
ext.enableCrashlytics = project.hasProperty("enableFirebase") ext.enableCrashlytics = project.hasProperty("enableFirebase")
buildConfigField "String", "MESSAGES_BASE_URL", "\"https://messages.wulkanowy.net.pl\"" buildConfigField "String", "MESSAGES_BASE_URL", "\"https://messages.wulkanowy.net.pl\""
buildConfigField "String", "SCHOOLS_BASE_URL", '"https://schools.wulkanowy.net.pl"'
} }
} }
flavorDimensions += "platform" flavorDimensions "platform"
productFlavors { productFlavors {
hms { hms {
@ -113,7 +116,6 @@ android {
buildFeatures { buildFeatures {
viewBinding true viewBinding true
buildConfig true
} }
bundle { bundle {
@ -122,29 +124,27 @@ android {
} }
} }
testOptions { testOptions.unitTests {
unitTests.includeAndroidResources = true includeAndroidResources = true
// workaround HMS test errors https://github.com/robolectric/robolectric/issues/2750 // workaround HMS test errors https://github.com/robolectric/robolectric/issues/2750
unitTests.all { jvmArgs '-noverify' } all { jvmArgs '-noverify' }
} }
compileOptions { compileOptions {
coreLibraryDesugaringEnabled true coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_17 sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_11
} }
kotlinOptions { kotlinOptions {
jvmTarget = "17" jvmTarget = "11"
freeCompilerArgs += ["-opt-in=kotlin.RequiresOptIn", "-Xjvm-default=all"] freeCompilerArgs += ["-opt-in=kotlin.RequiresOptIn", "-Xjvm-default=all"]
} }
packagingOptions { packagingOptions {
resources { resources {
excludes += ['META-INF/library_release.kotlin_module', excludes += ['META-INF/library_release.kotlin_module',
'META-INF/library-core_release.kotlin_module', 'META-INF/library-core_release.kotlin_module']
'META-INF/LICENSE.md',
'META-INF/LICENSE-notice.md']
} }
} }
@ -156,15 +156,12 @@ android {
kapt { kapt {
correctErrorTypes true correctErrorTypes true
} }
ksp {
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
play { play {
defaultToAppBundles = false defaultToAppBundles = false
track = 'production' track = 'production'
releaseStatus = ReleaseStatus.IN_PROGRESS releaseStatus = com.github.triplet.gradle.androidpublisher.ReleaseStatus.IN_PROGRESS
userFraction = 0.99d userFraction = 0.10d
updatePriority = 1 updatePriority = 1
enabled.set(false) enabled.set(false)
} }
@ -174,60 +171,54 @@ huaweiPublish {
hmsRelease { hmsRelease {
credentialsPath = "$rootDir/app/src/release/agconnect-credentials.json" credentialsPath = "$rootDir/app/src/release/agconnect-credentials.json"
buildFormat = "aab" buildFormat = "aab"
deployType = "publish" deployType = "draft"
releaseNotes = [
new ReleaseNote(
"pl-PL",
"$projectDir/src/main/play/release-notes/pl-PL/default.txt"
)
]
} }
} }
} }
ext { ext {
work_manager = "2.9.0" work_manager = "2.7.1"
android_hilt = "1.2.0" android_hilt = "1.0.0"
room = "2.6.1" room = "2.4.3"
chucker = "4.0.0" chucker = "3.5.2"
mockk = "1.13.10" mockk = "1.13.3"
coroutines = "1.8.0" coroutines = "1.6.4"
} }
dependencies { dependencies {
implementation 'io.github.wulkanowy:sdk:2.5.5' implementation "io.github.wulkanowy:sdk:1.9.0"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.8'
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3" implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines"
implementation 'androidx.core:core-ktx:1.12.0' implementation "androidx.core:core-ktx:1.9.0"
implementation 'androidx.core:core-splashscreen:1.0.1' implementation 'androidx.core:core-splashscreen:1.0.0'
implementation "androidx.activity:activity-ktx:1.8.2" implementation "androidx.activity:activity-ktx:1.6.1"
implementation "androidx.appcompat:appcompat:1.6.1" implementation "androidx.appcompat:appcompat:1.5.1"
implementation "androidx.fragment:fragment-ktx:1.6.2" implementation "androidx.fragment:fragment-ktx:1.5.5"
implementation "androidx.annotation:annotation:1.7.1" implementation "androidx.annotation:annotation:1.5.0"
implementation "androidx.preference:preference-ktx:1.2.1" implementation "androidx.preference:preference-ktx:1.2.0"
implementation "androidx.recyclerview:recyclerview:1.3.2" implementation "androidx.recyclerview:recyclerview:1.2.1"
implementation "androidx.viewpager2:viewpager2:1.1.0-beta02" implementation "androidx.viewpager2:viewpager2:1.1.0-beta01"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "androidx.constraintlayout:constraintlayout:2.1.4" implementation "androidx.constraintlayout:constraintlayout:2.1.4"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0" implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0"
implementation "com.google.android.material:material:1.10.0" implementation "com.google.android.material:material:1.7.0"
implementation "com.github.wulkanowy:material-chips-input:2.3.1" implementation "com.github.wulkanowy:material-chips-input:2.3.1"
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0" implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
implementation 'com.github.lopspower:CircularImageView:4.3.0' implementation 'com.github.lopspower:CircularImageView:4.3.0'
implementation "androidx.work:work-runtime:$work_manager" implementation "androidx.work:work-runtime-ktx:$work_manager"
playImplementation "androidx.work:work-gcm:$work_manager" playImplementation "androidx.work:work-gcm:$work_manager"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.7.0" implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1"
implementation "androidx.room:room-runtime:$room" implementation "androidx.room:room-runtime:$room"
implementation "androidx.room:room-ktx:$room" implementation "androidx.room:room-ktx:$room"
ksp "androidx.room:room-compiler:$room" kapt "androidx.room:room-compiler:$room"
implementation "com.google.dagger:hilt-android:$hilt_version" implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version" kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
@ -238,38 +229,33 @@ dependencies {
implementation "com.github.YarikSOffice:lingver:1.3.0" implementation "com.github.YarikSOffice:lingver:1.3.0"
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0" implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0"
implementation "com.squareup.okhttp3:logging-interceptor:4.12.0" implementation "com.squareup.okhttp3:logging-interceptor:4.10.0"
implementation "com.squareup.okhttp3:okhttp-urlconnection:4.12.0"
implementation "com.jakewharton.timber:timber:5.0.1" implementation "com.jakewharton.timber:timber:5.0.1"
implementation 'com.github.Faierbel:slf4j-timber:2.0' implementation "at.favre.lib:slf4j-timber:1.0.1"
implementation 'com.github.bastienpaulfr:Treessence:1.1.2' implementation 'com.github.bastienpaulfr:Treessence:1.0.5'
implementation "com.mikepenz:aboutlibraries-core:$about_libraries" implementation "com.mikepenz:aboutlibraries-core:$about_libraries"
implementation 'io.coil-kt:coil:2.6.0' implementation "io.coil-kt:coil:2.2.2"
implementation "io.github.wulkanowy:AppKillerManager:3.0.1" implementation "io.github.wulkanowy:AppKillerManager:3.0.1"
implementation 'me.xdrop:fuzzywuzzy:1.4.0' implementation 'me.xdrop:fuzzywuzzy:1.4.0'
implementation 'com.fredporciuncula:flow-preferences:1.9.1' implementation 'com.fredporciuncula:flow-preferences:1.8.0'
implementation 'org.apache.commons:commons-text:1.11.0' implementation 'org.apache.commons:commons-text:1.10.0'
playImplementation platform('com.google.firebase:firebase-bom:32.7.3') playImplementation platform('com.google.firebase:firebase-bom:31.1.1')
playImplementation 'com.google.firebase:firebase-analytics' playImplementation 'com.google.firebase:firebase-analytics-ktx'
playImplementation 'com.google.firebase:firebase-messaging' playImplementation 'com.google.firebase:firebase-messaging:'
playImplementation 'com.google.firebase:firebase-crashlytics:' playImplementation 'com.google.firebase:firebase-crashlytics:'
playImplementation 'com.google.firebase:firebase-config' playImplementation 'com.google.android.play:core:1.10.3'
playImplementation 'com.google.android.play:core-ktx:1.8.1'
playImplementation 'com.google.android.gms:play-services-ads:21.4.0'
playImplementation 'com.google.android.gms:play-services-ads:22.6.0' hmsImplementation 'com.huawei.hms:hianalytics:6.9.0.301'
playImplementation "com.google.android.play:integrity:1.3.0" hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.7.3.302'
playImplementation 'com.google.android.play:app-update-ktx:2.1.0'
playImplementation 'com.google.android.play:review-ktx:2.0.1'
playImplementation "com.google.android.ump:user-messaging-platform:2.1.0"
hmsImplementation 'com.huawei.hms:hianalytics:6.12.0.301' releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.9.1.303'
releaseImplementation "com.github.chuckerteam.chucker:library-no-op:$chucker" debugImplementation "com.github.ChuckerTeam.Chucker:library:$chucker"
debugImplementation "com.github.chuckerteam.chucker:library:$chucker"
debugImplementation 'com.github.amitshekhariitbhu.Android-Debug-Database:debug-db:1.0.6' debugImplementation 'com.github.amitshekhariitbhu.Android-Debug-Database:debug-db:1.0.6'
debugImplementation 'com.github.haroldadmin:WhatTheStack:1.0.0-alpha04' debugImplementation 'com.github.haroldadmin:WhatTheStack:1.0.0-alpha04'
@ -278,17 +264,17 @@ dependencies {
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines" testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines"
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version" testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testImplementation 'org.robolectric:robolectric:4.11.1' testImplementation 'org.robolectric:robolectric:4.9.1'
testImplementation "androidx.test:runner:1.5.2" testImplementation "androidx.test:runner:1.5.1"
testImplementation "androidx.test.ext:junit:1.1.5" testImplementation "androidx.test.ext:junit:1.1.4"
testImplementation "androidx.test:core:1.5.0" testImplementation "androidx.test:core:1.5.0"
testImplementation "androidx.room:room-testing:$room" testImplementation "androidx.room:room-testing:$room"
testImplementation "com.google.dagger:hilt-android-testing:$hilt_version" testImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
kaptTest "com.google.dagger:hilt-android-compiler:$hilt_version" kaptTest "com.google.dagger:hilt-android-compiler:$hilt_version"
androidTestImplementation "androidx.test:core:1.5.0" androidTestImplementation "androidx.test:core:1.5.0"
androidTestImplementation "androidx.test:runner:1.5.2" androidTestImplementation "androidx.test:runner:1.5.1"
androidTestImplementation "androidx.test.ext:junit:1.1.5" androidTestImplementation "androidx.test.ext:junit:1.1.4"
androidTestImplementation "io.mockk:mockk-android:$mockk" androidTestImplementation "io.mockk:mockk-android:$mockk"
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version" androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
} }

View file

@ -1,16 +1,16 @@
apply plugin: "jacoco" apply plugin: "jacoco"
jacoco { jacoco {
toolVersion "0.8.11" toolVersion "0.8.7"
reportsDirectory.set(file("$buildDir/reports")) reportsDirectory.set(file("$buildDir/reports"))
} }
tasks.withType(Test).configureEach { tasks.withType(Test) {
jacoco.includeNoLocationClasses = true jacoco.includeNoLocationClasses = true
jacoco.excludes = ['jdk.internal.*'] jacoco.excludes = ['jdk.internal.*']
} }
tasks.register('jacocoTestReport', JacocoReport) { task jacocoTestReport(type: JacocoReport) {
group = "Reporting" group = "Reporting"
description = "Generate Jacoco coverage reports" description = "Generate Jacoco coverage reports"
@ -33,19 +33,19 @@ tasks.register('jacocoTestReport', JacocoReport) {
'**/*_Factory.*'] '**/*_Factory.*']
classDirectories.setFrom(fileTree( classDirectories.setFrom(fileTree(
dir: "$buildDir/intermediates/classes/debug", dir: "$buildDir/intermediates/classes/debug",
excludes: excludes excludes: excludes
) + fileTree( ) + fileTree(
dir: "$buildDir/tmp/kotlin-classes/fdroidDebug", dir: "$buildDir/tmp/kotlin-classes/fdroidDebug",
excludes: excludes excludes: excludes
)) ))
sourceDirectories.setFrom(files([ sourceDirectories.setFrom(files([
"src/main/java", "src/main/java",
"src/fdroid/java" "src/fdroid/java"
])) ]))
executionData.setFrom(fileTree( executionData.setFrom(fileTree(
dir: project.projectDir, dir: project.projectDir,
includes: ["**/*.exec", "**/*.ec"] includes: ["**/*.exec", "**/*.ec"]
)) ))
} }

View file

@ -1,6 +1,5 @@
# General # General
-dontobfuscate -dontobfuscate
-ignorewarnings
#Config for wulkanowy #Config for wulkanowy
@ -25,18 +24,3 @@
#Config for Material Components #Config for Material Components
-keep class com.google.android.material.tabs.** { *; } -keep class com.google.android.material.tabs.** { *; }
#Config for HMS SDK
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keep class com.huawei.agconnect.**{*;}
-keep class com.huawei.hianalytics.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
#Config for Wulkanowy SDK
-keep,allowobfuscation,allowshrinking class retrofit2.Response

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -14,37 +14,34 @@ import kotlin.test.assertFailsWith
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class ScramblerTest { class ScramblerTest {
private val scrambler = Scrambler(ApplicationProvider.getApplicationContext())
@Test @Test
fun encryptDecryptTest() { fun encryptDecryptTest() {
assertEquals( assertEquals("TEST", decrypt(encrypt("TEST",
"TEST", scrambler.decrypt(scrambler.encrypt("TEST")) ApplicationProvider.getApplicationContext())))
)
} }
@Test @Test
fun emptyTextEncryptTest() { fun emptyTextEncryptTest() {
assertFailsWith<ScramblerException> { assertFailsWith<ScramblerException> {
scrambler.decrypt("") decrypt("")
} }
assertFailsWith<ScramblerException> { assertFailsWith<ScramblerException> {
scrambler.encrypt("") encrypt("", ApplicationProvider.getApplicationContext())
} }
} }
@Test @Test
@SdkSuppress(minSdkVersion = 18) @SdkSuppress(minSdkVersion = 18)
fun emptyKeyStoreTest() { fun emptyKeyStoreTest() {
val text = scrambler.encrypt("test") val text = encrypt("test", ApplicationProvider.getApplicationContext())
val keyStore = KeyStore.getInstance("AndroidKeyStore") val keyStore = KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null) keyStore.load(null)
keyStore.deleteEntry("wulkanowy_password") keyStore.deleteEntry("wulkanowy_password")
assertFailsWith<ScramblerException> { assertFailsWith<ScramblerException> {
scrambler.decrypt(text) decrypt(text)
} }
} }
} }

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/colorIcon" /> <background android:drawable="@color/colorPrimary" />
<foreground android:drawable="@drawable/ic_launcher_foreground_dev" /> <foreground android:drawable="@drawable/ic_launcher_foreground_dev" />
<monochrome android:drawable="@drawable/ic_launcher_foreground_dev_mono" /> <monochrome android:drawable="@drawable/ic_launcher_foreground_dev_mono" />
</adaptive-icon> </adaptive-icon>

View file

@ -5,7 +5,6 @@ import android.view.View
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
import kotlinx.coroutines.flow.MutableStateFlow
import javax.inject.Inject import javax.inject.Inject
@Suppress("unused") @Suppress("unused")
@ -14,11 +13,9 @@ class AdsHelper @Inject constructor(
private val preferencesRepository: PreferencesRepository private val preferencesRepository: PreferencesRepository
) { ) {
val isMobileAdsSdkInitialized = MutableStateFlow(false)
val canShowAd = false
fun initialize() { fun initialize() {
preferencesRepository.isAdsEnabled = false preferencesRepository.isAdsEnabled = false
preferencesRepository.isAgreeToProcessData = false
preferencesRepository.selectedDashboardTiles -= DashboardItem.Tile.ADS preferencesRepository.selectedDashboardTiles -= DashboardItem.Tile.ADS
} }

View file

@ -1,13 +0,0 @@
package io.github.wulkanowy.utils
import android.view.View
import javax.inject.Inject
class InAppUpdateHelper @Inject constructor() {
lateinit var messageContainer: View
fun checkAndInstallUpdates() {}
fun onResume() {}
}

View file

@ -1,11 +0,0 @@
package io.github.wulkanowy.utils
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class IntegrityHelper @Inject constructor() {
@Suppress("UNUSED_PARAMETER")
fun getIntegrityToken(requestId: String): String? = null
}

View file

@ -1,7 +0,0 @@
package io.github.wulkanowy.utils
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class RemoteConfigHelper @Inject constructor() : BaseRemoteConfigHelper()

View file

@ -0,0 +1,17 @@
package io.github.wulkanowy.utils
import android.app.Activity
import android.view.View
import javax.inject.Inject
@Suppress("UNUSED_PARAMETER")
class UpdateHelper @Inject constructor() {
lateinit var messageContainer: View
fun checkAndInstallUpdates(activity: Activity) {}
fun onActivityResult(requestCode: Int, resultCode: Int) {}
fun onResume(activity: Activity) {}
}

View file

@ -5,7 +5,6 @@ import android.view.View
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
import kotlinx.coroutines.flow.MutableStateFlow
import javax.inject.Inject import javax.inject.Inject
@Suppress("unused") @Suppress("unused")
@ -13,11 +12,10 @@ class AdsHelper @Inject constructor(
@ApplicationContext private val context: Context, @ApplicationContext private val context: Context,
private val preferencesRepository: PreferencesRepository private val preferencesRepository: PreferencesRepository
) { ) {
val isMobileAdsSdkInitialized = MutableStateFlow(false)
val canShowAd = false
fun initialize() { fun initialize() {
preferencesRepository.isAdsEnabled = false preferencesRepository.isAdsEnabled = false
preferencesRepository.isAgreeToProcessData = false
preferencesRepository.selectedDashboardTiles -= DashboardItem.Tile.ADS preferencesRepository.selectedDashboardTiles -= DashboardItem.Tile.ADS
} }

View file

@ -2,8 +2,8 @@ package io.github.wulkanowy.utils
import android.util.Log import android.util.Log
import com.huawei.agconnect.crash.AGConnectCrash import com.huawei.agconnect.crash.AGConnectCrash
import fr.bipi.treessence.base.FormatterPriorityTree import fr.bipi.tressence.base.FormatterPriorityTree
import fr.bipi.treessence.common.StackTraceRecorder import fr.bipi.tressence.common.StackTraceRecorder
class CrashLogTree : FormatterPriorityTree(Log.VERBOSE) { class CrashLogTree : FormatterPriorityTree(Log.VERBOSE) {

View file

@ -1,13 +0,0 @@
package io.github.wulkanowy.utils
import android.view.View
import javax.inject.Inject
class InAppUpdateHelper @Inject constructor() {
lateinit var messageContainer: View
fun checkAndInstallUpdates() {}
fun onResume() {}
}

View file

@ -1,11 +0,0 @@
package io.github.wulkanowy.utils
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class IntegrityHelper @Inject constructor() {
@Suppress("UNUSED_PARAMETER")
fun getIntegrityToken(requestId: String): String? = null
}

View file

@ -1,7 +0,0 @@
package io.github.wulkanowy.utils
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class RemoteConfigHelper @Inject constructor() : BaseRemoteConfigHelper()

View file

@ -0,0 +1,17 @@
package io.github.wulkanowy.utils
import android.app.Activity
import android.view.View
import javax.inject.Inject
@Suppress("UNUSED_PARAMETER")
class UpdateHelper @Inject constructor() {
lateinit var messageContainer: View
fun checkAndInstallUpdates(activity: Activity) {}
fun onActivityResult(requestCode: Int, resultCode: Int) {}
fun onResume(activity: Activity) {}
}

View file

@ -44,7 +44,6 @@
android:networkSecurityConfig="@xml/network_security_config" android:networkSecurityConfig="@xml/network_security_config"
android:supportsRtl="false" android:supportsRtl="false"
android:theme="@style/WulkanowyTheme" android:theme="@style/WulkanowyTheme"
android:resizeableActivity="true"
tools:ignore="DataExtractionRules,UnusedAttribute"> tools:ignore="DataExtractionRules,UnusedAttribute">
<activity <activity
android:name=".ui.modules.splash.SplashActivity" android:name=".ui.modules.splash.SplashActivity"
@ -73,7 +72,7 @@
android:name=".ui.modules.message.send.SendMessageActivity" android:name=".ui.modules.message.send.SendMessageActivity"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
android:label="@string/send_message_title" android:label="@string/send_message_title"
android:theme="@style/WulkanowyTheme.NoActionBar" android:theme="@style/WulkanowyTheme.MessageSend"
android:windowSoftInputMode="adjustResize" /> android:windowSoftInputMode="adjustResize" />
<activity <activity
android:name=".ui.modules.timetablewidget.TimetableWidgetConfigureActivity" android:name=".ui.modules.timetablewidget.TimetableWidgetConfigureActivity"

View file

@ -50,13 +50,5 @@
{ {
"displayName": "Tomasz F.", "displayName": "Tomasz F.",
"githubUsername": "Pengwius" "githubUsername": "Pengwius"
},
{
"displayName": "Antoni Paduch",
"githubUsername": "janAte1"
},
{
"displayName": "Kamil Wąsik",
"githubUsername": "JestemKamil"
} }
] ]

View file

@ -1,29 +1,24 @@
package io.github.wulkanowy package io.github.wulkanowy
import android.app.Application import android.app.Application
import android.util.Log.DEBUG import android.util.Log.*
import android.util.Log.INFO
import android.util.Log.VERBOSE
import androidx.hilt.work.HiltWorkerFactory import androidx.hilt.work.HiltWorkerFactory
import androidx.work.Configuration import androidx.work.Configuration
import com.yariksoffice.lingver.Lingver import com.yariksoffice.lingver.Lingver
import dagger.hilt.android.HiltAndroidApp import dagger.hilt.android.HiltAndroidApp
import fr.bipi.treessence.file.FileLoggerTree import fr.bipi.tressence.file.FileLoggerTree
import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.ui.base.ThemeManager import io.github.wulkanowy.ui.base.ThemeManager
import io.github.wulkanowy.utils.ActivityLifecycleLogger import io.github.wulkanowy.utils.*
import io.github.wulkanowy.utils.AnalyticsHelper
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.CrashLogExceptionTree
import io.github.wulkanowy.utils.CrashLogTree
import io.github.wulkanowy.utils.DebugLogTree
import io.github.wulkanowy.utils.RemoteConfigHelper
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@HiltAndroidApp @HiltAndroidApp
class WulkanowyApp : Application(), Configuration.Provider { class WulkanowyApp : Application(), Configuration.Provider {
@Inject
lateinit var workerFactory: HiltWorkerFactory
@Inject @Inject
lateinit var themeManager: ThemeManager lateinit var themeManager: ThemeManager
@ -37,22 +32,13 @@ class WulkanowyApp : Application(), Configuration.Provider {
lateinit var analyticsHelper: AnalyticsHelper lateinit var analyticsHelper: AnalyticsHelper
@Inject @Inject
lateinit var remoteConfigHelper: RemoteConfigHelper lateinit var adsHelper: AdsHelper
@Inject
lateinit var workerFactory: HiltWorkerFactory
override val workManagerConfiguration: Configuration
get() = Configuration.Builder()
.setWorkerFactory(workerFactory)
.setMinimumLoggingLevel(if (appInfo.isDebug) VERBOSE else INFO)
.build()
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
initializeAppLanguage() initializeAppLanguage()
themeManager.applyDefaultTheme() themeManager.applyDefaultTheme()
remoteConfigHelper.initialize() adsHelper.initialize()
initLogging() initLogging()
} }
@ -84,4 +70,9 @@ class WulkanowyApp : Application(), Configuration.Provider {
analyticsHelper.logEvent("language", "startup" to preferencesRepository.appLanguage) analyticsHelper.logEvent("language", "startup" to preferencesRepository.appLanguage)
} }
} }
override fun getWorkManagerConfiguration() = Configuration.Builder()
.setWorkerFactory(workerFactory)
.setMinimumLoggingLevel(if (appInfo.isDebug) VERBOSE else INFO)
.build()
} }

View file

@ -14,17 +14,19 @@ import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import io.github.wulkanowy.data.api.AdminMessageService import io.github.wulkanowy.data.api.AdminMessageService
import io.github.wulkanowy.data.api.SchoolsService
import io.github.wulkanowy.data.db.AppDatabase import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.SharedPrefProvider import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.AppInfo import io.github.wulkanowy.utils.AppInfo
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.create import retrofit2.create
import timber.log.Timber
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.inject.Singleton import javax.inject.Singleton
@ -32,6 +34,18 @@ import javax.inject.Singleton
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)
internal class DataModule { internal class DataModule {
@Singleton
@Provides
fun provideSdk(chuckerInterceptor: ChuckerInterceptor) =
Sdk().apply {
androidVersion = android.os.Build.VERSION.RELEASE
buildTag = android.os.Build.MODEL
setSimpleHttpLogger { Timber.d(it) }
// for debug only
addInterceptor(chuckerInterceptor, network = true)
}
@Singleton @Singleton
@Provides @Provides
fun provideChuckerCollector( fun provideChuckerCollector(
@ -65,31 +79,22 @@ internal class DataModule {
.readTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS)
.build() .build()
@OptIn(ExperimentalSerializationApi::class)
@Singleton @Singleton
@Provides @Provides
fun provideAdminMessageService( fun provideRetrofit(
okHttpClient: OkHttpClient, okHttpClient: OkHttpClient,
json: Json, json: Json,
appInfo: AppInfo appInfo: AppInfo
): AdminMessageService = Retrofit.Builder() ): Retrofit = Retrofit.Builder()
.baseUrl(appInfo.messagesBaseUrl) .baseUrl(appInfo.messagesBaseUrl)
.client(okHttpClient) .client(okHttpClient)
.addConverterFactory(json.asConverterFactory("application/json".toMediaType())) .addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.build() .build()
.create()
@Singleton @Singleton
@Provides @Provides
fun provideSchoolsService( fun provideAdminMessageService(retrofit: Retrofit): AdminMessageService = retrofit.create()
okHttpClient: OkHttpClient,
json: Json,
appInfo: AppInfo,
): SchoolsService = Retrofit.Builder()
.baseUrl(appInfo.schoolsBaseUrl)
.client(okHttpClient)
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.build()
.create()
@Singleton @Singleton
@Provides @Provides
@ -235,12 +240,4 @@ internal class DataModule {
@Singleton @Singleton
@Provides @Provides
fun provideAdminMessageDao(database: AppDatabase) = database.adminMessagesDao fun provideAdminMessageDao(database: AppDatabase) = database.adminMessagesDao
@Singleton
@Provides
fun provideMutesDao(database: AppDatabase) = database.mutedMessageSendersDao
@Singleton
@Provides
fun provideGradeDescriptiveDao(database: AppDatabase) = database.gradeDescriptiveDao
} }

View file

@ -1,16 +1,6 @@
package io.github.wulkanowy.data package io.github.wulkanowy.data
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.emitAll
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import timber.log.Timber import timber.log.Timber
@ -30,15 +20,8 @@ val <T> Resource<T>.dataOrNull: T?
get() = when (this) { get() = when (this) {
is Resource.Success -> this.data is Resource.Success -> this.data
is Resource.Intermediate -> this.data is Resource.Intermediate -> this.data
else -> null is Resource.Loading -> null
} is Resource.Error -> null
val <T> Resource<T>.dataOrThrow: T
get() = when (this) {
is Resource.Success -> this.data
is Resource.Intermediate -> this.data
is Resource.Loading -> throw IllegalStateException("Resource is in loading state")
is Resource.Error -> throw this.error
} }
val <T> Resource<T>.errorOrNull: Throwable? val <T> Resource<T>.errorOrNull: Throwable?
@ -148,7 +131,7 @@ inline fun <ResultType, RequestType> networkBoundResource(
query().map { Resource.Success(filterResult(it)) } query().map { Resource.Success(filterResult(it)) }
} catch (throwable: Throwable) { } catch (throwable: Throwable) {
onFetchFailed(throwable) onFetchFailed(throwable)
flowOf(Resource.Error(throwable)) query().map { Resource.Error(throwable) }
} }
} else { } else {
query().map { Resource.Success(filterResult(it)) } query().map { Resource.Success(filterResult(it)) }
@ -165,7 +148,7 @@ inline fun <ResultType, RequestType, T> networkBoundResource(
crossinline saveFetchResult: suspend (old: ResultType, new: RequestType) -> Unit, crossinline saveFetchResult: suspend (old: ResultType, new: RequestType) -> Unit,
crossinline onFetchFailed: (Throwable) -> Unit = { }, crossinline onFetchFailed: (Throwable) -> Unit = { },
crossinline shouldFetch: (ResultType) -> Boolean = { true }, crossinline shouldFetch: (ResultType) -> Boolean = { true },
crossinline mapResult: (ResultType) -> T, crossinline mapResult: (ResultType) -> T
) = flow { ) = flow {
emit(Resource.Loading()) emit(Resource.Loading())
@ -182,7 +165,7 @@ inline fun <ResultType, RequestType, T> networkBoundResource(
query().map { Resource.Success(mapResult(it)) } query().map { Resource.Success(mapResult(it)) }
} catch (throwable: Throwable) { } catch (throwable: Throwable) {
onFetchFailed(throwable) onFetchFailed(throwable)
flowOf(Resource.Error(throwable)) query().map { Resource.Error(throwable) }
} }
} else { } else {
query().map { Resource.Success(mapResult(it)) } query().map { Resource.Success(mapResult(it)) }

View file

@ -1,125 +0,0 @@
package io.github.wulkanowy.data
import com.chuckerteam.chucker.api.ChuckerInterceptor
import io.github.wulkanowy.data.db.dao.StudentDao
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.StudentIsEduOne
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.RemoteConfigHelper
import io.github.wulkanowy.utils.WebkitCookieManagerProxy
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class WulkanowySdkFactory @Inject constructor(
private val chuckerInterceptor: ChuckerInterceptor,
private val remoteConfig: RemoteConfigHelper,
private val webkitCookieManagerProxy: WebkitCookieManagerProxy,
private val studentDb: StudentDao,
) {
private val eduOneMutex = Mutex()
private val migrationFailedStudentIds = mutableSetOf<Long>()
private val sdk = Sdk().apply {
androidVersion = android.os.Build.VERSION.RELEASE
buildTag = android.os.Build.MODEL
userAgentTemplate = remoteConfig.userAgentTemplate
setSimpleHttpLogger { Timber.d(it) }
setAdditionalCookieManager(webkitCookieManagerProxy)
// for debug only
addInterceptor(chuckerInterceptor, network = true)
}
fun create() = sdk
suspend fun create(student: Student, semester: Semester? = null): Sdk {
val overrideIsEduOne = checkEduOneAndMigrateIfNecessary(student)
return buildSdk(student, semester, overrideIsEduOne)
}
private fun buildSdk(student: Student, semester: Semester?, isStudentEduOne: Boolean): Sdk {
return create().apply {
email = student.email
password = student.password
symbol = student.symbol
schoolSymbol = student.schoolSymbol
studentId = student.studentId
classId = student.classId
emptyCookieJarInterceptor = true
isEduOne = isStudentEduOne
if (Sdk.Mode.valueOf(student.loginMode) == Sdk.Mode.HEBE) {
mobileBaseUrl = student.mobileBaseUrl
} else {
scrapperBaseUrl = student.scrapperBaseUrl
domainSuffix = student.scrapperDomainSuffix
loginType = Sdk.ScrapperLoginType.valueOf(student.loginType)
}
mode = Sdk.Mode.valueOf(student.loginMode)
mobileBaseUrl = student.mobileBaseUrl
keyId = student.certificateKey
privatePem = student.privateKey
if (semester != null) {
diaryId = semester.diaryId
kindergartenDiaryId = semester.kindergartenDiaryId
schoolYear = semester.schoolYear
unitId = semester.unitId
}
}
}
private suspend fun checkEduOneAndMigrateIfNecessary(student: Student): Boolean {
if (student.isEduOne != null) return student.isEduOne
if (student.id in migrationFailedStudentIds) {
Timber.i("Migration eduOne: skipping because of previous failure")
return false
}
eduOneMutex.withLock {
if (student.id in migrationFailedStudentIds) {
Timber.i("Migration eduOne: skipping because of previous failure")
return false
}
val studentFromDatabase = studentDb.loadById(student.id)
if (studentFromDatabase?.isEduOne != null) {
Timber.i("Migration eduOne: already done")
return studentFromDatabase.isEduOne
}
Timber.i("Migration eduOne: flag missing. Running migration...")
val initializedSdk = buildSdk(
student = student,
semester = null,
isStudentEduOne = false, // doesn't matter
)
val newCurrentStudent = runCatching { initializedSdk.getCurrentStudent() }
.onFailure { Timber.e(it, "Migration eduOne: can't get current student") }
.getOrNull()
if (newCurrentStudent == null) {
Timber.i("Migration eduOne: failed, so skipping")
migrationFailedStudentIds.add(student.id)
return false
}
Timber.i("Migration eduOne: success. New isEduOne flag: ${newCurrentStudent.isEduOne}")
val studentIsEduOne = StudentIsEduOne(
id = student.id,
isEduOne = newCurrentStudent.isEduOne
)
studentDb.update(studentIsEduOne)
return newCurrentStudent.isEduOne
}
}
}

View file

@ -1,14 +0,0 @@
package io.github.wulkanowy.data.api
import io.github.wulkanowy.data.pojos.IntegrityRequest
import io.github.wulkanowy.data.pojos.LoginEvent
import retrofit2.http.Body
import retrofit2.http.POST
import javax.inject.Singleton
@Singleton
interface SchoolsService {
@POST("/log/loginEvent")
suspend fun logLoginEvent(@Body request: IntegrityRequest<LoginEvent>)
}

View file

@ -1,129 +1,11 @@
package io.github.wulkanowy.data.db package io.github.wulkanowy.data.db
import android.content.Context import android.content.Context
import androidx.room.AutoMigration import androidx.room.*
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.RoomDatabase.JournalMode.TRUNCATE import androidx.room.RoomDatabase.JournalMode.TRUNCATE
import androidx.room.TypeConverters import io.github.wulkanowy.data.db.dao.*
import io.github.wulkanowy.data.db.dao.AdminMessageDao import io.github.wulkanowy.data.db.entities.*
import io.github.wulkanowy.data.db.dao.AttendanceDao import io.github.wulkanowy.data.db.migrations.*
import io.github.wulkanowy.data.db.dao.AttendanceSummaryDao
import io.github.wulkanowy.data.db.dao.CompletedLessonsDao
import io.github.wulkanowy.data.db.dao.ConferenceDao
import io.github.wulkanowy.data.db.dao.ExamDao
import io.github.wulkanowy.data.db.dao.GradeDao
import io.github.wulkanowy.data.db.dao.GradeDescriptiveDao
import io.github.wulkanowy.data.db.dao.GradePartialStatisticsDao
import io.github.wulkanowy.data.db.dao.GradePointsStatisticsDao
import io.github.wulkanowy.data.db.dao.GradeSemesterStatisticsDao
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
import io.github.wulkanowy.data.db.dao.HomeworkDao
import io.github.wulkanowy.data.db.dao.LuckyNumberDao
import io.github.wulkanowy.data.db.dao.MailboxDao
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
import io.github.wulkanowy.data.db.dao.MessagesDao
import io.github.wulkanowy.data.db.dao.MobileDeviceDao
import io.github.wulkanowy.data.db.dao.MutedMessageSendersDao
import io.github.wulkanowy.data.db.dao.NoteDao
import io.github.wulkanowy.data.db.dao.NotificationDao
import io.github.wulkanowy.data.db.dao.RecipientDao
import io.github.wulkanowy.data.db.dao.SchoolAnnouncementDao
import io.github.wulkanowy.data.db.dao.SchoolDao
import io.github.wulkanowy.data.db.dao.SemesterDao
import io.github.wulkanowy.data.db.dao.StudentDao
import io.github.wulkanowy.data.db.dao.StudentInfoDao
import io.github.wulkanowy.data.db.dao.SubjectDao
import io.github.wulkanowy.data.db.dao.TeacherDao
import io.github.wulkanowy.data.db.dao.TimetableAdditionalDao
import io.github.wulkanowy.data.db.dao.TimetableDao
import io.github.wulkanowy.data.db.dao.TimetableHeaderDao
import io.github.wulkanowy.data.db.entities.AdminMessage
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.AttendanceSummary
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.data.db.entities.Conference
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradeDescriptive
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.data.db.entities.Mailbox
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageAttachment
import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.data.db.entities.MutedMessageSender
import io.github.wulkanowy.data.db.entities.Note
import io.github.wulkanowy.data.db.entities.Notification
import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.StudentInfo
import io.github.wulkanowy.data.db.entities.Subject
import io.github.wulkanowy.data.db.entities.Teacher
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.data.db.entities.TimetableAdditional
import io.github.wulkanowy.data.db.entities.TimetableHeader
import io.github.wulkanowy.data.db.migrations.Migration10
import io.github.wulkanowy.data.db.migrations.Migration11
import io.github.wulkanowy.data.db.migrations.Migration12
import io.github.wulkanowy.data.db.migrations.Migration13
import io.github.wulkanowy.data.db.migrations.Migration14
import io.github.wulkanowy.data.db.migrations.Migration15
import io.github.wulkanowy.data.db.migrations.Migration16
import io.github.wulkanowy.data.db.migrations.Migration17
import io.github.wulkanowy.data.db.migrations.Migration18
import io.github.wulkanowy.data.db.migrations.Migration19
import io.github.wulkanowy.data.db.migrations.Migration2
import io.github.wulkanowy.data.db.migrations.Migration20
import io.github.wulkanowy.data.db.migrations.Migration21
import io.github.wulkanowy.data.db.migrations.Migration22
import io.github.wulkanowy.data.db.migrations.Migration23
import io.github.wulkanowy.data.db.migrations.Migration24
import io.github.wulkanowy.data.db.migrations.Migration25
import io.github.wulkanowy.data.db.migrations.Migration26
import io.github.wulkanowy.data.db.migrations.Migration27
import io.github.wulkanowy.data.db.migrations.Migration28
import io.github.wulkanowy.data.db.migrations.Migration29
import io.github.wulkanowy.data.db.migrations.Migration3
import io.github.wulkanowy.data.db.migrations.Migration30
import io.github.wulkanowy.data.db.migrations.Migration31
import io.github.wulkanowy.data.db.migrations.Migration32
import io.github.wulkanowy.data.db.migrations.Migration33
import io.github.wulkanowy.data.db.migrations.Migration34
import io.github.wulkanowy.data.db.migrations.Migration35
import io.github.wulkanowy.data.db.migrations.Migration36
import io.github.wulkanowy.data.db.migrations.Migration37
import io.github.wulkanowy.data.db.migrations.Migration38
import io.github.wulkanowy.data.db.migrations.Migration39
import io.github.wulkanowy.data.db.migrations.Migration4
import io.github.wulkanowy.data.db.migrations.Migration40
import io.github.wulkanowy.data.db.migrations.Migration41
import io.github.wulkanowy.data.db.migrations.Migration42
import io.github.wulkanowy.data.db.migrations.Migration43
import io.github.wulkanowy.data.db.migrations.Migration44
import io.github.wulkanowy.data.db.migrations.Migration46
import io.github.wulkanowy.data.db.migrations.Migration49
import io.github.wulkanowy.data.db.migrations.Migration5
import io.github.wulkanowy.data.db.migrations.Migration50
import io.github.wulkanowy.data.db.migrations.Migration51
import io.github.wulkanowy.data.db.migrations.Migration53
import io.github.wulkanowy.data.db.migrations.Migration54
import io.github.wulkanowy.data.db.migrations.Migration55
import io.github.wulkanowy.data.db.migrations.Migration57
import io.github.wulkanowy.data.db.migrations.Migration58
import io.github.wulkanowy.data.db.migrations.Migration6
import io.github.wulkanowy.data.db.migrations.Migration63
import io.github.wulkanowy.data.db.migrations.Migration7
import io.github.wulkanowy.data.db.migrations.Migration8
import io.github.wulkanowy.data.db.migrations.Migration9
import io.github.wulkanowy.utils.AppInfo import io.github.wulkanowy.utils.AppInfo
import javax.inject.Singleton import javax.inject.Singleton
@ -159,24 +41,13 @@ import javax.inject.Singleton
TimetableHeader::class, TimetableHeader::class,
SchoolAnnouncement::class, SchoolAnnouncement::class,
Notification::class, Notification::class,
AdminMessage::class, AdminMessage::class
MutedMessageSender::class,
GradeDescriptive::class,
], ],
autoMigrations = [ autoMigrations = [
AutoMigration(from = 44, to = 45), AutoMigration(from = 44, to = 45),
AutoMigration(from = 46, to = 47), AutoMigration(from = 46, to = 47),
AutoMigration(from = 47, to = 48), AutoMigration(from = 47, to = 48),
AutoMigration(from = 51, to = 52), AutoMigration(from = 51, to = 52),
AutoMigration(from = 54, to = 55, spec = Migration55::class),
AutoMigration(from = 55, to = 56),
AutoMigration(from = 56, to = 57, spec = Migration57::class),
AutoMigration(from = 57, to = 58, spec = Migration58::class),
AutoMigration(from = 58, to = 59),
AutoMigration(from = 59, to = 60),
AutoMigration(from = 60, to = 61),
AutoMigration(from = 61, to = 62),
AutoMigration(from = 62, to = 63, spec = Migration63::class),
], ],
version = AppDatabase.VERSION_SCHEMA, version = AppDatabase.VERSION_SCHEMA,
exportSchema = true exportSchema = true
@ -185,7 +56,7 @@ import javax.inject.Singleton
abstract class AppDatabase : RoomDatabase() { abstract class AppDatabase : RoomDatabase() {
companion object { companion object {
const val VERSION_SCHEMA = 63 const val VERSION_SCHEMA = 54
fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf( fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf(
Migration2(), Migration2(),
@ -310,8 +181,4 @@ abstract class AppDatabase : RoomDatabase() {
abstract val notificationDao: NotificationDao abstract val notificationDao: NotificationDao
abstract val adminMessagesDao: AdminMessageDao abstract val adminMessagesDao: AdminMessageDao
abstract val mutedMessageSendersDao: MutedMessageSendersDao
abstract val gradeDescriptiveDao: GradeDescriptiveDao
} }

View file

@ -1,7 +1,6 @@
package io.github.wulkanowy.data.db package io.github.wulkanowy.data.db
import androidx.room.TypeConverter import androidx.room.TypeConverter
import io.github.wulkanowy.data.enums.MessageType
import io.github.wulkanowy.ui.modules.Destination import io.github.wulkanowy.ui.modules.Destination
import io.github.wulkanowy.utils.toTimestamp import io.github.wulkanowy.utils.toTimestamp
import kotlinx.serialization.SerializationException import kotlinx.serialization.SerializationException
@ -69,9 +68,4 @@ class Converters {
@TypeConverter @TypeConverter
fun stringToDestination(destination: String): Destination = json.decodeFromString(destination) fun stringToDestination(destination: String): Destination = json.decodeFromString(destination)
@TypeConverter
fun messageTypesToString(types: List<MessageType>): String = json.encodeToString(types)
@TypeConverter
fun stringToMessageTypes(text: String): List<MessageType> = json.decodeFromString(text)
} }

View file

@ -2,14 +2,24 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Query import androidx.room.Query
import androidx.room.Transaction
import io.github.wulkanowy.data.db.entities.AdminMessage import io.github.wulkanowy.data.db.entities.AdminMessage
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface AdminMessageDao : BaseDao<AdminMessage> { abstract class AdminMessageDao : BaseDao<AdminMessage> {
@Query("SELECT * FROM AdminMessages") @Query("SELECT * FROM AdminMessages")
fun loadAll(): Flow<List<AdminMessage>> abstract fun loadAll(): Flow<List<AdminMessage>>
}
@Transaction
open suspend fun removeOldAndSaveNew(
oldMessages: List<AdminMessage>,
newMessages: List<AdminMessage>
) {
deleteAll(oldMessages)
insertAll(newMessages)
}
}

View file

@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
import androidx.room.OnConflictStrategy import androidx.room.OnConflictStrategy
import androidx.room.Transaction
import androidx.room.Update import androidx.room.Update
interface BaseDao<T> { interface BaseDao<T> {
@ -16,10 +15,4 @@ interface BaseDao<T> {
@Delete @Delete
suspend fun deleteAll(items: List<T>) suspend fun deleteAll(items: List<T>)
@Transaction
suspend fun removeOldAndSaveNew(oldItems: List<T>, newItems: List<T>) {
deleteAll(oldItems)
insertAll(newItems)
}
} }

View file

@ -1,15 +0,0 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.GradeDescriptive
import kotlinx.coroutines.flow.Flow
import javax.inject.Singleton
@Singleton
@Dao
interface GradeDescriptiveDao : BaseDao<GradeDescriptive> {
@Query("SELECT * FROM GradesDescriptive WHERE semester_id = :semesterId AND student_id = :studentId")
fun loadAll(semesterId: Int, studentId: Int): Flow<List<GradeDescriptive>>
}

View file

@ -5,23 +5,15 @@ import androidx.room.Query
import androidx.room.Transaction import androidx.room.Transaction
import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageWithAttachment import io.github.wulkanowy.data.db.entities.MessageWithAttachment
import io.github.wulkanowy.data.db.entities.MessageWithMutedAuthor
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@Dao @Dao
interface MessagesDao : BaseDao<Message> { interface MessagesDao : BaseDao<Message> {
@Transaction @Transaction
@Query("SELECT * FROM Messages WHERE message_global_key = :messageGlobalKey") @Query("SELECT * FROM Messages WHERE message_global_key = :messageGlobalKey")
fun loadMessageWithAttachment(messageGlobalKey: String): Flow<MessageWithAttachment?> fun loadMessageWithAttachment(messageGlobalKey: String): Flow<MessageWithAttachment?>
@Transaction
@Query("SELECT * FROM Messages WHERE mailbox_key = :mailboxKey AND folder_id = :folder ORDER BY date DESC")
fun loadMessagesWithMutedAuthor(mailboxKey: String, folder: Int): Flow<List<MessageWithMutedAuthor>>
@Transaction
@Query("SELECT * FROM Messages WHERE email = :email AND folder_id = :folder ORDER BY date DESC")
fun loadMessagesWithMutedAuthor(folder: Int, email: String): Flow<List<MessageWithMutedAuthor>>
@Query("SELECT * FROM Messages WHERE mailbox_key = :mailboxKey AND folder_id = :folder ORDER BY date DESC") @Query("SELECT * FROM Messages WHERE mailbox_key = :mailboxKey AND folder_id = :folder ORDER BY date DESC")
fun loadAll(mailboxKey: String, folder: Int): Flow<List<Message>> fun loadAll(mailboxKey: String, folder: Int): Flow<List<Message>>

View file

@ -1,20 +0,0 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.MutedMessageSender
@Dao
interface MutedMessageSendersDao : BaseDao<MutedMessageSender> {
@Query("SELECT COUNT(*) FROM MutedMessageSenders WHERE author = :author")
suspend fun checkMute(author: String): Boolean
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertMute(mute: MutedMessageSender): Long
@Query("DELETE FROM MutedMessageSenders WHERE author = :author")
suspend fun deleteMute(author: String)
}

View file

@ -14,6 +14,6 @@ interface SemesterDao : BaseDao<Semester> {
@Insert(onConflict = OnConflictStrategy.IGNORE) @Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertSemesters(items: List<Semester>): List<Long> suspend fun insertSemesters(items: List<Semester>): List<Long>
@Query("SELECT * FROM Semesters WHERE (student_id = :studentId AND class_id = :classId) OR (student_id = :studentId AND class_id = 0)") @Query("SELECT * FROM Semesters WHERE student_id = :studentId AND class_id = :classId")
suspend fun loadAll(studentId: Int, classId: Int): List<Semester> suspend fun loadAll(studentId: Int, classId: Int): List<Semester>
} }

View file

@ -1,42 +1,25 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.*
import androidx.room.Delete import androidx.room.OnConflictStrategy.ABORT
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Transaction
import androidx.room.Update
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.StudentIsAuthorized
import io.github.wulkanowy.data.db.entities.StudentIsEduOne
import io.github.wulkanowy.data.db.entities.StudentName
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
abstract class StudentDao { abstract class StudentDao {
@Insert(onConflict = OnConflictStrategy.ABORT) @Insert(onConflict = ABORT)
abstract suspend fun insertAll(student: List<Student>): List<Long> abstract suspend fun insertAll(student: List<Student>): List<Long>
@Delete @Delete
abstract suspend fun delete(student: Student) abstract suspend fun delete(student: Student)
@Update(entity = Student::class)
abstract suspend fun update(studentIsAuthorized: StudentIsAuthorized)
@Update(entity = Student::class)
abstract suspend fun update(studentIsEduOne: StudentIsEduOne)
@Update(entity = Student::class) @Update(entity = Student::class)
abstract suspend fun update(studentNickAndAvatar: StudentNickAndAvatar) abstract suspend fun update(studentNickAndAvatar: StudentNickAndAvatar)
@Update(entity = Student::class)
abstract suspend fun update(studentName: StudentName)
@Query("SELECT * FROM Students WHERE is_current = 1") @Query("SELECT * FROM Students WHERE is_current = 1")
abstract suspend fun loadCurrent(): Student? abstract suspend fun loadCurrent(): Student?
@ -47,12 +30,12 @@ abstract class StudentDao {
abstract suspend fun loadAll(): List<Student> abstract suspend fun loadAll(): List<Student>
@Transaction @Transaction
@Query("SELECT * FROM Students JOIN Semesters ON (Students.student_id = Semesters.student_id AND Students.class_id = Semesters.class_id) OR (Students.student_id = Semesters.student_id AND Semesters.class_id = 0)") @Query("SELECT * FROM Students")
abstract suspend fun loadStudentsWithSemesters(): Map<Student, List<Semester>> abstract suspend fun loadStudentsWithSemesters(): List<StudentWithSemesters>
@Transaction @Transaction
@Query("SELECT * FROM Students JOIN Semesters ON (Students.student_id = Semesters.student_id AND Students.class_id = Semesters.class_id) OR (Students.student_id = Semesters.student_id AND Semesters.class_id = 0) WHERE Students.id = :id") @Query("SELECT * FROM Students WHERE id = :id")
abstract suspend fun loadStudentWithSemestersById(id: Long): Map<Student, List<Semester>> abstract suspend fun loadStudentWithSemestersById(id: Long): StudentWithSemesters?
@Query("UPDATE Students SET is_current = 1 WHERE id = :id") @Query("UPDATE Students SET is_current = 1 WHERE id = :id")
abstract suspend fun updateCurrent(id: Long) abstract suspend fun updateCurrent(id: Long)
@ -60,9 +43,6 @@ abstract class StudentDao {
@Query("UPDATE Students SET is_current = 0") @Query("UPDATE Students SET is_current = 0")
abstract suspend fun resetCurrent() abstract suspend fun resetCurrent()
@Query("DELETE FROM Students WHERE email = :email AND user_name = :userName")
abstract suspend fun deleteByEmailAndUserName(email: String, userName: String)
@Transaction @Transaction
open suspend fun switchCurrent(id: Long) { open suspend fun switchCurrent(id: Long) {
resetCurrent() resetCurrent()

View file

@ -15,5 +15,5 @@ interface TimetableDao : BaseDao<Timetable> {
fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Flow<List<Timetable>> fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Flow<List<Timetable>>
@Query("SELECT * FROM Timetable WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end") @Query("SELECT * FROM Timetable WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
suspend fun load(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): List<Timetable> fun load(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): List<Timetable>
} }

View file

@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import io.github.wulkanowy.data.enums.MessageType
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
@ -34,12 +33,8 @@ data class AdminMessage(
val priority: String, val priority: String,
@ColumnInfo(name = "types", defaultValue = "[]") val type: String,
val types: List<MessageType> = emptyList(),
@ColumnInfo(name = "is_ok_visible", defaultValue = "0") @ColumnInfo(name = "is_dismissible")
val isOkVisible: Boolean = false, val isDismissible: Boolean = false
@ColumnInfo(name = "is_x_visible", defaultValue = "0")
val isXVisible: Boolean = false
) )

View file

@ -22,7 +22,6 @@ data class Exam(
val subject: String, val subject: String,
@Deprecated("not available anymore")
val group: String, val group: String,
val type: String, val type: String,

View file

@ -1,27 +0,0 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
@Entity(tableName = "GradesDescriptive")
data class GradeDescriptive(
@ColumnInfo(name = "semester_id")
val semesterId: Int,
@ColumnInfo(name = "student_id")
val studentId: Int,
val subject: String,
val description: String,
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
@ColumnInfo(name = "is_notified")
var isNotified: Boolean = true
}

View file

@ -2,14 +2,16 @@ package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable import java.io.Serializable
@Entity( @Entity(tableName = "MessageAttachments")
tableName = "MessageAttachments",
primaryKeys = ["message_global_key", "url", "filename"],
)
data class MessageAttachment( data class MessageAttachment(
@PrimaryKey
@ColumnInfo(name = "real_id")
val realId: Int,
@ColumnInfo(name = "message_global_key") @ColumnInfo(name = "message_global_key")
val messageGlobalKey: String, val messageGlobalKey: String,

View file

@ -2,15 +2,11 @@ package io.github.wulkanowy.data.db.entities
import androidx.room.Embedded import androidx.room.Embedded
import androidx.room.Relation import androidx.room.Relation
import java.io.Serializable
data class MessageWithAttachment( data class MessageWithAttachment(
@Embedded @Embedded
val message: Message, val message: Message,
@Relation(parentColumn = "message_global_key", entityColumn = "message_global_key") @Relation(parentColumn = "message_global_key", entityColumn = "message_global_key")
val attachments: List<MessageAttachment>, val attachments: List<MessageAttachment>
)
@Relation(parentColumn = "correspondents", entityColumn = "author")
val mutedMessageSender: MutedMessageSender?,
) : Serializable

View file

@ -1,12 +0,0 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.Embedded
import androidx.room.Relation
data class MessageWithMutedAuthor(
@Embedded
val message: Message,
@Relation(parentColumn = "correspondents", entityColumn = "author")
val mutedMessageSender: MutedMessageSender?,
)

View file

@ -1,15 +0,0 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
@Entity(tableName = "MutedMessageSenders")
data class MutedMessageSender(
@ColumnInfo(name = "author")
val author: String,
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View file

@ -16,9 +16,7 @@ data class SchoolAnnouncement(
val subject: String, val subject: String,
val content: String, val content: String
val author: String? = null,
) : Serializable { ) : Serializable {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)

View file

@ -19,9 +19,6 @@ data class Student(
@ColumnInfo(name = "scrapper_base_url") @ColumnInfo(name = "scrapper_base_url")
val scrapperBaseUrl: String, val scrapperBaseUrl: String,
@ColumnInfo(name = "scrapper_domain_suffix", defaultValue = "")
val scrapperDomainSuffix: String,
@ColumnInfo(name = "mobile_base_url") @ColumnInfo(name = "mobile_base_url")
val mobileBaseUrl: String, val mobileBaseUrl: String,
@ -78,13 +75,6 @@ data class Student(
@ColumnInfo(name = "registration_date") @ColumnInfo(name = "registration_date")
val registrationDate: Instant, val registrationDate: Instant,
@ColumnInfo(name = "is_authorized", defaultValue = "0")
val isAuthorized: Boolean,
@ColumnInfo(name = "is_edu_one", defaultValue = "NULL")
val isEduOne: Boolean?,
) : Serializable { ) : Serializable {
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
@ -95,22 +85,3 @@ data class Student(
@ColumnInfo(name = "avatar_color") @ColumnInfo(name = "avatar_color")
var avatarColor = 0L var avatarColor = 0L
} }
@Entity
data class StudentIsAuthorized(
@PrimaryKey
var id: Long,
@ColumnInfo(name = "is_authorized", defaultValue = "NULL")
val isAuthorized: Boolean?,
) : Serializable
@Entity
data class StudentIsEduOne(
@PrimaryKey
var id: Long,
@ColumnInfo(name = "is_edu_one", defaultValue = "NULL")
val isEduOne: Boolean?,
) : Serializable

View file

@ -1,18 +0,0 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
@Entity
data class StudentName(
@ColumnInfo(name = "student_name")
val studentName: String
) : Serializable {
@PrimaryKey
var id: Long = 0
}

View file

@ -1,8 +1,13 @@
package io.github.wulkanowy.data.db.entities package io.github.wulkanowy.data.db.entities
import androidx.room.Embedded
import androidx.room.Relation
import java.io.Serializable import java.io.Serializable
data class StudentWithSemesters( data class StudentWithSemesters(
@Embedded
val student: Student, val student: Student,
@Relation(parentColumn = "student_id", entityColumn = "student_id")
val semesters: List<Semester> val semesters: List<Semester>
) : Serializable ) : Serializable

View file

@ -5,7 +5,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration10 : Migration(9, 10) { class Migration10 : Migration(9, 10) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE Grades_Summary RENAME TO GradesSummary") database.execSQL("ALTER TABLE Grades_Summary RENAME TO GradesSummary")
} }
} }

View file

@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration11 : Migration(10, 11) { class Migration11 : Migration(10, 11) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS Grades_temp ( CREATE TABLE IF NOT EXISTS Grades_temp (
id INTEGER PRIMARY KEY NOT NULL, id INTEGER PRIMARY KEY NOT NULL,
is_read INTEGER NOT NULL, is_read INTEGER NOT NULL,
@ -27,10 +26,9 @@ class Migration11 : Migration(10, 11) {
date INTEGER NOT NULL, date INTEGER NOT NULL,
teacher TEXT NOT NULL teacher TEXT NOT NULL
) )
""" """)
) database.execSQL("INSERT INTO Grades_temp SELECT * FROM Grades")
db.execSQL("INSERT INTO Grades_temp SELECT * FROM Grades") database.execSQL("DROP TABLE Grades")
db.execSQL("DROP TABLE Grades") database.execSQL("ALTER TABLE Grades_temp RENAME TO Grades")
db.execSQL("ALTER TABLE Grades_temp RENAME TO Grades")
} }
} }

View file

@ -5,17 +5,16 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration12 : Migration(11, 12) { class Migration12 : Migration(11, 12) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
createTempStudentsTable(db) createTempStudentsTable(database)
replaceStudentTable(db) replaceStudentTable(database)
updateStudentsWithClassId(db, getStudentsIds(db)) updateStudentsWithClassId(database, getStudentsIds(database))
removeStudentsWithNoClassId(db) removeStudentsWithNoClassId(database)
ensureThereIsOnlyOneCurrentStudent(db) ensureThereIsOnlyOneCurrentStudent(database)
} }
private fun createTempStudentsTable(db: SupportSQLiteDatabase) { private fun createTempStudentsTable(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS Students_tmp ( CREATE TABLE IF NOT EXISTS Students_tmp (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
endpoint TEXT NOT NULL, endpoint TEXT NOT NULL,
@ -31,16 +30,15 @@ class Migration12 : Migration(11, 12) {
registration_date INTEGER NOT NULL, registration_date INTEGER NOT NULL,
class_id INTEGER NOT NULL class_id INTEGER NOT NULL
) )
""" """)
) database.execSQL("CREATE UNIQUE INDEX index_Students_email_symbol_student_id_school_id_class_id ON Students_tmp (email, symbol, student_id, school_id, class_id)")
db.execSQL("CREATE UNIQUE INDEX index_Students_email_symbol_student_id_school_id_class_id ON Students_tmp (email, symbol, student_id, school_id, class_id)")
} }
private fun replaceStudentTable(db: SupportSQLiteDatabase) { private fun replaceStudentTable(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE Students ADD COLUMN class_id INTEGER DEFAULT 0 NOT NULL") database.execSQL("ALTER TABLE Students ADD COLUMN class_id INTEGER DEFAULT 0 NOT NULL")
db.execSQL("INSERT INTO Students_tmp SELECT * FROM Students") database.execSQL("INSERT INTO Students_tmp SELECT * FROM Students")
db.execSQL("DROP TABLE Students") database.execSQL("DROP TABLE Students")
db.execSQL("ALTER TABLE Students_tmp RENAME TO Students") database.execSQL("ALTER TABLE Students_tmp RENAME TO Students")
} }
private fun getStudentsIds(database: SupportSQLiteDatabase): List<Int> { private fun getStudentsIds(database: SupportSQLiteDatabase): List<Int> {
@ -56,18 +54,18 @@ class Migration12 : Migration(11, 12) {
return students return students
} }
private fun updateStudentsWithClassId(db: SupportSQLiteDatabase, students: List<Int>) { private fun updateStudentsWithClassId(database: SupportSQLiteDatabase, students: List<Int>) {
students.forEach { students.forEach {
db.execSQL("UPDATE Students SET class_id = IFNULL((SELECT class_id FROM Semesters WHERE student_id = $it), 0) WHERE student_id = $it") database.execSQL("UPDATE Students SET class_id = IFNULL((SELECT class_id FROM Semesters WHERE student_id = $it), 0) WHERE student_id = $it")
} }
} }
private fun removeStudentsWithNoClassId(db: SupportSQLiteDatabase) { private fun removeStudentsWithNoClassId(database: SupportSQLiteDatabase) {
db.execSQL("DELETE FROM Students WHERE class_id = 0") database.execSQL("DELETE FROM Students WHERE class_id = 0")
} }
private fun ensureThereIsOnlyOneCurrentStudent(db: SupportSQLiteDatabase) { private fun ensureThereIsOnlyOneCurrentStudent(database: SupportSQLiteDatabase) {
db.execSQL("UPDATE Students SET is_current = 0") database.execSQL("UPDATE Students SET is_current = 0")
db.execSQL("UPDATE Students SET is_current = 1 WHERE id = (SELECT MAX(id) FROM Students)") database.execSQL("UPDATE Students SET is_current = 1 WHERE id = (SELECT MAX(id) FROM Students)")
} }
} }

View file

@ -5,30 +5,27 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration13 : Migration(12, 13) { class Migration13 : Migration(12, 13) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
addClassNameToStudents(db, getStudentsIds(db)) addClassNameToStudents(database, getStudentsIds(database))
updateSemestersTable(db) updateSemestersTable(database)
markAtLeastAndOnlyOneSemesterAtCurrent(db, getStudentsAndClassIds(db)) markAtLeastAndOnlyOneSemesterAtCurrent(database, getStudentsAndClassIds(database))
clearMessagesTable(db) clearMessagesTable(database)
} }
private fun addClassNameToStudents( private fun addClassNameToStudents(database: SupportSQLiteDatabase, students: List<Pair<Int, String>>) {
db: SupportSQLiteDatabase, database.execSQL("ALTER TABLE Students ADD COLUMN class_name TEXT DEFAULT \"\" NOT NULL")
students: List<Pair<Int, String>>
) {
db.execSQL("ALTER TABLE Students ADD COLUMN class_name TEXT DEFAULT \"\" NOT NULL")
students.forEach { (id, name) -> students.forEach { (id, name) ->
val schoolName = name.substringAfter(" - ") val schoolName = name.substringAfter(" - ")
val className = name.substringBefore(" - ", "").replace("Klasa ", "") val className = name.substringBefore(" - ", "").replace("Klasa ", "")
db.execSQL("UPDATE Students SET class_name = '$className' WHERE id = '$id'") database.execSQL("UPDATE Students SET class_name = '$className' WHERE id = '$id'")
db.execSQL("UPDATE Students SET school_name = '$schoolName' WHERE id = '$id'") database.execSQL("UPDATE Students SET school_name = '$schoolName' WHERE id = '$id'")
} }
} }
private fun getStudentsIds(db: SupportSQLiteDatabase): MutableList<Pair<Int, String>> { private fun getStudentsIds(database: SupportSQLiteDatabase): MutableList<Pair<Int, String>> {
val students = mutableListOf<Pair<Int, String>>() val students = mutableListOf<Pair<Int, String>>()
db.query("SELECT id, school_name FROM Students").use { database.query("SELECT id, school_name FROM Students").use {
if (it.moveToFirst()) { if (it.moveToFirst()) {
do { do {
students.add(it.getInt(0) to it.getString(1)) students.add(it.getInt(0) to it.getString(1))
@ -39,15 +36,15 @@ class Migration13 : Migration(12, 13) {
return students return students
} }
private fun updateSemestersTable(db: SupportSQLiteDatabase) { private fun updateSemestersTable(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE Semesters ADD COLUMN school_year INTEGER DEFAULT 1970 NOT NULL") database.execSQL("ALTER TABLE Semesters ADD COLUMN school_year INTEGER DEFAULT 1970 NOT NULL")
db.execSQL("ALTER TABLE Semesters ADD COLUMN start INTEGER DEFAULT 0 NOT NULL") database.execSQL("ALTER TABLE Semesters ADD COLUMN start INTEGER DEFAULT 0 NOT NULL")
db.execSQL("ALTER TABLE Semesters ADD COLUMN `end` INTEGER DEFAULT 0 NOT NULL") database.execSQL("ALTER TABLE Semesters ADD COLUMN `end` INTEGER DEFAULT 0 NOT NULL")
} }
private fun getStudentsAndClassIds(db: SupportSQLiteDatabase): List<Pair<Int, Int>> { private fun getStudentsAndClassIds(database: SupportSQLiteDatabase): List<Pair<Int, Int>> {
val students = mutableListOf<Pair<Int, Int>>() val students = mutableListOf<Pair<Int, Int>>()
db.query("SELECT student_id, class_id FROM Students").use { database.query("SELECT student_id, class_id FROM Students").use {
if (it.moveToFirst()) { if (it.moveToFirst()) {
do { do {
students.add(it.getInt(0) to it.getInt(1)) students.add(it.getInt(0) to it.getInt(1))
@ -58,17 +55,14 @@ class Migration13 : Migration(12, 13) {
return students return students
} }
private fun markAtLeastAndOnlyOneSemesterAtCurrent( private fun markAtLeastAndOnlyOneSemesterAtCurrent(database: SupportSQLiteDatabase, students: List<Pair<Int, Int>>) {
db: SupportSQLiteDatabase,
students: List<Pair<Int, Int>>
) {
students.forEach { (studentId, classId) -> students.forEach { (studentId, classId) ->
db.execSQL("UPDATE Semesters SET is_current = 0 WHERE student_id = '$studentId' AND class_id = '$classId'") database.execSQL("UPDATE Semesters SET is_current = 0 WHERE student_id = '$studentId' AND class_id = '$classId'")
db.execSQL("UPDATE Semesters SET is_current = 1 WHERE id = (SELECT id FROM Semesters WHERE student_id = '$studentId' AND class_id = '$classId' ORDER BY semester_id DESC)") database.execSQL("UPDATE Semesters SET is_current = 1 WHERE id = (SELECT id FROM Semesters WHERE student_id = '$studentId' AND class_id = '$classId' ORDER BY semester_id DESC)")
} }
} }
private fun clearMessagesTable(db: SupportSQLiteDatabase) { private fun clearMessagesTable(database: SupportSQLiteDatabase) {
db.execSQL("DELETE FROM Messages") database.execSQL("DELETE FROM Messages")
} }
} }

View file

@ -5,10 +5,9 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration14 : Migration(13, 14) { class Migration14 : Migration(13, 14) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("DROP TABLE IF EXISTS GradesSummary") database.execSQL("DROP TABLE IF EXISTS GradesSummary")
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS GradesSummary ( CREATE TABLE IF NOT EXISTS GradesSummary (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
semester_id INTEGER NOT NULL, semester_id INTEGER NOT NULL,

View file

@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration15 : Migration(14, 15) { class Migration15 : Migration(14, 15) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS MobileDevices ( CREATE TABLE IF NOT EXISTS MobileDevices (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL, student_id INTEGER NOT NULL,
@ -15,7 +14,6 @@ class Migration15 : Migration(14, 15) {
name TEXT NOT NULL, name TEXT NOT NULL,
date INTEGER NOT NULL date INTEGER NOT NULL
) )
""" """)
)
} }
} }

View file

@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration16 : Migration(15, 16) { class Migration16 : Migration(15, 16) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS Teachers ( CREATE TABLE IF NOT EXISTS Teachers (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL, student_id INTEGER NOT NULL,
@ -16,7 +15,6 @@ class Migration16 : Migration(15, 16) {
name TEXT NOT NULL, name TEXT NOT NULL,
short_name TEXT NOT NULL short_name TEXT NOT NULL
) )
""" """)
)
} }
} }

View file

@ -5,14 +5,13 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration17 : Migration(16, 17) { class Migration17 : Migration(16, 17) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
createGradesPointsStatisticsTable(db) createGradesPointsStatisticsTable(database)
truncateSemestersTable(db) truncateSemestersTable(database)
} }
private fun createGradesPointsStatisticsTable(db: SupportSQLiteDatabase) { private fun createGradesPointsStatisticsTable(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS GradesPointsStatistics( CREATE TABLE IF NOT EXISTS GradesPointsStatistics(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL, student_id INTEGER NOT NULL,
@ -21,11 +20,10 @@ class Migration17 : Migration(16, 17) {
others REAL NOT NULL, others REAL NOT NULL,
student REAL NOT NULL student REAL NOT NULL
) )
""" """)
)
} }
private fun truncateSemestersTable(db: SupportSQLiteDatabase) { private fun truncateSemestersTable(database: SupportSQLiteDatabase) {
db.execSQL("DELETE FROM Semesters") database.execSQL("DELETE FROM Semesters")
} }
} }

View file

@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration18 : Migration(17, 18) { class Migration18 : Migration(17, 18) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS School ( CREATE TABLE IF NOT EXISTS School (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL, student_id INTEGER NOT NULL,

View file

@ -6,17 +6,16 @@ import io.github.wulkanowy.data.db.SharedPrefProvider
class Migration19(private val sharedPrefProvider: SharedPrefProvider) : Migration(18, 19) { class Migration19(private val sharedPrefProvider: SharedPrefProvider) : Migration(18, 19) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
migrateMessages(db) migrateMessages(database)
migrateGrades(db) migrateGrades(database)
migrateStudents(db) migrateStudents(database)
migrateSharedPreferences() migrateSharedPreferences()
} }
private fun migrateMessages(db: SupportSQLiteDatabase) { private fun migrateMessages(database: SupportSQLiteDatabase) {
db.execSQL("DROP TABLE Messages") database.execSQL("DROP TABLE Messages")
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS Messages ( CREATE TABLE IF NOT EXISTS Messages (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
is_notified INTEGER NOT NULL, is_notified INTEGER NOT NULL,
@ -35,14 +34,12 @@ class Migration19(private val sharedPrefProvider: SharedPrefProvider) : Migratio
read_by INTEGER NOT NULL, read_by INTEGER NOT NULL,
removed INTEGER NOT NULL removed INTEGER NOT NULL
) )
""" """)
)
} }
private fun migrateGrades(db: SupportSQLiteDatabase) { private fun migrateGrades(database: SupportSQLiteDatabase) {
db.execSQL("DROP TABLE Grades") database.execSQL("DROP TABLE Grades")
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS Grades ( CREATE TABLE IF NOT EXISTS Grades (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
is_read INTEGER NOT NULL, is_read INTEGER NOT NULL,
@ -62,13 +59,11 @@ class Migration19(private val sharedPrefProvider: SharedPrefProvider) : Migratio
date INTEGER NOT NULL, date INTEGER NOT NULL,
teacher TEXT NOT NULL teacher TEXT NOT NULL
) )
""" """)
)
} }
private fun migrateStudents(db: SupportSQLiteDatabase) { private fun migrateStudents(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS Students_tmp ( CREATE TABLE IF NOT EXISTS Students_tmp (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
scrapper_base_url TEXT NOT NULL, scrapper_base_url TEXT NOT NULL,
@ -91,29 +86,26 @@ class Migration19(private val sharedPrefProvider: SharedPrefProvider) : Migratio
is_current INTEGER NOT NULL, is_current INTEGER NOT NULL,
registration_date INTEGER NOT NULL registration_date INTEGER NOT NULL
) )
""" """)
)
db.execSQL("ALTER TABLE Students ADD COLUMN scrapperBaseUrl TEXT NOT NULL DEFAULT \"\";") database.execSQL("ALTER TABLE Students ADD COLUMN scrapperBaseUrl TEXT NOT NULL DEFAULT \"\";")
db.execSQL("ALTER TABLE Students ADD COLUMN apiBaseUrl TEXT NOT NULL DEFAULT \"\";") database.execSQL("ALTER TABLE Students ADD COLUMN apiBaseUrl TEXT NOT NULL DEFAULT \"\";")
db.execSQL("ALTER TABLE Students ADD COLUMN is_parent INT NOT NULL DEFAULT 0;") database.execSQL("ALTER TABLE Students ADD COLUMN is_parent INT NOT NULL DEFAULT 0;")
db.execSQL("ALTER TABLE Students ADD COLUMN loginMode TEXT NOT NULL DEFAULT \"\";") database.execSQL("ALTER TABLE Students ADD COLUMN loginMode TEXT NOT NULL DEFAULT \"\";")
db.execSQL("ALTER TABLE Students ADD COLUMN certificateKey TEXT NOT NULL DEFAULT \"\";") database.execSQL("ALTER TABLE Students ADD COLUMN certificateKey TEXT NOT NULL DEFAULT \"\";")
db.execSQL("ALTER TABLE Students ADD COLUMN privateKey TEXT NOT NULL DEFAULT \"\";") database.execSQL("ALTER TABLE Students ADD COLUMN privateKey TEXT NOT NULL DEFAULT \"\";")
db.execSQL("ALTER TABLE Students ADD COLUMN user_login_id INTEGER NOT NULL DEFAULT 0;") database.execSQL("ALTER TABLE Students ADD COLUMN user_login_id INTEGER NOT NULL DEFAULT 0;")
db.execSQL( database.execSQL("""
"""
INSERT INTO Students_tmp( INSERT INTO Students_tmp(
id, scrapper_base_url, mobile_base_url, is_parent, login_type, login_mode, certificate_key, private_key, email, password, symbol, student_id, user_login_id, student_name, school_id, school_name, school_id, school_name, class_name, class_id, is_current, registration_date) id, scrapper_base_url, mobile_base_url, is_parent, login_type, login_mode, certificate_key, private_key, email, password, symbol, student_id, user_login_id, student_name, school_id, school_name, school_id, school_name, class_name, class_id, is_current, registration_date)
SELECT SELECT
id, endpoint, apiBaseUrl, is_parent, loginType, "SCRAPPER", certificateKey, privateKey, email, password, symbol, student_id, user_login_id, student_name, school_id, school_name, school_id, school_name, class_name, class_id, is_current, registration_date id, endpoint, apiBaseUrl, is_parent, loginType, "SCRAPPER", certificateKey, privateKey, email, password, symbol, student_id, user_login_id, student_name, school_id, school_name, school_id, school_name, class_name, class_id, is_current, registration_date
FROM Students FROM Students
""" """)
) database.execSQL("DROP TABLE Students")
db.execSQL("DROP TABLE Students") database.execSQL("ALTER TABLE Students_tmp RENAME TO Students")
db.execSQL("ALTER TABLE Students_tmp RENAME TO Students") database.execSQL("CREATE UNIQUE INDEX index_Students_email_symbol_student_id_school_id_class_id ON Students (email, symbol, student_id, school_id, class_id)")
db.execSQL("CREATE UNIQUE INDEX index_Students_email_symbol_student_id_school_id_class_id ON Students (email, symbol, student_id, school_id, class_id)")
} }
private fun migrateSharedPreferences() { private fun migrateSharedPreferences() {

View file

@ -5,16 +5,14 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration2 : Migration(1, 2) { class Migration2 : Migration(1, 2) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS LuckyNumbers ( CREATE TABLE IF NOT EXISTS LuckyNumbers (
id INTEGER PRIMARY KEY NOT NULL, id INTEGER PRIMARY KEY NOT NULL,
is_notified INTEGER NOT NULL, is_notified INTEGER NOT NULL,
student_id INTEGER NOT NULL, student_id INTEGER NOT NULL,
date INTEGER NOT NULL, date INTEGER NOT NULL,
lucky_number INTEGER NOT NULL) lucky_number INTEGER NOT NULL)
""" """)
)
} }
} }

View file

@ -5,15 +5,14 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration20 : Migration(19, 20) { class Migration20 : Migration(19, 20) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
migrateTimetable(db) migrateTimetable(database)
truncateSubjects(db) truncateSubjects(database)
} }
private fun migrateTimetable(db: SupportSQLiteDatabase) { private fun migrateTimetable(database: SupportSQLiteDatabase) {
db.execSQL("DROP TABLE Timetable") database.execSQL("DROP TABLE Timetable")
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS `Timetable` ( CREATE TABLE IF NOT EXISTS `Timetable` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
`student_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL,
@ -34,11 +33,10 @@ class Migration20 : Migration(19, 20) {
`changes` INTEGER NOT NULL, `changes` INTEGER NOT NULL,
`canceled` INTEGER NOT NULL `canceled` INTEGER NOT NULL
) )
""" """)
)
} }
private fun truncateSubjects(db: SupportSQLiteDatabase) { private fun truncateSubjects(database: SupportSQLiteDatabase) {
db.execSQL("DELETE FROM Subjects") database.execSQL("DELETE FROM Subjects")
} }
} }

View file

@ -5,11 +5,11 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration21 : Migration(20, 21) { class Migration21 : Migration(20, 21) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE Attendance ADD COLUMN excusable INTEGER NOT NULL DEFAULT 0") database.execSQL("ALTER TABLE Attendance ADD COLUMN excusable INTEGER NOT NULL DEFAULT 0")
db.execSQL("ALTER TABLE Attendance ADD COLUMN time_id INTEGER NOT NULL DEFAULT 0") database.execSQL("ALTER TABLE Attendance ADD COLUMN time_id INTEGER NOT NULL DEFAULT 0")
db.execSQL("ALTER TABLE Attendance ADD COLUMN excuse_status TEXT DEFAULT NULL") database.execSQL("ALTER TABLE Attendance ADD COLUMN excuse_status TEXT DEFAULT NULL")
db.execSQL("DELETE FROM Semesters") database.execSQL("DELETE FROM Semesters")
} }
} }

View file

@ -5,7 +5,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration22 : Migration(21, 22) { class Migration22 : Migration(21, 22) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE Students ADD COLUMN school_short TEXT NOT NULL DEFAULT ''") database.execSQL("ALTER TABLE Students ADD COLUMN school_short TEXT NOT NULL DEFAULT ''")
} }
} }

View file

@ -5,10 +5,10 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration23 : Migration(22, 23) { class Migration23 : Migration(22, 23) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE Notes ADD COLUMN teacher_symbol TEXT NOT NULL DEFAULT ''") database.execSQL("ALTER TABLE Notes ADD COLUMN teacher_symbol TEXT NOT NULL DEFAULT ''")
db.execSQL("ALTER TABLE Notes ADD COLUMN category_type INTEGER NOT NULL DEFAULT 0") database.execSQL("ALTER TABLE Notes ADD COLUMN category_type INTEGER NOT NULL DEFAULT 0")
db.execSQL("ALTER TABLE Notes ADD COLUMN is_points_show INTEGER NOT NULL DEFAULT 0") database.execSQL("ALTER TABLE Notes ADD COLUMN is_points_show INTEGER NOT NULL DEFAULT 0")
db.execSQL("ALTER TABLE Notes ADD COLUMN points INTEGER NOT NULL DEFAULT 0") database.execSQL("ALTER TABLE Notes ADD COLUMN points INTEGER NOT NULL DEFAULT 0")
} }
} }

View file

@ -5,10 +5,9 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration24 : Migration(23, 24) { class Migration24 : Migration(23, 24) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE Messages ADD COLUMN has_attachments INTEGER NOT NULL DEFAULT 0") database.execSQL("ALTER TABLE Messages ADD COLUMN has_attachments INTEGER NOT NULL DEFAULT 0")
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS MessageAttachments ( CREATE TABLE IF NOT EXISTS MessageAttachments (
real_id INTEGER NOT NULL, real_id INTEGER NOT NULL,
message_id INTEGER NOT NULL, message_id INTEGER NOT NULL,
@ -17,7 +16,6 @@ class Migration24 : Migration(23, 24) {
filename TEXT NOT NULL, filename TEXT NOT NULL,
PRIMARY KEY(real_id) PRIMARY KEY(real_id)
) )
""" """)
)
} }
} }

View file

@ -5,8 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration25 : Migration(24, 25) { class Migration25 : Migration(24, 25) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE Homework ADD COLUMN is_done INTEGER NOT NULL DEFAULT 0") database.execSQL("ALTER TABLE Homework ADD COLUMN is_done INTEGER NOT NULL DEFAULT 0")
db.execSQL("ALTER TABLE Homework ADD COLUMN attachments TEXT NOT NULL DEFAULT \"[]\"") database.execSQL("ALTER TABLE Homework ADD COLUMN attachments TEXT NOT NULL DEFAULT \"[]\"")
} }
} }

View file

@ -5,10 +5,10 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration26 : Migration(25, 26) { class Migration26 : Migration(25, 26) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE GradesSummary ADD COLUMN is_predicted_grade_notified INTEGER NOT NULL DEFAULT 1") database.execSQL("ALTER TABLE GradesSummary ADD COLUMN is_predicted_grade_notified INTEGER NOT NULL DEFAULT 1")
db.execSQL("ALTER TABLE GradesSummary ADD COLUMN is_final_grade_notified INTEGER NOT NULL DEFAULT 1") database.execSQL("ALTER TABLE GradesSummary ADD COLUMN is_final_grade_notified INTEGER NOT NULL DEFAULT 1")
db.execSQL("ALTER TABLE GradesSummary ADD COLUMN predicted_grade_last_change INTEGER NOT NULL DEFAULT 0") database.execSQL("ALTER TABLE GradesSummary ADD COLUMN predicted_grade_last_change INTEGER NOT NULL DEFAULT 0")
db.execSQL("ALTER TABLE GradesSummary ADD COLUMN final_grade_last_change INTEGER NOT NULL DEFAULT 0") database.execSQL("ALTER TABLE GradesSummary ADD COLUMN final_grade_last_change INTEGER NOT NULL DEFAULT 0")
} }
} }

View file

@ -5,25 +5,24 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration27 : Migration(26, 27) { class Migration27 : Migration(26, 27) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE Students ADD COLUMN user_name TEXT NOT NULL DEFAULT \"\"") database.execSQL("ALTER TABLE Students ADD COLUMN user_name TEXT NOT NULL DEFAULT \"\"")
val students = getStudentsIdsAndNames(db) val students = getStudentsIdsAndNames(database)
val units = getReportingUnits(db) val units = getReportingUnits(database)
students.forEach { (id, userLoginId, studentName) -> students.forEach { (id, userLoginId, studentName) ->
val userNameFromUnits = val userNameFromUnits = units.singleOrNull { (senderId, _) -> senderId == userLoginId }?.second
units.singleOrNull { (senderId, _) -> senderId == userLoginId }?.second
val normalizedStudentName = studentName.split(" ").asReversed().joinToString(" ") val normalizedStudentName = studentName.split(" ").asReversed().joinToString(" ")
val userName = userNameFromUnits ?: normalizedStudentName val userName = userNameFromUnits ?: normalizedStudentName
db.execSQL("UPDATE Students SET user_name = '$userName' WHERE id = '$id'") database.execSQL("UPDATE Students SET user_name = '$userName' WHERE id = '$id'")
} }
} }
private fun getStudentsIdsAndNames(db: SupportSQLiteDatabase): MutableList<Triple<Long, Int, String>> { private fun getStudentsIdsAndNames(database: SupportSQLiteDatabase): MutableList<Triple<Long, Int, String>> {
val students = mutableListOf<Triple<Long, Int, String>>() val students = mutableListOf<Triple<Long, Int, String>>()
db.query("SELECT id, user_login_id, student_name FROM Students").use { database.query("SELECT id, user_login_id, student_name FROM Students").use {
if (it.moveToFirst()) { if (it.moveToFirst()) {
do { do {
students.add(Triple(it.getLong(0), it.getInt(1), it.getString(2))) students.add(Triple(it.getLong(0), it.getInt(1), it.getString(2)))
@ -34,9 +33,9 @@ class Migration27 : Migration(26, 27) {
return students return students
} }
private fun getReportingUnits(db: SupportSQLiteDatabase): MutableList<Pair<Int, String>> { private fun getReportingUnits(database: SupportSQLiteDatabase): MutableList<Pair<Int, String>> {
val units = mutableListOf<Pair<Int, String>>() val units = mutableListOf<Pair<Int, String>>()
db.query("SELECT sender_id, sender_name FROM ReportingUnits").use { database.query("SELECT sender_id, sender_name FROM ReportingUnits").use {
if (it.moveToFirst()) { if (it.moveToFirst()) {
do { do {
units.add(it.getInt(0) to it.getString(1)) units.add(it.getInt(0) to it.getString(1))

View file

@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration28 : Migration(27, 28) { class Migration28 : Migration(27, 28) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS Conferences ( CREATE TABLE IF NOT EXISTS Conferences (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL, student_id INTEGER NOT NULL,

View file

@ -5,10 +5,9 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration29 : Migration(28, 29) { class Migration29 : Migration(28, 29) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("DROP TABLE IF EXISTS GradesStatistics") database.execSQL("DROP TABLE IF EXISTS GradesStatistics")
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS GradeSemesterStatistics ( CREATE TABLE IF NOT EXISTS GradeSemesterStatistics (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL, student_id INTEGER NOT NULL,
@ -17,10 +16,8 @@ class Migration29 : Migration(28, 29) {
amounts TEXT NOT NULL, amounts TEXT NOT NULL,
student_grade INTEGER NOT NULL student_grade INTEGER NOT NULL
) )
""" """)
) database.execSQL("""
db.execSQL(
"""
CREATE TABLE IF NOT EXISTS GradePartialStatistics ( CREATE TABLE IF NOT EXISTS GradePartialStatistics (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL, student_id INTEGER NOT NULL,

View file

@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration3 : Migration(2, 3) { class Migration3 : Migration(2, 3) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS CompletedLesson ( CREATE TABLE IF NOT EXISTS CompletedLesson (
id INTEGER PRIMARY KEY NOT NULL, id INTEGER PRIMARY KEY NOT NULL,
student_id INTEGER NOT NULL, student_id INTEGER NOT NULL,

View file

@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration30 : Migration(29, 30) { class Migration30 : Migration(29, 30) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL("""
"""
CREATE TABLE TimetableAdditional ( CREATE TABLE TimetableAdditional (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL, student_id INTEGER NOT NULL,
@ -17,7 +16,6 @@ class Migration30 : Migration(29, 30) {
date INTEGER NOT NULL, date INTEGER NOT NULL,
subject TEXT NOT NULL subject TEXT NOT NULL
) )
""" """)
)
} }
} }

View file

@ -5,8 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration31 : Migration(30, 31) { class Migration31 : Migration(30, 31) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL(
"""CREATE TABLE IF NOT EXISTS StudentInfo ( """CREATE TABLE IF NOT EXISTS StudentInfo (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL, student_id INTEGER NOT NULL,

View file

@ -5,8 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration32 : Migration(31, 32) { class Migration32 : Migration(31, 32) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE Students ADD COLUMN nick TEXT NOT NULL DEFAULT \"\"") database.execSQL("ALTER TABLE Students ADD COLUMN nick TEXT NOT NULL DEFAULT \"\"")
} }
} }

View file

@ -5,10 +5,10 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration33 : Migration(32, 33) { class Migration33 : Migration(32, 33) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("DROP TABLE IF EXISTS StudentInfo") database.execSQL("DROP TABLE IF EXISTS StudentInfo")
db.execSQL( database.execSQL(
"""CREATE TABLE IF NOT EXISTS StudentInfo ( """CREATE TABLE IF NOT EXISTS StudentInfo (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL, student_id INTEGER NOT NULL,

View file

@ -5,9 +5,9 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration34 : Migration(33, 34) { class Migration34 : Migration(33, 34) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("DELETE FROM ReportingUnits") database.execSQL("DELETE FROM ReportingUnits")
db.execSQL("DELETE FROM Recipients") database.execSQL("DELETE FROM Recipients")
} }
} }

View file

@ -7,13 +7,13 @@ import io.github.wulkanowy.utils.AppInfo
class Migration35(private val appInfo: AppInfo) : Migration(34, 35) { class Migration35(private val appInfo: AppInfo) : Migration(34, 35) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE Students ADD COLUMN `avatar_color` INTEGER NOT NULL DEFAULT 0") database.execSQL("ALTER TABLE Students ADD COLUMN `avatar_color` INTEGER NOT NULL DEFAULT 0")
db.query("SELECT * FROM Students").use { database.query("SELECT * FROM Students").use {
while (it.moveToNext()) { while (it.moveToNext()) {
val studentId = it.getLongOrNull(0) val studentId = it.getLongOrNull(0)
db.execSQL( database.execSQL(
""" """
UPDATE Students UPDATE Students
SET avatar_color = ${appInfo.defaultColorsForAvatar.random()} SET avatar_color = ${appInfo.defaultColorsForAvatar.random()}

View file

@ -5,8 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration36 : Migration(35, 36) { class Migration36 : Migration(35, 36) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE Exams ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1") database.execSQL("ALTER TABLE Exams ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1")
db.execSQL("ALTER TABLE Homework ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1") database.execSQL("ALTER TABLE Homework ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1")
} }
} }

View file

@ -5,8 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration37 : Migration(36, 37) { class Migration37 : Migration(36, 37) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL(
""" """
CREATE TABLE IF NOT EXISTS TimetableHeaders ( CREATE TABLE IF NOT EXISTS TimetableHeaders (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,

View file

@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration38 : Migration(37, 38) { class Migration38 : Migration(37, 38) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS `SchoolAnnouncements` ( CREATE TABLE IF NOT EXISTS `SchoolAnnouncements` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
`student_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL,
@ -15,7 +14,6 @@ class Migration38 : Migration(37, 38) {
`subject` TEXT NOT NULL, `subject` TEXT NOT NULL,
`content` TEXT NOT NULL `content` TEXT NOT NULL
) )
""" """)
)
} }
} }

View file

@ -5,8 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration39 : Migration(38, 39) { class Migration39 : Migration(38, 39) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE Conferences ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1") database.execSQL("ALTER TABLE Conferences ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1")
db.execSQL("ALTER TABLE SchoolAnnouncements ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1") database.execSQL("ALTER TABLE SchoolAnnouncements ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1")
} }
} }

View file

@ -5,10 +5,9 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration4 : Migration(3, 4) { class Migration4 : Migration(3, 4) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("DROP TABLE IF EXISTS Messages") database.execSQL("DROP TABLE IF EXISTS Messages")
db.execSQL( database.execSQL("""
"""
CREATE TABLE IF NOT EXISTS Messages ( CREATE TABLE IF NOT EXISTS Messages (
id INTEGER PRIMARY KEY NOT NULL, id INTEGER PRIMARY KEY NOT NULL,
is_notified INTEGER NOT NULL, is_notified INTEGER NOT NULL,

View file

@ -5,8 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration40 : Migration(39, 40) { class Migration40 : Migration(39, 40) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL(
""" """
CREATE TABLE IF NOT EXISTS `Notifications` ( CREATE TABLE IF NOT EXISTS `Notifications` (
`student_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL,
@ -20,4 +20,4 @@ class Migration40 : Migration(39, 40) {
""" """
) )
} }
} }

View file

@ -7,9 +7,9 @@ import io.github.wulkanowy.data.enums.GradeExpandMode
class Migration41(private val sharedPrefProvider: SharedPrefProvider) : Migration(40, 41) { class Migration41(private val sharedPrefProvider: SharedPrefProvider) : Migration(40, 41) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
migrateSharedPreferences() migrateSharedPreferences()
db.execSQL("ALTER TABLE Homework ADD COLUMN is_added_by_user INTEGER NOT NULL DEFAULT 0") database.execSQL("ALTER TABLE Homework ADD COLUMN is_added_by_user INTEGER NOT NULL DEFAULT 0")
} }
private fun migrateSharedPreferences() { private fun migrateSharedPreferences() {
@ -18,4 +18,4 @@ class Migration41(private val sharedPrefProvider: SharedPrefProvider) : Migratio
} }
sharedPrefProvider.delete("pref_key_expand_grade") sharedPrefProvider.delete("pref_key_expand_grade")
} }
} }

View file

@ -5,8 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration42 : Migration(41, 42) { class Migration42 : Migration(41, 42) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL( database.execSQL(
"""CREATE TABLE IF NOT EXISTS `AdminMessages` ( """CREATE TABLE IF NOT EXISTS `AdminMessages` (
`id` INTEGER NOT NULL, `id` INTEGER NOT NULL,
`title` TEXT NOT NULL, `title` TEXT NOT NULL,
@ -21,4 +21,4 @@ class Migration42 : Migration(41, 42) {
PRIMARY KEY(`id`))""" PRIMARY KEY(`id`))"""
) )
} }
} }

View file

@ -5,8 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration43 : Migration(42, 43) { class Migration43 : Migration(42, 43) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE Timetable ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1") database.execSQL("ALTER TABLE Timetable ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1")
db.execSQL("ALTER TABLE Attendance ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1") database.execSQL("ALTER TABLE Attendance ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1")
} }
} }

View file

@ -5,7 +5,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration44 : Migration(43, 44) { class Migration44 : Migration(43, 44) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE AdminMessages ADD COLUMN is_dismissible INTEGER NOT NULL DEFAULT 0") database.execSQL("ALTER TABLE AdminMessages ADD COLUMN is_dismissible INTEGER NOT NULL DEFAULT 0")
} }
} }

View file

@ -8,65 +8,65 @@ import java.time.ZoneOffset
class Migration46 : Migration(45, 46) { class Migration46 : Migration(45, 46) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
migrateConferences(db) migrateConferences(database)
migrateMessages(db) migrateMessages(database)
migrateMobileDevices(db) migrateMobileDevices(database)
migrateNotifications(db) migrateNotifications(database)
migrateTimetable(db) migrateTimetable(database)
migrateTimetableAdditional(db) migrateTimetableAdditional(database)
} }
private fun migrateConferences(db: SupportSQLiteDatabase) { private fun migrateConferences(database: SupportSQLiteDatabase) {
db.query("SELECT * FROM Conferences").use { database.query("SELECT * FROM Conferences").use {
while (it.moveToNext()) { while (it.moveToNext()) {
val id = it.getLong(it.getColumnIndexOrThrow("id")) val id = it.getLong(it.getColumnIndexOrThrow("id"))
val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date")) val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date"))
val timestampUtc = timestampLocal.timestampLocalToUTC() val timestampUtc = timestampLocal.timestampLocalToUTC()
db.execSQL("UPDATE Conferences SET date = $timestampUtc WHERE id = $id") database.execSQL("UPDATE Conferences SET date = $timestampUtc WHERE id = $id")
} }
} }
} }
private fun migrateMessages(db: SupportSQLiteDatabase) { private fun migrateMessages(database: SupportSQLiteDatabase) {
db.query("SELECT * FROM Messages").use { database.query("SELECT * FROM Messages").use {
while (it.moveToNext()) { while (it.moveToNext()) {
val id = it.getLong(it.getColumnIndexOrThrow("id")) val id = it.getLong(it.getColumnIndexOrThrow("id"))
val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date")) val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date"))
val timestampUtc = timestampLocal.timestampLocalToUTC() val timestampUtc = timestampLocal.timestampLocalToUTC()
db.execSQL("UPDATE Messages SET date = $timestampUtc WHERE id = $id") database.execSQL("UPDATE Messages SET date = $timestampUtc WHERE id = $id")
} }
} }
} }
private fun migrateMobileDevices(db: SupportSQLiteDatabase) { private fun migrateMobileDevices(database: SupportSQLiteDatabase) {
db.query("SELECT * FROM MobileDevices").use { database.query("SELECT * FROM MobileDevices").use {
while (it.moveToNext()) { while (it.moveToNext()) {
val id = it.getLong(it.getColumnIndexOrThrow("id")) val id = it.getLong(it.getColumnIndexOrThrow("id"))
val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date")) val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date"))
val timestampUtc = timestampLocal.timestampLocalToUTC() val timestampUtc = timestampLocal.timestampLocalToUTC()
db.execSQL("UPDATE MobileDevices SET date = $timestampUtc WHERE id = $id") database.execSQL("UPDATE MobileDevices SET date = $timestampUtc WHERE id = $id")
} }
} }
} }
private fun migrateNotifications(db: SupportSQLiteDatabase) { private fun migrateNotifications(database: SupportSQLiteDatabase) {
db.query("SELECT * FROM Notifications").use { database.query("SELECT * FROM Notifications").use {
while (it.moveToNext()) { while (it.moveToNext()) {
val id = it.getLong(it.getColumnIndexOrThrow("id")) val id = it.getLong(it.getColumnIndexOrThrow("id"))
val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date")) val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date"))
val timestampUtc = timestampLocal.timestampLocalToUTC() val timestampUtc = timestampLocal.timestampLocalToUTC()
db.execSQL("UPDATE Notifications SET date = $timestampUtc WHERE id = $id") database.execSQL("UPDATE Notifications SET date = $timestampUtc WHERE id = $id")
} }
} }
} }
private fun migrateTimetable(db: SupportSQLiteDatabase) { private fun migrateTimetable(database: SupportSQLiteDatabase) {
db.query("SELECT * FROM Timetable").use { database.query("SELECT * FROM Timetable").use {
while (it.moveToNext()) { while (it.moveToNext()) {
val id = it.getLong(it.getColumnIndexOrThrow("id")) val id = it.getLong(it.getColumnIndexOrThrow("id"))
val timestampLocalStart = it.getLong(it.getColumnIndexOrThrow("start")) val timestampLocalStart = it.getLong(it.getColumnIndexOrThrow("start"))
@ -74,13 +74,13 @@ class Migration46 : Migration(45, 46) {
val timestampUtcStart = timestampLocalStart.timestampLocalToUTC() val timestampUtcStart = timestampLocalStart.timestampLocalToUTC()
val timestampUtcEnd = timestampLocalEnd.timestampLocalToUTC() val timestampUtcEnd = timestampLocalEnd.timestampLocalToUTC()
db.execSQL("UPDATE Timetable SET start = $timestampUtcStart, end = $timestampUtcEnd WHERE id = $id") database.execSQL("UPDATE Timetable SET start = $timestampUtcStart, end = $timestampUtcEnd WHERE id = $id")
} }
} }
} }
private fun migrateTimetableAdditional(db: SupportSQLiteDatabase) { private fun migrateTimetableAdditional(database: SupportSQLiteDatabase) {
db.query("SELECT * FROM TimetableAdditional").use { database.query("SELECT * FROM TimetableAdditional").use {
while (it.moveToNext()) { while (it.moveToNext()) {
val id = it.getLong(it.getColumnIndexOrThrow("id")) val id = it.getLong(it.getColumnIndexOrThrow("id"))
val timestampLocalStart = it.getLong(it.getColumnIndexOrThrow("start")) val timestampLocalStart = it.getLong(it.getColumnIndexOrThrow("start"))
@ -88,7 +88,7 @@ class Migration46 : Migration(45, 46) {
val timestampUtcStart = timestampLocalStart.timestampLocalToUTC() val timestampUtcStart = timestampLocalStart.timestampLocalToUTC()
val timestampUtcEnd = timestampLocalEnd.timestampLocalToUTC() val timestampUtcEnd = timestampLocalEnd.timestampLocalToUTC()
db.execSQL("UPDATE TimetableAdditional SET start = $timestampUtcStart, end = $timestampUtcEnd WHERE id = $id") database.execSQL("UPDATE TimetableAdditional SET start = $timestampUtcStart, end = $timestampUtcEnd WHERE id = $id")
} }
} }
} }

View file

@ -5,10 +5,10 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration49 : Migration(48, 49) { class Migration49 : Migration(48, 49) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("DROP TABLE IF EXISTS SchoolAnnouncements") database.execSQL("DROP TABLE IF EXISTS SchoolAnnouncements")
db.execSQL( database.execSQL(
""" """
CREATE TABLE IF NOT EXISTS `SchoolAnnouncements` ( CREATE TABLE IF NOT EXISTS `SchoolAnnouncements` (
`user_login_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL,

View file

@ -7,16 +7,11 @@ import java.time.ZoneOffset
class Migration5 : Migration(4, 5) { class Migration5 : Migration(4, 5) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE Students ADD COLUMN registration_date INTEGER DEFAULT 0 NOT NULL") database.execSQL("ALTER TABLE Students ADD COLUMN registration_date INTEGER DEFAULT 0 NOT NULL")
db.execSQL( database.execSQL("UPDATE Students SET registration_date = '${now().atZone(ZoneOffset.UTC).toInstant().toEpochMilli()}'")
"UPDATE Students SET registration_date = '${ database.execSQL("DROP TABLE IF EXISTS Notes")
now().atZone(ZoneOffset.UTC).toInstant().toEpochMilli() database.execSQL("""
}'"
)
db.execSQL("DROP TABLE IF EXISTS Notes")
db.execSQL(
"""
CREATE TABLE IF NOT EXISTS Notes ( CREATE TABLE IF NOT EXISTS Notes (
id INTEGER PRIMARY KEY NOT NULL, id INTEGER PRIMARY KEY NOT NULL,
is_read INTEGER NOT NULL, is_read INTEGER NOT NULL,
@ -26,7 +21,6 @@ class Migration5 : Migration(4, 5) {
teacher TEXT NOT NULL, teacher TEXT NOT NULL,
category TEXT NOT NULL, category TEXT NOT NULL,
content TEXT NOT NULL) content TEXT NOT NULL)
""" """)
)
} }
} }

View file

@ -5,9 +5,9 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration50 : Migration(49, 50) { class Migration50 : Migration(49, 50) {
override fun migrate(db: SupportSQLiteDatabase) { override fun migrate(database: SupportSQLiteDatabase) {
db.execSQL("DROP TABLE IF EXISTS MobileDevices") database.execSQL("DROP TABLE IF EXISTS MobileDevices")
db.execSQL( database.execSQL(
""" """
CREATE TABLE IF NOT EXISTS `MobileDevices` ( CREATE TABLE IF NOT EXISTS `MobileDevices` (
`user_login_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL,

Some files were not shown because too many files have changed in this diff Show more