From c018d89ca62fcfb6bf4dc3022ef36ec04f4a8449 Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Tue, 9 Apr 2019 08:43:23 -0500 Subject: [PATCH] Implement JsDatabase using sql.js --- .../kotlin/org/isoron/platform/io/Database.kt | 10 +-- .../org/isoron/platform/io/DatabaseTest.kt | 60 ++++++++++++++ .../org/isoron/platform/io/JsDatabase.kt | 80 +++++++++++++++++++ .../org/isoron/platform/io/JsDatabaseTest.kt | 30 +++++++ .../isoron/platform/io/JavaDatabaseTest.kt | 34 +------- web/Makefile | 2 +- web/package-lock.json | 10 +-- web/package.json | 3 +- web/test/index.html | 2 +- web/test/index.js | 6 +- 10 files changed, 188 insertions(+), 49 deletions(-) create mode 100644 core/src/commonTest/kotlin/org/isoron/platform/io/DatabaseTest.kt create mode 100644 core/src/jsMain/kotlin/org/isoron/platform/io/JsDatabase.kt create mode 100644 core/src/jsTest/kotlin/org/isoron/platform/io/JsDatabaseTest.kt diff --git a/core/src/commonMain/kotlin/org/isoron/platform/io/Database.kt b/core/src/commonMain/kotlin/org/isoron/platform/io/Database.kt index 9d4b957e9..047ec370c 100644 --- a/core/src/commonMain/kotlin/org/isoron/platform/io/Database.kt +++ b/core/src/commonMain/kotlin/org/isoron/platform/io/Database.kt @@ -47,7 +47,7 @@ interface Database { fun close() } -fun Database.runInBackground(sql: String) { +fun Database.run(sql: String) { val stmt = prepareStatement(sql) stmt.step() stmt.finalize() @@ -72,13 +72,13 @@ fun Database.nextId(tableName: String): Int { } } -fun Database.begin() = runInBackground("begin") +fun Database.begin() = run("begin") -fun Database.commit() = runInBackground("commit") +fun Database.commit() = run("commit") fun Database.getVersion() = queryInt("pragma user_version") -fun Database.setVersion(v: Int) = runInBackground("pragma user_version = $v") +fun Database.setVersion(v: Int) = run("pragma user_version = $v") fun Database.migrateTo(newVersion: Int, fileOpener: FileOpener, log: Log) { val currentVersion = getVersion() @@ -96,7 +96,7 @@ fun Database.migrateTo(newVersion: Int, fileOpener: FileOpener, log: Log) { val migrationFile = fileOpener.openResourceFile(filename) for (line in migrationFile.readLines()) { if (line.isEmpty()) continue - runInBackground(line) + run(line) } setVersion(v) } diff --git a/core/src/commonTest/kotlin/org/isoron/platform/io/DatabaseTest.kt b/core/src/commonTest/kotlin/org/isoron/platform/io/DatabaseTest.kt new file mode 100644 index 000000000..9b0dfe1e4 --- /dev/null +++ b/core/src/commonTest/kotlin/org/isoron/platform/io/DatabaseTest.kt @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2016-2019 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +package org.isoron.platform.io + +import kotlin.test.assertEquals + +class DatabaseTest(val db: Database) { + fun testUsage() { + db.setVersion(0) + assertEquals(0, db.getVersion()) + + db.setVersion(23) + assertEquals(23, db.getVersion()) + + var stmt = db.prepareStatement("drop table if exists demo") + stmt.step() + stmt.finalize() + + stmt = db.prepareStatement("create table if not exists demo(key int, value text)") + stmt.step() + stmt.finalize() + + stmt = db.prepareStatement("insert into demo(key, value) values (?, ?)") + stmt.bindInt(0, 42) + stmt.bindText(1, "Hello World") + stmt.step() + stmt.finalize() + + stmt = db.prepareStatement("select * from demo where key > ?") + stmt.bindInt(0, 10) + + var result = stmt.step() + assertEquals(StepResult.ROW, result) + assertEquals(42, stmt.getInt(0)) + assertEquals("Hello World", stmt.getText(1)) + + result = stmt.step() + assertEquals(StepResult.DONE, result) + + stmt.finalize() + db.close() + } +} \ No newline at end of file diff --git a/core/src/jsMain/kotlin/org/isoron/platform/io/JsDatabase.kt b/core/src/jsMain/kotlin/org/isoron/platform/io/JsDatabase.kt new file mode 100644 index 000000000..850b0e0d9 --- /dev/null +++ b/core/src/jsMain/kotlin/org/isoron/platform/io/JsDatabase.kt @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2016-2019 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +package org.isoron.platform.io + +external fun require(module: String): dynamic + +class JsPreparedStatement(val stmt: dynamic) : PreparedStatement { + + override fun step(): StepResult { + val isRowAvailable = stmt.step() as Boolean + return if(isRowAvailable) StepResult.ROW else StepResult.DONE + } + + override fun finalize() { + } + + override fun getInt(index: Int): Int { + return (stmt.getNumber(index) as Double).toInt() + } + + override fun getLong(index: Int): Long { + return (stmt.getNumber(index) as Double).toLong() + } + + override fun getText(index: Int): String { + return stmt.getString(index) as String + } + + override fun getReal(index: Int): Double { + return stmt.getNumber(index) as Double + } + + override fun bindInt(index: Int, value: Int) { + stmt.bindNumber(value, index + 1) + } + + override fun bindLong(index: Int, value: Long) { + stmt.bindNumber(value, index + 1) + } + + override fun bindText(index: Int, value: String) { + stmt.bindString(value, index + 1) + } + + override fun bindReal(index: Int, value: Double) { + stmt.bindNumber(value, index + 1) + } + + override fun reset() { + stmt.reset() + } + +} + +class JsDatabase(val db: dynamic) : Database { + override fun prepareStatement(sql: String): PreparedStatement { + println(sql) + return JsPreparedStatement(db.prepare(sql)) + } + + override fun close() { + } +} \ No newline at end of file diff --git a/core/src/jsTest/kotlin/org/isoron/platform/io/JsDatabaseTest.kt b/core/src/jsTest/kotlin/org/isoron/platform/io/JsDatabaseTest.kt new file mode 100644 index 000000000..7f7a8456e --- /dev/null +++ b/core/src/jsTest/kotlin/org/isoron/platform/io/JsDatabaseTest.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2016-2019 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +package org.isoron.platform.io + +import kotlin.test.* + +class JsDatabaseTest { + @Test + fun testUsage() { + val db = eval("new SQL.Database()") + DatabaseTest(JsDatabase(db)).testUsage() + } +} \ No newline at end of file diff --git a/core/src/jvmTest/kotlin/org/isoron/platform/io/JavaDatabaseTest.kt b/core/src/jvmTest/kotlin/org/isoron/platform/io/JavaDatabaseTest.kt index a6b82ec70..d5a88c522 100644 --- a/core/src/jvmTest/kotlin/org/isoron/platform/io/JavaDatabaseTest.kt +++ b/core/src/jvmTest/kotlin/org/isoron/platform/io/JavaDatabaseTest.kt @@ -27,38 +27,6 @@ import kotlin.test.assertEquals class JavaDatabaseTest : BaseTest() { @Test fun testUsage() { - db.setVersion(0) - assertEquals(db.getVersion(), 0) - - db.setVersion(23) - assertEquals(db.getVersion(), 23) - - var stmt = db.prepareStatement("drop table if exists demo") - stmt.step() - stmt.finalize() - - stmt = db.prepareStatement("create table if not exists demo(key int, value text)") - stmt.step() - stmt.finalize() - - stmt = db.prepareStatement("insert into demo(key, value) values (?, ?)") - stmt.bindInt(0, 42) - stmt.bindText(1, "Hello World") - stmt.step() - stmt.finalize() - - stmt = db.prepareStatement("select * from demo where key > ?") - stmt.bindInt(0, 10) - - var result = stmt.step() - assertEquals(result, StepResult.ROW) - assertEquals(stmt.getInt(0), 42) - assertEquals(stmt.getText(1), "Hello World") - - result = stmt.step() - assertEquals(result, StepResult.DONE) - - stmt.finalize() - db.close() + DatabaseTest(db).testUsage() } } \ No newline at end of file diff --git a/web/Makefile b/web/Makefile index 1e475f895..aca244bb2 100644 --- a/web/Makefile +++ b/web/Makefile @@ -10,7 +10,7 @@ core: $(test_bundle): test/index.js core mkdir -p build/bundles - npx webpack $< --silent --mode development --target web --output $@ + npx webpack $< --mode development --target web --output $@ test: $(test_bundle) $(node_modules) open test/index.html diff --git a/web/package-lock.json b/web/package-lock.json index 8f5f45c23..2a608c1a0 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -2231,11 +2231,6 @@ "readable-stream": "^2.3.6" } }, - "fontawesome": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/fontawesome/-/fontawesome-5.6.3.tgz", - "integrity": "sha512-FCc+CawwsJWWprVEg9X14yI7zI+l9YVAyhzgu70qwGeDn0tLLDH/dVfqgij72g4BBGgLGfK2qnvFGAmYUkhaWg==" - }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -4719,6 +4714,11 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "sql.js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/sql.js/-/sql.js-0.5.0.tgz", + "integrity": "sha1-+IDeoYKAqEDkHfIgnclnQi36jYE=" + }, "ssri": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", diff --git a/web/package.json b/web/package.json index 778afb06d..1823e162f 100644 --- a/web/package.json +++ b/web/package.json @@ -19,7 +19,8 @@ "babel-preset-env": "^1.7.0", "babel-preset-react": "^6.24.1", "kotlin": "^1.3.21", - "kotlin-test": "^1.3.21" + "kotlin-test": "^1.3.21", + "sql.js": "^0.5.0" }, "devDependencies": { "babel-loader": "^7.1.5", diff --git a/web/test/index.html b/web/test/index.html index 198a3e01e..45d15b6eb 100644 --- a/web/test/index.html +++ b/web/test/index.html @@ -3,11 +3,11 @@ Mocha Tests +
- diff --git a/web/test/index.js b/web/test/index.js index 8e7ea7631..3b911c6bb 100644 --- a/web/test/index.js +++ b/web/test/index.js @@ -1,3 +1,3 @@ -var assert = require('assert'); -var coreTest = require('core_test'); -document.coreTest = coreTest +let assert = require('assert'); +let coreTest = require('core_test'); +document.coreTest = coreTest; \ No newline at end of file