Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the problem about empty ByteArray #30

Merged
merged 1 commit into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,17 @@ import kotlin.test.assertEquals

class CommonBasicTest(private val path: DatabasePath) {

private data class Book(
private class Book(
val name: String,
val author: String,
val pages: Int,
val price: Double,
val array: ByteArray,
)

private val bookList = listOf(
Book(name = "The Da Vinci Code", author = "Dan Brown", pages = 454, price = 16.96),
Book(name = "The Lost Symbol", author = "Dan Brown", pages = 510, price = 19.95),
Book(name = "The Da Vinci Code", author = "Dan Brown", pages = 454, price = 16.96, byteArrayOf()),
Book(name = "The Lost Symbol", author = "Dan Brown", pages = 510, price = 19.95, byteArrayOf(1, 2, 3)),
)

fun testCreateAndUpgrade() {
Expand Down Expand Up @@ -84,8 +85,8 @@ class CommonBasicTest(private val path: DatabasePath) {
val readWriteConfig = getDefaultDBConfig(false)
openDatabase(readWriteConfig) {
it.withTransaction { connection ->
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("The Da Vinci Code", "Dan Brown", 454, 16.96))
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("The Lost Symbol", "Dan Brown", 510, 19.95))
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("The Da Vinci Code", "Dan Brown", 454, 16.96, byteArrayOf()))
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("The Lost Symbol", "Dan Brown", 510, 19.95, byteArrayOf(1, 2, 3)))
}
}
val readOnlyConfig = getDefaultDBConfig(true)
Expand All @@ -98,6 +99,7 @@ class CommonBasicTest(private val path: DatabasePath) {
assertEquals(book.author, cursor.getString(++columnIndex))
assertEquals(book.pages, cursor.getInt(++columnIndex))
assertEquals(book.price, cursor.getDouble(++columnIndex))
assertEquals(book.array.size, cursor.getByteArray(++columnIndex)?.size)
}
}
}
Expand Down Expand Up @@ -161,8 +163,8 @@ class CommonBasicTest(private val path: DatabasePath) {
val readWriteConfig = getDefaultDBConfig(false)
openDatabase(readWriteConfig) {
it.withTransaction { connection ->
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("The Da Vinci Code", "Dan Brown", 454, 16.96))
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("The Lost Symbol", "Dan Brown", 510, 19.95))
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("The Da Vinci Code", "Dan Brown", 454, 16.96, byteArrayOf()))
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("The Lost Symbol", "Dan Brown", 510, 19.95, byteArrayOf(1, 2, 3)))
}

try {
Expand Down Expand Up @@ -202,13 +204,14 @@ class CommonBasicTest(private val path: DatabasePath) {
assertEquals(book.author, cursor.getString(++columnIndex))
assertEquals(book.pages, cursor.getInt(++columnIndex))
assertEquals(book.price, cursor.getDouble(++columnIndex))
assertEquals(book.array.size, cursor.getByteArray(++columnIndex)?.size)
}
}
}
}
it.withTransaction { connection ->
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("The Da Vinci Code", "Dan Brown", 454, 16.96))
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("The Lost Symbol", "Dan Brown", 510, 19.95))
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("The Da Vinci Code", "Dan Brown", 454, 16.96, byteArrayOf()))
connection.executeInsert(SQL.INSERT_BOOK, arrayOf("The Lost Symbol", "Dan Brown", 510, 19.95, byteArrayOf(1, 2, 3)))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ object SQL {

const val DATABASE_NAME = "BookStore.db"

const val CREATE_BOOK = "create table book (id integer primary key autoincrement, name text, author text, pages integer, price real)"
const val CREATE_BOOK = "create table book (id integer primary key autoincrement, name text, author text, pages integer, price real, array blob)"

const val CREATE_CATEGORY = "create table Category (id integer primary key autoincrement, category_name text, category_code integer)"

const val ASSOCIATE = "alter table Book add column category_id integer"

const val INSERT_BOOK = "insert into Book (name, author, pages, price) values (?, ?, ?, ?)"
const val INSERT_BOOK = "insert into Book (name, author, pages, price, array) values (?, ?, ?, ?, ?)"

const val QUERY_BOOK = "select * from Book"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import com.ctrip.sqllin.sqlite3.sqlite3_bind_int64
import com.ctrip.sqllin.sqlite3.sqlite3_bind_null
import com.ctrip.sqllin.sqlite3.sqlite3_bind_parameter_index
import com.ctrip.sqllin.sqlite3.sqlite3_bind_text
import com.ctrip.sqllin.sqlite3.sqlite3_bind_zeroblob
import com.ctrip.sqllin.sqlite3.sqlite3_changes
import com.ctrip.sqllin.sqlite3.sqlite3_clear_bindings
import com.ctrip.sqllin.sqlite3.sqlite3_column_blob
Expand Down Expand Up @@ -86,12 +87,11 @@ internal class NativeStatement(

override fun columnGetBlob(columnIndex: Int): ByteArray {
val blobSize = sqlite3_column_bytes(cStatementPointer, columnIndex)
val blob = sqlite3_column_blob(cStatementPointer, columnIndex)

if (blobSize < 0 || blob == null)
throw sqliteException("Byte array size/type issue col $columnIndex")

return blob.readBytes(blobSize)
return if (blobSize == 0)
byteArrayOf()
else
sqlite3_column_blob(cStatementPointer, columnIndex)?.readBytes(blobSize)
?: throw sqliteException("Byte array size/type issue col $columnIndex")
}

override fun columnCount(): Int = sqlite3_column_count(cStatementPointer)
Expand All @@ -106,9 +106,7 @@ internal class NativeStatement(
when (val err = sqlite3_step(cStatementPointer)) {
SQLITE_ROW -> return true
SQLITE_DONE -> return false
SQLITE_LOCKED, SQLITE_BUSY -> {
usleep(1000u)
}
SQLITE_LOCKED, SQLITE_BUSY -> usleep(1000u)
else -> throw sqliteException("sqlite3_step failed", err)
}
}
Expand Down Expand Up @@ -151,12 +149,11 @@ internal class NativeStatement(
}

private fun executeForLastInsertedRowId(): Long {
val err = executeNonQuery();
return if (err == SQLITE_DONE && sqlite3_changes(database.dbPointer) > 0) {
val err = executeNonQuery()
return if (err == SQLITE_DONE && sqlite3_changes(database.dbPointer) > 0)
sqlite3_last_insert_rowid(database.dbPointer)
} else {
else
-1
}
}

override fun executeUpdateDelete(): Int = try {
Expand All @@ -168,11 +165,10 @@ internal class NativeStatement(

private fun executeForChangedRowCount(): Int {
val err = executeNonQuery()
return if (err == SQLITE_DONE) {
return if (err == SQLITE_DONE)
sqlite3_changes(database.dbPointer)
} else {
else
-1
}
}

private fun executeNonQuery(): Int {
Expand All @@ -199,12 +195,14 @@ internal class NativeStatement(
}

override fun bindString(index: Int, value: String) = opResult(database) {
// TODO: Was using UTF 16 function previously. Do a little research.
sqlite3_bind_text(cStatementPointer, index, value, -1, SQLITE_TRANSIENT)
}

override fun bindBlob(index: Int, value: ByteArray) = opResult(database) {
sqlite3_bind_blob(cStatementPointer, index, value.refTo(0), value.size, SQLITE_TRANSIENT)
if (value.isEmpty())
sqlite3_bind_zeroblob(cStatementPointer, index, 0)
else
sqlite3_bind_blob(cStatementPointer, index, value.refTo(0), value.size, SQLITE_TRANSIENT)
}

private inline fun opResult(database: NativeDatabase, block: () -> Int) {
Expand Down