diff --git a/CHANGELOG.md b/CHANGELOG.md index d4cfa5e..01ce638 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,25 @@ - Date format: YYYY-MM-dd +## v1.2.1 / 2023-10-18 + +### All + +* Update `Kotlin`'s version to `1.9.10` + +### sqllin-driver + +* Fix the problem: [Native driver does not respect isReadOnly](https://github.com/ctripcorp/SQLlin/issues/50). ***On native platforms***. +Now, if a user set `isReadOnly = true` in `DatabaseConfigurtaion`, the database file must exist. And, if opening in read-write mode +fails due to OS-level permissions, the user will get a read-only database, and if the user try to modify the database, will receive +a runtime exception. Thanks for [@nbransby](https://github.com/nbransby) + +### sqllin-processor + +* Update `KSP`'s version to `1.9.10-1.0.13` +* Now, if your data class with `@DBRow` can't be solved or imported successfully(Using `KSNode#validate` to judge), the +`ClauseProcessor` would try to resolve it in second round + ## v1.2.0 / 2023-09-19 ### sqllin-dsl diff --git a/gradle.properties b/gradle.properties index e489a9d..f34b5fb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,8 @@ -VERSION=1.2.0 +VERSION=1.2.1 GROUP=com.ctrip.kotlin -kotlinVersion=1.9.0 -kspVersion=1.9.0-1.0.13 +kotlinVersion=1.9.10 +kspVersion=1.9.10-1.0.13 #Maven Publish Information githubURL=https://github.com/ctripcorp/SQLlin diff --git a/sqllin-architecture.png b/sqllin-architecture.png index 7b6b73b..45a5882 100644 Binary files a/sqllin-architecture.png and b/sqllin-architecture.png differ diff --git a/sqllin-driver/build.gradle.kts b/sqllin-driver/build.gradle.kts index b1516ee..d8ea219 100644 --- a/sqllin-driver/build.gradle.kts +++ b/sqllin-driver/build.gradle.kts @@ -68,7 +68,7 @@ kotlin { } val androidMain by getting { dependencies { - implementation("androidx.annotation:annotation:1.6.0") + implementation("androidx.annotation:annotation:1.7.0") } } val androidInstrumentedTest by getting { diff --git a/sqllin-driver/src/nativeMain/kotlin/com/ctrip/sqllin/driver/cinterop/NativeDatabase.kt b/sqllin-driver/src/nativeMain/kotlin/com/ctrip/sqllin/driver/cinterop/NativeDatabase.kt index 9f18baa..91f20bf 100644 --- a/sqllin-driver/src/nativeMain/kotlin/com/ctrip/sqllin/driver/cinterop/NativeDatabase.kt +++ b/sqllin-driver/src/nativeMain/kotlin/com/ctrip/sqllin/driver/cinterop/NativeDatabase.kt @@ -28,7 +28,6 @@ import com.ctrip.sqllin.sqlite3.SQLITE_OPEN_URI import com.ctrip.sqllin.sqlite3.sqlite3_busy_timeout import com.ctrip.sqllin.sqlite3.sqlite3_close_v2 import com.ctrip.sqllin.sqlite3.sqlite3_db_config -import com.ctrip.sqllin.sqlite3.sqlite3_db_readonly import com.ctrip.sqllin.sqlite3.sqlite3_errmsg import com.ctrip.sqllin.sqlite3.sqlite3_exec import com.ctrip.sqllin.sqlite3.sqlite3_open_v2 @@ -49,15 +48,15 @@ internal class NativeDatabase private constructor(val dbPointer: CPointer>() - if(configuration.isReadOnly) { - //from sqlite3_open_v2 docs: if opening in read-write mode fails due to OS-level permissions, an attempt is made to open it in read-only mode + if (configuration.isReadOnly) { + // From sqlite3_open_v2 docs: "if opening in read-write mode fails due to OS-level permissions, an attempt is made to open it in read-only mode." val openResult = sqlite3_open_v2(realPath, dbPtr.ptr, SQLITE_OPEN_READWRITE or SQLITE_OPEN_URI, null) - if (openResult == SQLITE_OK) return@memScoped dbPtr.value!! + if (openResult == SQLITE_OK) + return@memScoped dbPtr.value!! } val openResult = sqlite3_open_v2(realPath, dbPtr.ptr, sqliteFlags, null) - if (openResult != SQLITE_OK) { + if (openResult != SQLITE_OK) throw sqliteException(sqlite3_errmsg(dbPtr.value)?.toKString() ?: "", openResult) - } dbPtr.value!! } @@ -71,10 +70,10 @@ internal class NativeDatabase private constructor(val dbPointer: CPointer 0) && sqlite3_db_readonly(db, null) != 0) { + /*if ((sqliteFlags and SQLITE_OPEN_READWRITE > 0) && sqlite3_db_readonly(db, null) != 0) { sqlite3_close_v2(db) throw sqliteException("Could not open the database in read/write mode") - } + }*/ // Set the default busy handler to retry automatically before returning SQLITE_BUSY. val err = sqlite3_busy_timeout(db, configuration.busyTimeout) diff --git a/sqllin-dsl/build.gradle.kts b/sqllin-dsl/build.gradle.kts index a8cec39..1ca485d 100644 --- a/sqllin-dsl/build.gradle.kts +++ b/sqllin-dsl/build.gradle.kts @@ -74,7 +74,7 @@ kotlin { } val androidMain by getting { dependencies { - implementation("androidx.annotation:annotation:1.6.0") + implementation("androidx.annotation:annotation:1.7.0") } } val androidInstrumentedTest by getting { diff --git a/sqllin-processor/src/main/kotlin/com/ctrip/sqllin/processor/ClauseProcessor.kt b/sqllin-processor/src/main/kotlin/com/ctrip/sqllin/processor/ClauseProcessor.kt index 96f70a5..5a10d85 100644 --- a/sqllin-processor/src/main/kotlin/com/ctrip/sqllin/processor/ClauseProcessor.kt +++ b/sqllin-processor/src/main/kotlin/com/ctrip/sqllin/processor/ClauseProcessor.kt @@ -21,6 +21,7 @@ import com.google.devtools.ksp.processing.Resolver import com.google.devtools.ksp.processing.SymbolProcessor import com.google.devtools.ksp.processing.SymbolProcessorEnvironment import com.google.devtools.ksp.symbol.* +import com.google.devtools.ksp.validate import java.io.OutputStreamWriter /** @@ -37,17 +38,15 @@ class ClauseProcessor( const val ANNOTATION_SERIALIZABLE = "kotlinx.serialization.Serializable" } - private var invoked = false - @Suppress("UNCHECKED_CAST") override fun process(resolver: Resolver): List { - if (invoked) return emptyList() - invoked = true + val allDBRowClasses = resolver.getSymbolsWithAnnotation(ANNOTATION_DATABASE_ROW_NAME) + val invalidateDBRowClasses = allDBRowClasses.filter { !it.validate() }.toList() - val allClassAnnotatedWhereProperties = resolver.getSymbolsWithAnnotation(ANNOTATION_DATABASE_ROW_NAME) as Sequence + val validateDBRowClasses = allDBRowClasses.filter { it.validate() } as Sequence val serializableType = resolver.getClassDeclarationByName(resolver.getKSNameFromString(ANNOTATION_SERIALIZABLE))!!.asStarProjectedType() - for (classDeclaration in allClassAnnotatedWhereProperties) { + for (classDeclaration in validateDBRowClasses) { if (classDeclaration.annotations.all { !it.annotationType.resolve().isAssignableFrom(serializableType) }) continue // Don't handle the class that don't annotated 'Serializable' @@ -101,7 +100,7 @@ class ClauseProcessor( writer.write("}") } } - return emptyList() + return invalidateDBRowClasses } private fun getClauseElementTypeStr(property: KSPropertyDeclaration): String? = when (