diff --git a/SQLiter/build.gradle b/SQLiter/build.gradle index 5f6d99ac..3d005083 100644 --- a/SQLiter/build.gradle +++ b/SQLiter/build.gradle @@ -39,97 +39,100 @@ repositories { group = GROUP version = VERSION_NAME +def ideaActive = System.getProperty("idea.active") == "true" + kotlin { targets { - fromPreset(presets.jvm, 'jvm') - -// fromPreset(presets.macosX64, 'nativeCommon') - - fromPreset(presets.macosX64, 'macos'){ - compilations.main { - it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/macos_x64/tlruntime.bc"] - } - compilations.test { - it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] - } - } - - fromPreset(presets.mingwX64, 'mingw'){ - compilations.main { - it.kotlinOptions.freeCompilerArgs += ["-native-library", "C:\\Users\\kgalligan\\devel\\SQLiter\\KotlinCpp\\bcdist\\mingw_x64\\tlruntime.bc"] - } - compilations.each { - it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-Lc:\\msys64\\mingw64\\lib"] - it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] - } - } - - fromPreset(presets.iosX64, 'iosX64'){ - compilations.main { - it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/ios_x64/tlruntime.bc"] - } - compilations.test { - it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] - } - } - - fromPreset(presets.iosArm64, 'iosArm64'){ - compilations.main { - it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/ios_arm64/tlruntime.bc"] - } - compilations.test { - it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] - } - } - - fromPreset(presets.iosArm32, 'iosArm32'){ - compilations.main { - it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/ios_arm32/tlruntime.bc"] - } - compilations.test { - it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] - } - } - - fromPreset(presets.watchosArm32, 'watchosArm32'){ - compilations.main { - it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/watchos_arm32/tlruntime.bc"] - } - compilations.test { - it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] - } - } - fromPreset(presets.watchosArm64, 'watchosArm64'){ - compilations.main { - it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/watchos_arm64/tlruntime.bc"] - } - compilations.test { - it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] - } - } - fromPreset(presets.watchosX86, 'watchosX86'){ - compilations.main { - it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/watchos_x86/tlruntime.bc"] - } - compilations.test { - it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] - } - } - fromPreset(presets.tvosArm64, 'tvosArm64'){ - compilations.main { - it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/tvos_arm64/tlruntime.bc"] - } - compilations.test { - it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] - } - } - fromPreset(presets.tvosX64, 'tvosX64'){ - compilations.main { - it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/tvos_x64/tlruntime.bc"] - } - compilations.test { - it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] + if (ideaActive) { + macosX64("nativeCommon") + } else { + fromPreset(presets.jvm, 'jvm') + fromPreset(presets.macosX64, 'macos') { + compilations.main { + it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/macos_x64/tlruntime.bc"] + } + compilations.test { + it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] + } + } + + fromPreset(presets.mingwX64, 'mingw') { + compilations.main { + it.kotlinOptions.freeCompilerArgs += ["-native-library", "C:\\Users\\kgalligan\\devel\\SQLiter\\KotlinCpp\\bcdist\\mingw_x64\\tlruntime.bc"] + } + compilations.each { + it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-Lc:\\msys64\\mingw64\\lib"] + it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] + } + } + + fromPreset(presets.iosX64, 'iosX64') { + compilations.main { + it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/ios_x64/tlruntime.bc"] + } + compilations.test { + it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] + } + } + + fromPreset(presets.iosArm64, 'iosArm64') { + compilations.main { + it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/ios_arm64/tlruntime.bc"] + } + compilations.test { + it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] + } + } + + fromPreset(presets.iosArm32, 'iosArm32') { + compilations.main { + it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/ios_arm32/tlruntime.bc"] + } + compilations.test { + it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] + } + } + + fromPreset(presets.watchosArm32, 'watchosArm32') { + compilations.main { + it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/watchos_arm32/tlruntime.bc"] + } + compilations.test { + it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] + } + } + fromPreset(presets.watchosArm64, 'watchosArm64') { + compilations.main { + it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/watchos_arm64/tlruntime.bc"] + } + compilations.test { + it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] + } + } + fromPreset(presets.watchosX86, 'watchosX86') { + compilations.main { + it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/watchos_x86/tlruntime.bc"] + } + compilations.test { + it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] + } + } + fromPreset(presets.tvosArm64, 'tvosArm64') { + compilations.main { + it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/tvos_arm64/tlruntime.bc"] + } + compilations.test { + it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] + } + } + fromPreset(presets.tvosX64, 'tvosX64') { + compilations.main { + it.kotlinOptions.freeCompilerArgs += ["-native-library", "../KotlinCpp/bcdist/tvos_x64/tlruntime.bc"] + } + compilations.test { + it.kotlinOptions.freeCompilerArgs += ["-linker-options", "-lsqlite3"] + } } } } @@ -190,3 +193,51 @@ configurations { } apply from: "$rootDir/gradle/gradle-mvn-mpp-push.gradle" + +task mergeLldbTask() { + doLast { + mergeLldb() + } +} + +void mergeLldb(){ + try { + ant.zip( + update: "true", + destfile: "/Users/kgalligan/Downloads/kmm/lib/kmm.jar" + ) { + zipfileset( + dir: "${project.projectDir}", + prefix: "scripts" + ) { + include(name: 'konan_lldb.py') + } + } + } catch (Throwable t) { + t.printStackTrace() + } +} + +task mergeToZipTask() { + doLast { + mergeLldb() + } +} + +void mergeToZip(){ + try { + ant.zip( + update: "true", + destfile: "/Users/kgalligan/Downloads/kmm-plugin-0.1.2-release-53-Studio4.0.zip" + ) { + zipfileset( + dir: "/Users/kgalligan/Downloads/kmm/lib/", + prefix: "kmm/lib" + ) { + include(name: 'kmm.jar') + } + } + } catch (Throwable t) { + t.printStackTrace() + } +} diff --git a/SQLiter/gradle.properties b/SQLiter/gradle.properties index 6bdb8e91..c1bbfb34 100644 --- a/SQLiter/gradle.properties +++ b/SQLiter/gradle.properties @@ -17,10 +17,10 @@ kotlin.code.style=official GROUP=co.touchlab -VERSION_NAME=0.7.1 +VERSION_NAME=0.7.2 STATELY_VERSION=1.1.0 -KOTLIN_VERSION=1.4.0 +KOTLIN_VERSION=1.4.20 kotlin.native.ignoreDisabledTargets=true POM_URL=https://github.com/touchlab/SQLiter diff --git a/SQLiter/src/appleMain/kotlin/co/touchlab/sqliter/DatabaseFileContext.kt b/SQLiter/src/appleMain/kotlin/co/touchlab/sqliter/DatabaseFileContext.kt index 03dc5037..b597faa5 100644 --- a/SQLiter/src/appleMain/kotlin/co/touchlab/sqliter/DatabaseFileContext.kt +++ b/SQLiter/src/appleMain/kotlin/co/touchlab/sqliter/DatabaseFileContext.kt @@ -28,12 +28,8 @@ actual object DatabaseFileContext{ deleteDatabaseFile(databaseFile(name, basePath)) } - internal fun databasePath(databaseName:String, inMemory:Boolean, datapathPath:String?):String{ - return if(inMemory){ - "file:$databaseName?mode=memory&cache=shared" - }else{ - databaseFile(databaseName, datapathPath).path - } + internal fun databasePath(databaseName:String, datapathPath:String?):String{ + return databaseFile(databaseName, datapathPath).path } internal fun databaseDirPath():String = iosDirPath("databases") diff --git a/SQLiter/src/commonMain/kotlin/co/touchlab/sqliter/DatabaseConfiguration.kt b/SQLiter/src/commonMain/kotlin/co/touchlab/sqliter/DatabaseConfiguration.kt index 73cfb32c..1b5c9903 100644 --- a/SQLiter/src/commonMain/kotlin/co/touchlab/sqliter/DatabaseConfiguration.kt +++ b/SQLiter/src/commonMain/kotlin/co/touchlab/sqliter/DatabaseConfiguration.kt @@ -17,8 +17,7 @@ package co.touchlab.sqliter data class DatabaseConfiguration( - - val name: String, + val name: String?, val version: Int, val create: (DatabaseConnection) -> Unit, val upgrade: (DatabaseConnection, Int, Int) -> Unit = { _, _, _ -> }, @@ -37,8 +36,8 @@ data class DatabaseConfiguration( } } -private fun checkFilename(name: String) { - if (name.contains("/")) { +private fun checkFilename(name: String?) { + if (name != null && name.contains("/")) { throw IllegalArgumentException( "File $name contains a path separator" ) diff --git a/SQLiter/src/commonMain/kotlin/co/touchlab/sqliter/DatabaseFileContext.kt b/SQLiter/src/commonMain/kotlin/co/touchlab/sqliter/DatabaseFileContext.kt index ec6c740d..d7575f33 100644 --- a/SQLiter/src/commonMain/kotlin/co/touchlab/sqliter/DatabaseFileContext.kt +++ b/SQLiter/src/commonMain/kotlin/co/touchlab/sqliter/DatabaseFileContext.kt @@ -21,5 +21,6 @@ expect object DatabaseFileContext{ } fun DatabaseFileContext.deleteDatabase(configuration: DatabaseConfiguration){ - deleteDatabase(configuration.name, configuration.basePath) + if(configuration.name != null) + deleteDatabase(configuration.name, configuration.basePath) } \ No newline at end of file diff --git a/SQLiter/src/mingwMain/kotlin/co/touchlab/sqliter/DatabaseFileContext.kt b/SQLiter/src/mingwMain/kotlin/co/touchlab/sqliter/DatabaseFileContext.kt index 477c2e61..cb0d9e98 100644 --- a/SQLiter/src/mingwMain/kotlin/co/touchlab/sqliter/DatabaseFileContext.kt +++ b/SQLiter/src/mingwMain/kotlin/co/touchlab/sqliter/DatabaseFileContext.kt @@ -9,12 +9,8 @@ actual object DatabaseFileContext { deleteDatabaseFile(databaseFile(name, basePath)) } - internal fun databasePath(databaseName:String, inMemory:Boolean, datapathPath:String?):String { - return if(inMemory) { - "file:$databaseName?mode=memory&cache=shared" - } else { - databaseFile(databaseName, datapathPath).path - } + internal fun databasePath(databaseName:String, datapathPath:String?):String { + return databaseFile(databaseName, datapathPath).path } internal fun databaseFile(databaseName:String, datapathPath:String?):File { diff --git a/SQLiter/src/nativeCommonMain/kotlin/co/touchlab/sqliter/createDatabaseManager.kt b/SQLiter/src/nativeCommonMain/kotlin/co/touchlab/sqliter/createDatabaseManager.kt index 3ca2ce09..49a82c6e 100644 --- a/SQLiter/src/nativeCommonMain/kotlin/co/touchlab/sqliter/createDatabaseManager.kt +++ b/SQLiter/src/nativeCommonMain/kotlin/co/touchlab/sqliter/createDatabaseManager.kt @@ -17,6 +17,17 @@ package co.touchlab.sqliter fun createDatabaseManager(configuration: DatabaseConfiguration): DatabaseManager { - val databasePath = DatabaseFileContext.databasePath(configuration.name, configuration.inMemory, configuration.basePath) + val databasePath = diskOrMemoryPath(configuration) return NativeDatabaseManager(databasePath, configuration) +} + +internal fun diskOrMemoryPath(configuration: DatabaseConfiguration) = if (configuration.inMemory) { + if (configuration.name == null) { + ":memory:" + } else { + "file:${configuration.name}?mode=memory&cache=shared" + } +} else { + val dbName = configuration.name ?: throw NullPointerException("Database name cannot be null") + DatabaseFileContext.databasePath(dbName, configuration.basePath) } \ No newline at end of file diff --git a/SQLiter/src/nativeCommonTest/kotlin/co/touchlab/sqliter/DatabaseConfigurationTest.kt b/SQLiter/src/nativeCommonTest/kotlin/co/touchlab/sqliter/DatabaseConfigurationTest.kt index e13a2f75..b7c2d1bc 100644 --- a/SQLiter/src/nativeCommonTest/kotlin/co/touchlab/sqliter/DatabaseConfigurationTest.kt +++ b/SQLiter/src/nativeCommonTest/kotlin/co/touchlab/sqliter/DatabaseConfigurationTest.kt @@ -22,13 +22,37 @@ class DatabaseConfigurationTest : BaseDatabaseTest(){ @Test fun pathTest(){ - val dbPathString = DatabaseFileContext.databasePath(TEST_DB_NAME, false, null) + val dbPathString = DatabaseFileContext.databasePath(TEST_DB_NAME, null) assertTrue(dbPathString.endsWith(TEST_DB_NAME)) } + @Test + fun memoryOnlyTest(){ + val conf = DatabaseConfiguration( + name = null, + basePath = null, + inMemory = true, + version = 1, create = { db -> + db.withStatement(TWO_COL) { + execute() + } + }) + val dbPathString = diskOrMemoryPath(conf) + assertEquals(":memory:", dbPathString) + } + @Test fun memoryPathTest(){ - val dbPathString = DatabaseFileContext.databasePath(TEST_DB_NAME, true, null) + val conf = DatabaseConfiguration( + name = TEST_DB_NAME, + basePath = null, + inMemory = true, + version = 1, create = { db -> + db.withStatement(TWO_COL) { + execute() + } + }) + val dbPathString = diskOrMemoryPath(conf) assertEquals("file:$TEST_DB_NAME?mode=memory&cache=shared", dbPathString) } diff --git a/SQLiter/src/nativeCommonTest/kotlin/co/touchlab/sqliter/DatabaseConnectionTest.kt b/SQLiter/src/nativeCommonTest/kotlin/co/touchlab/sqliter/DatabaseConnectionTest.kt index 9229b4b8..6421a2f3 100644 --- a/SQLiter/src/nativeCommonTest/kotlin/co/touchlab/sqliter/DatabaseConnectionTest.kt +++ b/SQLiter/src/nativeCommonTest/kotlin/co/touchlab/sqliter/DatabaseConnectionTest.kt @@ -235,9 +235,76 @@ class DatabaseConnectionTest { @Test fun memoryDatabase() { assertFalse(checkDbIsFile("chevychasevoicemail", true)) + assertFalse(checkDbIsFile(null, true)) assertTrue(checkDbIsFile("heyfile", false)) } + @Test + fun memoryDatabaseNoNameMultipleConnections(){ + val conf = DatabaseConfiguration( + name = null, + version = 1, + create = { + it.withStatement(TWO_COL) { + execute() + } + }, + inMemory = true + ) + val man = createDatabaseManager( + conf + ) + + val conn1 = man.surpriseMeConnection() + + conn1.withTransaction { + it.withStatement("insert into test(num, str)values(?,?)") { + bindLong(1, 232) + bindString(2, "asdf") + executeInsert() + } + } + + assertEquals(1, conn1.longForQuery("select count(*) from test")) + + assertFails { + val connFail = man.surpriseMeConnection() + connFail.withTransaction { + it.withStatement("insert into test(num, str)values(?,?)") { + bindLong(1, 232) + bindString(2, "asdf") + executeInsert() + } + } + } + + val man2 = createDatabaseManager( + conf + ) + val conn2 = man2.surpriseMeConnection() + conn2.withTransaction { + it.withStatement("insert into test(num, str)values(?,?)") { + bindLong(1, 232) + bindString(2, "asdf") + executeInsert() + } + } + + assertEquals(1, conn2.longForQuery("select count(*) from test")) + + conn1.close() + + assertEquals(1, conn2.longForQuery("select count(*) from test")) + + conn2.close() + + assertFails { + man.withConnection { + assertEquals(0, it.longForQuery("select count(*) from test")) + } + } + } + @Test fun memoryDatabaseMultipleConnections(){ val memoryName = "asdfasdf" @@ -298,8 +365,9 @@ class DatabaseConnectionTest { } } - private fun checkDbIsFile(memoryName: String, mem:Boolean): Boolean { + private fun checkDbIsFile(memoryName: String?, mem:Boolean): Boolean { var dbFileExists = false + val checkName = memoryName ?: ":memory:" try { val man = createDatabaseManager( DatabaseConfiguration( @@ -323,11 +391,11 @@ class DatabaseConnectionTest { } } - dbFileExists = DatabaseFileContext.databaseFile(memoryName, null).exists() + dbFileExists = DatabaseFileContext.databaseFile(checkName, null).exists() } } finally { if (!mem) { - DatabaseFileContext.deleteDatabase(memoryName) + DatabaseFileContext.deleteDatabase(checkName) } } return dbFileExists diff --git a/SQLiter/src/nativeCommonTest/kotlin/co/touchlab/sqliter/performance/DbPerformanceTest.kt b/SQLiter/src/nativeCommonTest/kotlin/co/touchlab/sqliter/performance/DbPerformanceTest.kt new file mode 100644 index 00000000..081f773e --- /dev/null +++ b/SQLiter/src/nativeCommonTest/kotlin/co/touchlab/sqliter/performance/DbPerformanceTest.kt @@ -0,0 +1,37 @@ +package co.touchlab.sqliter.performance + +import co.touchlab.sqliter.* +import kotlin.test.Test +import kotlin.test.assertTrue + +class DbPerformanceTest:BaseDatabaseTest() { + @Test + fun bigInsertTest() { + val manager = createDatabaseManager( + DatabaseConfiguration(name = TEST_DB_NAME, version = 1, + journalMode = JournalMode.WAL, create = { db -> + db.withStatement(TWO_COL) { + execute() + } + }) + ) + + val insertList = (0..50_000).map { i -> + Pair(i.toLong(), "row $i") + } + + val connection = manager.surpriseMeConnection() + + val start = currentTimeMillis() + connection.withStatement("insert into test(num, str)values(?,?)"){ + insertList.forEach { + bindLong(1, it.first) + bindString(2, it.second) + executeInsert() + } + } + + val time = currentTimeMillis() - start + assertTrue("Insert took time ${time}") {time < 6000} + } +} \ No newline at end of file