This commit is contained in:
2019-03-23 06:29:32 -05:00
parent 7cab0a39e5
commit a546f6de73
39 changed files with 974 additions and 331 deletions

View File

@@ -18,8 +18,8 @@
0021019C21F8AA3E00F9283D /* IosDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0021019B21F8AA3E00F9283D /* IosDatabase.swift */; };
002101A421F936A300F9283D /* IosSqlDatabaseTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 002101A321F936A300F9283D /* IosSqlDatabaseTest.swift */; };
002101AC21F9428C00F9283D /* core.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0008A5C021F16D25000DB3E7 /* core.framework */; };
0091878521FD70B5001BDE6B /* IosLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0091878421FD70B5001BDE6B /* IosLog.swift */; };
00B2AC3D21FCA9D900CBEC8E /* IosFiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B2AC3C21FCA9D900CBEC8E /* IosFiles.swift */; };
00513C3B2200843F00702112 /* libthird-party.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DF0FFE32056DD460020B375 /* libthird-party.a */; };
00513C3C2200843F00702112 /* libyoga.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA51DF850E9000B6D8A /* libyoga.a */; };
00B2AC6521FD1A4500CBEC8E /* migrations in Resources */ = {isa = PBXBuildFile; fileRef = 00B2AC6421FD1A4500CBEC8E /* migrations */; };
00B2AC6821FD1DA700CBEC8E /* IosFilesTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B2AC6621FD1CEF00CBEC8E /* IosFilesTest.swift */; };
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
@@ -339,8 +339,6 @@
002101A121F936A300F9283D /* uhabitsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = uhabitsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
002101A321F936A300F9283D /* IosSqlDatabaseTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IosSqlDatabaseTest.swift; sourceTree = "<group>"; };
002101A521F936A300F9283D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0091878421FD70B5001BDE6B /* IosLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = IosLog.swift; path = uhabits/IosLog.swift; sourceTree = "<group>"; };
00B2AC3C21FCA9D900CBEC8E /* IosFiles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = IosFiles.swift; path = uhabits/IosFiles.swift; sourceTree = "<group>"; };
00B2AC6421FD1A4500CBEC8E /* migrations */ = {isa = PBXFileReference; lastKnownFileType = folder; name = migrations; path = ../core/assets/main/migrations; sourceTree = "<group>"; };
00B2AC6621FD1CEF00CBEC8E /* IosFilesTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IosFilesTest.swift; sourceTree = "<group>"; };
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = "<group>"; };
@@ -373,6 +371,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
00513C3B2200843F00702112 /* libthird-party.a in Frameworks */,
00513C3C2200843F00702112 /* libyoga.a in Frameworks */,
000BCE0521F6CB1100F4DA11 /* libRCTWebSocket.a in Frameworks */,
000C283821F51C9B00C5EC6D /* libRNSVG.a in Frameworks */,
ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */,
@@ -425,8 +425,8 @@
isa = PBXGroup;
children = (
002101A521F936A300F9283D /* Info.plist */,
002101A321F936A300F9283D /* IosSqlDatabaseTest.swift */,
00B2AC6621FD1CEF00CBEC8E /* IosFilesTest.swift */,
002101A321F936A300F9283D /* IosSqlDatabaseTest.swift */,
);
name = "Unit Tests";
path = uhabitsTest;
@@ -478,16 +478,14 @@
13B07FAE1A68108700A75B9A /* Application */ = {
isa = PBXGroup;
children = (
13B07FB61A68108700A75B9A /* Info.plist */,
13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
0008A5F721F17531000DB3E7 /* BridgingHeader.h */,
0008A62B21F2B755000DB3E7 /* CoreModuleBridge.m */,
13B07FB61A68108700A75B9A /* Info.plist */,
0008A5F521F17513000DB3E7 /* AppDelegate.swift */,
0008A62921F2B728000DB3E7 /* CoreModule.swift */,
0021019B21F8AA3E00F9283D /* IosDatabase.swift */,
00B2AC3C21FCA9D900CBEC8E /* IosFiles.swift */,
0091878421FD70B5001BDE6B /* IosLog.swift */,
13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
);
name = Application;
sourceTree = "<group>";
@@ -545,11 +543,8 @@
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
isa = PBXGroup;
children = (
000BCDF621F6CAFF00F4DA11 /* RCTWebSocket.xcodeproj */,
000C280A21F51C4E00C5EC6D /* RNSVG.xcodeproj */,
5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */,
146833FF1AC3E56700842450 /* React.xcodeproj */,
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */,
5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */,
ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */,
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */,
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */,
@@ -557,6 +552,9 @@
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */,
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */,
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
000BCDF621F6CAFF00F4DA11 /* RCTWebSocket.xcodeproj */,
146833FF1AC3E56700842450 /* React.xcodeproj */,
000C280A21F51C4E00C5EC6D /* RNSVG.xcodeproj */,
);
name = Libraries;
sourceTree = "<group>";
@@ -1055,9 +1053,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
00B2AC3D21FCA9D900CBEC8E /* IosFiles.swift in Sources */,
0008A62C21F2B755000DB3E7 /* CoreModuleBridge.m in Sources */,
0091878521FD70B5001BDE6B /* IosLog.swift in Sources */,
0021019C21F8AA3E00F9283D /* IosDatabase.swift in Sources */,
0008A62A21F2B728000DB3E7 /* CoreModule.swift in Sources */,
0008A5F621F17513000DB3E7 /* AppDelegate.swift in Sources */,

View File

@@ -25,9 +25,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var bridge: RCTBridge!
static var backend = Backend(databaseOpener: IosDatabaseOpener(),
static var backend = Backend(databaseOpener: IosDatabaseOpener(withLog: StandardLog()),
fileOpener: IosFileOpener(),
log: IosLog())
log: StandardLog())
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let jsCodeLocation = RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index.ios", fallbackResource: nil)

View File

@@ -24,7 +24,6 @@ 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
@@ -53,12 +52,20 @@ class IosPreparedStatement : NSObject, PreparedStatement {
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, value)
sqlite3_bind_int(statement, index + 1, value)
}
func bindText(index: Int32, value: String) {
sqlite3_bind_text(statement, index, value, -1, SQLITE_TRANSIENT)
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() {
@@ -72,16 +79,18 @@ class IosPreparedStatement : NSObject, PreparedStatement {
class IosDatabase : NSObject, Database {
var db: OpaquePointer
var log: Log
init(withDb db: OpaquePointer) {
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")
}
print("Running SQL: \(sql)")
log.debug(tag: "IosDatabase", msg: "Preparing: \(sql)")
var statement : OpaquePointer?
let result = sqlite3_prepare_v2(db, sql, -1, &statement, nil)
if result == SQLITE_OK {
@@ -98,16 +107,23 @@ class IosDatabase : NSObject, Database {
}
class IosDatabaseOpener : NSObject, DatabaseOpener {
var log: Log
init(withLog log: Log) {
self.log = log
}
func open(file: UserFile) -> Database {
let dbPath = (file as! IosUserFile).path
let version = String(cString: sqlite3_libversion())
print("SQLite \(version)")
print("Opening database: \(dbPath)")
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!)
return IosDatabase(withDb: db!, withLog: log)
} else {
fatalError("Error opening database (code \(result))")
}

View File

@@ -1,77 +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
class IosResourceFile : NSObject, ResourceFile {
var path: String
var fileManager = FileManager.default
init(forPath path: String) {
self.path = path
}
func readLines() -> [String] {
do {
let contents = try String(contentsOfFile: self.path, encoding: .utf8)
return contents.components(separatedBy: CharacterSet.newlines)
} catch {
return [""]
}
}
}
class IosUserFile : NSObject, UserFile {
var path: String
init(forPath path: String) {
self.path = path
}
func delete() {
do {
try FileManager.default.removeItem(atPath: path)
} catch {
}
}
func exists() -> Bool {
return FileManager.default.fileExists(atPath: path)
}
}
class IosFileOpener : NSObject, FileOpener {
func openResourceFile(filename: String) -> ResourceFile {
let path = "\(Bundle.main.resourcePath!)/\(filename)"
return IosResourceFile(forPath: path)
}
func openUserFile(filename: String) -> UserFile {
do {
let root = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).path
return IosUserFile(forPath: "\(root)/\(filename)")
} catch {
return IosUserFile(forPath: "invalid")
}
}
}

View File

@@ -1,30 +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
class IosLog : NSObject, Log {
func info(msg: String) {
print("[I] \(msg)")
}
func debug(msg: String) {
print("[D] \(msg)")
}
}

View File

@@ -32,6 +32,7 @@ class IosFilesTest: XCTestCase {
let fm = FileManager.default
let root = try fm.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).path
let path = "\(root)/test.txt"
print(path)
fm.createFile(atPath: path, contents: "Hello world\nThis is line 2".data(using: .utf8), attributes: nil)
let fileOpener = IosFileOpener()

View File

@@ -22,7 +22,7 @@ import XCTest
class IosDatabaseTest: XCTestCase {
func testUsage() {
let databaseOpener = IosDatabaseOpener()
let databaseOpener = IosDatabaseOpener(withLog: StandardLog())
let fileOpener = IosFileOpener()
let dbFile = fileOpener.openUserFile(filename: "test.sqlite3")