mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Move IosDatabase to Kotlin
This commit is contained in:
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2019 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
import SQLite3
|
||||
|
||||
internal let SQLITE_STATIC = unsafeBitCast(0, to: sqlite3_destructor_type.self)
|
||||
internal let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self)
|
||||
|
||||
class IosPreparedStatement : NSObject, PreparedStatement {
|
||||
|
||||
|
||||
var db: OpaquePointer
|
||||
var statement: OpaquePointer
|
||||
|
||||
init(withStatement statement: OpaquePointer, withDb db: OpaquePointer) {
|
||||
self.statement = statement
|
||||
self.db = db
|
||||
}
|
||||
|
||||
func step() -> StepResult {
|
||||
let result = sqlite3_step(statement)
|
||||
if result == SQLITE_ROW {
|
||||
return StepResult.row
|
||||
} else if result == SQLITE_DONE {
|
||||
return StepResult.done
|
||||
} else {
|
||||
let errMsg = String(cString: sqlite3_errmsg(db)!)
|
||||
fatalError("Database error: \(errMsg) (\(result))")
|
||||
}
|
||||
}
|
||||
|
||||
func getInt(index: Int32) -> Int32 {
|
||||
return sqlite3_column_int(statement, index)
|
||||
}
|
||||
|
||||
func getLong(index: Int32) -> Int64 {
|
||||
return sqlite3_column_int64(statement, index)
|
||||
}
|
||||
|
||||
func getText(index: Int32) -> String {
|
||||
return String(cString: sqlite3_column_text(statement, index))
|
||||
}
|
||||
|
||||
func getReal(index: Int32) -> Double {
|
||||
return sqlite3_column_double(statement, index)
|
||||
}
|
||||
|
||||
func bindInt(index: Int32, value: Int32) {
|
||||
sqlite3_bind_int(statement, index + 1, value)
|
||||
}
|
||||
|
||||
func bindText(index: Int32, value: String) {
|
||||
sqlite3_bind_text(statement, index + 1, value, -1, SQLITE_TRANSIENT)
|
||||
}
|
||||
|
||||
func bindReal(index: Int32, value: Double) {
|
||||
sqlite3_bind_double(statement, index + 1, value)
|
||||
}
|
||||
|
||||
func reset() {
|
||||
sqlite3_reset(statement)
|
||||
}
|
||||
|
||||
override func finalize() {
|
||||
sqlite3_finalize(statement)
|
||||
}
|
||||
|
||||
func bindLong(index: Int32, value: Int64) {
|
||||
sqlite3_bind_int64(statement, index + 1, value)
|
||||
}
|
||||
}
|
||||
|
||||
class IosDatabase : NSObject, Database {
|
||||
var db: OpaquePointer
|
||||
var log: Log
|
||||
|
||||
init(withDb db: OpaquePointer, withLog log: Log) {
|
||||
self.db = db
|
||||
self.log = log
|
||||
}
|
||||
|
||||
func prepareStatement(sql: String) -> PreparedStatement {
|
||||
if sql.isEmpty {
|
||||
fatalError("Provided SQL query is empty")
|
||||
}
|
||||
var statement : OpaquePointer?
|
||||
let result = sqlite3_prepare_v2(db, sql, -1, &statement, nil)
|
||||
if result == SQLITE_OK {
|
||||
return IosPreparedStatement(withStatement: statement!, withDb: db)
|
||||
} else {
|
||||
let errMsg = String(cString: sqlite3_errmsg(db)!)
|
||||
fatalError("Database error: \(errMsg)")
|
||||
}
|
||||
}
|
||||
|
||||
func close() {
|
||||
sqlite3_close(db)
|
||||
}
|
||||
}
|
||||
|
||||
class IosDatabaseOpener : NSObject, DatabaseOpener {
|
||||
|
||||
var log: Log
|
||||
|
||||
init(withLog log: Log) {
|
||||
self.log = log
|
||||
}
|
||||
|
||||
func open(file: UserFile) -> Database {
|
||||
let dbPath = (file as! IosFile).path
|
||||
|
||||
let version = String(cString: sqlite3_libversion())
|
||||
log.info(tag: "IosDatabaseOpener", msg: "SQLite \(version)")
|
||||
log.info(tag: "IosDatabaseOpener", msg: "Opening database: \(dbPath)")
|
||||
var db: OpaquePointer?
|
||||
let result = sqlite3_open(dbPath, &db)
|
||||
if result == SQLITE_OK {
|
||||
return IosDatabase(withDb: db!, withLog: log)
|
||||
} else {
|
||||
fatalError("Error opening database (code \(result))")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2019 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import XCTest
|
||||
@testable import uhabits
|
||||
|
||||
class IosDatabaseTest: XCTestCase {
|
||||
func testUsage() {
|
||||
let databaseOpener = IosDatabaseOpener(withLog: StandardLog())
|
||||
let fileOpener = IosFileOpener()
|
||||
|
||||
let dbFile = fileOpener.openUserFile(path: "test.sqlite3")
|
||||
let db = databaseOpener.open(file: dbFile)
|
||||
|
||||
var stmt = db.prepareStatement(sql: "drop table if exists demo")
|
||||
stmt.step()
|
||||
stmt.finalize()
|
||||
|
||||
stmt = db.prepareStatement(sql: "begin")
|
||||
stmt.step()
|
||||
stmt.finalize()
|
||||
|
||||
stmt = db.prepareStatement(sql: "create table if not exists demo(key int, value text)")
|
||||
stmt.step()
|
||||
stmt.finalize()
|
||||
|
||||
stmt = db.prepareStatement(sql: "insert into demo(key, value) values (?, ?)")
|
||||
stmt.bindInt(index: 0, value: 42)
|
||||
stmt.bindText(index: 1, value: "Hello World")
|
||||
stmt.step()
|
||||
stmt.finalize()
|
||||
|
||||
stmt = db.prepareStatement(sql: "select * from demo where key > ?")
|
||||
stmt.bindInt(index: 0, value: 10)
|
||||
var result = stmt.step()
|
||||
XCTAssertEqual(result, StepResult.row)
|
||||
XCTAssertEqual(stmt.getInt(index: 0), 42)
|
||||
XCTAssertEqual(stmt.getText(index: 1), "Hello World")
|
||||
result = stmt.step()
|
||||
XCTAssertEqual(result, StepResult.done)
|
||||
stmt.finalize()
|
||||
|
||||
stmt = db.prepareStatement(sql: "drop table demo")
|
||||
stmt.step()
|
||||
stmt.finalize()
|
||||
|
||||
stmt = db.prepareStatement(sql: "commit")
|
||||
stmt.step()
|
||||
stmt.finalize()
|
||||
|
||||
db.close()
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,6 @@
|
||||
00A5B42822009F590024E00C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00A5B42722009F590024E00C /* AppDelegate.swift */; };
|
||||
00A5B42A22009F590024E00C /* MainScreenController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00A5B42922009F590024E00C /* MainScreenController.swift */; };
|
||||
00A5B42F22009F5A0024E00C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 00A5B42E22009F5A0024E00C /* Assets.xcassets */; };
|
||||
00C0C6A62246537E003D8AF0 /* IosDatabaseTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00C0C6A222465365003D8AF0 /* IosDatabaseTest.swift */; };
|
||||
00C0C6A8224654A2003D8AF0 /* IosDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00C0C6A7224654A2003D8AF0 /* IosDatabase.swift */; };
|
||||
00C0C6BD22465F65003D8AF0 /* fonts in Resources */ = {isa = PBXBuildFile; fileRef = 00C0C6BA22465F65003D8AF0 /* fonts */; };
|
||||
00C0C6BE22465F65003D8AF0 /* databases in Resources */ = {isa = PBXBuildFile; fileRef = 00C0C6BB22465F65003D8AF0 /* databases */; };
|
||||
00C0C6BF22465F65003D8AF0 /* migrations in Resources */ = {isa = PBXBuildFile; fileRef = 00C0C6BC22465F65003D8AF0 /* migrations */; };
|
||||
@@ -59,8 +57,6 @@
|
||||
00A5B43322009F5A0024E00C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
00A5B43822009F5A0024E00C /* uhabitsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = uhabitsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
00A5B43E22009F5A0024E00C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
00C0C6A222465365003D8AF0 /* IosDatabaseTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IosDatabaseTest.swift; sourceTree = "<group>"; };
|
||||
00C0C6A7224654A2003D8AF0 /* IosDatabase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IosDatabase.swift; sourceTree = "<group>"; };
|
||||
00C0C6AE224655D8003D8AF0 /* BridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BridgingHeader.h; sourceTree = "<group>"; };
|
||||
00C0C6BA22465F65003D8AF0 /* fonts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = fonts; sourceTree = "<group>"; };
|
||||
00C0C6BB22465F65003D8AF0 /* databases */ = {isa = PBXFileReference; lastKnownFileType = folder; path = databases; sourceTree = "<group>"; };
|
||||
@@ -170,7 +166,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00C0C6D022470705003D8AF0 /* IosCanvas.swift */,
|
||||
00C0C6A7224654A2003D8AF0 /* IosDatabase.swift */,
|
||||
);
|
||||
path = Platform;
|
||||
sourceTree = "<group>";
|
||||
@@ -179,7 +174,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00C0C6D82247DC13003D8AF0 /* IosCanvasTest.swift */,
|
||||
00C0C6A222465365003D8AF0 /* IosDatabaseTest.swift */,
|
||||
);
|
||||
path = Platform;
|
||||
sourceTree = "<group>";
|
||||
@@ -312,7 +306,6 @@
|
||||
files = (
|
||||
00C0C6D122470705003D8AF0 /* IosCanvas.swift in Sources */,
|
||||
00C0C6E0224A3602003D8AF0 /* DetailScreenController.swift in Sources */,
|
||||
00C0C6A8224654A2003D8AF0 /* IosDatabase.swift in Sources */,
|
||||
00A5B42A22009F590024E00C /* MainScreenController.swift in Sources */,
|
||||
00A5B42822009F590024E00C /* AppDelegate.swift in Sources */,
|
||||
00D48BD32200AC1600CC4527 /* EditHabitController.swift in Sources */,
|
||||
@@ -325,7 +318,6 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
00C0C6D92247DC13003D8AF0 /* IosCanvasTest.swift in Sources */,
|
||||
00C0C6A62246537E003D8AF0 /* IosDatabaseTest.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user