Skip to content

Commit

Permalink
Feature/added local storage implementation (#164)
Browse files Browse the repository at this point in the history
* Added local storage dependencies implementation

* Introduced remote data source dependency implementation

* Version update
  • Loading branch information
oleksandrsarapulovgl authored Jul 26, 2021
1 parent 501282d commit aa3909e
Show file tree
Hide file tree
Showing 29 changed files with 1,216 additions and 15 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ dependencies {
implementation Deps.androidx_navigation_fragment
implementation Deps.androidx_navigation_ui
implementation Deps.room_runtime
implementation Deps.room_ktx
implementation Deps.androidx_worker_ktx
implementation Deps.kotlinx_coroutines
implementation Deps.zxing
Expand All @@ -119,6 +120,7 @@ dependencies {
implementation Deps.retrofit2
implementation Deps.log_interceptor
implementation Deps.gson_converter
implementation Deps.jackson_kotlin

implementation Deps.timber

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* ---license-start
* eu-digital-green-certificates / dgca-verifier-app-android
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*
* Created by osarapulov on 7/26/21 11:53 AM
*/

package dgca.verifier.app.android.data.local.countries

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import kotlinx.coroutines.flow.Flow

@Dao
interface CountriesDao {
@Query("SELECT * from countries")
fun getAll(): Flow<List<CountryLocal>>

@Insert
fun insertAll(vararg countriesLocal: CountryLocal)

@Query("DELETE FROM countries")
fun deleteAll()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* ---license-start
* eu-digital-green-certificates / dgca-verifier-app-android
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*
* Created by osarapulov on 7/26/21 11:56 AM
*/

package dgca.verifier.app.android.data.local.countries

import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "countries")
data class CountryLocal(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
val isoCode: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* ---license-start
* eu-digital-green-certificates / dgca-verifier-app-android
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*
* Created by osarapulov on 7/26/21 11:56 AM
*/

package dgca.verifier.app.android.data.local.countries

import dgca.verifier.app.engine.data.source.local.countries.CountriesLocalDataSource
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import java.util.*

class DefaultCountriesLocalDataSource(private val countriesDao: CountriesDao) :
CountriesLocalDataSource {
override suspend fun updateCountries(countriesIsoCodes: List<String>) {
countriesDao.apply {
deleteAll()
insertAll(*countriesIsoCodes.map { it.toCountryLocal() }.toTypedArray())
}
}

override fun getCountries(): Flow<List<String>> =
countriesDao.getAll().map { it.map { it.toCountry() } }
}

fun String.toCountryLocal(): CountryLocal = CountryLocal(isoCode = this.toLowerCase(Locale.ROOT))

fun CountryLocal.toCountry(): String = this.isoCode
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* ---license-start
* eu-digital-green-certificates / dgca-verifier-app-android
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*
* Created by osarapulov on 7/26/21 11:59 AM
*/

package dgca.verifier.app.android.data.local.rules

import androidx.room.TypeConverter
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import dgca.verifier.app.engine.UTC_ZONE_ID
import java.time.Instant
import java.time.LocalDate
import java.time.ZonedDateTime
import java.time.temporal.ChronoUnit

class Converters {
@TypeConverter
fun timestampToLocalDate(value: Long?): LocalDate = if (value != null) {
val instant: Instant = Instant.ofEpochMilli(value)
ZonedDateTime.ofInstant(instant, UTC_ZONE_ID)
} else {
ZonedDateTime.now(UTC_ZONE_ID)
}.toLocalDate()

@TypeConverter
fun localDateToTimestamp(localDate: LocalDate?): Long {
return (localDate?.atStartOfDay(UTC_ZONE_ID)
?: ZonedDateTime.now(UTC_ZONE_ID)).toInstant().toEpochMilli()
}

@TypeConverter
fun fromTimestamp(value: Long?): ZonedDateTime = if (value != null) {
val instant: Instant = Instant.EPOCH.plus(value, ChronoUnit.MICROS)
ZonedDateTime.ofInstant(instant, UTC_ZONE_ID)
} else {
ZonedDateTime.now(UTC_ZONE_ID)
}

@TypeConverter
fun zonedDateTimeToTimestamp(zonedDateTime: ZonedDateTime?): Long {
return ChronoUnit.MICROS.between(
Instant.EPOCH,
(zonedDateTime?.withZoneSameInstant(UTC_ZONE_ID)
?: ZonedDateTime.now(UTC_ZONE_ID)).toInstant()
)
}

@TypeConverter
fun fromString(value: String?): List<String> {
val objectMap = ObjectMapper()
return objectMap.readValue(value, Array<String>::class.java).toList()
}

@TypeConverter
fun fromList(list: List<String?>?): String {
val objectMapper = ObjectMapper()
return objectMapper.writeValueAsString(list ?: emptyList<String>())
}

@TypeConverter
fun fromJsonNode(value: JsonNode?): String {
val objectMap = ObjectMapper()
return objectMap.writeValueAsString(value ?: objectMap.createObjectNode())
}

@TypeConverter
fun toJsonNodeList(value: String?): JsonNode {
val objectMapper = ObjectMapper()
return objectMapper.readValue(value ?: "")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* ---license-start
* eu-digital-green-certificates / dgca-wallet-app-android
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*
* Created by osarapulov on 7/26/21 12:33 PM
*/

package dgca.verifier.app.android.data.local.rules

import dgca.verifier.app.engine.data.Rule
import dgca.verifier.app.engine.data.RuleCertificateType
import dgca.verifier.app.engine.data.RuleIdentifier
import dgca.verifier.app.engine.data.Type
import dgca.verifier.app.engine.data.source.local.rules.RulesLocalDataSource
import java.time.ZonedDateTime

class DefaultRulesLocalDataSource(private val rulesDao: RulesDao) : RulesLocalDataSource {

override fun addRules(ruleIdentifiers: Collection<RuleIdentifier>, rules: Collection<Rule>) {
rulesDao.insertRulesData(
ruleIdentifiers.map { it.toRuleIdentifierLocal() },
rules.map { it.toRuleWithDescriptionLocal() })
}

override fun removeRulesBy(identifiers: Collection<String>) {
rulesDao.deleteRulesDataBy(identifiers)
}

override fun getRuleIdentifiers(): List<RuleIdentifier> =
rulesDao.getRuleIdentifiers().map { it.toRuleIdentifier() }

override fun getRulesBy(
countryIsoCode: String,
validationClock: ZonedDateTime,
type: Type,
ruleCertificateType: RuleCertificateType
): List<Rule> = rulesDao.getRulesWithDescriptionsBy(
countryIsoCode,
validationClock,
type,
ruleCertificateType,
RuleCertificateType.GENERAL
).toRules()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* ---license-start
* eu-digital-green-certificates / dgca-verifier-app-android
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*
* Created by osarapulov on 7/26/21 12:01 PM
*/

package dgca.verifier.app.android.data.local.rules

import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.PrimaryKey

@Entity(
tableName = "descriptions",
foreignKeys = [ForeignKey(
entity = RuleLocal::class,
parentColumns = arrayOf("ruleId"),
childColumns = arrayOf("ruleContainerId"),
onDelete = ForeignKey.CASCADE
)]
)
data class DescriptionLocal(
@PrimaryKey(autoGenerate = true)
val descriptionId: Long = 0,
val ruleContainerId: Long = 0,
val lang: String,
val desc: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* ---license-start
* eu-digital-green-certificates / dgca-verifier-app-android
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*
* Created by osarapulov on 7/26/21 12:03 PM
*/

package dgca.verifier.app.android.data.local.rules

import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import dgca.verifier.app.android.data.local.countries.CountriesDao
import dgca.verifier.app.android.data.local.countries.CountryLocal
import dgca.verifier.app.android.data.local.valuesets.ValueSetLocal
import dgca.verifier.app.android.data.local.valuesets.ValueSetsDao

@Database(
entities = [RuleIdentifierLocal::class, RuleLocal::class, DescriptionLocal::class, CountryLocal::class, ValueSetLocal::class],
version = 1
)
@TypeConverters(Converters::class)
abstract class EngineDatabase : RoomDatabase() {
abstract fun rulesDao(): RulesDao

abstract fun countriesDao(): CountriesDao

abstract fun valueSetsDao(): ValueSetsDao
}
Loading

0 comments on commit aa3909e

Please sign in to comment.