generated from GSM-MSG/MSG-Repository-Generator
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #54 from Team-Ampersand/46-abstraction-module
🔀 :: 추상화 모듈 작업
- Loading branch information
Showing
17 changed files
with
483 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>com.apple.security.application-groups</key> | ||
<array> | ||
<string>group.msg.dotori</string> | ||
</array> | ||
</dict> | ||
</plist> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import Foundation | ||
import GRDB | ||
|
||
public protocol LocalDatabase { | ||
func save(record: some FetchableRecord & PersistableRecord) throws | ||
|
||
func save(records: [some FetchableRecord & PersistableRecord]) throws | ||
|
||
func readRecords<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
filter: [String: some DatabaseValueConvertible], | ||
ordered: [some SQLOrderingTerm] | ||
) throws -> [Record] | ||
|
||
func readRecords<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
filter: [String: some DatabaseValueConvertible], | ||
ordered: [some SQLOrderingTerm], | ||
limit: Int, | ||
offset: Int? | ||
) throws -> [Record] | ||
|
||
func readRecord<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
at key: some DatabaseValueConvertible | ||
) throws -> Record? | ||
|
||
func updateRecord<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
at key: some DatabaseValueConvertible, | ||
transform: (inout Record) -> Void | ||
) throws | ||
|
||
func delete( | ||
as record: some FetchableRecord & PersistableRecord | ||
) throws | ||
|
||
func delete<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
key: some DatabaseValueConvertible | ||
) throws | ||
|
||
func deleteAll<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type | ||
) throws | ||
} | ||
|
||
public extension LocalDatabase { | ||
func readRecords<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
filter: [String: some DatabaseValueConvertible], | ||
ordered: [some SQLOrderingTerm], | ||
limit: Int, | ||
offset: Int? | ||
) throws -> [Record] { | ||
try self.readRecords( | ||
as: record, | ||
filter: filter, | ||
ordered: ordered, | ||
limit: limit, | ||
offset: offset | ||
) | ||
} | ||
|
||
func readRecords<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
filter: [String: some DatabaseValueConvertible], | ||
ordered: [some SQLOrderingTerm] | ||
) throws -> [Record] { | ||
try self.readRecords( | ||
as: record, | ||
filter: filter, | ||
ordered: ordered | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import ProjectDescription | ||
import ProjectDescriptionHelpers | ||
import DependencyPlugin | ||
|
||
let project = Project.module( | ||
name: ModulePaths.Core.Database.rawValue, | ||
targets: [ | ||
.interface(module: .core(.Database), dependencies: [ | ||
.SPM.GRDB | ||
]), | ||
.implements(module: .core(.Database), dependencies: [ | ||
.core(target: .Database, type: .interface), | ||
]), | ||
.testing(module: .core(.Database), dependencies: [ | ||
.core(target: .Database, type: .interface) | ||
]), | ||
.tests(module: .core(.Database), dependencies: [ | ||
.core(target: .Database) | ||
]) | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import DatabaseInterface | ||
import Foundation | ||
import GRDB | ||
|
||
final class GRDBLocalDatabase: LocalDatabase { | ||
private let dbQueue: DatabaseQueue | ||
private let migrator: DatabaseMigrator | ||
|
||
init(migrate: (inout DatabaseMigrator) -> Void) { | ||
var url = FileManager.default | ||
.containerURL(forSecurityApplicationGroupIdentifier: "group.msg.dotori")! | ||
|
||
if #available(iOS 16, macOS 13.0, *) { | ||
url.append(path: "Dotori") | ||
} else { | ||
url.appendPathComponent("Dotori") | ||
} | ||
|
||
try? FileManager.default.createDirectory( | ||
at: url, | ||
withIntermediateDirectories: false, | ||
attributes: [ | ||
FileAttributeKey.protectionKey: URLFileProtection.none | ||
] | ||
) | ||
|
||
if #available(iOS 16.0, macOS 13.0, *) { | ||
url.append(path: "Dotori.sqlite") | ||
} else { | ||
url.appendPathComponent("Dotori.sqlite") | ||
} | ||
|
||
var dir = "" | ||
|
||
if #available(iOS 16.0, macOS 13.0, *) { | ||
dir = url.path() | ||
} else { | ||
dir = url.path | ||
} | ||
|
||
if #available(iOS 16.0, macOS 13.0, *) { | ||
dir.replace("%20", with: " ") | ||
} else { | ||
dir = dir.replacingOccurrences(of: "%20", with: " ") | ||
} | ||
|
||
do { | ||
self.dbQueue = try DatabaseQueue(path: dir) | ||
} catch { | ||
fatalError() | ||
} | ||
|
||
var migrator = DatabaseMigrator() | ||
migrate(&migrator) | ||
self.migrator = migrator | ||
try? self.migrator.migrate(self.dbQueue) | ||
} | ||
|
||
func save(record: some FetchableRecord & PersistableRecord) throws { | ||
try self.dbQueue.write { db in | ||
try record.save(db) | ||
} | ||
} | ||
|
||
func save(records: [some FetchableRecord & PersistableRecord]) throws { | ||
try self.dbQueue.write { db in | ||
try records.forEach { | ||
try $0.save(db) | ||
} | ||
} | ||
} | ||
|
||
func readRecords<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
filter: [String: some DatabaseValueConvertible], | ||
ordered: [some SQLOrderingTerm] | ||
) throws -> [Record] { | ||
try self.dbQueue.read { db in | ||
try record | ||
.filter(key: filter) | ||
.order(ordered) | ||
.fetchAll(db) | ||
} | ||
} | ||
|
||
func readRecords<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
filter: [String: some DatabaseValueConvertible], | ||
ordered: [some SQLOrderingTerm], | ||
limit: Int, | ||
offset: Int? | ||
) throws -> [Record] { | ||
try self.dbQueue.read { db in | ||
try record | ||
.filter(key: filter) | ||
.order(ordered) | ||
.limit(limit, offset: offset) | ||
.fetchAll(db) | ||
} | ||
} | ||
|
||
func readRecord<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
at key: some DatabaseValueConvertible | ||
) throws -> Record? { | ||
try dbQueue.read { db in | ||
try record.fetchOne(db, key: key) | ||
} | ||
} | ||
|
||
func updateRecord<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
at key: some DatabaseValueConvertible, | ||
transform: (inout Record) -> Void | ||
) throws { | ||
try dbQueue.write { db in | ||
if var value = try record.fetchOne(db, key: key) { | ||
try value.updateChanges(db, modify: transform) | ||
} | ||
} | ||
} | ||
|
||
func delete( | ||
as record: some FetchableRecord & PersistableRecord | ||
) throws { | ||
try dbQueue.write { db in | ||
_ = try record.delete(db) | ||
} | ||
} | ||
|
||
func delete<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
key: some DatabaseValueConvertible | ||
) throws { | ||
try dbQueue.write { db in | ||
_ = try record.deleteOne(db, key: key) | ||
} | ||
} | ||
|
||
func deleteAll<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type | ||
) throws { | ||
try dbQueue.write { db in | ||
_ = try record.deleteAll(db) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import DatabaseInterface | ||
import GRDB | ||
|
||
final class MockLocalDatabase: LocalDatabase { | ||
var saveCallCount = 0 | ||
func save(record: some FetchableRecord & PersistableRecord) throws { | ||
saveCallCount += 1 | ||
} | ||
|
||
var allSaveCallCount = 0 | ||
func save(records: [some FetchableRecord & PersistableRecord]) throws { | ||
allSaveCallCount += 1 | ||
} | ||
|
||
var readRecordsCallCount = 0 | ||
func readRecords<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
filter: [String: some DatabaseValueConvertible], | ||
ordered: [some SQLOrderingTerm] | ||
) throws -> [Record] { | ||
readRecordsCallCount += 1 | ||
return [] | ||
} | ||
|
||
var readRecordsWithLimitCallCount = 0 | ||
func readRecords<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
filter: [String: some DatabaseValueConvertible], | ||
ordered: [some SQLOrderingTerm], | ||
limit: Int, | ||
offset: Int? | ||
) throws -> [Record] { | ||
readRecordsWithLimitCallCount += 1 | ||
return [] | ||
} | ||
|
||
var readRecordCallCount = 0 | ||
func readRecord<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
at key: some DatabaseValueConvertible | ||
) throws -> Record? { | ||
readRecordCallCount += 1 | ||
return nil | ||
} | ||
|
||
var updateRecordCallCount = 0 | ||
func updateRecord<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
at key: some DatabaseValueConvertible, | ||
transform: (inout Record) -> Void | ||
) throws { | ||
updateRecordCallCount += 1 | ||
} | ||
|
||
var deleteCallCount = 0 | ||
func delete( | ||
as record: some FetchableRecord & PersistableRecord | ||
) throws { | ||
deleteCallCount += 1 | ||
} | ||
|
||
var deleteKeyCallCount = 0 | ||
func delete<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type, | ||
key: some DatabaseValueConvertible | ||
) throws { | ||
deleteKeyCallCount += 1 | ||
} | ||
|
||
var deleteAllCallCount = 0 | ||
func deleteAll<Record: FetchableRecord & PersistableRecord>( | ||
as record: Record.Type | ||
) throws { | ||
deleteAllCallCount += 1 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import XCTest | ||
|
||
final class DatabaseTests: XCTestCase { | ||
override func setUpWithError() throws {} | ||
|
||
override func tearDownWithError() throws {} | ||
|
||
func testExample() { | ||
XCTAssertEqual(1, 1) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import Foundation | ||
|
||
public protocol KeyValueStore { | ||
func save(key: String, value: Any) | ||
func load(key: String) -> Any? | ||
func load<T>(key: String) -> T? | ||
func delete(key: String) | ||
} |
Oops, something went wrong.