Skip to content

Commit

Permalink
Implement database access (with migrations)
Browse files Browse the repository at this point in the history
  • Loading branch information
iSoron committed Mar 31, 2019
1 parent e19339d commit 7cab0a3
Show file tree
Hide file tree
Showing 67 changed files with 1,828 additions and 138 deletions.
1 change: 1 addition & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ dependencies {
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation files("../core/build/libs/core-jvm.jar")
implementation "com.facebook.react:react-native:0.57.8"
implementation 'org.sqldroid:sqldroid:1.0.3'
implementation project(':react-native-svg')

testImplementation 'junit:junit:4.12'
Expand Down
19 changes: 19 additions & 0 deletions android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
#
# Copyright (C) 2016-2019 Álinson Santos Xavier <[email protected]>
#
# 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 <http://www.gnu.org/licenses/>.
#

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-bin.zip
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright (C) 2016-2019 Álinson Santos Xavier <[email protected]>
*
* 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 <http://www.gnu.org/licenses/>.
*/

package org.isoron.habits

import junit.framework.Assert.*
import org.isoron.uhabits.utils.*
import org.junit.*

class AndroidDatabaseTest : BaseTest() {
@Test
fun testUsage() {
val dbFile = fileOpener.openUserFile("test.sqlite3")
if (dbFile.exists()) dbFile.delete()
val db = databaseOpener.open(dbFile)

var stmt = db.prepareStatement("drop table if exists demo")
stmt.step()
stmt.finalize()

stmt = db.prepareStatement("begin")
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 (?1, ?2)")
stmt.bindInt(1, 42)
stmt.bindText(2, "Hello World")
stmt.step()
stmt.finalize()

stmt = db.prepareStatement("select * from demo where key > ?1")
stmt.bindInt(1, 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()

stmt = db.prepareStatement("drop table demo")
stmt.step()
stmt.finalize()

stmt = db.prepareStatement("commit")
stmt.step()
stmt.finalize()

db.close()
dbFile.delete()
}
}
46 changes: 46 additions & 0 deletions android/src/androidTest/java/org/isoron/habits/AndroidFilesTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2016-2019 Álinson Santos Xavier <[email protected]>
*
* 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 <http://www.gnu.org/licenses/>.
*/

package org.isoron.habits

import org.junit.Test

import org.junit.Assert.*
import java.io.*

class AndroidFilesTest : BaseTest() {

@Test
fun testUserFiles() {
val file = File(context.filesDir, "test.txt")
file.writeText("Hello world!")

val af = fileOpener.openUserFile("test.txt")
assertTrue(af.exists())
af.delete()
assertFalse(af.exists())
}

@Test
fun testResourceFiles() {
val file = fileOpener.openResourceFile("migrations/010.sql")
val lines = file.readLines()
assertEquals("delete from Score", lines[0])
}
}
28 changes: 28 additions & 0 deletions android/src/androidTest/java/org/isoron/habits/BaseTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2016-2019 Álinson Santos Xavier <[email protected]>
*
* 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 <http://www.gnu.org/licenses/>.
*/

package org.isoron.habits

import android.support.test.*

open class BaseTest {
val context = InstrumentationRegistry.getTargetContext()
val fileOpener = AndroidFileOpener(context)
val databaseOpener = AndroidDatabaseOpener()
}
1 change: 1 addition & 0 deletions android/src/main/assets
33 changes: 33 additions & 0 deletions android/src/main/java/org/isoron/habits/AndroidDatabase.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2016-2019 Álinson Santos Xavier <[email protected]>
*
* 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 <http://www.gnu.org/licenses/>.
*/

package org.isoron.habits

import org.isoron.uhabits.database.*
import org.isoron.uhabits.utils.*
import java.sql.*

class AndroidDatabaseOpener : DatabaseOpener {
override fun open(file: UserFile): Database {
val platformFile = file as AndroidUserFile
DriverManager.registerDriver(Class.forName("org.sqldroid.SQLDroidDriver").newInstance() as Driver)
val conn = DriverManager.getConnection("jdbc:sqlite:${platformFile.file.absolutePath}")
return JavaDatabase(conn, AndroidLog())
}
}
62 changes: 62 additions & 0 deletions android/src/main/java/org/isoron/habits/AndroidFiles.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (C) 2016-2019 Álinson Santos Xavier <[email protected]>
*
* 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 <http://www.gnu.org/licenses/>.
*/

package org.isoron.habits

import android.content.*
import org.isoron.uhabits.utils.*
import java.io.*
import java.util.*


class AndroidFileOpener(val context: Context) : FileOpener {
override fun openUserFile(filename: String): UserFile {
return AndroidUserFile(File(context.filesDir, filename))
}

override fun openResourceFile(filename: String): ResourceFile {
return AndroidResourceFile(context, filename)
}
}

class AndroidResourceFile(val context: Context,
val filename: String) : ResourceFile {

override fun readLines(): List<String> {
val asset = context.assets.open(filename)
val reader = BufferedReader(InputStreamReader(asset))
val lines = ArrayList<String>()
while (true) {
val line = reader.readLine() ?: break
lines.add(line)
}
return lines
}
}

class AndroidUserFile(val file: File) : UserFile {
override fun delete() {
file.delete()
}

override fun exists(): Boolean {
return file.exists()
}

}
32 changes: 32 additions & 0 deletions android/src/main/java/org/isoron/habits/AndroidLog.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2016-2019 Álinson Santos Xavier <[email protected]>
*
* 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 <http://www.gnu.org/licenses/>.
*/

package org.isoron.habits

import org.isoron.uhabits.utils.*

class AndroidLog : Log {
override fun debug(msg: String) {
android.util.Log.d("LOOP", msg)
}

override fun info(msg: String) {
android.util.Log.i("LOOP", msg)
}
}
33 changes: 14 additions & 19 deletions android/src/main/java/org/isoron/habits/CoreModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,17 @@ import com.facebook.react.modules.core.DeviceEventManagerModule.*
import org.isoron.uhabits.*


class CoreModule(
private val context: ReactApplicationContext
) : ReactContextBaseJavaModule(context) {
class CoreModule(private val context: ReactApplicationContext) : ReactContextBaseJavaModule(context) {

private var backend = Backend(AndroidDatabaseOpener(),
AndroidFileOpener(context),
AndroidLog())

private var backend = Backend()
private lateinit var emitter: RCTDeviceEventEmitter

override fun initialize() {
super.initialize()
emitter = context.getJSModule(RCTDeviceEventEmitter::class.java)
backend.createHabit("Wake up early")
backend.createHabit("Wash clothes")
backend.createHabit("Exercise")
backend.createHabit("Meditate")
backend.createHabit("Take vitamins")
backend.createHabit("Write 'the quick brown fox jumps over the lazy dog' daily")
backend.createHabit("Write journal")
backend.createHabit("Study French")
}

override fun getName(): String {
Expand All @@ -50,15 +43,17 @@ class CoreModule(

@ReactMethod
fun requestHabitList() {
val params = Arguments.createArray()
for ((id, data) in backend.getHabitList()) {
params.pushMap(Arguments.createMap().apply {
putString("key", id.toString())
putString("name", data["name"] as String)
putInt("color", data["color"] as Int)
val result = backend.getHabitList()
val data = Arguments.createArray()
for (r in result) {
data.pushMap(Arguments.createMap().apply {
for ((key, value) in r) {
if (value is String) putString(key, value)
else if (value is Int) putInt(key, value)
}
})
}
emitter.emit("onHabitList", params)
emitter.emit("onHabitList", data)
}

@ReactMethod
Expand Down
File renamed without changes.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
5 changes: 5 additions & 0 deletions core/assets/main/migrations/009.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
create table Habits ( id integer primary key autoincrement, archived integer, color integer, description text, freq_den integer, freq_num integer, highlight integer, name text, position integer, reminder_hour integer, reminder_min integer )
create table Checkmarks ( id integer primary key autoincrement, habit integer references habits(id), timestamp integer, value integer )
create table Repetitions ( id integer primary key autoincrement, habit integer references habits(id), timestamp integer )
create table Streak ( id integer primary key autoincrement, end integer, habit integer references habits(id), length integer, start integer )
create table Score ( id integer primary key autoincrement, habit integer references habits(id), score integer, timestamp integer )
3 changes: 3 additions & 0 deletions core/assets/main/migrations/010.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
delete from Score
delete from Streak
delete from Checkmarks
1 change: 1 addition & 0 deletions core/assets/main/migrations/011.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
alter table Habits add column reminder_days integer not null default 127
3 changes: 3 additions & 0 deletions core/assets/main/migrations/012.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
delete from Score
delete from Streak
delete from Checkmarks
4 changes: 4 additions & 0 deletions core/assets/main/migrations/013.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
create index idx_score_habit_timestamp on Score(habit, timestamp)
create index idx_checkmark_habit_timestamp on Checkmarks(habit, timestamp)
create index idx_repetitions_habit_timestamp on Repetitions(habit, timestamp)
create index idx_streak_habit_end on Streak(habit, end)
Loading

0 comments on commit 7cab0a3

Please sign in to comment.