Skip to content

Commit 5c8fd07

Browse files
authored
Merge pull request #85 from qiaoyuang/main
Update version to 1.3.1
2 parents 5bc84a2 + c988a55 commit 5c8fd07

File tree

29 files changed

+287
-120
lines changed

29 files changed

+287
-120
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@
22

33
- Date format: YYYY-MM-dd
44

5+
## v1.3.1 / 2024-04-24
6+
7+
### sqllin-dsl
8+
9+
* Fix a crash when a data class doesn't contain any `String` element.
10+
* Fix the [issue#81](https://github.com/ctripcorp/SQLlin/issues/81) about insert and query null values
11+
* Fix some wrongs about generation of SQL syntax
12+
13+
### sqllin-driver
14+
15+
* **Breaking change**: Remove the deprecated API `CommonCursor#forEachRows`
16+
* **Breaking change**: the `getInt`, `getLong`, `getFloat` and `getDouble` will throw an exception when the value is NULl in SQLite
17+
* Add a new public API: `CommonCursor#isNull`, for check if the value is NULL in SQLite
18+
519
## v1.3.0 / 2024-04-21
620

721
### All

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION=1.3.0
1+
VERSION=1.3.1
22
GROUP=com.ctrip.kotlin
33

44
kotlinVersion=1.9.23

sqllin-driver/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ databaseConnection.executeUpdateDelete(SQL.UPDATE, arrayOf(20, "Tom"))
102102

103103
// SELECT
104104
val cursor: CommonCursor = databaseConnection.query(SQL.QUERY, arrayOf(20, "Tom"))
105-
cursor.forEachRows { index -> // Index of rows
105+
cursor.forEachRow { index -> // Index of rows
106106
val age: Int = cursor.getInt("age")
107107
val name: String = cursor.getString("name")
108108
}

sqllin-driver/README_CN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ databaseConnection.executeUpdateDelete(SQL.UPDATE, arrayOf(20, "Tom"))
9191

9292
// SELECT
9393
val cursor: CommonCursor = databaseConnection.query(SQL.QUERY, arrayOf(20, "Tom"))
94-
cursor.forEachRows { index -> // Index of rows
94+
cursor.forEachRow { index -> // Index of rows
9595
val age: Int = cursor.getInt("age")
9696
val name: String = cursor.getString("name")
9797
}

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

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,33 @@ import android.database.Cursor
2525

2626
internal class AndroidCursor(private val cursor: Cursor) : CommonCursor {
2727

28-
override fun getInt(columnIndex: Int): Int = cursor.getInt(columnIndex)
29-
override fun getLong(columnIndex: Int): Long = cursor.getLong(columnIndex)
30-
override fun getFloat(columnIndex: Int): Float = cursor.getFloat(columnIndex)
31-
override fun getDouble(columnIndex: Int): Double = cursor.getDouble(columnIndex)
28+
override fun getInt(columnIndex: Int): Int = try {
29+
cursor.getInt(columnIndex)
30+
} catch (e: Exception) {
31+
e.printStackTrace()
32+
throw SQLiteException("The value of column $columnIndex is NULL")
33+
}
34+
35+
override fun getLong(columnIndex: Int): Long = try {
36+
cursor.getLong(columnIndex)
37+
} catch (e: Exception) {
38+
e.printStackTrace()
39+
throw SQLiteException("The value of column $columnIndex is NULL")
40+
}
41+
42+
override fun getFloat(columnIndex: Int): Float = try {
43+
cursor.getFloat(columnIndex)
44+
} catch (e: Exception) {
45+
e.printStackTrace()
46+
throw SQLiteException("The value of column $columnIndex is NULL")
47+
}
48+
49+
override fun getDouble(columnIndex: Int): Double = try {
50+
cursor.getDouble(columnIndex)
51+
} catch (e: Exception) {
52+
e.printStackTrace()
53+
throw SQLiteException("The value of column $columnIndex is NULL")
54+
}
3255

3356
override fun getString(columnIndex: Int): String? = try {
3457
cursor.getString(columnIndex)
@@ -46,12 +69,6 @@ internal class AndroidCursor(private val cursor: Cursor) : CommonCursor {
4669

4770
override fun getColumnIndex(columnName: String): Int = cursor.getColumnIndexOrThrow(columnName)
4871

49-
@Deprecated(
50-
message = "Please use the new API: forEachRow",
51-
replaceWith = ReplaceWith(expression = "forEachRow"),
52-
)
53-
override fun forEachRows(block: (Int) -> Unit) = forEachRow(block)
54-
5572
override fun forEachRow(block: (Int) -> Unit) {
5673
if (!cursor.moveToFirst()) return
5774
var index = 0
@@ -61,5 +78,7 @@ internal class AndroidCursor(private val cursor: Cursor) : CommonCursor {
6178

6279
override fun next(): Boolean = cursor.moveToNext()
6380

81+
override fun isNull(columnIndex: Int): Boolean = cursor.isNull(columnIndex)
82+
6483
override fun close() = cursor.close()
6584
}

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,11 @@ public interface CommonCursor : AutoCloseable {
3333

3434
public fun getColumnIndex(columnName: String): Int
3535

36-
@Deprecated(
37-
message = "Please use the new API: forEachRow",
38-
replaceWith = ReplaceWith(expression = "forEachRow"),
39-
)
40-
public fun forEachRows(block: (Int) -> Unit)
4136
public fun forEachRow(block: (Int) -> Unit)
4237

4338
public fun next(): Boolean
4439

40+
public fun isNull(columnIndex: Int): Boolean
41+
4542
public override fun close()
4643
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ internal fun DatabaseConnection.migrateIfNeeded(
9393
) = withTransaction {
9494
val initialVersion = withQuery("PRAGMA user_version;") {
9595
it.next()
96-
it.getInt(0)
96+
it.getInt(0) ?: 0
9797
}
9898
if (initialVersion == 0) {
9999
create(this)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (C) 2024 Trip.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
18+
19+
/**
20+
* The exceptions about SQLite, they include the native SQLite result codes and error message
21+
* @author Yuang Qiao
22+
*/
23+
24+
public open class SQLiteException(message: String) : Exception(message)

sqllin-driver/src/commonTest/kotlin/com/ctrip/sqllin/driver/CommonBasicTest.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,17 @@ class CommonBasicTest(private val path: DatabasePath) {
2828

2929
private class Book(
3030
val name: String,
31-
val author: String,
31+
val author: String?,
3232
val pages: Int,
3333
val price: Double,
34-
val array: ByteArray,
34+
val array: ByteArray?,
3535
)
3636

3737
private val bookList = listOf(
3838
Book(name = "The Da Vinci Code", author = "Dan Brown", pages = 454, price = 16.96, byteArrayOf()),
3939
Book(name = "The Lost Symbol", author = "Dan Brown", pages = 510, price = 19.95, byteArrayOf(1, 2, 3)),
40+
Book(name = "", author = "Dan Brown", pages = 454, price = 16.96, byteArrayOf()),
41+
Book(name = "The Lost Symbol", author = null, pages = 510, price = 19.95, null),
4042
)
4143

4244
fun testCreateAndUpgrade() {
@@ -87,6 +89,8 @@ class CommonBasicTest(private val path: DatabasePath) {
8789
it.withTransaction { connection ->
8890
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("The Da Vinci Code", "Dan Brown", 454, 16.96, byteArrayOf()))
8991
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("The Lost Symbol", "Dan Brown", 510, 19.95, byteArrayOf(1, 2, 3)))
92+
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("", "Dan Brown", 454, 16.96, byteArrayOf()))
93+
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("The Lost Symbol", null, 510, 19.95, null))
9094
}
9195
}
9296
val readOnlyConfig = getDefaultDBConfig(true)
@@ -99,7 +103,7 @@ class CommonBasicTest(private val path: DatabasePath) {
99103
assertEquals(book.author, cursor.getString(++columnIndex))
100104
assertEquals(book.pages, cursor.getInt(++columnIndex))
101105
assertEquals(book.price, cursor.getDouble(++columnIndex))
102-
assertEquals(book.array.size, cursor.getByteArray(++columnIndex)?.size)
106+
assertEquals(book.array?.size, cursor.getByteArray(++columnIndex)?.size)
103107
}
104108
}
105109
}
@@ -204,7 +208,7 @@ class CommonBasicTest(private val path: DatabasePath) {
204208
assertEquals(book.author, cursor.getString(++columnIndex))
205209
assertEquals(book.pages, cursor.getInt(++columnIndex))
206210
assertEquals(book.price, cursor.getDouble(++columnIndex))
207-
assertEquals(book.array.size, cursor.getByteArray(++columnIndex)?.size)
211+
assertEquals(book.array?.size, cursor.getByteArray(++columnIndex)?.size)
208212
}
209213
}
210214
}

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

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,40 @@ import java.sql.ResultSet
2424
*/
2525
internal class JdbcCursor(private val resultSet: ResultSet) : CommonCursor {
2626

27-
override fun getInt(columnIndex: Int): Int = resultSet.getInt(columnIndex + 1)
27+
override fun getInt(columnIndex: Int): Int {
28+
val result = resultSet.getInt(columnIndex + 1)
29+
if (resultSet.wasNull())
30+
throw SQLiteException("The value of column $columnIndex is NULL")
31+
return result
32+
}
2833

29-
override fun getLong(columnIndex: Int): Long = resultSet.getLong(columnIndex + 1)
34+
override fun getLong(columnIndex: Int): Long {
35+
val result = resultSet.getLong(columnIndex + 1)
36+
if (resultSet.wasNull())
37+
throw SQLiteException("The value of column $columnIndex is NULL")
38+
return result
39+
}
3040

31-
override fun getFloat(columnIndex: Int): Float = resultSet.getFloat(columnIndex + 1)
41+
override fun getFloat(columnIndex: Int): Float {
42+
val result = resultSet.getFloat(columnIndex + 1)
43+
if (resultSet.wasNull())
44+
throw SQLiteException("The value of column $columnIndex is NULL")
45+
return result
46+
}
3247

33-
override fun getDouble(columnIndex: Int): Double = resultSet.getDouble(columnIndex + 1)
48+
override fun getDouble(columnIndex: Int): Double {
49+
val result = resultSet.getDouble(columnIndex + 1)
50+
if (resultSet.wasNull())
51+
throw SQLiteException("The value of column $columnIndex is NULL")
52+
return result
53+
}
3454

3555
override fun getString(columnIndex: Int): String? = resultSet.getString(columnIndex + 1)
3656

3757
override fun getByteArray(columnIndex: Int): ByteArray? = resultSet.getBytes(columnIndex + 1)
3858

3959
override fun getColumnIndex(columnName: String): Int = resultSet.findColumn(columnName) - 1
4060

41-
@Deprecated(
42-
message = "Please use the new API: forEachRow",
43-
replaceWith = ReplaceWith(expression = "forEachRow"),
44-
)
45-
override fun forEachRows(block: (Int) -> Unit) = forEachRow(block)
46-
4761
override fun forEachRow(block: (Int) -> Unit) {
4862
var index = 0
4963
while (next())
@@ -52,6 +66,11 @@ internal class JdbcCursor(private val resultSet: ResultSet) : CommonCursor {
5266

5367
override fun next(): Boolean = resultSet.next()
5468

69+
override fun isNull(columnIndex: Int): Boolean {
70+
resultSet.getObject(columnIndex + 1)
71+
return resultSet.wasNull()
72+
}
73+
5574
override fun close() {
5675
resultSet.close()
5776
resultSet.statement.close()

sqllin-driver/src/nativeMain/kotlin/com/ctrip/sqllin/driver/ConcurrentStatement.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ internal class ConcurrentStatement(
3030
private val accessLock: Lock,
3131
) : SQLiteStatement {
3232

33+
override fun isNull(columnIndex: Int): Boolean = accessLock.withLock {
34+
delegateStatement.isNull(columnIndex)
35+
}
36+
3337
override fun columnGetLong(columnIndex: Int): Long = accessLock.withLock {
3438
delegateStatement.columnGetLong(columnIndex)
3539
}
@@ -38,11 +42,11 @@ internal class ConcurrentStatement(
3842
delegateStatement.columnGetDouble(columnIndex)
3943
}
4044

41-
override fun columnGetString(columnIndex: Int): String = accessLock.withLock {
45+
override fun columnGetString(columnIndex: Int): String? = accessLock.withLock {
4246
delegateStatement.columnGetString(columnIndex)
4347
}
4448

45-
override fun columnGetBlob(columnIndex: Int): ByteArray = accessLock.withLock {
49+
override fun columnGetBlob(columnIndex: Int): ByteArray? = accessLock.withLock {
4650
delegateStatement.columnGetBlob(columnIndex)
4751
}
4852

sqllin-driver/src/nativeMain/kotlin/com/ctrip/sqllin/driver/NativeCursor.kt

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,28 @@ internal class NativeCursor(
2727

2828
override fun getInt(columnIndex: Int): Int = getLong(columnIndex).toInt()
2929

30-
override fun getLong(columnIndex: Int): Long = statement.columnGetLong(columnIndex)
30+
override fun getLong(columnIndex: Int): Long {
31+
if (isNull(columnIndex))
32+
throw SQLiteException("The value of column $columnIndex is NULL")
33+
return statement.columnGetLong(columnIndex)
34+
}
3135

3236
override fun getFloat(columnIndex: Int): Float = getDouble(columnIndex).toFloat()
3337

34-
override fun getDouble(columnIndex: Int): Double = statement.columnGetDouble(columnIndex)
38+
override fun getDouble(columnIndex: Int): Double {
39+
if (isNull(columnIndex))
40+
throw SQLiteException("The value of column $columnIndex is NULL")
41+
return statement.columnGetDouble(columnIndex)
42+
}
3543

36-
override fun getString(columnIndex: Int): String = statement.columnGetString(columnIndex)
44+
override fun getString(columnIndex: Int): String? = statement.columnGetString(columnIndex)
3745

38-
override fun getByteArray(columnIndex: Int): ByteArray = statement.columnGetBlob(columnIndex)
46+
override fun getByteArray(columnIndex: Int): ByteArray? = statement.columnGetBlob(columnIndex)
3947

4048
override fun getColumnIndex(columnName: String): Int = columnNames[columnName] ?: throw IllegalArgumentException("Col for $columnName not found")
4149

4250
override fun next(): Boolean = statement.step()
4351

44-
@Deprecated(
45-
message = "Please use the new API: forEachRow",
46-
replaceWith = ReplaceWith(expression = "forEachRow"),
47-
)
48-
override fun forEachRows(block: (Int) -> Unit) = forEachRow(block)
49-
5052
override fun forEachRow(block: (Int) -> Unit) {
5153
var index = 0
5254
while (next())
@@ -55,6 +57,8 @@ internal class NativeCursor(
5557

5658
override fun close() = statement.finalizeStatement()
5759

60+
override fun isNull(columnIndex: Int): Boolean = statement.isNull(columnIndex)
61+
5862
private val columnNames: Map<String, Int> by lazy {
5963
val count = statement.columnCount()
6064
val map = HashMap<String, Int>(count)

sqllin-driver/src/nativeMain/kotlin/com/ctrip/sqllin/driver/SQLiteException.kt renamed to sqllin-driver/src/nativeMain/kotlin/com/ctrip/sqllin/driver/SQLiteResultCode.kt

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,9 @@ package com.ctrip.sqllin.driver
1919
import com.ctrip.sqllin.driver.SQLiteResultCode.Companion.INVALID_CODE
2020
import com.ctrip.sqllin.driver.cinterop.SQLiteErrorType
2121

22-
/**
23-
* The exceptions about SQLite, they include the native SQLite result codes and error message
24-
* @author yaqiao
25-
*/
26-
27-
public open class SQLiteException(message: String) : Exception(message)
28-
2922
/**
3023
* The result codes in SQLite
24+
* @author Yuang Qiao
3125
*/
3226
public class SQLiteResultCode(message: String, resultCode: Int) : SQLiteException(
3327
"$message | error code ${

sqllin-driver/src/nativeMain/kotlin/com/ctrip/sqllin/driver/SQLiteStatement.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ package com.ctrip.sqllin.driver
2323

2424
internal interface SQLiteStatement {
2525

26+
fun isNull(columnIndex: Int): Boolean
27+
2628
fun columnGetLong(columnIndex: Int): Long
2729

2830
fun columnGetDouble(columnIndex: Int): Double
2931

30-
fun columnGetString(columnIndex: Int): String
32+
fun columnGetString(columnIndex: Int): String?
3133

32-
fun columnGetBlob(columnIndex: Int): ByteArray
34+
fun columnGetBlob(columnIndex: Int): ByteArray?
3335

3436
fun columnCount(): Int
3537

0 commit comments

Comments
 (0)