Skip to content

Commit 22f17ad

Browse files
authored
Merge pull request #45 from qiaoyuang/main
Update version to 1.2.0
2 parents 3893d79 + b83586c commit 22f17ad

File tree

25 files changed

+257
-287
lines changed

25 files changed

+257
-287
lines changed

CHANGELOG.md

+12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22

33
- Date format: YYYY-MM-dd
44

5+
## v1.2.0 / 2023-09-19
6+
7+
### sqllin-dsl
8+
9+
* Add the new JVM target
10+
11+
### sqllin-driver
12+
13+
* Add the new JVM target
14+
* Breaking change: Remove the public property: `DatabaseConnection#closed`
15+
* The Android (<= 9) target supports to set the `journalMode` and `synchronousMode` now
16+
517
## v1.1.1 / 2023-08-12
618

719
### All

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ SQLlin supports these platforms:
3232

3333
- Multiplatform Common
3434
- Android (6.0+)
35+
- JVM (Java 11+, since `1.2.0`)
3536
- iOS (x64, arm64, simulatorArm64)
3637
- macOS (x64, arm64)
3738
- watchOS (x64, arm32, arm64, simulatorArm64, deviceArm64)

README_CN.md

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ SQLlin 支持如下平台:
2929

3030
- Multiplatform Common
3131
- Android (6.0+)
32+
- JVM (Java 11+, since `1.2.0`)
3233
- iOS (x64, arm64, simulatorArm64)
3334
- macOS (x64, arm64)
3435
- watchOS (x64, arm32, arm64, simulatorArm64, deviceArm64)

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION=1.1.1
1+
VERSION=1.2.0
22
GROUP=com.ctrip.kotlin
33

44
kotlinVersion=1.9.0

sqllin-driver/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ _sqllin-driver_ use the _New Native Driver_.
3636
Whatever, [SQLiter](https://github.com/touchlab/SQLiter) still is a good project. I referred to a lot of designs and code
3737
details from it and use them in _New Native Driver_ in _sqllin-driver_ .
3838

39+
Since `1.2.0`, SQLlin started to support JVM target, and it's base on [sqlite-jdbc](https://github.com/xerial/sqlite-jdbc).
40+
3941
## Basic usage
4042

4143
I don't recommend you use _sqllin-driver_ in your application projects directly, but if you want to develop your own SQLite

sqllin-driver/src/androidMain/kotlin/com/ctrip/sqllin/driver/AndroidDatabaseConnection.kt

-7
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,6 @@ internal class AndroidDatabaseConnection(private val database: SQLiteDatabase) :
4343

4444
override fun close() = database.close()
4545

46-
@Deprecated(
47-
message = "The property closed has been deprecated, please use the isClosed to replace it",
48-
replaceWith = ReplaceWith("isClosed")
49-
)
50-
override val closed: Boolean
51-
get() = !database.isOpen
52-
5346
override val isClosed: Boolean
5447
get() = !database.isOpen
5548
}

sqllin-driver/src/androidMain/kotlin/com/ctrip/sqllin/driver/ExtensionAndroid.kt

+8-2
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,21 @@ internal value class AndroidDatabasePath(val context: Context) : DatabasePath
3636
public actual fun openDatabase(config: DatabaseConfiguration): DatabaseConnection {
3737
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && config.inMemory)
3838
return AndroidDatabaseConnection(createInMemory(config.toAndroidOpenParams()))
39-
val helper = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
39+
val isEqualsOrHigherThanAndroidP = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
40+
val helper = if (isEqualsOrHigherThanAndroidP)
4041
AndroidDBHelper(config)
4142
else
4243
OldAndroidDBHelper(config)
4344
val database = if (config.isReadOnly)
4445
helper.readableDatabase
4546
else
4647
helper.writableDatabase
47-
return AndroidDatabaseConnection(database)
48+
val connection = AndroidDatabaseConnection(database)
49+
if (!isEqualsOrHigherThanAndroidP) {
50+
connection.updateSynchronousMode(config.synchronousMode)
51+
connection.updateJournalMode(config.journalMode)
52+
}
53+
return connection
4854
}
4955

5056
private class OldAndroidDBHelper(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (C) 2023 Ctrip.com.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.ctrip.sqllin.driver.platform
18+
19+
/**
20+
* The tools with Android implementation
21+
* @author yaqiao
22+
*/
23+
24+
internal actual inline val separatorChar: Char
25+
get() = '/'

sqllin-driver/src/commonMain/kotlin/com/ctrip/sqllin/driver/DatabaseConnection.kt

-6
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,5 @@ public interface DatabaseConnection {
3535

3636
public fun close()
3737

38-
@Deprecated(
39-
message = "The property closed has been deprecated, please use the isClosed to replace it",
40-
replaceWith = ReplaceWith("isClosed")
41-
)
42-
public val closed: Boolean
43-
4438
public val isClosed: Boolean
4539
}

sqllin-driver/src/commonMain/kotlin/com/ctrip/sqllin/driver/Extension.kt

+108-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
package com.ctrip.sqllin.driver
1818

19+
import com.ctrip.sqllin.driver.platform.separatorChar
20+
import kotlin.jvm.JvmInline
21+
1922
/**
2023
* SQLite extension function
2124
* @author yaqiao
@@ -62,4 +65,108 @@ public inline fun <T> DatabaseConnection.withQuery(
6265
}
6366
}
6467

65-
public expect fun deleteDatabase(path: DatabasePath, name: String): Boolean
68+
public expect fun deleteDatabase(path: DatabasePath, name: String): Boolean
69+
70+
internal infix fun DatabaseConnection.updateSynchronousMode(mode: SynchronousMode) {
71+
val currentJournalMode = withQuery("PRAGMA synchronous;") {
72+
it.next()
73+
it.getInt(0)
74+
}
75+
if (currentJournalMode != mode.value)
76+
execSQL("PRAGMA synchronous=${mode.value};")
77+
}
78+
79+
internal infix fun DatabaseConnection.updateJournalMode(mode: JournalMode) {
80+
val currentJournalMode = withQuery("PRAGMA journal_mode;") {
81+
it.next()
82+
it.getString(0)
83+
}
84+
if (!currentJournalMode.equals(mode.name, ignoreCase = true))
85+
withQuery("PRAGMA journal_mode=${mode.name};") {}
86+
}
87+
88+
internal fun DatabaseConnection.migrateIfNeeded(
89+
create: (DatabaseConnection) -> Unit,
90+
upgrade: (DatabaseConnection, Int, Int) -> Unit,
91+
version: Int,
92+
) = withTransaction {
93+
val initialVersion = withQuery("PRAGMA user_version;") {
94+
it.next()
95+
it.getInt(0)
96+
}
97+
if (initialVersion == 0) {
98+
create(this)
99+
execSQL("PRAGMA user_version = $version;")
100+
} else if (initialVersion != version) {
101+
if (initialVersion > version) {
102+
throw IllegalStateException("Database version $initialVersion newer than config version $version")
103+
}
104+
upgrade(this, initialVersion, version)
105+
execSQL("PRAGMA user_version = $version;")
106+
}
107+
}
108+
109+
internal fun DatabaseConfiguration.diskOrMemoryPath(): String =
110+
if (inMemory) {
111+
if (name.isBlank())
112+
":memory:"
113+
else
114+
"file:$name?mode=memory&cache=shared"
115+
} else {
116+
require(name.isNotBlank()) { "Database name cannot be blank" }
117+
getDatabaseFullPath((path as StringDatabasePath).pathString, name)
118+
}
119+
120+
internal fun getDatabaseFullPath(dirPath: String, name: String): String {
121+
val param = when {
122+
dirPath.isEmpty() -> name
123+
name.isEmpty() -> dirPath
124+
else -> join(dirPath, name)
125+
}
126+
return fixSlashes(param)
127+
}
128+
129+
private fun join(prefix: String, suffix: String): String {
130+
val haveSlash = (prefix.isNotEmpty() && prefix.last() == separatorChar)
131+
|| (suffix.isNotEmpty() && suffix.first() == separatorChar)
132+
return buildString {
133+
append(prefix)
134+
if (!haveSlash)
135+
append(separatorChar)
136+
append(suffix)
137+
}
138+
}
139+
140+
private fun fixSlashes(origPath: String): String {
141+
// Remove duplicate adjacent slashes.
142+
var lastWasSlash = false
143+
val newPath = origPath.toCharArray()
144+
val length = newPath.size
145+
var newLength = 0
146+
val initialIndex = if (origPath.startsWith("file://", true)) 7 else 0
147+
for (i in initialIndex ..< length) {
148+
val ch = newPath[i]
149+
if (ch == separatorChar) {
150+
if (!lastWasSlash) {
151+
newPath[newLength++] = separatorChar
152+
lastWasSlash = true
153+
}
154+
} else {
155+
newPath[newLength++] = ch
156+
lastWasSlash = false
157+
}
158+
}
159+
// Remove any trailing slash (unless this is the root of the file system).
160+
if (lastWasSlash && newLength > 1) {
161+
newLength--
162+
}
163+
164+
// Reuse the original string if possible.
165+
return if (newLength != length) buildString(newLength) {
166+
append(newPath)
167+
setLength(newLength)
168+
} else origPath
169+
}
170+
171+
@JvmInline
172+
internal value class StringDatabasePath(val pathString: String) : DatabasePath

sqllin-driver/src/nativeMain/kotlin/com/ctrip/sqllin/driver/platform/Utils.kt renamed to sqllin-driver/src/commonMain/kotlin/com/ctrip/sqllin/driver/platform/Utils.kt

-7
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,9 @@
1616

1717
package com.ctrip.sqllin.driver.platform
1818

19-
import kotlinx.cinterop.ByteVar
20-
import kotlinx.cinterop.CPointer
21-
import kotlinx.cinterop.ExperimentalForeignApi
22-
2319
/**
2420
* The tools with platform-specific implementation
2521
* @author yaqiao
2622
*/
2723

28-
@OptIn(ExperimentalForeignApi::class)
29-
internal expect fun bytesToString(bv: CPointer<ByteVar>): String
30-
3124
internal expect val separatorChar: Char

sqllin-driver/src/jvmMain/kotlin/com/ctrip/sqllin/driver/ConcurrentDatabaseConnection.kt

-6
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,6 @@ internal class ConcurrentDatabaseConnection(private val delegateConnection: Data
6060
delegateConnection.close()
6161
}
6262

63-
@Deprecated(
64-
message = "The property closed has been deprecated, please use the isClosed to replace it",
65-
replaceWith = ReplaceWith("isClosed")
66-
)
67-
override val closed: Boolean
68-
get() = delegateConnection.isClosed
6963
override val isClosed: Boolean
7064
get() = delegateConnection.isClosed
7165
}

0 commit comments

Comments
 (0)