Repo created
This commit is contained in:
parent
d6b5d53060
commit
d90a1dc8df
2145 changed files with 210227 additions and 2 deletions
1
data/.gitignore
vendored
Normal file
1
data/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
31
data/build.gradle.kts
Normal file
31
data/build.gradle.kts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
plugins {
|
||||
id("breezy.library")
|
||||
kotlin("android")
|
||||
kotlin("plugin.serialization")
|
||||
id("app.cash.sqldelight")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "breezyweather.data"
|
||||
|
||||
defaultConfig {
|
||||
consumerProguardFiles("consumer-rules.pro")
|
||||
}
|
||||
|
||||
sqldelight {
|
||||
databases {
|
||||
create("Database") {
|
||||
packageName.set("breezyweather.data")
|
||||
dialect(libs.sqldelight.dialects.sql)
|
||||
schemaOutputDirectory.set(project.file("./src/main/sqldelight"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.domain)
|
||||
implementation(projects.weatherUnit)
|
||||
|
||||
api(libs.bundles.sqldelight)
|
||||
}
|
||||
0
data/consumer-rules.pro
Normal file
0
data/consumer-rules.pro
Normal file
21
data/proguard-rules.pro
vendored
Normal file
21
data/proguard-rules.pro
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
2
data/src/main/AndroidManifest.xml
Normal file
2
data/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest />
|
||||
107
data/src/main/java/breezyweather/data/AndroidDatabaseHandler.kt
Normal file
107
data/src/main/java/breezyweather/data/AndroidDatabaseHandler.kt
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/**
|
||||
* This file is part of Breezy Weather.
|
||||
*
|
||||
* Breezy Weather is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Breezy Weather is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Breezy Weather. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package breezyweather.data
|
||||
|
||||
import app.cash.sqldelight.ExecutableQuery
|
||||
import app.cash.sqldelight.Query
|
||||
import app.cash.sqldelight.coroutines.asFlow
|
||||
import app.cash.sqldelight.coroutines.mapToList
|
||||
import app.cash.sqldelight.coroutines.mapToOne
|
||||
import app.cash.sqldelight.coroutines.mapToOneOrNull
|
||||
import app.cash.sqldelight.db.SqlDriver
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class AndroidDatabaseHandler(
|
||||
val db: Database,
|
||||
private val driver: SqlDriver,
|
||||
val queryDispatcher: CoroutineDispatcher = Dispatchers.IO,
|
||||
val transactionDispatcher: CoroutineDispatcher = queryDispatcher,
|
||||
) : DatabaseHandler {
|
||||
|
||||
val suspendingTransactionId = ThreadLocal<Int>()
|
||||
|
||||
override suspend fun <T> await(inTransaction: Boolean, block: suspend Database.() -> T): T {
|
||||
return dispatch(inTransaction, block)
|
||||
}
|
||||
|
||||
override suspend fun <T : Any> awaitList(
|
||||
inTransaction: Boolean,
|
||||
block: suspend Database.() -> Query<T>,
|
||||
): List<T> {
|
||||
return dispatch(inTransaction) { block(db).executeAsList() }
|
||||
}
|
||||
|
||||
override suspend fun <T : Any> awaitOne(
|
||||
inTransaction: Boolean,
|
||||
block: suspend Database.() -> Query<T>,
|
||||
): T {
|
||||
return dispatch(inTransaction) { block(db).executeAsOne() }
|
||||
}
|
||||
|
||||
override suspend fun <T : Any> awaitOneExecutable(
|
||||
inTransaction: Boolean,
|
||||
block: suspend Database.() -> ExecutableQuery<T>,
|
||||
): T {
|
||||
return dispatch(inTransaction) { block(db).executeAsOne() }
|
||||
}
|
||||
|
||||
override suspend fun <T : Any> awaitOneOrNull(
|
||||
inTransaction: Boolean,
|
||||
block: suspend Database.() -> Query<T>,
|
||||
): T? {
|
||||
return dispatch(inTransaction) { block(db).executeAsOneOrNull() }
|
||||
}
|
||||
|
||||
override suspend fun <T : Any> awaitOneOrNullExecutable(
|
||||
inTransaction: Boolean,
|
||||
block: suspend Database.() -> ExecutableQuery<T>,
|
||||
): T? {
|
||||
return dispatch(inTransaction) { block(db).executeAsOneOrNull() }
|
||||
}
|
||||
|
||||
override fun <T : Any> subscribeToList(block: Database.() -> Query<T>): Flow<List<T>> {
|
||||
return block(db).asFlow().mapToList(queryDispatcher)
|
||||
}
|
||||
|
||||
override fun <T : Any> subscribeToOne(block: Database.() -> Query<T>): Flow<T> {
|
||||
return block(db).asFlow().mapToOne(queryDispatcher)
|
||||
}
|
||||
|
||||
override fun <T : Any> subscribeToOneOrNull(block: Database.() -> Query<T>): Flow<T?> {
|
||||
return block(db).asFlow().mapToOneOrNull(queryDispatcher)
|
||||
}
|
||||
|
||||
private suspend fun <T> dispatch(inTransaction: Boolean, block: suspend Database.() -> T): T {
|
||||
// Create a transaction if needed and run the calling block inside it.
|
||||
if (inTransaction) {
|
||||
return withTransaction { block(db) }
|
||||
}
|
||||
|
||||
// If we're currently in the transaction thread, there's no need to dispatch our query.
|
||||
if (driver.currentTransaction() != null) {
|
||||
return block(db)
|
||||
}
|
||||
|
||||
// Get the current database context and run the calling block.
|
||||
val context = getCurrentDatabaseContext()
|
||||
return withContext(context) { block(db) }
|
||||
}
|
||||
}
|
||||
132
data/src/main/java/breezyweather/data/DatabaseAdapter.kt
Normal file
132
data/src/main/java/breezyweather/data/DatabaseAdapter.kt
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/**
|
||||
* This file is part of Breezy Weather.
|
||||
*
|
||||
* Breezy Weather is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Breezy Weather is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Breezy Weather. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package breezyweather.data
|
||||
|
||||
import app.cash.sqldelight.ColumnAdapter
|
||||
import breezyweather.domain.weather.reference.AlertSeverity
|
||||
import breezyweather.domain.weather.reference.WeatherCode
|
||||
import org.breezyweather.unit.distance.Distance
|
||||
import org.breezyweather.unit.distance.Distance.Companion.meters
|
||||
import org.breezyweather.unit.pollen.PollenConcentration
|
||||
import org.breezyweather.unit.pollen.PollenConcentration.Companion.perCubicMeter
|
||||
import org.breezyweather.unit.pollutant.PollutantConcentration
|
||||
import org.breezyweather.unit.pollutant.PollutantConcentration.Companion.microgramsPerCubicMeter
|
||||
import org.breezyweather.unit.precipitation.Precipitation
|
||||
import org.breezyweather.unit.precipitation.Precipitation.Companion.micrometers
|
||||
import org.breezyweather.unit.pressure.Pressure
|
||||
import org.breezyweather.unit.pressure.Pressure.Companion.pascals
|
||||
import org.breezyweather.unit.ratio.Ratio
|
||||
import org.breezyweather.unit.ratio.Ratio.Companion.permille
|
||||
import org.breezyweather.unit.speed.Speed
|
||||
import org.breezyweather.unit.speed.Speed.Companion.centimetersPerSecond
|
||||
import org.breezyweather.unit.temperature.Temperature
|
||||
import org.breezyweather.unit.temperature.Temperature.Companion.deciCelsius
|
||||
import java.util.Date
|
||||
import java.util.TimeZone
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.nanoseconds
|
||||
|
||||
object DateColumnAdapter : ColumnAdapter<Date, Long> {
|
||||
override fun decode(databaseValue: Long): Date = Date(databaseValue)
|
||||
override fun encode(value: Date): Long = value.time
|
||||
}
|
||||
|
||||
private const val LIST_OF_STRINGS_SEPARATOR = ", "
|
||||
object StringListColumnAdapter : ColumnAdapter<List<String>, String> {
|
||||
override fun decode(databaseValue: String) = if (databaseValue.isEmpty()) {
|
||||
emptyList()
|
||||
} else {
|
||||
databaseValue.split(LIST_OF_STRINGS_SEPARATOR)
|
||||
}
|
||||
override fun encode(value: List<String>) = value.joinToString(
|
||||
separator = LIST_OF_STRINGS_SEPARATOR
|
||||
)
|
||||
}
|
||||
|
||||
object TimeZoneColumnAdapter : ColumnAdapter<TimeZone, String> {
|
||||
override fun decode(databaseValue: String): TimeZone = TimeZone.getTimeZone(databaseValue)
|
||||
|
||||
override fun encode(value: TimeZone): String = value.id
|
||||
}
|
||||
|
||||
object WeatherCodeColumnAdapter : ColumnAdapter<WeatherCode, String> {
|
||||
override fun decode(databaseValue: String): WeatherCode =
|
||||
WeatherCode.getInstance(databaseValue) ?: WeatherCode.CLEAR
|
||||
|
||||
override fun encode(value: WeatherCode): String = value.id
|
||||
}
|
||||
|
||||
object AlertSeverityColumnAdapter : ColumnAdapter<AlertSeverity, Long> {
|
||||
override fun decode(databaseValue: Long): AlertSeverity = AlertSeverity.getInstance(databaseValue.toInt())
|
||||
|
||||
override fun encode(value: AlertSeverity): Long = value.id.toLong()
|
||||
}
|
||||
|
||||
object TemperatureColumnAdapter : ColumnAdapter<Temperature, Long> {
|
||||
override fun decode(databaseValue: Long): Temperature = databaseValue.deciCelsius
|
||||
|
||||
override fun encode(value: Temperature): Long = value.value
|
||||
}
|
||||
|
||||
object PrecipitationColumnAdapter : ColumnAdapter<Precipitation, Long> {
|
||||
override fun decode(databaseValue: Long): Precipitation = databaseValue.micrometers
|
||||
|
||||
override fun encode(value: Precipitation): Long = value.value
|
||||
}
|
||||
|
||||
object SpeedColumnAdapter : ColumnAdapter<Speed, Long> {
|
||||
override fun decode(databaseValue: Long): Speed = databaseValue.centimetersPerSecond
|
||||
|
||||
override fun encode(value: Speed): Long = value.value
|
||||
}
|
||||
|
||||
object DistanceColumnAdapter : ColumnAdapter<Distance, Long> {
|
||||
override fun decode(databaseValue: Long): Distance = databaseValue.meters
|
||||
|
||||
override fun encode(value: Distance): Long = value.value
|
||||
}
|
||||
|
||||
object PressureColumnAdapter : ColumnAdapter<Pressure, Long> {
|
||||
override fun decode(databaseValue: Long): Pressure = databaseValue.pascals
|
||||
|
||||
override fun encode(value: Pressure): Long = value.value
|
||||
}
|
||||
|
||||
object PollutantConcentrationColumnAdapter : ColumnAdapter<PollutantConcentration, Long> {
|
||||
override fun decode(databaseValue: Long): PollutantConcentration = databaseValue.microgramsPerCubicMeter
|
||||
|
||||
override fun encode(value: PollutantConcentration): Long = value.value
|
||||
}
|
||||
|
||||
object PollenConcentrationColumnAdapter : ColumnAdapter<PollenConcentration, Long> {
|
||||
override fun decode(databaseValue: Long): PollenConcentration = databaseValue.perCubicMeter
|
||||
|
||||
override fun encode(value: PollenConcentration): Long = value.value
|
||||
}
|
||||
|
||||
object DurationColumnAdapter : ColumnAdapter<Duration, Long> {
|
||||
override fun decode(databaseValue: Long): Duration = databaseValue.nanoseconds
|
||||
|
||||
override fun encode(value: Duration): Long = value.inWholeNanoseconds
|
||||
}
|
||||
|
||||
object RatioColumnAdapter : ColumnAdapter<Ratio, Long> {
|
||||
override fun decode(databaseValue: Long): Ratio = databaseValue.permille
|
||||
|
||||
override fun encode(value: Ratio): Long = value.value
|
||||
}
|
||||
58
data/src/main/java/breezyweather/data/DatabaseHandler.kt
Normal file
58
data/src/main/java/breezyweather/data/DatabaseHandler.kt
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* This file is part of Breezy Weather.
|
||||
*
|
||||
* Breezy Weather is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Breezy Weather is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Breezy Weather. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package breezyweather.data
|
||||
|
||||
import app.cash.sqldelight.ExecutableQuery
|
||||
import app.cash.sqldelight.Query
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface DatabaseHandler {
|
||||
|
||||
suspend fun <T> await(inTransaction: Boolean = false, block: suspend Database.() -> T): T
|
||||
|
||||
suspend fun <T : Any> awaitList(
|
||||
inTransaction: Boolean = false,
|
||||
block: suspend Database.() -> Query<T>,
|
||||
): List<T>
|
||||
|
||||
suspend fun <T : Any> awaitOne(
|
||||
inTransaction: Boolean = false,
|
||||
block: suspend Database.() -> Query<T>,
|
||||
): T
|
||||
|
||||
suspend fun <T : Any> awaitOneExecutable(
|
||||
inTransaction: Boolean = false,
|
||||
block: suspend Database.() -> ExecutableQuery<T>,
|
||||
): T
|
||||
|
||||
suspend fun <T : Any> awaitOneOrNull(
|
||||
inTransaction: Boolean = false,
|
||||
block: suspend Database.() -> Query<T>,
|
||||
): T?
|
||||
|
||||
suspend fun <T : Any> awaitOneOrNullExecutable(
|
||||
inTransaction: Boolean = false,
|
||||
block: suspend Database.() -> ExecutableQuery<T>,
|
||||
): T?
|
||||
|
||||
fun <T : Any> subscribeToList(block: Database.() -> Query<T>): Flow<List<T>>
|
||||
|
||||
fun <T : Any> subscribeToOne(block: Database.() -> Query<T>): Flow<T>
|
||||
|
||||
fun <T : Any> subscribeToOneOrNull(block: Database.() -> Query<T>): Flow<T?>
|
||||
}
|
||||
177
data/src/main/java/breezyweather/data/TransactionContext.kt
Normal file
177
data/src/main/java/breezyweather/data/TransactionContext.kt
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/**
|
||||
* This file is part of Breezy Weather.
|
||||
*
|
||||
* Breezy Weather is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Breezy Weather is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Breezy Weather. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package breezyweather.data
|
||||
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.asContextElement
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.concurrent.RejectedExecutionException
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.coroutines.ContinuationInterceptor
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.coroutines.coroutineContext
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
/**
|
||||
* Returns the transaction dispatcher if we are on a transaction, or the database dispatchers.
|
||||
*/
|
||||
internal suspend fun AndroidDatabaseHandler.getCurrentDatabaseContext(): CoroutineContext {
|
||||
return coroutineContext[TransactionElement]?.transactionDispatcher ?: queryDispatcher
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the specified suspending [block] in a database transaction. The transaction will be
|
||||
* marked as successful unless an exception is thrown in the suspending [block] or the coroutine
|
||||
* is cancelled.
|
||||
*
|
||||
* SQLDelight will only perform at most one transaction at a time, additional transactions are queued
|
||||
* and executed on a first come, first serve order.
|
||||
*
|
||||
* Performing blocking database operations is not permitted in a coroutine scope other than the
|
||||
* one received by the suspending block. It is recommended that all [Dao] function invoked within
|
||||
* the [block] be suspending functions.
|
||||
*
|
||||
* The dispatcher used to execute the given [block] will utilize threads from SQLDelight's query executor.
|
||||
*/
|
||||
internal suspend fun <T> AndroidDatabaseHandler.withTransaction(block: suspend () -> T): T {
|
||||
// Use inherited transaction context if available, this allows nested suspending transactions.
|
||||
val transactionContext = coroutineContext[TransactionElement]?.transactionDispatcher ?: createTransactionContext()
|
||||
return withContext(transactionContext) {
|
||||
val transactionElement = coroutineContext[TransactionElement]!!
|
||||
transactionElement.acquire()
|
||||
try {
|
||||
db.transactionWithResult {
|
||||
runBlocking(transactionContext) {
|
||||
block()
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
transactionElement.release()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a [CoroutineContext] for performing database operations within a coroutine transaction.
|
||||
*
|
||||
* The context is a combination of a dispatcher, a [TransactionElement] and a thread local element.
|
||||
*
|
||||
* * The dispatcher will dispatch coroutines to a single thread that is taken over from the SQLDelight
|
||||
* query executor. If the coroutine context is switched, suspending DAO functions will be able to
|
||||
* dispatch to the transaction thread.
|
||||
*
|
||||
* * The [TransactionElement] serves as an indicator for inherited context, meaning, if there is a
|
||||
* switch of context, suspending DAO methods will be able to use the indicator to dispatch the
|
||||
* database operation to the transaction thread.
|
||||
*
|
||||
* * The thread local element serves as a second indicator and marks threads that are used to
|
||||
* execute coroutines within the coroutine transaction, more specifically it allows us to identify
|
||||
* if a blocking DAO method is invoked within the transaction coroutine. Never assign meaning to
|
||||
* this value, for now all we care is if its present or not.
|
||||
*/
|
||||
private suspend fun AndroidDatabaseHandler.createTransactionContext(): CoroutineContext {
|
||||
val controlJob = Job()
|
||||
// make sure to tie the control job to this context to avoid blocking the transaction if
|
||||
// context get cancelled before we can even start using this job. Otherwise, the acquired
|
||||
// transaction thread will forever wait for the controlJob to be cancelled.
|
||||
// see b/148181325
|
||||
coroutineContext[Job]?.invokeOnCompletion {
|
||||
controlJob.cancel()
|
||||
}
|
||||
|
||||
val dispatcher = transactionDispatcher.acquireTransactionThread(controlJob)
|
||||
val transactionElement = TransactionElement(controlJob, dispatcher)
|
||||
val threadLocalElement =
|
||||
suspendingTransactionId.asContextElement(System.identityHashCode(controlJob))
|
||||
return dispatcher + transactionElement + threadLocalElement
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquires a thread from the executor and returns a [ContinuationInterceptor] to dispatch
|
||||
* coroutines to the acquired thread. The [controlJob] is used to control the release of the
|
||||
* thread by cancelling the job.
|
||||
*/
|
||||
private suspend fun CoroutineDispatcher.acquireTransactionThread(
|
||||
controlJob: Job,
|
||||
): ContinuationInterceptor {
|
||||
return suspendCancellableCoroutine { continuation ->
|
||||
continuation.invokeOnCancellation {
|
||||
// We got cancelled while waiting to acquire a thread, we can't stop our attempt to
|
||||
// acquire a thread, but we can cancel the controlling job so once it gets acquired it
|
||||
// is quickly released.
|
||||
controlJob.cancel()
|
||||
}
|
||||
try {
|
||||
dispatch(EmptyCoroutineContext) {
|
||||
runBlocking {
|
||||
// Thread acquired, resume coroutine
|
||||
continuation.resume(coroutineContext[ContinuationInterceptor]!!)
|
||||
controlJob.join()
|
||||
}
|
||||
}
|
||||
} catch (ex: RejectedExecutionException) {
|
||||
// Couldn't acquire a thread, cancel coroutine
|
||||
continuation.cancel(
|
||||
IllegalStateException(
|
||||
"Unable to acquire a thread to perform the database transaction",
|
||||
ex
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A [CoroutineContext.Element] that indicates there is an on-going database transaction.
|
||||
*/
|
||||
private class TransactionElement(
|
||||
private val transactionThreadControlJob: Job,
|
||||
val transactionDispatcher: ContinuationInterceptor,
|
||||
) : CoroutineContext.Element {
|
||||
|
||||
companion object Key : CoroutineContext.Key<TransactionElement>
|
||||
|
||||
override val key: CoroutineContext.Key<TransactionElement>
|
||||
get() = TransactionElement
|
||||
|
||||
/**
|
||||
* Number of transactions (including nested ones) started with this element.
|
||||
* Call [acquire] to increase the count and [release] to decrease it. If the count reaches zero
|
||||
* when [release] is invoked then the transaction job is cancelled and the transaction thread
|
||||
* is released.
|
||||
*/
|
||||
private val referenceCount = AtomicInteger(0)
|
||||
|
||||
fun acquire() {
|
||||
referenceCount.incrementAndGet()
|
||||
}
|
||||
|
||||
fun release() {
|
||||
val count = referenceCount.decrementAndGet()
|
||||
if (count < 0) {
|
||||
throw IllegalStateException("Transaction was never started or was already released")
|
||||
} else if (count == 0) {
|
||||
// Cancel the job that controls the transaction thread, causing it to be released.
|
||||
transactionThreadControlJob.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* This file is part of Breezy Weather.
|
||||
*
|
||||
* Breezy Weather is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Breezy Weather is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Breezy Weather. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package breezyweather.data.location
|
||||
|
||||
import breezyweather.domain.location.model.Location
|
||||
import java.util.TimeZone
|
||||
|
||||
object LocationMapper {
|
||||
|
||||
fun mapLocation(
|
||||
cityId: String?,
|
||||
latitude: Double,
|
||||
longitude: Double,
|
||||
timeZone: TimeZone,
|
||||
customName: String?,
|
||||
country: String,
|
||||
countryCode: String?,
|
||||
admin1: String?,
|
||||
admin1Code: String?,
|
||||
admin2: String?,
|
||||
admin2Code: String?,
|
||||
admin3: String?,
|
||||
admin3Code: String?,
|
||||
admin4: String?,
|
||||
admin4Code: String?,
|
||||
city: String,
|
||||
district: String?,
|
||||
weatherSource: String,
|
||||
currentSource: String?,
|
||||
airQualitySource: String?,
|
||||
pollenSource: String?,
|
||||
minutelySource: String?,
|
||||
alertSource: String?,
|
||||
normalsSource: String?,
|
||||
reverseGeocodingSource: String?,
|
||||
isCurrentPosition: Boolean,
|
||||
needsGeocodeRefresh: Boolean,
|
||||
backgroundWeatherKind: String?, // TODO: Deprecated
|
||||
backgroundDayNightType: String?, // TODO: Deprecated
|
||||
): Location = Location(
|
||||
cityId = cityId,
|
||||
latitude = latitude,
|
||||
longitude = longitude,
|
||||
timeZone = timeZone,
|
||||
customName = customName,
|
||||
country = country,
|
||||
countryCode = countryCode,
|
||||
admin1 = admin1,
|
||||
admin1Code = admin1Code,
|
||||
admin2 = admin2,
|
||||
admin2Code = admin2Code,
|
||||
admin3 = admin3,
|
||||
admin3Code = admin3Code,
|
||||
admin4 = admin4,
|
||||
admin4Code = admin4Code,
|
||||
city = city,
|
||||
district = district,
|
||||
forecastSource = weatherSource,
|
||||
currentSource = currentSource,
|
||||
airQualitySource = airQualitySource,
|
||||
pollenSource = pollenSource,
|
||||
minutelySource = minutelySource,
|
||||
alertSource = alertSource,
|
||||
normalsSource = normalsSource,
|
||||
reverseGeocodingSource = reverseGeocodingSource,
|
||||
isCurrentPosition = isCurrentPosition,
|
||||
needsGeocodeRefresh = needsGeocodeRefresh
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,295 @@
|
|||
/**
|
||||
* This file is part of Breezy Weather.
|
||||
*
|
||||
* Breezy Weather is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Breezy Weather is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Breezy Weather. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package breezyweather.data.location
|
||||
|
||||
import android.util.Log
|
||||
import breezyweather.data.DatabaseHandler
|
||||
import breezyweather.domain.location.model.Location
|
||||
|
||||
class LocationRepository(
|
||||
private val handler: DatabaseHandler,
|
||||
) {
|
||||
|
||||
suspend fun getLocation(formattedId: String, withParameters: Boolean = true): Location? {
|
||||
val location = handler.awaitOneOrNull {
|
||||
locationsQueries.getLocationById(formattedId, LocationMapper::mapLocation)
|
||||
}
|
||||
return if (withParameters) {
|
||||
location?.copy(
|
||||
// I'm sure there must be a more efficient way
|
||||
parameters = handler.awaitList {
|
||||
location_parametersQueries.getLocationParametersByLocationId(location.formattedId)
|
||||
}.groupBy(
|
||||
{ it.source },
|
||||
{ it.parameter to it.value_ }
|
||||
).mapValues { parameterList ->
|
||||
parameterList.value.associate { it.first to it.second }
|
||||
}
|
||||
)
|
||||
} else {
|
||||
location
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getFirstLocation(withParameters: Boolean = true): Location? {
|
||||
val location = handler.awaitOneOrNull {
|
||||
locationsQueries.getFirstLocation(LocationMapper::mapLocation)
|
||||
}
|
||||
return if (withParameters) {
|
||||
location?.copy(
|
||||
// I'm sure there must be a more efficient way
|
||||
parameters = handler.awaitList {
|
||||
location_parametersQueries.getLocationParametersByLocationId(location.formattedId)
|
||||
}.groupBy(
|
||||
{ it.source },
|
||||
{ it.parameter to it.value_ }
|
||||
).mapValues { parameterList ->
|
||||
parameterList.value.associate { it.first to it.second }
|
||||
}
|
||||
)
|
||||
} else {
|
||||
location
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getXLocations(limit: Int, withParameters: Boolean = true): List<Location> {
|
||||
val locations = handler.awaitList {
|
||||
locationsQueries.getXLocations(limit.toLong(), LocationMapper::mapLocation)
|
||||
}
|
||||
return if (withParameters) {
|
||||
locations.map { location ->
|
||||
location.copy(
|
||||
// I'm sure there must be a more efficient way
|
||||
parameters = handler.awaitList {
|
||||
location_parametersQueries.getLocationParametersByLocationId(location.formattedId)
|
||||
}.groupBy(
|
||||
{ it.source },
|
||||
{ it.parameter to it.value_ }
|
||||
).mapValues { parameterList ->
|
||||
parameterList.value.associate { it.first to it.second }
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
locations
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getAllLocations(withParameters: Boolean = true): List<Location> {
|
||||
val locations = handler.awaitList {
|
||||
locationsQueries.getAllLocations(LocationMapper::mapLocation)
|
||||
}
|
||||
return if (withParameters) {
|
||||
locations.map { location ->
|
||||
location.copy(
|
||||
// I'm sure there must be a more efficient way
|
||||
parameters = handler.awaitList {
|
||||
location_parametersQueries.getLocationParametersByLocationId(location.formattedId)
|
||||
}.groupBy(
|
||||
{ it.source },
|
||||
{ it.parameter to it.value_ }
|
||||
).mapValues { parameterList ->
|
||||
parameterList.value.associate { it.first to it.second }
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
locations
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun addAll(locations: List<Location>): List<Location> {
|
||||
return try {
|
||||
handler.await(inTransaction = true) {
|
||||
// 1. Delete every location that was removed
|
||||
locationsQueries.deleteAllNonMatchingLocations(locations.map { it.formattedId })
|
||||
|
||||
// 2. Insert/Replace locations
|
||||
locations.mapIndexed { index, location ->
|
||||
locationsQueries.insert( // Will do a replace if formattedId already exists
|
||||
formattedId = location.formattedId,
|
||||
listOrder = index + 1L,
|
||||
cityId = location.cityId,
|
||||
latitude = location.latitude,
|
||||
longitude = location.longitude,
|
||||
timezone = location.timeZone,
|
||||
customName = location.customName,
|
||||
country = location.country,
|
||||
countryCode = location.countryCode,
|
||||
admin1 = location.admin1,
|
||||
admin1Code = location.admin1Code,
|
||||
admin2 = location.admin2,
|
||||
admin2Code = location.admin2Code,
|
||||
admin3 = location.admin3,
|
||||
admin3Code = location.admin3Code,
|
||||
admin4 = location.admin4,
|
||||
admin4Code = location.admin4Code,
|
||||
city = location.city,
|
||||
district = location.district,
|
||||
weatherSource = location.forecastSource,
|
||||
currentSource = location.currentSource,
|
||||
airQualitySource = location.airQualitySource,
|
||||
pollenSource = location.pollenSource,
|
||||
minutelySource = location.minutelySource,
|
||||
alertSource = location.alertSource,
|
||||
normalsSource = location.normalsSource,
|
||||
reverseGeocodingSource = location.reverseGeocodingSource,
|
||||
currentPosition = location.isCurrentPosition,
|
||||
needsGeocodeRefresh = location.needsGeocodeRefresh,
|
||||
backgroundWeatherKind = null, // TODO: Deprecated
|
||||
backgroundDayNightType = null // TODO: Deprecated
|
||||
)
|
||||
|
||||
// 3. Update location parameters
|
||||
// 3a. Delete no longer existing parameters
|
||||
location_parametersQueries.deleteAllNonMatchingParameters(
|
||||
location.formattedId,
|
||||
location.parameters.map { it.key }
|
||||
)
|
||||
|
||||
// 3b. Insert/replace parameters
|
||||
location.parameters.forEach { source ->
|
||||
source.value.forEach {
|
||||
// Will do a replace if formattedId/parameter already exists
|
||||
location_parametersQueries.insert(
|
||||
location.formattedId,
|
||||
source.key,
|
||||
it.key,
|
||||
it.value
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
location
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("BreezyWeather", e.toString())
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun insertParameters(locationFormattedId: String, locationParameters: Map<String, Map<String, String>>) {
|
||||
handler.await(inTransaction = true) {
|
||||
// 3a. Delete no longer existing parameters
|
||||
location_parametersQueries.deleteAllNonMatchingParameters(
|
||||
locationFormattedId,
|
||||
locationParameters.map { it.key }
|
||||
)
|
||||
|
||||
// 3b. Insert/replace parameters
|
||||
locationParameters.forEach { source ->
|
||||
source.value.forEach {
|
||||
// Will do a replace if formattedId/parameter already exists
|
||||
location_parametersQueries.insert(
|
||||
locationFormattedId,
|
||||
source.key,
|
||||
it.key,
|
||||
it.value
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun updateParameters(
|
||||
source: String,
|
||||
parameter: String,
|
||||
values: Map<String, String>,
|
||||
) {
|
||||
handler.await {
|
||||
values.entries.forEach { (oldValue, newValue) ->
|
||||
location_parametersQueries.updateParameters(
|
||||
source = source,
|
||||
parameter = parameter,
|
||||
oldValue = oldValue,
|
||||
newValue = newValue
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun deleteParameters(
|
||||
source: String,
|
||||
parameter: String,
|
||||
values: List<String>,
|
||||
) {
|
||||
handler.await {
|
||||
location_parametersQueries.deleteParameters(
|
||||
source,
|
||||
parameter,
|
||||
values
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun update(location: Location, oldFormattedId: String? = null): Boolean {
|
||||
return try {
|
||||
handler.await(inTransaction = true) {
|
||||
if (oldFormattedId != null && oldFormattedId != location.formattedId) {
|
||||
locationsQueries.updateFormattedId(
|
||||
oldFormattedId = oldFormattedId,
|
||||
newFormattedId = location.formattedId
|
||||
)
|
||||
}
|
||||
locationsQueries.update(
|
||||
formattedId = location.formattedId,
|
||||
cityId = location.cityId,
|
||||
latitude = location.latitude,
|
||||
longitude = location.longitude,
|
||||
timezone = location.timeZone.id,
|
||||
customName = location.customName,
|
||||
country = location.country,
|
||||
countryCode = location.countryCode,
|
||||
admin1 = location.admin1,
|
||||
admin1Code = location.admin1Code,
|
||||
admin2 = location.admin2,
|
||||
admin2Code = location.admin2Code,
|
||||
admin3 = location.admin3,
|
||||
admin3Code = location.admin3Code,
|
||||
admin4 = location.admin4,
|
||||
admin4Code = location.admin4Code,
|
||||
city = location.city,
|
||||
district = location.district,
|
||||
weatherSource = location.forecastSource,
|
||||
currentSource = location.currentSource,
|
||||
airQualitySource = location.airQualitySource,
|
||||
pollenSource = location.pollenSource,
|
||||
minutelySource = location.minutelySource,
|
||||
alertSource = location.alertSource,
|
||||
normalsSource = location.normalsSource,
|
||||
reverseGeocodingSource = location.reverseGeocodingSource,
|
||||
currentPosition = location.isCurrentPosition,
|
||||
needsGeocodeRefresh = location.needsGeocodeRefresh,
|
||||
backgroundWeatherKind = null, // TODO: Deprecated
|
||||
backgroundDayNightType = null // TODO: Deprecated
|
||||
)
|
||||
}
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
Log.e("BreezyWeather", e.toString())
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun delete(formattedId: String) {
|
||||
handler.await {
|
||||
locationsQueries.deleteLocation(formattedId)
|
||||
}
|
||||
}
|
||||
}
|
||||
516
data/src/main/java/breezyweather/data/weather/WeatherMapper.kt
Normal file
516
data/src/main/java/breezyweather/data/weather/WeatherMapper.kt
Normal file
|
|
@ -0,0 +1,516 @@
|
|||
/*
|
||||
* This file is part of Breezy Weather.
|
||||
*
|
||||
* Breezy Weather is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Breezy Weather is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Breezy Weather. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package breezyweather.data.weather
|
||||
|
||||
import breezyweather.domain.weather.model.AirQuality
|
||||
import breezyweather.domain.weather.model.Alert
|
||||
import breezyweather.domain.weather.model.Astro
|
||||
import breezyweather.domain.weather.model.Base
|
||||
import breezyweather.domain.weather.model.Current
|
||||
import breezyweather.domain.weather.model.Daily
|
||||
import breezyweather.domain.weather.model.DailyCloudCover
|
||||
import breezyweather.domain.weather.model.DailyDewPoint
|
||||
import breezyweather.domain.weather.model.DailyPressure
|
||||
import breezyweather.domain.weather.model.DailyRelativeHumidity
|
||||
import breezyweather.domain.weather.model.DailyVisibility
|
||||
import breezyweather.domain.weather.model.DegreeDay
|
||||
import breezyweather.domain.weather.model.HalfDay
|
||||
import breezyweather.domain.weather.model.Hourly
|
||||
import breezyweather.domain.weather.model.Minutely
|
||||
import breezyweather.domain.weather.model.MoonPhase
|
||||
import breezyweather.domain.weather.model.Normals
|
||||
import breezyweather.domain.weather.model.Pollen
|
||||
import breezyweather.domain.weather.model.PrecipitationDuration
|
||||
import breezyweather.domain.weather.model.PrecipitationProbability
|
||||
import breezyweather.domain.weather.model.UV
|
||||
import breezyweather.domain.weather.model.Weather
|
||||
import breezyweather.domain.weather.model.Wind
|
||||
import breezyweather.domain.weather.reference.AlertSeverity
|
||||
import breezyweather.domain.weather.reference.Month
|
||||
import breezyweather.domain.weather.reference.WeatherCode
|
||||
import org.breezyweather.unit.distance.Distance
|
||||
import org.breezyweather.unit.pollen.PollenConcentration
|
||||
import org.breezyweather.unit.pollutant.PollutantConcentration
|
||||
import org.breezyweather.unit.precipitation.Precipitation
|
||||
import org.breezyweather.unit.pressure.Pressure
|
||||
import org.breezyweather.unit.ratio.Ratio
|
||||
import org.breezyweather.unit.speed.Speed
|
||||
import org.breezyweather.unit.temperature.Temperature
|
||||
import java.util.Date
|
||||
import kotlin.time.Duration
|
||||
|
||||
object WeatherMapper {
|
||||
|
||||
fun mapWeather(
|
||||
refreshTime: Long?,
|
||||
mainUpdateTime: Long?,
|
||||
currentUpdateTime: Long?,
|
||||
airQualityUpdateTime: Long?,
|
||||
pollenUpdateTime: Long?,
|
||||
minutelyUpdateTime: Long?,
|
||||
alertsUpdateTime: Long?,
|
||||
normalsUpdateTime: Long?,
|
||||
normalsUpdateLatitude: Double,
|
||||
normalsUpdateLongitude: Double,
|
||||
weatherText: String?,
|
||||
weatherCode: WeatherCode?,
|
||||
temperature: Temperature?,
|
||||
sourceFeelsLikeTemperature: Temperature?,
|
||||
apparentTemperature: Temperature?,
|
||||
windChillTemperature: Temperature?,
|
||||
humidex: Temperature?,
|
||||
windDegree: Double?,
|
||||
windSpeed: Speed?,
|
||||
windGusts: Speed?,
|
||||
uvIndex: Double?,
|
||||
pm25: PollutantConcentration?,
|
||||
pm10: PollutantConcentration?,
|
||||
so2: PollutantConcentration?,
|
||||
no2: PollutantConcentration?,
|
||||
o3: PollutantConcentration?,
|
||||
co: PollutantConcentration?,
|
||||
relativeHumidity: Ratio?,
|
||||
dewPoint: Temperature?,
|
||||
pressure: Pressure?,
|
||||
visibility: Distance?,
|
||||
cloudCover: Ratio?,
|
||||
ceiling: Distance?,
|
||||
dailyForecast: String?,
|
||||
hourlyForecast: String?,
|
||||
): Weather = Weather(
|
||||
Base(
|
||||
refreshTime?.let { Date(it) },
|
||||
mainUpdateTime?.let { Date(it) },
|
||||
currentUpdateTime?.let { Date(it) },
|
||||
airQualityUpdateTime?.let { Date(it) },
|
||||
pollenUpdateTime?.let { Date(it) },
|
||||
minutelyUpdateTime?.let { Date(it) },
|
||||
alertsUpdateTime?.let { Date(it) },
|
||||
normalsUpdateTime?.let { Date(it) },
|
||||
normalsUpdateLatitude,
|
||||
normalsUpdateLongitude
|
||||
),
|
||||
Current(
|
||||
weatherText,
|
||||
weatherCode,
|
||||
breezyweather.domain.weather.model.Temperature(
|
||||
temperature,
|
||||
sourceFeelsLike = sourceFeelsLikeTemperature,
|
||||
computedApparent = apparentTemperature,
|
||||
computedWindChill = windChillTemperature,
|
||||
computedHumidex = humidex
|
||||
),
|
||||
Wind(
|
||||
windDegree,
|
||||
windSpeed,
|
||||
windGusts
|
||||
),
|
||||
UV(uvIndex),
|
||||
AirQuality(
|
||||
pm25,
|
||||
pm10,
|
||||
so2,
|
||||
no2,
|
||||
o3,
|
||||
co
|
||||
),
|
||||
relativeHumidity,
|
||||
dewPoint,
|
||||
pressure,
|
||||
cloudCover,
|
||||
visibility,
|
||||
ceiling,
|
||||
dailyForecast,
|
||||
hourlyForecast
|
||||
)
|
||||
)
|
||||
|
||||
fun mapDaily(
|
||||
date: Long,
|
||||
daytimeWeatherText: String?,
|
||||
daytimeweatherSummary: String?,
|
||||
daytimeWeatherCode: WeatherCode?,
|
||||
daytimeTemperature: Temperature?,
|
||||
daytimeSourceFeelsLikeTemperature: Temperature?,
|
||||
daytimeApparentTemperature: Temperature?,
|
||||
daytimeWindChillTemperature: Temperature?,
|
||||
daytimeHumidex: Temperature?,
|
||||
daytimeTotalPrecipitation: Precipitation?,
|
||||
daytimeThunderstormPrecipitation: Precipitation?,
|
||||
daytimeRainPrecipitation: Precipitation?,
|
||||
daytimeSnowPrecipitation: Precipitation?,
|
||||
daytimeIcePrecipitation: Precipitation?,
|
||||
daytimeTotalPrecipitationProbability: Ratio?,
|
||||
daytimeThunderstormPrecipitationProbability: Ratio?,
|
||||
daytimeRainPrecipitationProbability: Ratio?,
|
||||
daytimeSnowPrecipitationProbability: Ratio?,
|
||||
daytimeIcePrecipitationProbability: Ratio?,
|
||||
daytimeTotalPrecipitationDuration: Duration?,
|
||||
daytimeThunderstormPrecipitationDuration: Duration?,
|
||||
daytimeRainPrecipitationDuration: Duration?,
|
||||
daytimeSnowPrecipitationDuration: Duration?,
|
||||
daytimeIcePrecipitationDuration: Duration?,
|
||||
daytimeWindDegree: Double?,
|
||||
daytimeWindSpeed: Speed?,
|
||||
daytimeWindGusts: Speed?,
|
||||
nighttimeWeatherText: String?,
|
||||
nighttimeweatherSummary: String?,
|
||||
nighttimeWeatherCode: WeatherCode?,
|
||||
nighttimeTemperature: Temperature?,
|
||||
nighttimeSourceFeelsLikeTemperature: Temperature?,
|
||||
nighttimeApparentTemperature: Temperature?,
|
||||
nighttimeWindChillTemperature: Temperature?,
|
||||
nighttimeHumidex: Temperature?,
|
||||
nighttimeTotalPrecipitation: Precipitation?,
|
||||
nighttimeThunderstormPrecipitation: Precipitation?,
|
||||
nighttimeRainPrecipitation: Precipitation?,
|
||||
nighttimeSnowPrecipitation: Precipitation?,
|
||||
nighttimeIcePrecipitation: Precipitation?,
|
||||
nighttimeTotalPrecipitationProbability: Ratio?,
|
||||
nighttimeThunderstormPrecipitationProbability: Ratio?,
|
||||
nighttimeRainPrecipitationProbability: Ratio?,
|
||||
nighttimeSnowPrecipitationProbability: Ratio?,
|
||||
nighttimeIcePrecipitationProbability: Ratio?,
|
||||
nighttimeTotalPrecipitationDuration: Duration?,
|
||||
nighttimeThunderstormPrecipitationDuration: Duration?,
|
||||
nighttimeRainPrecipitationDuration: Duration?,
|
||||
nighttimeSnowPrecipitationDuration: Duration?,
|
||||
nighttimeIcePrecipitationDuration: Duration?,
|
||||
nighttimeWindDegree: Double?,
|
||||
nighttimeWindSpeed: Speed?,
|
||||
nighttimeWindGusts: Speed?,
|
||||
degreeDayHeating: Temperature?,
|
||||
degreeDayCooling: Temperature?,
|
||||
sunRiseDate: Long?,
|
||||
sunSetDate: Long?,
|
||||
twilightRiseDate: Long?,
|
||||
twilightSetDate: Long?,
|
||||
moonRiseDate: Long?,
|
||||
moonSetDate: Long?,
|
||||
moonPhaseAngle: Long?,
|
||||
pm25: PollutantConcentration?,
|
||||
pm10: PollutantConcentration?,
|
||||
so2: PollutantConcentration?,
|
||||
no2: PollutantConcentration?,
|
||||
o3: PollutantConcentration?,
|
||||
co: PollutantConcentration?,
|
||||
alder: PollenConcentration?,
|
||||
ash: PollenConcentration?,
|
||||
birch: PollenConcentration?,
|
||||
chestnut: PollenConcentration?,
|
||||
cypress: PollenConcentration?,
|
||||
grass: PollenConcentration?,
|
||||
hazel: PollenConcentration?,
|
||||
hornbeam: PollenConcentration?,
|
||||
linden: PollenConcentration?,
|
||||
mold: PollenConcentration?,
|
||||
mugwort: PollenConcentration?,
|
||||
oak: PollenConcentration?,
|
||||
olive: PollenConcentration?,
|
||||
plane: PollenConcentration?,
|
||||
plantain: PollenConcentration?,
|
||||
poplar: PollenConcentration?,
|
||||
ragweed: PollenConcentration?,
|
||||
sorrel: PollenConcentration?,
|
||||
tree: PollenConcentration?,
|
||||
urticaceae: PollenConcentration?,
|
||||
willow: PollenConcentration?,
|
||||
uvIndex: Double?,
|
||||
sunshineDuration: Duration?,
|
||||
relativeHumidityAverage: Ratio?,
|
||||
relativeHumidityMin: Ratio?,
|
||||
relativeHumidityMax: Ratio?,
|
||||
dewpointAverage: Temperature?,
|
||||
dewpointMin: Temperature?,
|
||||
dewpointMax: Temperature?,
|
||||
pressureAverage: Pressure?,
|
||||
pressureMin: Pressure?,
|
||||
pressureMax: Pressure?,
|
||||
cloudCoverAverage: Ratio?,
|
||||
cloudCoverMin: Ratio?,
|
||||
cloudCoverMax: Ratio?,
|
||||
visibilityAverage: Distance?,
|
||||
visibilityMin: Distance?,
|
||||
visibilityMax: Distance?,
|
||||
): Daily = Daily(
|
||||
Date(date),
|
||||
HalfDay(
|
||||
daytimeWeatherText,
|
||||
daytimeweatherSummary,
|
||||
daytimeWeatherCode,
|
||||
breezyweather.domain.weather.model.Temperature(
|
||||
daytimeTemperature,
|
||||
sourceFeelsLike = daytimeSourceFeelsLikeTemperature,
|
||||
daytimeApparentTemperature,
|
||||
daytimeWindChillTemperature,
|
||||
daytimeHumidex
|
||||
),
|
||||
breezyweather.domain.weather.model.Precipitation(
|
||||
daytimeTotalPrecipitation,
|
||||
daytimeThunderstormPrecipitation,
|
||||
daytimeRainPrecipitation,
|
||||
daytimeSnowPrecipitation,
|
||||
daytimeIcePrecipitation
|
||||
),
|
||||
PrecipitationProbability(
|
||||
daytimeTotalPrecipitationProbability,
|
||||
daytimeThunderstormPrecipitationProbability,
|
||||
daytimeRainPrecipitationProbability,
|
||||
daytimeSnowPrecipitationProbability,
|
||||
daytimeIcePrecipitationProbability
|
||||
),
|
||||
PrecipitationDuration(
|
||||
daytimeTotalPrecipitationDuration,
|
||||
daytimeThunderstormPrecipitationDuration,
|
||||
daytimeRainPrecipitationDuration,
|
||||
daytimeSnowPrecipitationDuration,
|
||||
daytimeIcePrecipitationDuration
|
||||
),
|
||||
Wind(
|
||||
daytimeWindDegree,
|
||||
daytimeWindSpeed,
|
||||
daytimeWindGusts
|
||||
)
|
||||
),
|
||||
HalfDay(
|
||||
nighttimeWeatherText,
|
||||
nighttimeweatherSummary,
|
||||
nighttimeWeatherCode,
|
||||
breezyweather.domain.weather.model.Temperature(
|
||||
nighttimeTemperature,
|
||||
sourceFeelsLike = nighttimeSourceFeelsLikeTemperature,
|
||||
nighttimeApparentTemperature,
|
||||
nighttimeWindChillTemperature,
|
||||
nighttimeHumidex
|
||||
),
|
||||
breezyweather.domain.weather.model.Precipitation(
|
||||
nighttimeTotalPrecipitation,
|
||||
nighttimeThunderstormPrecipitation,
|
||||
nighttimeRainPrecipitation,
|
||||
nighttimeSnowPrecipitation,
|
||||
nighttimeIcePrecipitation
|
||||
),
|
||||
PrecipitationProbability(
|
||||
nighttimeTotalPrecipitationProbability,
|
||||
nighttimeThunderstormPrecipitationProbability,
|
||||
nighttimeRainPrecipitationProbability,
|
||||
nighttimeSnowPrecipitationProbability,
|
||||
nighttimeIcePrecipitationProbability
|
||||
),
|
||||
PrecipitationDuration(
|
||||
nighttimeTotalPrecipitationDuration,
|
||||
nighttimeThunderstormPrecipitationDuration,
|
||||
nighttimeRainPrecipitationDuration,
|
||||
nighttimeSnowPrecipitationDuration,
|
||||
nighttimeIcePrecipitationDuration
|
||||
),
|
||||
Wind(
|
||||
nighttimeWindDegree,
|
||||
nighttimeWindSpeed,
|
||||
nighttimeWindGusts
|
||||
)
|
||||
),
|
||||
DegreeDay(degreeDayHeating, degreeDayCooling),
|
||||
Astro(sunRiseDate?.let { Date(it) }, sunSetDate?.let { Date(it) }),
|
||||
Astro(twilightRiseDate?.let { Date(it) }, twilightSetDate?.let { Date(it) }),
|
||||
Astro(moonRiseDate?.let { Date(it) }, moonSetDate?.let { Date(it) }),
|
||||
MoonPhase(moonPhaseAngle?.toInt()),
|
||||
AirQuality(
|
||||
pm25,
|
||||
pm10,
|
||||
so2,
|
||||
no2,
|
||||
o3,
|
||||
co
|
||||
),
|
||||
Pollen(
|
||||
alder = alder,
|
||||
ash = ash,
|
||||
birch = birch,
|
||||
chestnut = chestnut,
|
||||
cypress = cypress,
|
||||
grass = grass,
|
||||
hazel = hazel,
|
||||
hornbeam = hornbeam,
|
||||
linden = linden,
|
||||
mugwort = mugwort,
|
||||
mold = mold,
|
||||
oak = oak,
|
||||
olive = olive,
|
||||
plane = plane,
|
||||
plantain = plantain,
|
||||
poplar = poplar,
|
||||
ragweed = ragweed,
|
||||
sorrel = sorrel,
|
||||
tree = tree,
|
||||
urticaceae = urticaceae,
|
||||
willow = willow
|
||||
),
|
||||
UV(uvIndex),
|
||||
sunshineDuration,
|
||||
relativeHumidity = DailyRelativeHumidity(
|
||||
average = relativeHumidityAverage,
|
||||
min = relativeHumidityMin,
|
||||
max = relativeHumidityMax
|
||||
),
|
||||
dewPoint = DailyDewPoint(
|
||||
average = dewpointAverage,
|
||||
min = dewpointMin,
|
||||
max = dewpointMax
|
||||
),
|
||||
pressure = DailyPressure(
|
||||
average = pressureAverage,
|
||||
min = pressureMin,
|
||||
max = pressureMax
|
||||
),
|
||||
cloudCover = DailyCloudCover(
|
||||
average = cloudCoverAverage,
|
||||
min = cloudCoverMin,
|
||||
max = cloudCoverMax
|
||||
),
|
||||
visibility = DailyVisibility(
|
||||
average = visibilityAverage,
|
||||
min = visibilityMin,
|
||||
max = visibilityMax
|
||||
)
|
||||
)
|
||||
|
||||
fun mapHourly(
|
||||
date: Long,
|
||||
daylight: Boolean,
|
||||
weatherText: String?,
|
||||
weatherCode: WeatherCode?,
|
||||
temperature: Temperature?,
|
||||
sourceFeelsLikeTemperature: Temperature?,
|
||||
apparentTemperature: Temperature?,
|
||||
windChillTemperature: Temperature?,
|
||||
humidex: Temperature?,
|
||||
totalPrecipitation: Precipitation?,
|
||||
thunderstormPrecipitation: Precipitation?,
|
||||
rainPrecipitation: Precipitation?,
|
||||
snowPrecipitation: Precipitation?,
|
||||
icePrecipitation: Precipitation?,
|
||||
totalPrecipitationProbability: Ratio?,
|
||||
thunderstormPrecipitationProbability: Ratio?,
|
||||
rainPrecipitationProbability: Ratio?,
|
||||
snowPrecipitationProbability: Ratio?,
|
||||
icePrecipitationProbability: Ratio?,
|
||||
windDegree: Double?,
|
||||
windSpeed: Speed?,
|
||||
windGusts: Speed?,
|
||||
pm25: PollutantConcentration?,
|
||||
pm10: PollutantConcentration?,
|
||||
so2: PollutantConcentration?,
|
||||
no2: PollutantConcentration?,
|
||||
o3: PollutantConcentration?,
|
||||
co: PollutantConcentration?,
|
||||
uvIndex: Double?,
|
||||
relativeHumidity: Ratio?,
|
||||
dewPoint: Temperature?,
|
||||
pressure: Pressure?,
|
||||
cloudCover: Ratio?,
|
||||
visibility: Distance?,
|
||||
): Hourly = Hourly(
|
||||
Date(date),
|
||||
daylight,
|
||||
weatherText,
|
||||
weatherCode,
|
||||
breezyweather.domain.weather.model.Temperature(
|
||||
temperature,
|
||||
sourceFeelsLike = sourceFeelsLikeTemperature,
|
||||
computedApparent = apparentTemperature,
|
||||
computedWindChill = windChillTemperature,
|
||||
computedHumidex = humidex
|
||||
),
|
||||
breezyweather.domain.weather.model.Precipitation(
|
||||
totalPrecipitation,
|
||||
thunderstormPrecipitation,
|
||||
rainPrecipitation,
|
||||
snowPrecipitation,
|
||||
icePrecipitation
|
||||
),
|
||||
PrecipitationProbability(
|
||||
totalPrecipitationProbability,
|
||||
thunderstormPrecipitationProbability,
|
||||
rainPrecipitationProbability,
|
||||
snowPrecipitationProbability,
|
||||
icePrecipitationProbability
|
||||
),
|
||||
Wind(
|
||||
windDegree,
|
||||
windSpeed,
|
||||
windGusts
|
||||
),
|
||||
AirQuality(
|
||||
pm25,
|
||||
pm10,
|
||||
so2,
|
||||
no2,
|
||||
o3,
|
||||
co
|
||||
),
|
||||
UV(uvIndex),
|
||||
relativeHumidity,
|
||||
dewPoint,
|
||||
pressure,
|
||||
cloudCover,
|
||||
visibility
|
||||
)
|
||||
|
||||
fun mapAlert(
|
||||
alertId: String,
|
||||
startDate: Long?,
|
||||
endDate: Long?,
|
||||
headline: String?,
|
||||
description: String?,
|
||||
instruction: String?,
|
||||
source: String?,
|
||||
severity: AlertSeverity,
|
||||
color: Long,
|
||||
): Alert = Alert(
|
||||
alertId = alertId,
|
||||
startDate = startDate?.let { Date(it) },
|
||||
endDate = endDate?.let { Date(it) },
|
||||
headline = headline,
|
||||
description = description,
|
||||
instruction = instruction,
|
||||
source = source,
|
||||
severity = severity,
|
||||
color = color.toInt()
|
||||
)
|
||||
|
||||
fun mapMinutely(
|
||||
date: Long,
|
||||
minuteInterval: Long,
|
||||
intensity: Precipitation?,
|
||||
): Minutely = Minutely(
|
||||
Date(date),
|
||||
minuteInterval.toInt(),
|
||||
intensity
|
||||
)
|
||||
|
||||
fun mapNormals(
|
||||
month: Long,
|
||||
daytimeTemperature: Temperature?,
|
||||
nighttimeTemperature: Temperature?,
|
||||
): Map<Month, Normals> = mapOf(
|
||||
Month.of(month.toInt()) to Normals(
|
||||
daytimeTemperature,
|
||||
nighttimeTemperature
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,422 @@
|
|||
/**
|
||||
* This file is part of Breezy Weather.
|
||||
*
|
||||
* Breezy Weather is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Breezy Weather is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Breezy Weather. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package breezyweather.data.weather
|
||||
|
||||
import breezyweather.data.DatabaseHandler
|
||||
import breezyweather.domain.location.model.Location
|
||||
import breezyweather.domain.weather.model.Alert
|
||||
import breezyweather.domain.weather.model.Daily
|
||||
import breezyweather.domain.weather.model.Hourly
|
||||
import breezyweather.domain.weather.model.Minutely
|
||||
import breezyweather.domain.weather.model.Normals
|
||||
import breezyweather.domain.weather.model.Weather
|
||||
import breezyweather.domain.weather.reference.Month
|
||||
import java.util.Date
|
||||
|
||||
class WeatherRepository(
|
||||
private val handler: DatabaseHandler,
|
||||
) {
|
||||
|
||||
suspend fun getWeatherByLocationId(
|
||||
locationFormattedId: String,
|
||||
withDaily: Boolean = true,
|
||||
withHourly: Boolean = true,
|
||||
withMinutely: Boolean = true,
|
||||
withAlerts: Boolean = true,
|
||||
withNormals: Boolean = true,
|
||||
): Weather? {
|
||||
val weather = handler.awaitOneOrNull {
|
||||
weathersQueries.getWeatherByLocationId(locationFormattedId, WeatherMapper::mapWeather)
|
||||
}
|
||||
|
||||
return if (withDaily || withHourly || withMinutely || withAlerts) {
|
||||
weather?.copy(
|
||||
dailyForecast = if (withDaily) {
|
||||
getDailyListByLocationId(locationFormattedId)
|
||||
} else {
|
||||
emptyList()
|
||||
},
|
||||
hourlyForecast = if (withHourly) {
|
||||
getHourlyListByLocationId(locationFormattedId)
|
||||
} else {
|
||||
emptyList()
|
||||
},
|
||||
minutelyForecast = if (withMinutely) {
|
||||
getMinutelyListByLocationId(locationFormattedId)
|
||||
} else {
|
||||
emptyList()
|
||||
},
|
||||
alertList = if (withAlerts) {
|
||||
getAlertListByLocationId(locationFormattedId)
|
||||
} else {
|
||||
emptyList()
|
||||
},
|
||||
normals = if (withNormals) {
|
||||
getNormalsByLocationId(locationFormattedId)
|
||||
} else {
|
||||
emptyMap()
|
||||
}
|
||||
)
|
||||
} else {
|
||||
weather
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getDailyListByLocationId(locationFormattedId: String): List<Daily> {
|
||||
return handler.awaitList {
|
||||
dailysQueries.getDailyListByLocationId(locationFormattedId, WeatherMapper::mapDaily)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getHourlyListByLocationId(locationFormattedId: String): List<Hourly> {
|
||||
return handler.awaitList {
|
||||
hourlysQueries.getHourlyListByLocationId(locationFormattedId, WeatherMapper::mapHourly)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getMinutelyListByLocationId(locationFormattedId: String): List<Minutely> {
|
||||
return handler.awaitList {
|
||||
minutelysQueries.getMinutelyListByLocationId(locationFormattedId, WeatherMapper::mapMinutely)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getAlertListByLocationId(locationFormattedId: String): List<Alert> {
|
||||
return handler.awaitList {
|
||||
alertsQueries.getAlertListByLocationId(locationFormattedId, WeatherMapper::mapAlert)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getNormalsByLocationId(locationFormattedId: String): Map<Month, Normals> {
|
||||
return handler.awaitList {
|
||||
normalsQueries.getNormalsByLocationId(locationFormattedId)
|
||||
}.associate {
|
||||
Month.of(it.month.toInt()) to Normals(
|
||||
daytimeTemperature = it.temperature_max_average,
|
||||
nighttimeTemperature = it.temperature_min_average
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getCurrentAlertsByLocationId(locationFormattedId: String): List<Alert> {
|
||||
return handler.awaitList {
|
||||
alertsQueries.getCurrentAlertsByLocationId(
|
||||
locationFormattedId,
|
||||
Date().time,
|
||||
WeatherMapper::mapAlert
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun insert(location: Location, weather: Weather) {
|
||||
handler.await(inTransaction = true) {
|
||||
// 1. Save Weather (will replace if necessary)
|
||||
weathersQueries.insert(
|
||||
// base
|
||||
locationFormattedId = location.formattedId,
|
||||
refreshTime = weather.base.refreshTime?.time,
|
||||
mainUpdateTime = weather.base.forecastUpdateTime?.time,
|
||||
currentUpdateTime = weather.base.currentUpdateTime?.time,
|
||||
airQualityUpdateTime = weather.base.airQualityUpdateTime?.time,
|
||||
pollenUpdateTime = weather.base.pollenUpdateTime?.time,
|
||||
minutelyUpdateTime = weather.base.minutelyUpdateTime?.time,
|
||||
alertsUpdateTime = weather.base.alertsUpdateTime?.time,
|
||||
normalsUpdateTime = weather.base.normalsUpdateTime?.time,
|
||||
normalsUpdateLatitude = weather.base.normalsUpdateLatitude,
|
||||
normalsUpdateLongitude = weather.base.normalsUpdateLongitude,
|
||||
|
||||
// current
|
||||
weatherText = weather.current?.weatherText,
|
||||
weatherCode = weather.current?.weatherCode,
|
||||
|
||||
temperature = weather.current?.temperature?.temperature,
|
||||
temperatureSourceFeelsLike = weather.current?.temperature?.sourceFeelsLike,
|
||||
temperatureApparent = weather.current?.temperature?.computedApparent,
|
||||
temperatureWindChill = weather.current?.temperature?.computedWindChill,
|
||||
humidex = weather.current?.temperature?.computedHumidex,
|
||||
|
||||
windDegree = weather.current?.wind?.degree,
|
||||
windSpeed = weather.current?.wind?.speed,
|
||||
windGusts = weather.current?.wind?.gusts,
|
||||
|
||||
uvIndex = weather.current?.uV?.index,
|
||||
|
||||
pm25 = weather.current?.airQuality?.pM25,
|
||||
pm10 = weather.current?.airQuality?.pM10,
|
||||
so2 = weather.current?.airQuality?.sO2,
|
||||
no2 = weather.current?.airQuality?.nO2,
|
||||
o3 = weather.current?.airQuality?.o3,
|
||||
co = weather.current?.airQuality?.cO,
|
||||
|
||||
relativeHumidity = weather.current?.relativeHumidity,
|
||||
dewPoint = weather.current?.dewPoint,
|
||||
pressure = weather.current?.pressure,
|
||||
cloudCover = weather.current?.cloudCover,
|
||||
visibility = weather.current?.visibility,
|
||||
ceiling = weather.current?.ceiling,
|
||||
dailyForecast = weather.current?.dailyForecast,
|
||||
hourlyForecast = weather.current?.hourlyForecast
|
||||
)
|
||||
|
||||
// 2. Save daily (delete first, then re-add)
|
||||
dailysQueries.deleteDailyListForLocationId(location.formattedId)
|
||||
weather.dailyForecast.forEach { daily ->
|
||||
dailysQueries.insert(
|
||||
locationFormattedId = location.formattedId,
|
||||
date = daily.date.time,
|
||||
|
||||
// daytime.
|
||||
daytimeWeatherText = daily.day?.weatherText,
|
||||
daytimeweatherSummary = daily.day?.weatherSummary,
|
||||
daytimeWeatherCode = daily.day?.weatherCode,
|
||||
|
||||
daytimeTemperature = daily.day?.temperature?.temperature,
|
||||
daytimeTemperatureSourceFeelsLike = daily.day?.temperature?.sourceFeelsLike,
|
||||
daytimeTemperatureApparent = daily.day?.temperature?.computedApparent,
|
||||
daytimeTemperatureWindChill = daily.day?.temperature?.computedWindChill,
|
||||
daytimeHumidex = daily.day?.temperature?.computedHumidex,
|
||||
|
||||
daytimeTotalPrecipitation = daily.day?.precipitation?.total,
|
||||
daytimeThunderstormPrecipitation = daily.day?.precipitation?.thunderstorm,
|
||||
daytimeRainPrecipitation = daily.day?.precipitation?.rain,
|
||||
daytimeSnowPrecipitation = daily.day?.precipitation?.snow,
|
||||
daytimeIcePrecipitation = daily.day?.precipitation?.ice,
|
||||
|
||||
daytimeTotalPrecipitationProbability = daily.day?.precipitationProbability?.total,
|
||||
daytimeThunderstormPrecipitationProbability = daily.day?.precipitationProbability?.thunderstorm,
|
||||
daytimeRainPrecipitationProbability = daily.day?.precipitationProbability?.rain,
|
||||
daytimeSnowPrecipitationProbability = daily.day?.precipitationProbability?.snow,
|
||||
daytimeIcePrecipitationProbability = daily.day?.precipitationProbability?.ice,
|
||||
|
||||
daytimeTotalPrecipitationDuration = daily.day?.precipitationDuration?.total,
|
||||
daytimeThunderstormPrecipitationDuration = daily.day?.precipitationDuration?.thunderstorm,
|
||||
daytimeRainPrecipitationDuration = daily.day?.precipitationDuration?.rain,
|
||||
daytimeSnowPrecipitationDuration = daily.day?.precipitationDuration?.snow,
|
||||
daytimeIcePrecipitationDuration = daily.day?.precipitationDuration?.ice,
|
||||
|
||||
daytimeWindDegree = daily.day?.wind?.degree,
|
||||
daytimeWindSpeed = daily.day?.wind?.speed,
|
||||
daytimeWindGusts = daily.day?.wind?.gusts,
|
||||
|
||||
// nighttime.
|
||||
nighttimeWeatherText = daily.night?.weatherText,
|
||||
nighttimeweatherSummary = daily.night?.weatherSummary,
|
||||
nighttimeWeatherCode = daily.night?.weatherCode,
|
||||
|
||||
nighttimeTemperature = daily.night?.temperature?.temperature,
|
||||
nighttimeTemperatureSourceFeelsLike = daily.night?.temperature?.sourceFeelsLike,
|
||||
nighttimeTemperatureApparent = daily.night?.temperature?.computedApparent,
|
||||
nighttimeTemperatureWindChill = daily.night?.temperature?.computedWindChill,
|
||||
nighttimeHumidex = daily.night?.temperature?.computedHumidex,
|
||||
|
||||
nighttimeTotalPrecipitation = daily.night?.precipitation?.total,
|
||||
nighttimeThunderstormPrecipitation = daily.night?.precipitation?.thunderstorm,
|
||||
nighttimeRainPrecipitation = daily.night?.precipitation?.rain,
|
||||
nighttimeSnowPrecipitation = daily.night?.precipitation?.snow,
|
||||
nighttimeIcePrecipitation = daily.night?.precipitation?.ice,
|
||||
|
||||
nighttimeTotalPrecipitationProbability = daily.night?.precipitationProbability?.total,
|
||||
nighttimeThunderstormPrecipitationProbability = daily.night?.precipitationProbability?.thunderstorm,
|
||||
nighttimeRainPrecipitationProbability = daily.night?.precipitationProbability?.rain,
|
||||
nighttimeSnowPrecipitationProbability = daily.night?.precipitationProbability?.snow,
|
||||
nighttimeIcePrecipitationProbability = daily.night?.precipitationProbability?.ice,
|
||||
|
||||
nighttimeTotalPrecipitationDuration = daily.night?.precipitationDuration?.total,
|
||||
nighttimeThunderstormPrecipitationDuration = daily.night?.precipitationDuration?.thunderstorm,
|
||||
nighttimeRainPrecipitationDuration = daily.night?.precipitationDuration?.rain,
|
||||
nighttimeSnowPrecipitationDuration = daily.night?.precipitationDuration?.snow,
|
||||
nighttimeIcePrecipitationDuration = daily.night?.precipitationDuration?.ice,
|
||||
|
||||
nighttimeWindDegree = daily.night?.wind?.degree,
|
||||
nighttimeWindSpeed = daily.night?.wind?.speed,
|
||||
nighttimeWindGusts = daily.night?.wind?.gusts,
|
||||
|
||||
degreeDayHeating = daily.degreeDay?.heating,
|
||||
degreeDayCooling = daily.degreeDay?.cooling,
|
||||
|
||||
// sun
|
||||
sunRiseDate = daily.sun?.riseDate?.time,
|
||||
sunSetDate = daily.sun?.setDate?.time,
|
||||
|
||||
// twilight
|
||||
twilightRiseDate = daily.twilight?.riseDate?.time,
|
||||
twilightSetDate = daily.twilight?.setDate?.time,
|
||||
|
||||
// moon
|
||||
moonRiseDate = daily.moon?.riseDate?.time,
|
||||
moonSetDate = daily.moon?.setDate?.time,
|
||||
|
||||
// moon phase
|
||||
moonPhaseAngle = daily.moonPhase?.angle?.toLong(),
|
||||
|
||||
// aqi.
|
||||
pm25 = daily.airQuality?.pM25,
|
||||
pm10 = daily.airQuality?.pM10,
|
||||
so2 = daily.airQuality?.sO2,
|
||||
no2 = daily.airQuality?.nO2,
|
||||
o3 = daily.airQuality?.o3,
|
||||
co = daily.airQuality?.cO,
|
||||
|
||||
// pollen
|
||||
alder = daily.pollen?.alder,
|
||||
ash = daily.pollen?.ash,
|
||||
birch = daily.pollen?.birch,
|
||||
chestnut = daily.pollen?.chestnut,
|
||||
cypress = daily.pollen?.cypress,
|
||||
grass = daily.pollen?.grass,
|
||||
hazel = daily.pollen?.hazel,
|
||||
hornbeam = daily.pollen?.hornbeam,
|
||||
linden = daily.pollen?.linden,
|
||||
mold = daily.pollen?.mold,
|
||||
mugwort = daily.pollen?.mugwort,
|
||||
oak = daily.pollen?.oak,
|
||||
olive = daily.pollen?.olive,
|
||||
plane = daily.pollen?.plane,
|
||||
plantain = daily.pollen?.plantain,
|
||||
poplar = daily.pollen?.poplar,
|
||||
ragweed = daily.pollen?.ragweed,
|
||||
sorrel = daily.pollen?.sorrel,
|
||||
tree = daily.pollen?.tree,
|
||||
urticaceae = daily.pollen?.urticaceae,
|
||||
willow = daily.pollen?.willow,
|
||||
|
||||
// uv.
|
||||
uvIndex = daily.uV?.index,
|
||||
|
||||
sunshineDuration = daily.sunshineDuration,
|
||||
|
||||
relativeHumidityAverage = daily.relativeHumidity?.average,
|
||||
relativeHumidityMin = daily.relativeHumidity?.min,
|
||||
relativeHumidityMax = daily.relativeHumidity?.max,
|
||||
|
||||
dewpointAverage = daily.dewPoint?.average,
|
||||
dewpointMin = daily.dewPoint?.min,
|
||||
dewpointMax = daily.dewPoint?.max,
|
||||
|
||||
pressureAverage = daily.pressure?.average,
|
||||
pressureMin = daily.pressure?.min,
|
||||
pressureMax = daily.pressure?.max,
|
||||
|
||||
cloudCoverAverage = daily.cloudCover?.average,
|
||||
cloudCoverMin = daily.cloudCover?.min,
|
||||
cloudCoverMax = daily.cloudCover?.max,
|
||||
|
||||
visibilityAverage = daily.visibility?.average,
|
||||
visibilityMin = daily.visibility?.min,
|
||||
visibilityMax = daily.visibility?.max
|
||||
)
|
||||
}
|
||||
|
||||
// 3. Save hourly (delete first, then re-add)
|
||||
hourlysQueries.deleteHourlyListForLocationId(location.formattedId)
|
||||
weather.hourlyForecast.forEach { hourly ->
|
||||
hourlysQueries.insert(
|
||||
locationFormattedId = location.formattedId,
|
||||
date = hourly.date.time,
|
||||
daylight = hourly.isDaylight,
|
||||
weatherCode = hourly.weatherCode,
|
||||
weatherText = hourly.weatherText,
|
||||
|
||||
temperature = hourly.temperature?.temperature,
|
||||
temperatureSourceFeelsLike = hourly.temperature?.sourceFeelsLike,
|
||||
temperatureApparent = hourly.temperature?.computedApparent,
|
||||
temperatureWindChill = hourly.temperature?.computedWindChill,
|
||||
humidex = hourly.temperature?.computedHumidex,
|
||||
|
||||
totalPrecipitation = hourly.precipitation?.total,
|
||||
thunderstormPrecipitation = hourly.precipitation?.thunderstorm,
|
||||
rainPrecipitation = hourly.precipitation?.rain,
|
||||
snowPrecipitation = hourly.precipitation?.snow,
|
||||
icePrecipitation = hourly.precipitation?.ice,
|
||||
|
||||
totalPrecipitationProbability = hourly.precipitationProbability?.total,
|
||||
thunderstormPrecipitationProbability = hourly.precipitationProbability?.thunderstorm,
|
||||
rainPrecipitationProbability = hourly.precipitationProbability?.rain,
|
||||
snowPrecipitationProbability = hourly.precipitationProbability?.snow,
|
||||
icePrecipitationProbability = hourly.precipitationProbability?.ice,
|
||||
|
||||
windDegree = hourly.wind?.degree,
|
||||
windSpeed = hourly.wind?.speed,
|
||||
windGusts = hourly.wind?.gusts,
|
||||
|
||||
// aqi.
|
||||
pm25 = hourly.airQuality?.pM25,
|
||||
pm10 = hourly.airQuality?.pM10,
|
||||
so2 = hourly.airQuality?.sO2,
|
||||
no2 = hourly.airQuality?.nO2,
|
||||
o3 = hourly.airQuality?.o3,
|
||||
co = hourly.airQuality?.cO,
|
||||
|
||||
// uv.
|
||||
uvIndex = hourly.uV?.index,
|
||||
|
||||
// details
|
||||
relativeHumidity = hourly.relativeHumidity,
|
||||
dewPoint = hourly.dewPoint,
|
||||
pressure = hourly.pressure,
|
||||
cloudCover = hourly.cloudCover,
|
||||
visibility = hourly.visibility
|
||||
)
|
||||
}
|
||||
|
||||
// 4. Save minutely (delete first, then re-add)
|
||||
minutelysQueries.deleteMinutelyListForLocationId(location.formattedId)
|
||||
weather.minutelyForecast.forEach { minutely ->
|
||||
minutelysQueries.insert(
|
||||
locationFormattedId = location.formattedId,
|
||||
date = minutely.date.time,
|
||||
minuteInterval = minutely.minuteInterval.toLong(),
|
||||
precipitationIntensity = minutely.precipitationIntensity
|
||||
)
|
||||
}
|
||||
|
||||
// 5. Save alerts (delete first, then re-add)
|
||||
alertsQueries.deleteAlertListForLocationId(location.formattedId)
|
||||
weather.alertList.forEach { alert ->
|
||||
alertsQueries.insert(
|
||||
locationFormattedId = location.formattedId,
|
||||
alertId = alert.alertId,
|
||||
startDate = alert.startDate?.time,
|
||||
endDate = alert.endDate?.time,
|
||||
headline = alert.headline,
|
||||
description = alert.description,
|
||||
instruction = alert.instruction,
|
||||
source = alert.source,
|
||||
severity = alert.severity,
|
||||
color = alert.color.toLong()
|
||||
)
|
||||
}
|
||||
|
||||
// 6. Save normals (delete first, then re-add)
|
||||
normalsQueries.deleteNormalsForLocationId(location.formattedId)
|
||||
weather.normals.forEach { normals ->
|
||||
normalsQueries.insert(
|
||||
locationFormattedId = location.formattedId,
|
||||
month = normals.key.value.toLong(),
|
||||
temperatureMaxAverage = normals.value.daytimeTemperature,
|
||||
temperatureMinAverage = normals.value.nighttimeTemperature
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun deleteAllWeathers() {
|
||||
handler.await {
|
||||
weathersQueries.deleteAllWeathers()
|
||||
}
|
||||
}
|
||||
}
|
||||
41
data/src/main/sqldelight/breezyweather/data/alerts.sq
Normal file
41
data/src/main/sqldelight/breezyweather/data/alerts.sq
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import breezyweather.domain.weather.reference.AlertSeverity;
|
||||
|
||||
CREATE TABLE alerts(
|
||||
_id INTEGER NOT NULL PRIMARY KEY,
|
||||
location_formatted_id TEXT NOT NULL,
|
||||
alert_id TEXT NOT NULL,
|
||||
start_date INTEGER,
|
||||
end_date INTEGER,
|
||||
headline TEXT,
|
||||
description TEXT,
|
||||
instruction TEXT,
|
||||
source TEXT,
|
||||
severity INTEGER AS AlertSeverity NOT NULL,
|
||||
color INTEGER NOT NULL,
|
||||
|
||||
FOREIGN KEY(location_formatted_id) REFERENCES locations (formatted_id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX alerts_location_formatted_id_index ON alerts(location_formatted_id);
|
||||
|
||||
getAlertListByLocationId:
|
||||
SELECT alert_id, start_date, end_date, headline, description, instruction, source, severity, color
|
||||
FROM alerts
|
||||
WHERE location_formatted_id = :locationFormattedId
|
||||
ORDER BY severity DESC, start_date ASC;
|
||||
|
||||
getCurrentAlertsByLocationId:
|
||||
SELECT alert_id, start_date, end_date, headline, description, instruction, source, severity, color
|
||||
FROM alerts
|
||||
WHERE location_formatted_id = :locationFormattedId
|
||||
AND (end_date IS NULL OR end_date > :now)
|
||||
ORDER BY severity DESC, start_date ASC;
|
||||
|
||||
insert:
|
||||
INSERT INTO alerts(location_formatted_id, alert_id, start_date, end_date, headline, description, instruction, source, severity, color)
|
||||
VALUES (:locationFormattedId, :alertId, :startDate, :endDate, :headline, :description, :instruction, :source, :severity, :color);
|
||||
|
||||
deleteAlertListForLocationId:
|
||||
DELETE FROM alerts
|
||||
WHERE location_formatted_id = :locationFormattedId;
|
||||
182
data/src/main/sqldelight/breezyweather/data/dailys.sq
Normal file
182
data/src/main/sqldelight/breezyweather/data/dailys.sq
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
import breezyweather.domain.weather.reference.WeatherCode;
|
||||
import kotlin.time.Duration;
|
||||
import org.breezyweather.unit.distance.Distance;
|
||||
import org.breezyweather.unit.pollen.PollenConcentration;
|
||||
import org.breezyweather.unit.pollutant.PollutantConcentration;
|
||||
import org.breezyweather.unit.precipitation.Precipitation;
|
||||
import org.breezyweather.unit.pressure.Pressure;
|
||||
import org.breezyweather.unit.ratio.Ratio;
|
||||
import org.breezyweather.unit.speed.Speed;
|
||||
import org.breezyweather.unit.temperature.Temperature;
|
||||
|
||||
CREATE TABLE dailys(
|
||||
_id INTEGER NOT NULL PRIMARY KEY,
|
||||
location_formatted_id TEXT NOT NULL,
|
||||
|
||||
date INTEGER NOT NULL,
|
||||
|
||||
-- daytime
|
||||
daytime_weather_text TEXT,
|
||||
daytime_weather_summary TEXT,
|
||||
daytime_weather_code TEXT AS WeatherCode,
|
||||
|
||||
daytime_temperature INTEGER AS Temperature,
|
||||
daytime_temperature_source_feels_like INTEGER AS Temperature,
|
||||
daytime_temperature_apparent INTEGER AS Temperature,
|
||||
daytime_temperature_wind_chill INTEGER AS Temperature,
|
||||
daytime_humidex INTEGER AS Temperature,
|
||||
|
||||
daytime_total_precipitation INTEGER AS Precipitation,
|
||||
daytime_thunderstorm_precipitation INTEGER AS Precipitation,
|
||||
daytime_rain_precipitation INTEGER AS Precipitation,
|
||||
daytime_snow_precipitation INTEGER AS Precipitation,
|
||||
daytime_ice_precipitation INTEGER AS Precipitation,
|
||||
|
||||
daytime_total_precipitation_probability INTEGER AS Ratio,
|
||||
daytime_thunderstorm_precipitation_probability INTEGER AS Ratio,
|
||||
daytime_rain_precipitation_probability INTEGER AS Ratio,
|
||||
daytime_snow_precipitation_probability INTEGER AS Ratio,
|
||||
daytime_ice_precipitation_probability INTEGER AS Ratio,
|
||||
|
||||
daytime_total_precipitation_duration INTEGER AS Duration,
|
||||
daytime_thunderstorm_precipitation_duration INTEGER AS Duration,
|
||||
daytime_rain_precipitation_duration INTEGER AS Duration,
|
||||
daytime_snow_precipitation_duration INTEGER AS Duration,
|
||||
daytime_ice_precipitation_duration INTEGER AS Duration,
|
||||
|
||||
daytime_wind_degree REAL,
|
||||
daytime_wind_speed INTEGER AS Speed,
|
||||
daytime_wind_gusts INTEGER AS Speed,
|
||||
|
||||
-- nighttime
|
||||
nighttime_weather_text TEXT,
|
||||
nighttime_weather_summary TEXT,
|
||||
nighttime_weather_code TEXT AS WeatherCode,
|
||||
|
||||
nighttime_temperature INTEGER AS Temperature,
|
||||
nighttime_temperature_source_feels_like INTEGER AS Temperature,
|
||||
nighttime_temperature_apparent INTEGER AS Temperature,
|
||||
nighttime_temperature_wind_chill INTEGER AS Temperature,
|
||||
nighttime_humidex INTEGER AS Temperature,
|
||||
|
||||
nighttime_total_precipitation INTEGER AS Precipitation,
|
||||
nighttime_thunderstorm_precipitation INTEGER AS Precipitation,
|
||||
nighttime_rain_precipitation INTEGER AS Precipitation,
|
||||
nighttime_snow_precipitation INTEGER AS Precipitation,
|
||||
nighttime_ice_precipitation INTEGER AS Precipitation,
|
||||
|
||||
nighttime_total_precipitation_probability INTEGER AS Ratio,
|
||||
nighttime_thunderstorm_precipitation_probability INTEGER AS Ratio,
|
||||
nighttime_rain_precipitation_probability INTEGER AS Ratio,
|
||||
nighttime_snow_precipitation_probability INTEGER AS Ratio,
|
||||
nighttime_ice_precipitation_probability INTEGER AS Ratio,
|
||||
|
||||
nighttime_total_precipitation_duration INTEGER AS Duration,
|
||||
nighttime_thunderstorm_precipitation_duration INTEGER AS Duration,
|
||||
nighttime_rain_precipitation_duration INTEGER AS Duration,
|
||||
nighttime_snow_precipitation_duration INTEGER AS Duration,
|
||||
nighttime_ice_precipitation_duration INTEGER AS Duration,
|
||||
|
||||
nighttime_wind_degree REAL,
|
||||
nighttime_wind_speed INTEGER AS Speed,
|
||||
nighttime_wind_gusts INTEGER AS Speed,
|
||||
|
||||
degree_day_heating INTEGER AS Temperature,
|
||||
degree_day_cooling INTEGER AS Temperature,
|
||||
|
||||
-- sun
|
||||
sun_rise_date INTEGER,
|
||||
sun_set_date INTEGER,
|
||||
|
||||
-- twilight
|
||||
twilight_rise_date INTEGER,
|
||||
twilight_set_date INTEGER,
|
||||
|
||||
-- moon
|
||||
moon_rise_date INTEGER,
|
||||
moon_set_date INTEGER,
|
||||
|
||||
-- moon phase
|
||||
moon_phase_angle INTEGER,
|
||||
|
||||
-- aqi.
|
||||
pm25 INTEGER AS PollutantConcentration,
|
||||
pm10 INTEGER AS PollutantConcentration,
|
||||
so2 INTEGER AS PollutantConcentration,
|
||||
no2 INTEGER AS PollutantConcentration,
|
||||
o3 INTEGER AS PollutantConcentration,
|
||||
co INTEGER AS PollutantConcentration,
|
||||
|
||||
-- pollen
|
||||
alder INTEGER AS PollenConcentration,
|
||||
ash INTEGER AS PollenConcentration,
|
||||
birch INTEGER AS PollenConcentration,
|
||||
chestnut INTEGER AS PollenConcentration,
|
||||
cypress INTEGER AS PollenConcentration,
|
||||
grass INTEGER AS PollenConcentration,
|
||||
hazel INTEGER AS PollenConcentration,
|
||||
hornbeam INTEGER AS PollenConcentration,
|
||||
linden INTEGER AS PollenConcentration,
|
||||
mold INTEGER AS PollenConcentration,
|
||||
mugwort INTEGER AS PollenConcentration,
|
||||
oak INTEGER AS PollenConcentration,
|
||||
olive INTEGER AS PollenConcentration,
|
||||
plane INTEGER AS PollenConcentration,
|
||||
plantain INTEGER AS PollenConcentration,
|
||||
poplar INTEGER AS PollenConcentration,
|
||||
ragweed INTEGER AS PollenConcentration,
|
||||
sorrel INTEGER AS PollenConcentration,
|
||||
tree INTEGER AS PollenConcentration,
|
||||
urticaceae INTEGER AS PollenConcentration,
|
||||
willow INTEGER AS PollenConcentration,
|
||||
|
||||
-- uv.
|
||||
uv_index REAL,
|
||||
|
||||
sunshine_duration INTEGER AS Duration,
|
||||
|
||||
-- relative humidity
|
||||
relative_humidity_average INTEGER AS Ratio,
|
||||
relative_humidity_min INTEGER AS Ratio,
|
||||
relative_humidity_max INTEGER AS Ratio,
|
||||
|
||||
-- dewpoint
|
||||
dewpoint_average INTEGER AS Temperature,
|
||||
dewpoint_min INTEGER AS Temperature,
|
||||
dewpoint_max INTEGER AS Temperature,
|
||||
|
||||
-- pressure
|
||||
pressure_average INTEGER AS Pressure,
|
||||
pressure_min INTEGER AS Pressure,
|
||||
pressure_max INTEGER AS Pressure,
|
||||
|
||||
-- cloud cover
|
||||
cloud_cover_average INTEGER AS Ratio,
|
||||
cloud_cover_min INTEGER AS Ratio,
|
||||
cloud_cover_max INTEGER AS Ratio,
|
||||
|
||||
-- visibility
|
||||
visibility_average INTEGER AS Distance,
|
||||
visibility_min INTEGER AS Distance,
|
||||
visibility_max INTEGER AS Distance,
|
||||
|
||||
UNIQUE(location_formatted_id, date) ON CONFLICT REPLACE,
|
||||
FOREIGN KEY(location_formatted_id) REFERENCES locations (formatted_id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX dailys_location_formatted_id_index ON dailys(location_formatted_id);
|
||||
|
||||
getDailyListByLocationId:
|
||||
SELECT date, daytime_weather_text, daytime_weather_summary, daytime_weather_code, daytime_temperature, daytime_temperature_source_feels_like, daytime_temperature_apparent, daytime_temperature_wind_chill, daytime_humidex, daytime_total_precipitation, daytime_thunderstorm_precipitation, daytime_rain_precipitation, daytime_snow_precipitation, daytime_ice_precipitation, daytime_total_precipitation_probability, daytime_thunderstorm_precipitation_probability, daytime_rain_precipitation_probability, daytime_snow_precipitation_probability, daytime_ice_precipitation_probability, daytime_total_precipitation_duration, daytime_thunderstorm_precipitation_duration, daytime_rain_precipitation_duration, daytime_snow_precipitation_duration, daytime_ice_precipitation_duration, daytime_wind_degree, daytime_wind_speed, daytime_wind_gusts, nighttime_weather_text, nighttime_weather_summary, nighttime_weather_code, nighttime_temperature, nighttime_temperature_source_feels_like, nighttime_temperature_apparent, nighttime_temperature_wind_chill, nighttime_humidex, nighttime_total_precipitation, nighttime_thunderstorm_precipitation, nighttime_rain_precipitation, nighttime_snow_precipitation, nighttime_ice_precipitation, nighttime_total_precipitation_probability, nighttime_thunderstorm_precipitation_probability, nighttime_rain_precipitation_probability, nighttime_snow_precipitation_probability, nighttime_ice_precipitation_probability, nighttime_total_precipitation_duration, nighttime_thunderstorm_precipitation_duration, nighttime_rain_precipitation_duration, nighttime_snow_precipitation_duration, nighttime_ice_precipitation_duration, nighttime_wind_degree, nighttime_wind_speed, nighttime_wind_gusts, degree_day_heating, degree_day_cooling, sun_rise_date, sun_set_date, twilight_rise_date, twilight_set_date, moon_rise_date, moon_set_date, moon_phase_angle, pm25, pm10, so2, no2, o3, co, alder, ash, birch, chestnut, cypress, grass, hazel, hornbeam, linden, mold, mugwort, oak, olive, plane, plantain, poplar, ragweed, sorrel, tree, urticaceae, willow, uv_index, sunshine_duration, relative_humidity_average, relative_humidity_min, relative_humidity_max, dewpoint_average, dewpoint_min, dewpoint_max, pressure_average, pressure_min, pressure_max, cloud_cover_average, cloud_cover_min, cloud_cover_max, visibility_average, visibility_min, visibility_max
|
||||
FROM dailys
|
||||
WHERE location_formatted_id = :locationFormattedId
|
||||
ORDER BY date;
|
||||
|
||||
insert:
|
||||
INSERT INTO dailys(location_formatted_id, date, daytime_weather_text, daytime_weather_summary, daytime_weather_code, daytime_temperature, daytime_temperature_source_feels_like, daytime_temperature_apparent, daytime_temperature_wind_chill, daytime_humidex, daytime_total_precipitation, daytime_thunderstorm_precipitation, daytime_rain_precipitation, daytime_snow_precipitation, daytime_ice_precipitation, daytime_total_precipitation_probability, daytime_thunderstorm_precipitation_probability, daytime_rain_precipitation_probability, daytime_snow_precipitation_probability, daytime_ice_precipitation_probability, daytime_total_precipitation_duration, daytime_thunderstorm_precipitation_duration, daytime_rain_precipitation_duration, daytime_snow_precipitation_duration, daytime_ice_precipitation_duration, daytime_wind_degree, daytime_wind_speed, daytime_wind_gusts, nighttime_weather_text, nighttime_weather_summary, nighttime_weather_code, nighttime_temperature, nighttime_temperature_source_feels_like, nighttime_temperature_apparent, nighttime_temperature_wind_chill, nighttime_humidex, nighttime_total_precipitation, nighttime_thunderstorm_precipitation, nighttime_rain_precipitation, nighttime_snow_precipitation, nighttime_ice_precipitation, nighttime_total_precipitation_probability, nighttime_thunderstorm_precipitation_probability, nighttime_rain_precipitation_probability, nighttime_snow_precipitation_probability, nighttime_ice_precipitation_probability, nighttime_total_precipitation_duration, nighttime_thunderstorm_precipitation_duration, nighttime_rain_precipitation_duration, nighttime_snow_precipitation_duration, nighttime_ice_precipitation_duration, nighttime_wind_degree, nighttime_wind_speed, nighttime_wind_gusts, degree_day_heating, degree_day_cooling, sun_rise_date, sun_set_date, twilight_rise_date, twilight_set_date, moon_rise_date, moon_set_date, moon_phase_angle, pm25, pm10, so2, no2, o3, co, alder, ash, birch, chestnut, cypress, grass, hazel, hornbeam, linden, mold, mugwort, oak, olive, plane, plantain, poplar, ragweed, sorrel, tree, urticaceae, willow, uv_index, sunshine_duration, relative_humidity_average, relative_humidity_min, relative_humidity_max, dewpoint_average, dewpoint_min, dewpoint_max, pressure_average, pressure_min, pressure_max, cloud_cover_average, cloud_cover_min, cloud_cover_max, visibility_average, visibility_min, visibility_max)
|
||||
VALUES (:locationFormattedId, :date, :daytimeWeatherText, :daytimeweatherSummary, :daytimeWeatherCode, :daytimeTemperature, :daytimeTemperatureSourceFeelsLike, :daytimeTemperatureApparent, :daytimeTemperatureWindChill, :daytimeHumidex, :daytimeTotalPrecipitation, :daytimeThunderstormPrecipitation, :daytimeRainPrecipitation, :daytimeSnowPrecipitation, :daytimeIcePrecipitation, :daytimeTotalPrecipitationProbability, :daytimeThunderstormPrecipitationProbability, :daytimeRainPrecipitationProbability, :daytimeSnowPrecipitationProbability, :daytimeIcePrecipitationProbability, :daytimeTotalPrecipitationDuration, :daytimeThunderstormPrecipitationDuration, :daytimeRainPrecipitationDuration, :daytimeSnowPrecipitationDuration, :daytimeIcePrecipitationDuration, :daytimeWindDegree, :daytimeWindSpeed, :daytimeWindGusts, :nighttimeWeatherText, :nighttimeweatherSummary, :nighttimeWeatherCode, :nighttimeTemperature, :nighttimeTemperatureSourceFeelsLike, :nighttimeTemperatureApparent, :nighttimeTemperatureWindChill, :nighttimeHumidex, :nighttimeTotalPrecipitation, :nighttimeThunderstormPrecipitation, :nighttimeRainPrecipitation, :nighttimeSnowPrecipitation, :nighttimeIcePrecipitation, :nighttimeTotalPrecipitationProbability, :nighttimeThunderstormPrecipitationProbability, :nighttimeRainPrecipitationProbability, :nighttimeSnowPrecipitationProbability, :nighttimeIcePrecipitationProbability, :nighttimeTotalPrecipitationDuration, :nighttimeThunderstormPrecipitationDuration, :nighttimeRainPrecipitationDuration, :nighttimeSnowPrecipitationDuration, :nighttimeIcePrecipitationDuration, :nighttimeWindDegree, :nighttimeWindSpeed, :nighttimeWindGusts, :degreeDayHeating, :degreeDayCooling, :sunRiseDate, :sunSetDate, :twilightRiseDate, :twilightSetDate, :moonRiseDate, :moonSetDate, :moonPhaseAngle, :pm25, :pm10, :so2, :no2, :o3, :co, :alder, :ash, :birch, :chestnut, :cypress, :grass, :hazel, :hornbeam, :linden, :mold, :mugwort, :oak, :olive, :plane, :plantain, :poplar, :ragweed, :sorrel, :tree, :urticaceae, :willow, :uvIndex, :sunshineDuration, :relativeHumidityAverage, :relativeHumidityMin, :relativeHumidityMax, :dewpointAverage, :dewpointMin, :dewpointMax, :pressureAverage, :pressureMin, :pressureMax, :cloudCoverAverage, :cloudCoverMin, :cloudCoverMax, :visibilityAverage, :visibilityMin, :visibilityMax);
|
||||
|
||||
deleteDailyListForLocationId:
|
||||
DELETE FROM dailys
|
||||
WHERE location_formatted_id = :locationFormattedId;
|
||||
79
data/src/main/sqldelight/breezyweather/data/hourlys.sq
Normal file
79
data/src/main/sqldelight/breezyweather/data/hourlys.sq
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
import breezyweather.domain.weather.reference.WeatherCode;
|
||||
import kotlin.Boolean;
|
||||
import org.breezyweather.unit.distance.Distance;
|
||||
import org.breezyweather.unit.pollutant.PollutantConcentration;
|
||||
import org.breezyweather.unit.precipitation.Precipitation;
|
||||
import org.breezyweather.unit.pressure.Pressure;
|
||||
import org.breezyweather.unit.ratio.Ratio;
|
||||
import org.breezyweather.unit.speed.Speed;
|
||||
import org.breezyweather.unit.temperature.Temperature;
|
||||
|
||||
CREATE TABLE hourlys(
|
||||
_id INTEGER NOT NULL PRIMARY KEY,
|
||||
location_formatted_id TEXT NOT NULL,
|
||||
|
||||
date INTEGER NOT NULL,
|
||||
|
||||
daylight INTEGER AS Boolean NOT NULL DEFAULT 1,
|
||||
weather_text TEXT,
|
||||
weather_code TEXT AS WeatherCode,
|
||||
|
||||
temperature INTEGER AS Temperature,
|
||||
temperature_source_feels_like INTEGER AS Temperature,
|
||||
temperature_apparent INTEGER AS Temperature,
|
||||
temperature_wind_chill INTEGER AS Temperature,
|
||||
humidex INTEGER AS Temperature,
|
||||
|
||||
total_precipitation INTEGER AS Precipitation,
|
||||
thunderstorm_precipitation INTEGER AS Precipitation,
|
||||
rain_precipitation INTEGER AS Precipitation,
|
||||
snow_precipitation INTEGER AS Precipitation,
|
||||
ice_precipitation INTEGER AS Precipitation,
|
||||
|
||||
total_precipitation_probability INTEGER AS Ratio,
|
||||
thunderstorm_precipitation_probability INTEGER AS Ratio,
|
||||
rain_precipitation_probability INTEGER AS Ratio,
|
||||
snow_precipitation_probability INTEGER AS Ratio,
|
||||
ice_precipitation_probability INTEGER AS Ratio,
|
||||
|
||||
wind_degree REAL,
|
||||
wind_speed INTEGER AS Speed,
|
||||
wind_gusts INTEGER AS Speed,
|
||||
|
||||
pm25 INTEGER AS PollutantConcentration,
|
||||
pm10 INTEGER AS PollutantConcentration,
|
||||
so2 INTEGER AS PollutantConcentration,
|
||||
no2 INTEGER AS PollutantConcentration,
|
||||
o3 INTEGER AS PollutantConcentration,
|
||||
co INTEGER AS PollutantConcentration,
|
||||
|
||||
-- uv.
|
||||
uvIndex REAL,
|
||||
|
||||
-- details
|
||||
relative_humidity INTEGER AS Ratio,
|
||||
dew_point INTEGER AS Temperature,
|
||||
pressure INTEGER AS Pressure,
|
||||
cloud_cover INTEGER AS Ratio,
|
||||
visibility INTEGER AS Distance,
|
||||
|
||||
UNIQUE(location_formatted_id, date) ON CONFLICT REPLACE,
|
||||
FOREIGN KEY(location_formatted_id) REFERENCES locations (formatted_id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX hourlys_location_formatted_id_index ON hourlys(location_formatted_id);
|
||||
|
||||
getHourlyListByLocationId:
|
||||
SELECT date, daylight, weather_text, weather_code, temperature, temperature_source_feels_like, temperature_apparent, temperature_wind_chill, humidex, total_precipitation, thunderstorm_precipitation, rain_precipitation, snow_precipitation, ice_precipitation, total_precipitation_probability, thunderstorm_precipitation_probability, rain_precipitation_probability, snow_precipitation_probability, ice_precipitation_probability, wind_degree, wind_speed, wind_gusts, pm25, pm10, so2, no2, o3, co, uvIndex, relative_humidity, dew_point, pressure, cloud_cover, visibility
|
||||
FROM hourlys
|
||||
WHERE location_formatted_id = :locationFormattedId
|
||||
ORDER BY date;
|
||||
|
||||
insert:
|
||||
INSERT INTO hourlys(location_formatted_id, date, daylight, weather_text, weather_code, temperature, temperature_source_feels_like, temperature_apparent, temperature_wind_chill, humidex, total_precipitation, thunderstorm_precipitation, rain_precipitation, snow_precipitation, ice_precipitation, total_precipitation_probability, thunderstorm_precipitation_probability, rain_precipitation_probability, snow_precipitation_probability, ice_precipitation_probability, wind_degree, wind_speed, wind_gusts, pm25, pm10, so2, no2, o3, co, uvIndex, relative_humidity, dew_point, pressure, cloud_cover, visibility)
|
||||
VALUES (:locationFormattedId, :date, :daylight, :weatherText, :weatherCode, :temperature, :temperatureSourceFeelsLike, :temperatureApparent, :temperatureWindChill, :humidex, :totalPrecipitation, :thunderstormPrecipitation, :rainPrecipitation, :snowPrecipitation, :icePrecipitation, :totalPrecipitationProbability, :thunderstormPrecipitationProbability, :rainPrecipitationProbability, :snowPrecipitationProbability, :icePrecipitationProbability, :windDegree, :windSpeed, :windGusts, :pm25, :pm10, :so2, :no2, :o3, :co, :uvIndex, :relativeHumidity, :dewPoint, :pressure, :cloudCover, :visibility);
|
||||
|
||||
deleteHourlyListForLocationId:
|
||||
DELETE FROM hourlys
|
||||
WHERE location_formatted_id = :locationFormattedId;
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
CREATE TABLE location_parameters(
|
||||
_id INTEGER NOT NULL PRIMARY KEY,
|
||||
location_formatted_id TEXT NOT NULL,
|
||||
source TEXT NOT NULL,
|
||||
parameter TEXT NOT NULL,
|
||||
value TEXT NOT NULL,
|
||||
|
||||
UNIQUE(location_formatted_id, source, parameter) ON CONFLICT REPLACE,
|
||||
FOREIGN KEY(location_formatted_id) REFERENCES locations (formatted_id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX location_parameters_location_formatted_id_index ON location_parameters(location_formatted_id);
|
||||
|
||||
getLocationParametersByLocationId:
|
||||
SELECT source, parameter, value
|
||||
FROM location_parameters
|
||||
WHERE location_formatted_id = :locationFormattedId;
|
||||
|
||||
insert:
|
||||
INSERT INTO location_parameters(location_formatted_id, source, parameter, value)
|
||||
VALUES (:locationFormattedId, :source, :parameter, :value);
|
||||
|
||||
updateParameters:
|
||||
UPDATE location_parameters
|
||||
SET value = :newValue
|
||||
WHERE source = :source
|
||||
AND parameter = :parameter
|
||||
AND value = :oldValue;
|
||||
|
||||
deleteAllNonMatchingParameters:
|
||||
DELETE FROM location_parameters
|
||||
WHERE location_formatted_id = :locationFormattedId
|
||||
AND parameter NOT IN :locationParameterNames;
|
||||
|
||||
deleteParameters:
|
||||
DELETE FROM location_parameters
|
||||
WHERE source = :source
|
||||
AND parameter = :parameter
|
||||
AND value IN :parameterValues;
|
||||
145
data/src/main/sqldelight/breezyweather/data/locations.sq
Normal file
145
data/src/main/sqldelight/breezyweather/data/locations.sq
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
import java.util.TimeZone;
|
||||
import kotlin.Boolean;
|
||||
|
||||
CREATE TABLE locations(
|
||||
formatted_id TEXT NOT NULL PRIMARY KEY,
|
||||
list_order INTEGER NOT NULL,
|
||||
|
||||
city_id TEXT,
|
||||
latitude REAL NOT NULL,
|
||||
longitude REAL NOT NULL,
|
||||
timezone TEXT AS TimeZone NOT NULL,
|
||||
custom_name TEXT,
|
||||
country TEXT NOT NULL,
|
||||
country_code TEXT,
|
||||
admin1 TEXT,
|
||||
admin1_code TEXT,
|
||||
admin2 TEXT,
|
||||
admin2_code TEXT,
|
||||
admin3 TEXT,
|
||||
admin3_code TEXT,
|
||||
admin4 TEXT,
|
||||
admin4_code TEXT,
|
||||
city TEXT NOT NULL,
|
||||
district TEXT,
|
||||
|
||||
-- Sources
|
||||
weather_source TEXT NOT NULL,
|
||||
current_source TEXT,
|
||||
air_quality_source TEXT,
|
||||
pollen_source TEXT,
|
||||
minutely_source TEXT,
|
||||
alert_source TEXT,
|
||||
normals_source TEXT,
|
||||
reverse_geocoding_source TEXT,
|
||||
|
||||
current_position INTEGER AS Boolean NOT NULL DEFAULT 0,
|
||||
|
||||
needs_geocode_refresh INTEGER AS Boolean NOT NULL DEFAULT 0,
|
||||
|
||||
background_weather_kind TEXT,
|
||||
background_day_night_type TEXT
|
||||
);
|
||||
|
||||
getLocationById:
|
||||
SELECT city_id, latitude, longitude, timezone, custom_name, country, country_code, admin1, admin1_code, admin2, admin2_code, admin3, admin3_code, admin4, admin4_code, city, district, weather_source, current_source, air_quality_source, pollen_source, minutely_source, alert_source, normals_source, reverse_geocoding_source, current_position, needs_geocode_refresh, background_weather_kind, background_day_night_type
|
||||
FROM locations
|
||||
WHERE formatted_id = :formattedId;
|
||||
|
||||
getAllLocations:
|
||||
SELECT city_id, latitude, longitude, timezone, custom_name, country, country_code, admin1, admin1_code, admin2, admin2_code, admin3, admin3_code, admin4, admin4_code, city, district, weather_source, current_source, air_quality_source, pollen_source, minutely_source, alert_source, normals_source, reverse_geocoding_source, current_position, needs_geocode_refresh, background_weather_kind, background_day_night_type
|
||||
FROM locations
|
||||
ORDER BY list_order;
|
||||
|
||||
getXLocations:
|
||||
SELECT city_id, latitude, longitude, timezone, custom_name, country, country_code, admin1, admin1_code, admin2, admin2_code, admin3, admin3_code, admin4, admin4_code, city, district, weather_source, current_source, air_quality_source, pollen_source, minutely_source, alert_source, normals_source, reverse_geocoding_source, current_position, needs_geocode_refresh, background_weather_kind, background_day_night_type
|
||||
FROM locations
|
||||
ORDER BY list_order
|
||||
LIMIT :limit;
|
||||
|
||||
getFirstLocation:
|
||||
SELECT city_id, latitude, longitude, timezone, custom_name, country, country_code, admin1, admin1_code, admin2, admin2_code, admin3, admin3_code, admin4, admin4_code, city, district, weather_source, current_source, air_quality_source, pollen_source, minutely_source, alert_source, normals_source, reverse_geocoding_source, current_position, needs_geocode_refresh, background_weather_kind, background_day_night_type
|
||||
FROM locations
|
||||
ORDER BY list_order
|
||||
LIMIT 1;
|
||||
|
||||
insert:
|
||||
INSERT INTO locations(formatted_id, list_order, city_id, latitude, longitude, timezone, custom_name, country, country_code, admin1, admin1_code, admin2, admin2_code, admin3, admin3_code, admin4, admin4_code, city, district, weather_source, current_source, air_quality_source, pollen_source, minutely_source, alert_source, normals_source, reverse_geocoding_source, current_position, needs_geocode_refresh, background_weather_kind, background_day_night_type)
|
||||
VALUES (:formattedId, :listOrder, :cityId, :latitude, :longitude, :timezone, :customName, :country, :countryCode, :admin1, :admin1Code, :admin2, :admin2Code, :admin3, :admin3Code, :admin4, :admin4Code, :city, :district, :weatherSource, :currentSource, :airQualitySource, :pollenSource, :minutelySource, :alertSource, :normalsSource, :reverseGeocodingSource, :currentPosition, :needsGeocodeRefresh, :backgroundWeatherKind, :backgroundDayNightType)
|
||||
ON CONFLICT(formatted_id) DO UPDATE SET
|
||||
list_order = coalesce(:listOrder, list_order),
|
||||
city_id = coalesce(:cityId, city_id),
|
||||
latitude = coalesce(:latitude, latitude),
|
||||
longitude = coalesce(:longitude, longitude),
|
||||
timezone = coalesce(:timezone, timezone),
|
||||
custom_name = coalesce(:customName, custom_name),
|
||||
country = coalesce(:country, country),
|
||||
country_code = coalesce(:countryCode, country_code),
|
||||
admin1 = coalesce(:admin1, admin1),
|
||||
admin1_code = coalesce(:admin1Code, admin1_code),
|
||||
admin2 = coalesce(:admin2, admin2),
|
||||
admin2_code = coalesce(:admin2Code, admin2_code),
|
||||
admin3 = coalesce(:admin3, admin3),
|
||||
admin3_code = coalesce(:admin3Code, admin3_code),
|
||||
admin4 = coalesce(:admin4, admin4),
|
||||
admin4_code = coalesce(:admin4Code, admin4_code),
|
||||
city = coalesce(:city, city),
|
||||
district = coalesce(:district, district),
|
||||
weather_source = coalesce(:weatherSource, weather_source),
|
||||
current_source = coalesce(:currentSource, current_source),
|
||||
air_quality_source = coalesce(:airQualitySource, air_quality_source),
|
||||
pollen_source = coalesce(:pollenSource, pollen_source),
|
||||
minutely_source = coalesce(:minutelySource, minutely_source),
|
||||
alert_source = coalesce(:alertSource, alert_source),
|
||||
normals_source = coalesce(:normalsSource, normals_source),
|
||||
reverse_geocoding_source = coalesce(:reverseGeocodingSource, reverse_geocoding_source),
|
||||
current_position = coalesce(:currentPosition, current_position),
|
||||
needs_geocode_refresh = coalesce(:needsGeocodeRefresh, needs_geocode_refresh),
|
||||
background_weather_kind = coalesce(:backgroundWeatherKind, background_weather_kind),
|
||||
background_day_night_type = coalesce(:backgroundDayNightType, background_day_night_type);
|
||||
|
||||
updateFormattedId:
|
||||
UPDATE locations
|
||||
SET formatted_id = coalesce(:newFormattedId, formatted_id)
|
||||
WHERE formatted_id = coalesce(:oldFormattedId, formatted_id);
|
||||
|
||||
update:
|
||||
UPDATE locations
|
||||
SET city_id = coalesce(:cityId, city_id),
|
||||
latitude = coalesce(:latitude, latitude),
|
||||
longitude = coalesce(:longitude, longitude),
|
||||
timezone = coalesce(:timezone, timezone),
|
||||
custom_name = coalesce(:customName, custom_name),
|
||||
country = coalesce(:country, country),
|
||||
country_code = coalesce(:countryCode, country_code),
|
||||
admin1 = coalesce(:admin1, admin1),
|
||||
admin1_code = coalesce(:admin1Code, admin1_code),
|
||||
admin2 = coalesce(:admin2, admin2),
|
||||
admin2_code = coalesce(:admin2Code, admin2_code),
|
||||
admin3 = coalesce(:admin3, admin3),
|
||||
admin3_code = coalesce(:admin3Code, admin3_code),
|
||||
admin4 = coalesce(:admin4, admin4),
|
||||
admin4_code = coalesce(:admin4Code, admin4_code),
|
||||
city = coalesce(:city, city),
|
||||
district = coalesce(:district, district),
|
||||
weather_source = coalesce(:weatherSource, weather_source),
|
||||
current_source = coalesce(:currentSource, current_source),
|
||||
air_quality_source = coalesce(:airQualitySource, air_quality_source),
|
||||
pollen_source = coalesce(:pollenSource, pollen_source),
|
||||
minutely_source = coalesce(:minutelySource, minutely_source),
|
||||
alert_source = coalesce(:alertSource, alert_source),
|
||||
normals_source = coalesce(:normalsSource, normals_source),
|
||||
reverse_geocoding_source = coalesce(:reverseGeocodingSource, reverse_geocoding_source),
|
||||
current_position = coalesce(:currentPosition, current_position),
|
||||
needs_geocode_refresh = coalesce(:needsGeocodeRefresh, needs_geocode_refresh),
|
||||
background_weather_kind = coalesce(:backgroundWeatherKind, background_weather_kind),
|
||||
background_day_night_type = coalesce(:backgroundDayNightType, background_day_night_type)
|
||||
WHERE formatted_id = coalesce(:formattedId, formatted_id);
|
||||
|
||||
deleteLocation:
|
||||
DELETE FROM locations
|
||||
WHERE formatted_id = :formattedId;
|
||||
|
||||
deleteAllNonMatchingLocations:
|
||||
DELETE FROM locations
|
||||
WHERE formatted_id NOT IN :formattedIds;
|
||||
29
data/src/main/sqldelight/breezyweather/data/minutelys.sq
Normal file
29
data/src/main/sqldelight/breezyweather/data/minutelys.sq
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import org.breezyweather.unit.precipitation.Precipitation;
|
||||
|
||||
CREATE TABLE minutelys(
|
||||
_id INTEGER NOT NULL PRIMARY KEY,
|
||||
location_formatted_id TEXT NOT NULL,
|
||||
|
||||
date INTEGER NOT NULL,
|
||||
minute_interval INTEGER NOT NULL,
|
||||
precipitation_intensity INTEGER AS Precipitation,
|
||||
|
||||
FOREIGN KEY(location_formatted_id) REFERENCES locations (formatted_id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX minutelys_location_formatted_id_index ON minutelys(location_formatted_id);
|
||||
|
||||
getMinutelyListByLocationId:
|
||||
SELECT date, minute_interval, precipitation_intensity
|
||||
FROM minutelys
|
||||
WHERE location_formatted_id = :locationFormattedId
|
||||
ORDER BY date;
|
||||
|
||||
insert:
|
||||
INSERT INTO minutelys(location_formatted_id, date, minute_interval, precipitation_intensity)
|
||||
VALUES (:locationFormattedId, :date, :minuteInterval, :precipitationIntensity);
|
||||
|
||||
deleteMinutelyListForLocationId:
|
||||
DELETE FROM minutelys
|
||||
WHERE location_formatted_id = :locationFormattedId;
|
||||
30
data/src/main/sqldelight/breezyweather/data/normals.sq
Normal file
30
data/src/main/sqldelight/breezyweather/data/normals.sq
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import org.breezyweather.unit.temperature.Temperature;
|
||||
|
||||
CREATE TABLE normals(
|
||||
_id INTEGER NOT NULL PRIMARY KEY,
|
||||
location_formatted_id TEXT NOT NULL,
|
||||
|
||||
month INTEGER NOT NULL,
|
||||
temperature_max_average INTEGER AS Temperature,
|
||||
temperature_min_average INTEGER AS Temperature,
|
||||
|
||||
UNIQUE(location_formatted_id, month) ON CONFLICT REPLACE,
|
||||
FOREIGN KEY(location_formatted_id) REFERENCES locations (formatted_id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX normals_location_formatted_id_index ON normals(location_formatted_id);
|
||||
|
||||
getNormalsByLocationId:
|
||||
SELECT month, temperature_max_average, temperature_min_average
|
||||
FROM normals
|
||||
WHERE location_formatted_id = :locationFormattedId
|
||||
ORDER BY month;
|
||||
|
||||
insert:
|
||||
INSERT INTO normals(location_formatted_id, month, temperature_max_average, temperature_min_average)
|
||||
VALUES (:locationFormattedId, :month, :temperatureMaxAverage, :temperatureMinAverage);
|
||||
|
||||
deleteNormalsForLocationId:
|
||||
DELETE FROM normals
|
||||
WHERE location_formatted_id = :locationFormattedId;
|
||||
118
data/src/main/sqldelight/breezyweather/data/weathers.sq
Normal file
118
data/src/main/sqldelight/breezyweather/data/weathers.sq
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
import breezyweather.domain.weather.reference.WeatherCode;
|
||||
import org.breezyweather.unit.distance.Distance;
|
||||
import org.breezyweather.unit.pollutant.PollutantConcentration;
|
||||
import org.breezyweather.unit.pressure.Pressure;
|
||||
import org.breezyweather.unit.ratio.Ratio;
|
||||
import org.breezyweather.unit.speed.Speed;
|
||||
import org.breezyweather.unit.temperature.Temperature;
|
||||
|
||||
CREATE TABLE weathers(
|
||||
_id INTEGER NOT NULL PRIMARY KEY,
|
||||
location_formatted_id TEXT NOT NULL,
|
||||
|
||||
-- Base
|
||||
refresh_time INTEGER,
|
||||
main_update_time INTEGER,
|
||||
current_update_time INTEGER,
|
||||
air_quality_update_time INTEGER,
|
||||
pollen_update_time INTEGER,
|
||||
minutely_update_time INTEGER,
|
||||
alerts_update_time INTEGER,
|
||||
normals_update_time INTEGER,
|
||||
normals_update_latitude REAL NOT NULL DEFAULT 0.0,
|
||||
normals_update_longitude REAL NOT NULL DEFAULT 0.0,
|
||||
|
||||
-- Current
|
||||
weather_text TEXT,
|
||||
weather_code TEXT AS WeatherCode,
|
||||
|
||||
temperature INTEGER AS Temperature,
|
||||
temperature_source_feels_like INTEGER AS Temperature,
|
||||
temperature_apparent INTEGER AS Temperature,
|
||||
temperature_wind_chill INTEGER AS Temperature,
|
||||
humidex INTEGER AS Temperature,
|
||||
|
||||
wind_degree REAL,
|
||||
wind_speed INTEGER AS Speed,
|
||||
wind_gusts INTEGER AS Speed,
|
||||
|
||||
uv_index REAL,
|
||||
|
||||
pm25 INTEGER AS PollutantConcentration,
|
||||
pm10 INTEGER AS PollutantConcentration,
|
||||
so2 INTEGER AS PollutantConcentration,
|
||||
no2 INTEGER AS PollutantConcentration,
|
||||
o3 INTEGER AS PollutantConcentration,
|
||||
co INTEGER AS PollutantConcentration,
|
||||
|
||||
relative_humidity INTEGER AS Ratio,
|
||||
dew_point INTEGER AS Temperature,
|
||||
pressure INTEGER AS Pressure,
|
||||
visibility INTEGER AS Distance,
|
||||
cloud_cover INTEGER AS Ratio,
|
||||
ceiling INTEGER AS Distance,
|
||||
daily_forecast TEXT,
|
||||
hourly_forecast TEXT,
|
||||
|
||||
UNIQUE(location_formatted_id) ON CONFLICT REPLACE,
|
||||
FOREIGN KEY(location_formatted_id) REFERENCES locations (formatted_id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX weathers_location_formatted_id_index ON weathers(location_formatted_id);
|
||||
|
||||
getWeatherByLocationId:
|
||||
SELECT refresh_time, main_update_time, current_update_time, air_quality_update_time, pollen_update_time, minutely_update_time, alerts_update_time, normals_update_time, normals_update_latitude, normals_update_longitude, weather_text, weather_code, temperature, temperature_source_feels_like, temperature_apparent, temperature_wind_chill, humidex, wind_degree, wind_speed, wind_gusts, uv_index, pm25, pm10, so2, no2, o3, co, relative_humidity, dew_point, pressure, visibility, cloud_cover, ceiling, daily_forecast, hourly_forecast
|
||||
FROM weathers
|
||||
WHERE location_formatted_id = :locationFormattedId;
|
||||
|
||||
insert:
|
||||
INSERT INTO weathers(location_formatted_id, refresh_time, main_update_time, current_update_time, air_quality_update_time, pollen_update_time, minutely_update_time, alerts_update_time, normals_update_time, normals_update_latitude, normals_update_longitude, weather_text, weather_code, temperature, temperature_source_feels_like, temperature_apparent, temperature_wind_chill, humidex, wind_degree, wind_speed, wind_gusts, uv_index, pm25, pm10, so2, no2, o3, co, relative_humidity, dew_point, pressure, visibility, cloud_cover, ceiling, daily_forecast, hourly_forecast)
|
||||
VALUES (:locationFormattedId, :refreshTime, :mainUpdateTime, :currentUpdateTime, :airQualityUpdateTime, :pollenUpdateTime, :minutelyUpdateTime, :alertsUpdateTime, :normalsUpdateTime, :normalsUpdateLatitude, :normalsUpdateLongitude, :weatherText, :weatherCode, :temperature, :temperatureSourceFeelsLike, :temperatureApparent, :temperatureWindChill, :humidex, :windDegree, :windSpeed, :windGusts, :uvIndex, :pm25, :pm10, :so2, :no2, :o3, :co, :relativeHumidity, :dewPoint, :pressure, :visibility, :cloudCover, :ceiling, :dailyForecast, :hourlyForecast);
|
||||
|
||||
update:
|
||||
UPDATE weathers SET
|
||||
location_formatted_id = coalesce(:locationFormattedId, location_formatted_id),
|
||||
refresh_time = coalesce(:refreshTime, refresh_time),
|
||||
main_update_time = coalesce(:mainUpdateTime, main_update_time),
|
||||
current_update_time = coalesce(:currentUpdateTime, current_update_time),
|
||||
air_quality_update_time = coalesce(:airQualityUpdateTime, air_quality_update_time),
|
||||
pollen_update_time = coalesce(:pollenUpdateTime, pollen_update_time),
|
||||
minutely_update_time = coalesce(:minutelyUpdateTime, minutely_update_time),
|
||||
alerts_update_time = coalesce(:alertsUpdateTime, alerts_update_time),
|
||||
normals_update_time = coalesce(:normalsUpdateTime, normals_update_time),
|
||||
normals_update_latitude = coalesce(:normalsUpdateTime, normals_update_latitude),
|
||||
normals_update_longitude = coalesce(:normalsUpdateTime, normals_update_longitude),
|
||||
weather_text = coalesce(:weatherText, weather_text),
|
||||
weather_code = coalesce(:weatherCode, weather_code),
|
||||
temperature = coalesce(:temperature, temperature),
|
||||
temperature_source_feels_like = coalesce(:temperatureSourceFeelsLike, temperature_source_feels_like),
|
||||
temperature_apparent = coalesce(:apparentTemperature, temperature_apparent),
|
||||
temperature_wind_chill = coalesce(:windChillTemperature, temperature_wind_chill),
|
||||
humidex = coalesce(:humidex, humidex),
|
||||
wind_degree = coalesce(:windDegree, wind_degree),
|
||||
wind_speed = coalesce(:windSpeed, wind_speed),
|
||||
wind_gusts = coalesce(:windGusts, wind_gusts),
|
||||
uv_index = coalesce(:uvIndex, uv_index),
|
||||
pm25 = coalesce(:pm25, pm25),
|
||||
pm10 = coalesce(:pm10, pm10),
|
||||
so2 = coalesce(:so2, so2),
|
||||
no2 = coalesce(:no2, no2),
|
||||
o3 = coalesce(:o3, o3),
|
||||
co = coalesce(:co, co),
|
||||
relative_humidity = coalesce(:relativeHumidity, relative_humidity),
|
||||
dew_point = coalesce(:dewPoint, dew_point),
|
||||
pressure = coalesce(:pressure, pressure),
|
||||
visibility = coalesce(:visibility, visibility),
|
||||
cloud_cover = coalesce(:cloudCover, cloud_cover),
|
||||
ceiling = coalesce(:ceiling, ceiling),
|
||||
daily_forecast = coalesce(:dailyForecast, daily_forecast),
|
||||
hourly_forecast = coalesce(:hourlyForecast, hourly_forecast)
|
||||
WHERE location_formatted_id = :locationFormattedId;
|
||||
|
||||
deleteWeatherForLocationId:
|
||||
DELETE FROM weathers
|
||||
WHERE location_formatted_id = :locationFormattedId;
|
||||
|
||||
deleteAllWeathers:
|
||||
DELETE FROM weathers;
|
||||
38
data/src/main/sqldelight/breezyweather/migrations/1.sqm
Normal file
38
data/src/main/sqldelight/breezyweather/migrations/1.sqm
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
ALTER TABLE dailys
|
||||
ADD COLUMN ash INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN chestnut INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN cypress INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN hazel INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN hornbeam INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN linden INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN oak INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN plane INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN plantain INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN poplar INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN sorrel INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN urticaceae INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN willow INTEGER;
|
||||
5
data/src/main/sqldelight/breezyweather/migrations/10.sqm
Normal file
5
data/src/main/sqldelight/breezyweather/migrations/10.sqm
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
ALTER TABLE dailys
|
||||
ADD COLUMN twilight_rise_date INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN twilight_set_date INTEGER;
|
||||
37
data/src/main/sqldelight/breezyweather/migrations/11.sqm
Normal file
37
data/src/main/sqldelight/breezyweather/migrations/11.sqm
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_real_feel_shader_temperature;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_real_feel_shader_temperature;
|
||||
|
||||
ALTER TABLE dailys
|
||||
RENAME COLUMN daytime_real_feel_temperature TO daytime_source_feels_like_temperature;
|
||||
|
||||
ALTER TABLE dailys
|
||||
RENAME COLUMN nighttime_real_feel_temperature TO nighttime_source_feels_like_temperature;
|
||||
|
||||
ALTER TABLE dailys
|
||||
RENAME COLUMN daytime_wet_bulb_temperature TO daytime_humidex;
|
||||
|
||||
ALTER TABLE dailys
|
||||
RENAME COLUMN nighttime_wet_bulb_temperature TO nighttime_humidex;
|
||||
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN real_feel_shader_temperature;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
RENAME COLUMN real_feel_temperature TO source_feels_like_temperature;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
RENAME COLUMN wet_bulb_temperature TO humidex;
|
||||
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN real_feel_shader_temperature;
|
||||
|
||||
ALTER TABLE weathers
|
||||
RENAME COLUMN real_feel_temperature TO source_feels_like_temperature;
|
||||
|
||||
ALTER TABLE weathers
|
||||
RENAME COLUMN wet_bulb_temperature TO humidex;
|
||||
8
data/src/main/sqldelight/breezyweather/migrations/12.sqm
Normal file
8
data/src/main/sqldelight/breezyweather/migrations/12.sqm
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
ALTER TABLE weathers
|
||||
DROP COLUMN normals_month;
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN normals_daytime_temperature;
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN normals_nighttime_temperature;
|
||||
14
data/src/main/sqldelight/breezyweather/migrations/13.sqm
Normal file
14
data/src/main/sqldelight/breezyweather/migrations/13.sqm
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
CREATE TABLE normals(
|
||||
_id INTEGER NOT NULL PRIMARY KEY,
|
||||
location_formatted_id TEXT NOT NULL,
|
||||
|
||||
month INTEGER NOT NULL,
|
||||
daytime_temperature REAL,
|
||||
nighttime_temperature REAL,
|
||||
|
||||
UNIQUE(location_formatted_id, month) ON CONFLICT REPLACE,
|
||||
FOREIGN KEY(location_formatted_id) REFERENCES locations (formatted_id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX normals_location_formatted_id_index ON normals(location_formatted_id);
|
||||
5
data/src/main/sqldelight/breezyweather/migrations/14.sqm
Normal file
5
data/src/main/sqldelight/breezyweather/migrations/14.sqm
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
ALTER TABLE weathers
|
||||
ADD COLUMN normals_update_latitude REAL NOT NULL DEFAULT 0.0;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN normals_update_longitude REAL NOT NULL DEFAULT 0.0;
|
||||
44
data/src/main/sqldelight/breezyweather/migrations/15.sqm
Normal file
44
data/src/main/sqldelight/breezyweather/migrations/15.sqm
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
ALTER TABLE dailys
|
||||
ADD COLUMN relative_humidity_average REAL;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN relative_humidity_min REAL;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN relative_humidity_max REAL;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN dewpoint_average REAL;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN dewpoint_min REAL;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN dewpoint_max REAL;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN pressure_average REAL;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN pressure_min REAL;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN pressure_max REAL;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN cloud_cover_average INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN cloud_cover_min INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN cloud_cover_max INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN visibility_average REAL;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN visibility_min REAL;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN visibility_max REAL;
|
||||
5
data/src/main/sqldelight/breezyweather/migrations/16.sqm
Normal file
5
data/src/main/sqldelight/breezyweather/migrations/16.sqm
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_cloud_cover;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_cloud_cover;
|
||||
5
data/src/main/sqldelight/breezyweather/migrations/17.sqm
Normal file
5
data/src/main/sqldelight/breezyweather/migrations/17.sqm
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
ALTER TABLE dailys
|
||||
RENAME COLUMN daytime_weather_phase TO daytime_weather_summary;
|
||||
|
||||
ALTER TABLE dailys
|
||||
RENAME COLUMN nighttime_weather_phase TO nighttime_weather_summary;
|
||||
29
data/src/main/sqldelight/breezyweather/migrations/18.sqm
Normal file
29
data/src/main/sqldelight/breezyweather/migrations/18.sqm
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
ALTER TABLE weathers
|
||||
DROP COLUMN pressure;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN pressure INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN pressure_average;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN pressure_average INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN pressure_min;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN pressure_min INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN pressure_max;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN pressure_max INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN pressure;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN pressure INTEGER;
|
||||
65
data/src/main/sqldelight/breezyweather/migrations/19.sqm
Normal file
65
data/src/main/sqldelight/breezyweather/migrations/19.sqm
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_total_precipitation_duration;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_total_precipitation_duration INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_thunderstorm_precipitation_duration;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_thunderstorm_precipitation_duration INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_rain_precipitation_duration;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_rain_precipitation_duration INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_snow_precipitation_duration;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_snow_precipitation_duration INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_ice_precipitation_duration;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_ice_precipitation_duration INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_total_precipitation_duration;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_total_precipitation_duration INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_thunderstorm_precipitation_duration;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_thunderstorm_precipitation_duration INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_rain_precipitation_duration;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_rain_precipitation_duration INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_snow_precipitation_duration;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_snow_precipitation_duration INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_ice_precipitation_duration;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_ice_precipitation_duration INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN sunshine_duration;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN sunshine_duration INTEGER;
|
||||
2
data/src/main/sqldelight/breezyweather/migrations/2.sqm
Normal file
2
data/src/main/sqldelight/breezyweather/migrations/2.sqm
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE dailys
|
||||
RENAME COLUMN hours_of_sun TO sunshine_duration;
|
||||
35
data/src/main/sqldelight/breezyweather/migrations/20.sqm
Normal file
35
data/src/main/sqldelight/breezyweather/migrations/20.sqm
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
ALTER TABLE weathers
|
||||
DROP COLUMN visibility;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN visibility INTEGER;
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN ceiling;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN ceiling INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN visibility_average;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN visibility_average INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN visibility_min;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN visibility_min INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN visibility_max;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN visibility_max INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN visibility;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN visibility INTEGER;
|
||||
95
data/src/main/sqldelight/breezyweather/migrations/21.sqm
Normal file
95
data/src/main/sqldelight/breezyweather/migrations/21.sqm
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_total_precipitation;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_total_precipitation INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_thunderstorm_precipitation;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_thunderstorm_precipitation INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_rain_precipitation;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_rain_precipitation INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_snow_precipitation;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_snow_precipitation INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_ice_precipitation;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_ice_precipitation INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_total_precipitation;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_total_precipitation INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_thunderstorm_precipitation;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_thunderstorm_precipitation INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_rain_precipitation;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_rain_precipitation INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_snow_precipitation;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_snow_precipitation INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_ice_precipitation;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_ice_precipitation INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN total_precipitation;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN total_precipitation INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN thunderstorm_precipitation;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN thunderstorm_precipitation INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN rain_precipitation;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN rain_precipitation INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN snow_precipitation;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN snow_precipitation INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN ice_precipitation;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN ice_precipitation INTEGER;
|
||||
|
||||
ALTER TABLE minutelys
|
||||
DROP COLUMN precipitation_intensity;
|
||||
|
||||
ALTER TABLE minutelys
|
||||
ADD COLUMN precipitation_intensity INTEGER;
|
||||
107
data/src/main/sqldelight/breezyweather/migrations/22.sqm
Normal file
107
data/src/main/sqldelight/breezyweather/migrations/22.sqm
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
ALTER TABLE dailys
|
||||
DROP COLUMN pm25;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN pm25 INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN pm10;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN pm10 INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN so2;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN so2 INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN no2;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN no2 INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN o3;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN o3 INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN co;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN co INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN pm25;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN pm25 INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN pm10;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN pm10 INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN so2;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN so2 INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN no2;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN no2 INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN o3;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN o3 INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN co;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN co INTEGER;
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN pm25;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN pm25 INTEGER;
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN pm10;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN pm10 INTEGER;
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN so2;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN so2 INTEGER;
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN no2;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN no2 INTEGER;
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN o3;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN o3 INTEGER;
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN co;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN co INTEGER;
|
||||
49
data/src/main/sqldelight/breezyweather/migrations/23.sqm
Normal file
49
data/src/main/sqldelight/breezyweather/migrations/23.sqm
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_wind_speed;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_wind_speed INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_wind_gusts;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_wind_gusts INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_wind_speed;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_wind_speed INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_wind_gusts;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_wind_gusts INTEGER;
|
||||
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN wind_speed;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN wind_speed INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN wind_gusts;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN wind_gusts INTEGER;
|
||||
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN wind_speed;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN wind_speed INTEGER;
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN wind_gusts;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN wind_gusts INTEGER;
|
||||
179
data/src/main/sqldelight/breezyweather/migrations/24.sqm
Normal file
179
data/src/main/sqldelight/breezyweather/migrations/24.sqm
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_temperature;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_temperature INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_source_feels_like_temperature;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_temperature_source_feels_like INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_apparent_temperature;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_temperature_apparent INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_wind_chill_temperature;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_temperature_wind_chill INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_humidex;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_humidex INTEGER;
|
||||
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_temperature;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_temperature INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_source_feels_like_temperature;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_temperature_source_feels_like INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_apparent_temperature;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_temperature_apparent INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_wind_chill_temperature;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_temperature_wind_chill INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_humidex;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_humidex INTEGER;
|
||||
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN degree_day_heating;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN degree_day_heating INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN degree_day_cooling;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN degree_day_cooling INTEGER;
|
||||
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN dewpoint_average;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN dewpoint_average INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN dewpoint_min;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN dewpoint_min INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN dewpoint_max;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN dewpoint_max INTEGER;
|
||||
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN temperature;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN temperature INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN source_feels_like_temperature;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN temperature_source_feels_like INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN apparent_temperature;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN temperature_apparent INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN wind_chill_temperature;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN temperature_wind_chill INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN humidex;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN humidex INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN dew_point;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN dew_point INTEGER;
|
||||
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN temperature;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN temperature INTEGER;
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN source_feels_like_temperature;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN temperature_source_feels_like INTEGER;
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN apparent_temperature;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN temperature_apparent INTEGER;
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN wind_chill_temperature;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN temperature_wind_chill INTEGER;
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN humidex;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN humidex INTEGER;
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN dew_point;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN dew_point INTEGER;
|
||||
|
||||
|
||||
ALTER TABLE normals
|
||||
DROP COLUMN daytime_temperature;
|
||||
|
||||
ALTER TABLE normals
|
||||
ADD COLUMN temperature_max_average INTEGER;
|
||||
|
||||
ALTER TABLE normals
|
||||
DROP COLUMN nighttime_temperature;
|
||||
|
||||
ALTER TABLE normals
|
||||
ADD COLUMN temperature_min_average INTEGER;
|
||||
123
data/src/main/sqldelight/breezyweather/migrations/25.sqm
Normal file
123
data/src/main/sqldelight/breezyweather/migrations/25.sqm
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_total_precipitation_probability;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_total_precipitation_probability INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_thunderstorm_precipitation_probability;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_thunderstorm_precipitation_probability INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_rain_precipitation_probability;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_rain_precipitation_probability INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_snow_precipitation_probability;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_snow_precipitation_probability INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN daytime_ice_precipitation_probability;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN daytime_ice_precipitation_probability INTEGER;
|
||||
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_total_precipitation_probability;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_total_precipitation_probability INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_thunderstorm_precipitation_probability;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_thunderstorm_precipitation_probability INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_rain_precipitation_probability;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_rain_precipitation_probability INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_snow_precipitation_probability;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_snow_precipitation_probability INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN nighttime_ice_precipitation_probability;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN nighttime_ice_precipitation_probability INTEGER;
|
||||
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN relative_humidity_average;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN relative_humidity_average INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN relative_humidity_min;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN relative_humidity_min INTEGER;
|
||||
|
||||
ALTER TABLE dailys
|
||||
DROP COLUMN relative_humidity_max;
|
||||
|
||||
ALTER TABLE dailys
|
||||
ADD COLUMN relative_humidity_max INTEGER;
|
||||
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN total_precipitation_probability;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN total_precipitation_probability INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN thunderstorm_precipitation_probability;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN thunderstorm_precipitation_probability INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN rain_precipitation_probability;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN rain_precipitation_probability INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN snow_precipitation_probability;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN snow_precipitation_probability INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN ice_precipitation_probability;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN ice_precipitation_probability INTEGER;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
DROP COLUMN relative_humidity;
|
||||
|
||||
ALTER TABLE hourlys
|
||||
ADD COLUMN relative_humidity INTEGER;
|
||||
|
||||
|
||||
ALTER TABLE weathers
|
||||
DROP COLUMN relative_humidity;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN relative_humidity INTEGER;
|
||||
14
data/src/main/sqldelight/breezyweather/migrations/3.sqm
Normal file
14
data/src/main/sqldelight/breezyweather/migrations/3.sqm
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
ALTER TABLE alerts
|
||||
DROP COLUMN description;
|
||||
|
||||
ALTER TABLE alerts
|
||||
ADD COLUMN headline TEXT;
|
||||
|
||||
ALTER TABLE alerts
|
||||
RENAME COLUMN content TO description;
|
||||
|
||||
ALTER TABLE alerts
|
||||
ADD COLUMN instruction TEXT;
|
||||
|
||||
ALTER TABLE alerts
|
||||
RENAME COLUMN priority TO severity;
|
||||
5
data/src/main/sqldelight/breezyweather/migrations/4.sqm
Normal file
5
data/src/main/sqldelight/breezyweather/migrations/4.sqm
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
ALTER TABLE locations
|
||||
ADD COLUMN background_weather_kind TEXT;
|
||||
|
||||
ALTER TABLE locations
|
||||
ADD COLUMN background_day_night_type TEXT;
|
||||
2
data/src/main/sqldelight/breezyweather/migrations/5.sqm
Normal file
2
data/src/main/sqldelight/breezyweather/migrations/5.sqm
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE alerts
|
||||
ADD COLUMN source TEXT;
|
||||
23
data/src/main/sqldelight/breezyweather/migrations/6.sqm
Normal file
23
data/src/main/sqldelight/breezyweather/migrations/6.sqm
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
ALTER TABLE locations
|
||||
RENAME COLUMN province TO admin2;
|
||||
|
||||
ALTER TABLE locations
|
||||
RENAME COLUMN province_code TO admin2_code;
|
||||
|
||||
ALTER TABLE locations
|
||||
ADD COLUMN admin1 TEXT;
|
||||
|
||||
ALTER TABLE locations
|
||||
ADD COLUMN admin1_code TEXT;
|
||||
|
||||
ALTER TABLE locations
|
||||
ADD COLUMN admin3 TEXT;
|
||||
|
||||
ALTER TABLE locations
|
||||
ADD COLUMN admin3_code TEXT;
|
||||
|
||||
ALTER TABLE locations
|
||||
ADD COLUMN admin4 TEXT;
|
||||
|
||||
ALTER TABLE locations
|
||||
ADD COLUMN admin4_code TEXT;
|
||||
5
data/src/main/sqldelight/breezyweather/migrations/7.sqm
Normal file
5
data/src/main/sqldelight/breezyweather/migrations/7.sqm
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
ALTER TABLE locations
|
||||
ADD COLUMN current_source TEXT;
|
||||
|
||||
ALTER TABLE weathers
|
||||
ADD COLUMN current_update_time INTEGER;
|
||||
2
data/src/main/sqldelight/breezyweather/migrations/8.sqm
Normal file
2
data/src/main/sqldelight/breezyweather/migrations/8.sqm
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE locations
|
||||
ADD COLUMN custom_name TEXT;
|
||||
2
data/src/main/sqldelight/breezyweather/migrations/9.sqm
Normal file
2
data/src/main/sqldelight/breezyweather/migrations/9.sqm
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE locations
|
||||
ADD COLUMN reverse_geocoding_source TEXT;
|
||||
Loading…
Add table
Add a link
Reference in a new issue