Skip to content

Commit 8b286c5

Browse files
committed
Fix some bugs
1 parent 5f04641 commit 8b286c5

File tree

16 files changed

+188
-107
lines changed

16 files changed

+188
-107
lines changed

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,19 @@
22

33
- Date format: YYYY-MM-dd
44

5-
## v1.3.1 / 2024-04-xx
5+
## v1.3.1 / 2024-04-24
66

77
### sqllin-dsl
88

99
* Fix a crash when a data class doesn't contain any `String` element.
1010
* 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
1118

1219
## v1.3.0 / 2024-04-21
1320

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

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

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

28-
override fun getInt(columnIndex: Int): Int? = try {
28+
override fun getInt(columnIndex: Int): Int = try {
2929
cursor.getInt(columnIndex)
3030
} catch (e: Exception) {
3131
e.printStackTrace()
32-
null
32+
throw SQLiteException("The value of column $columnIndex is NULL")
3333
}
3434

35-
override fun getLong(columnIndex: Int): Long? = try {
35+
override fun getLong(columnIndex: Int): Long = try {
3636
cursor.getLong(columnIndex)
3737
} catch (e: Exception) {
3838
e.printStackTrace()
39-
null
39+
throw SQLiteException("The value of column $columnIndex is NULL")
4040
}
4141

42-
override fun getFloat(columnIndex: Int): Float? = try {
42+
override fun getFloat(columnIndex: Int): Float = try {
4343
cursor.getFloat(columnIndex)
4444
} catch (e: Exception) {
4545
e.printStackTrace()
46-
null
46+
throw SQLiteException("The value of column $columnIndex is NULL")
4747
}
4848

49-
override fun getDouble(columnIndex: Int): Double? = try {
49+
override fun getDouble(columnIndex: Int): Double = try {
5050
cursor.getDouble(columnIndex)
5151
} catch (e: Exception) {
5252
e.printStackTrace()
53-
null
53+
throw SQLiteException("The value of column $columnIndex is NULL")
5454
}
5555

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

7070
override fun getColumnIndex(columnName: String): Int = cursor.getColumnIndexOrThrow(columnName)
7171

72-
@Deprecated(
73-
message = "Please use the new API: forEachRow",
74-
replaceWith = ReplaceWith(expression = "forEachRow"),
75-
)
76-
override fun forEachRows(block: (Int) -> Unit) = forEachRow(block)
77-
7872
override fun forEachRow(block: (Int) -> Unit) {
7973
if (!cursor.moveToFirst()) return
8074
var index = 0
@@ -84,5 +78,7 @@ internal class AndroidCursor(private val cursor: Cursor) : CommonCursor {
8478

8579
override fun next(): Boolean = cursor.moveToNext()
8680

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

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

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,20 @@ package com.ctrip.sqllin.driver
2424
@OptIn(ExperimentalStdlibApi::class)
2525
public interface CommonCursor : AutoCloseable {
2626

27-
public fun getInt(columnIndex: Int): Int?
28-
public fun getLong(columnIndex: Int): Long?
29-
public fun getFloat(columnIndex: Int): Float?
30-
public fun getDouble(columnIndex: Int): Double?
27+
public fun getInt(columnIndex: Int): Int
28+
public fun getLong(columnIndex: Int): Long
29+
public fun getFloat(columnIndex: Int): Float
30+
public fun getDouble(columnIndex: Int): Double
3131
public fun getString(columnIndex: Int): String?
3232
public fun getByteArray(columnIndex: Int): ByteArray?
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
}
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 & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,40 @@ import java.sql.ResultSet
2424
*/
2525
internal class JdbcCursor(private val resultSet: ResultSet) : CommonCursor {
2626

27-
override fun getInt(columnIndex: Int): Int? =
28-
resultSet.getInt(columnIndex + 1).takeUnless { resultSet.wasNull() }
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+
}
2933

30-
override fun getLong(columnIndex: Int): Long? =
31-
resultSet.getLong(columnIndex + 1).takeUnless { resultSet.wasNull() }
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+
}
3240

33-
override fun getFloat(columnIndex: Int): Float? =
34-
resultSet.getFloat(columnIndex + 1).takeUnless { resultSet.wasNull() }
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+
}
3547

36-
override fun getDouble(columnIndex: Int): Double? =
37-
resultSet.getDouble(columnIndex + 1).takeUnless { resultSet.wasNull() }
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+
}
3854

3955
override fun getString(columnIndex: Int): String? = resultSet.getString(columnIndex + 1)
4056

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

4359
override fun getColumnIndex(columnName: String): Int = resultSet.findColumn(columnName) - 1
4460

45-
@Deprecated(
46-
message = "Please use the new API: forEachRow",
47-
replaceWith = ReplaceWith(expression = "forEachRow"),
48-
)
49-
override fun forEachRows(block: (Int) -> Unit) = forEachRow(block)
50-
5161
override fun forEachRow(block: (Int) -> Unit) {
5262
var index = 0
5363
while (next())
@@ -56,6 +66,11 @@ internal class JdbcCursor(private val resultSet: ResultSet) : CommonCursor {
5666

5767
override fun next(): Boolean = resultSet.next()
5868

69+
override fun isNull(columnIndex: Int): Boolean {
70+
resultSet.getObject(columnIndex + 1)
71+
return resultSet.wasNull()
72+
}
73+
5974
override fun close() {
6075
resultSet.close()
6176
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,11 +30,15 @@ internal class ConcurrentStatement(
3030
private val accessLock: Lock,
3131
) : SQLiteStatement {
3232

33-
override fun columnGetLong(columnIndex: Int): Long? = accessLock.withLock {
33+
override fun isNull(columnIndex: Int): Boolean = accessLock.withLock {
34+
delegateStatement.isNull(columnIndex)
35+
}
36+
37+
override fun columnGetLong(columnIndex: Int): Long = accessLock.withLock {
3438
delegateStatement.columnGetLong(columnIndex)
3539
}
3640

37-
override fun columnGetDouble(columnIndex: Int): Double? = accessLock.withLock {
41+
override fun columnGetDouble(columnIndex: Int): Double = accessLock.withLock {
3842
delegateStatement.columnGetDouble(columnIndex)
3943
}
4044

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
@@ -25,13 +25,21 @@ internal class NativeCursor(
2525
private val statement: SQLiteStatement
2626
) : CommonCursor {
2727

28-
override fun getInt(columnIndex: Int): Int? = getLong(columnIndex)?.toInt()
28+
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

32-
override fun getFloat(columnIndex: Int): Float? = getDouble(columnIndex)?.toFloat()
36+
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

3644
override fun getString(columnIndex: Int): String? = statement.columnGetString(columnIndex)
3745

@@ -41,12 +49,6 @@ internal class NativeCursor(
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,9 +23,11 @@ package com.ctrip.sqllin.driver
2323

2424
internal interface SQLiteStatement {
2525

26-
fun columnGetLong(columnIndex: Int): Long?
26+
fun isNull(columnIndex: Int): Boolean
2727

28-
fun columnGetDouble(columnIndex: Int): Double?
28+
fun columnGetLong(columnIndex: Int): Long
29+
30+
fun columnGetDouble(columnIndex: Int): Double
2931

3032
fun columnGetString(columnIndex: Int): String?
3133

0 commit comments

Comments
 (0)