mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Convert Articles, ArticlesDatabase, and SyncDatabase to Swift Packages
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
//
|
||||
// Constants.swift
|
||||
// SyncDatabase
|
||||
//
|
||||
// Created by Maurice Parker on 5/14/19.
|
||||
// Copyright © 2019 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct DatabaseTableName {
|
||||
|
||||
static let syncStatus = "syncStatus"
|
||||
|
||||
}
|
||||
|
||||
struct DatabaseKey {
|
||||
|
||||
// Sync Status
|
||||
static let articleID = "articleID"
|
||||
static let key = "key"
|
||||
static let flag = "flag"
|
||||
static let selected = "selected"
|
||||
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
//
|
||||
// SyncDatabase.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 5/14/19.
|
||||
// Copyright © 2019 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import RSCore
|
||||
import RSDatabase
|
||||
|
||||
public typealias SyncStatusesResult = Result<Array<SyncStatus>, DatabaseError>
|
||||
public typealias SyncStatusesCompletionBlock = (SyncStatusesResult) -> Void
|
||||
|
||||
public typealias SyncStatusArticleIDsResult = Result<Set<String>, DatabaseError>
|
||||
public typealias SyncStatusArticleIDsCompletionBlock = (SyncStatusArticleIDsResult) -> Void
|
||||
|
||||
public struct SyncDatabase {
|
||||
|
||||
private let syncStatusTable: SyncStatusTable
|
||||
private let queue: DatabaseQueue
|
||||
|
||||
public init(databaseFilePath: String) {
|
||||
let queue = DatabaseQueue(databasePath: databaseFilePath)
|
||||
try! queue.runCreateStatements(SyncDatabase.tableCreationStatements)
|
||||
queue.vacuumIfNeeded(daysBetweenVacuums: 11)
|
||||
self.queue = queue
|
||||
|
||||
self.syncStatusTable = SyncStatusTable(queue: queue)
|
||||
}
|
||||
|
||||
// MARK: - API
|
||||
|
||||
public func insertStatuses(_ statuses: [SyncStatus]) throws {
|
||||
try syncStatusTable.insertStatuses(statuses)
|
||||
}
|
||||
|
||||
public func insertStatuses(_ statuses: [SyncStatus], completion: @escaping DatabaseCompletionBlock) {
|
||||
syncStatusTable.insertStatuses(statuses, completion: completion)
|
||||
}
|
||||
|
||||
public func selectForProcessing(limit: Int? = nil, completion: @escaping SyncStatusesCompletionBlock) {
|
||||
return syncStatusTable.selectForProcessing(limit: limit, completion: completion)
|
||||
}
|
||||
|
||||
public func selectPendingCount(completion: @escaping DatabaseIntCompletionBlock) {
|
||||
syncStatusTable.selectPendingCount(completion)
|
||||
}
|
||||
|
||||
public func selectPendingReadStatusArticleIDs(completion: @escaping SyncStatusArticleIDsCompletionBlock) {
|
||||
syncStatusTable.selectPendingReadStatusArticleIDs(completion: completion)
|
||||
}
|
||||
|
||||
public func selectPendingStarredStatusArticleIDs(completion: @escaping SyncStatusArticleIDsCompletionBlock) {
|
||||
syncStatusTable.selectPendingStarredStatusArticleIDs(completion: completion)
|
||||
}
|
||||
|
||||
public func resetAllSelectedForProcessing(completion: DatabaseCompletionBlock? = nil) {
|
||||
syncStatusTable.resetAllSelectedForProcessing(completion: completion)
|
||||
}
|
||||
|
||||
public func resetSelectedForProcessing(_ articleIDs: [String], completion: DatabaseCompletionBlock? = nil) {
|
||||
syncStatusTable.resetSelectedForProcessing(articleIDs, completion: completion)
|
||||
}
|
||||
|
||||
public func deleteSelectedForProcessing(_ articleIDs: [String], completion: DatabaseCompletionBlock? = nil) {
|
||||
syncStatusTable.deleteSelectedForProcessing(articleIDs, completion: completion)
|
||||
}
|
||||
|
||||
// MARK: - Suspend and Resume (for iOS)
|
||||
|
||||
/// Close the database and stop running database calls.
|
||||
/// Any pending calls will complete first.
|
||||
public func suspend() {
|
||||
queue.suspend()
|
||||
}
|
||||
|
||||
/// Open the database and allow for running database calls again.
|
||||
public func resume() {
|
||||
queue.resume()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private extension SyncDatabase {
|
||||
|
||||
static let tableCreationStatements = """
|
||||
CREATE TABLE if not EXISTS syncStatus (articleID TEXT NOT NULL, key TEXT NOT NULL, flag BOOL NOT NULL DEFAULT 0, selected BOOL NOT NULL DEFAULT 0, PRIMARY KEY (articleID, key));
|
||||
"""
|
||||
}
|
||||
@@ -1,298 +0,0 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 52;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
51554C15228B6F0D0055115A /* SyncStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51554C12228B6F0D0055115A /* SyncStatus.swift */; };
|
||||
51554C16228B6F0D0055115A /* SyncStatusTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51554C13228B6F0D0055115A /* SyncStatusTable.swift */; };
|
||||
51554C17228B6F0D0055115A /* SyncDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51554C14228B6F0D0055115A /* SyncDatabase.swift */; };
|
||||
51554C1E228B701F0055115A /* SyncDatabase_project.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 51554C19228B701F0055115A /* SyncDatabase_project.xcconfig */; };
|
||||
51554C1F228B701F0055115A /* SyncDatabase_project_debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 51554C1A228B701F0055115A /* SyncDatabase_project_debug.xcconfig */; };
|
||||
51554C21228B701F0055115A /* SyncDatabase_project_release.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 51554C1C228B701F0055115A /* SyncDatabase_project_release.xcconfig */; };
|
||||
51554C22228B701F0055115A /* SyncDatabase_target.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 51554C1D228B701F0055115A /* SyncDatabase_target.xcconfig */; };
|
||||
51554C38228B7DAC0055115A /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51554C37228B7DAC0055115A /* Constants.swift */; };
|
||||
51554C3A228B83380055115A /* Articles.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51554C39228B83380055115A /* Articles.framework */; };
|
||||
51B0DF1324D24EA6000AD99E /* RSDatabase in Frameworks */ = {isa = PBXBuildFile; productRef = 51B0DF1224D24EA6000AD99E /* RSDatabase */; };
|
||||
51B0DF1424D24EA6000AD99E /* RSDatabase in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 51B0DF1224D24EA6000AD99E /* RSDatabase */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
51B0DEC524D245A2000AD99E /* Embed Frameworks */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
51B0DF1424D24EA6000AD99E /* RSDatabase in Embed Frameworks */,
|
||||
);
|
||||
name = "Embed Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
51554BEB228B6E8F0055115A /* SyncDatabase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SyncDatabase.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
51554BEF228B6E8F0055115A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
51554C12228B6F0D0055115A /* SyncStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SyncStatus.swift; sourceTree = "<group>"; };
|
||||
51554C13228B6F0D0055115A /* SyncStatusTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SyncStatusTable.swift; sourceTree = "<group>"; };
|
||||
51554C14228B6F0D0055115A /* SyncDatabase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SyncDatabase.swift; sourceTree = "<group>"; };
|
||||
51554C19228B701F0055115A /* SyncDatabase_project.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = SyncDatabase_project.xcconfig; sourceTree = "<group>"; };
|
||||
51554C1A228B701F0055115A /* SyncDatabase_project_debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = SyncDatabase_project_debug.xcconfig; sourceTree = "<group>"; };
|
||||
51554C1C228B701F0055115A /* SyncDatabase_project_release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = SyncDatabase_project_release.xcconfig; sourceTree = "<group>"; };
|
||||
51554C1D228B701F0055115A /* SyncDatabase_target.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = SyncDatabase_target.xcconfig; sourceTree = "<group>"; };
|
||||
51554C35228B72F40055115A /* RSDatabase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSDatabase.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
51554C37228B7DAC0055115A /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
|
||||
51554C39228B83380055115A /* Articles.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Articles.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
51554BE8228B6E8F0055115A /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
51B0DF1324D24EA6000AD99E /* RSDatabase in Frameworks */,
|
||||
51554C3A228B83380055115A /* Articles.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
51554BE1228B6E8F0055115A = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
51554C37228B7DAC0055115A /* Constants.swift */,
|
||||
51554C14228B6F0D0055115A /* SyncDatabase.swift */,
|
||||
51554C12228B6F0D0055115A /* SyncStatus.swift */,
|
||||
51554C13228B6F0D0055115A /* SyncStatusTable.swift */,
|
||||
51554BEF228B6E8F0055115A /* Info.plist */,
|
||||
51554BEC228B6E8F0055115A /* Products */,
|
||||
51554C18228B6FBE0055115A /* xcconfig */,
|
||||
51554C34228B72F40055115A /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
51554BEC228B6E8F0055115A /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
51554BEB228B6E8F0055115A /* SyncDatabase.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
51554C18228B6FBE0055115A /* xcconfig */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
51554C1A228B701F0055115A /* SyncDatabase_project_debug.xcconfig */,
|
||||
51554C1C228B701F0055115A /* SyncDatabase_project_release.xcconfig */,
|
||||
51554C19228B701F0055115A /* SyncDatabase_project.xcconfig */,
|
||||
51554C1D228B701F0055115A /* SyncDatabase_target.xcconfig */,
|
||||
);
|
||||
path = xcconfig;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
51554C34228B72F40055115A /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
51554C39228B83380055115A /* Articles.framework */,
|
||||
51554C35228B72F40055115A /* RSDatabase.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
51554BE6228B6E8F0055115A /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
51554BEA228B6E8F0055115A /* SyncDatabase */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 51554BF3228B6E8F0055115A /* Build configuration list for PBXNativeTarget "SyncDatabase" */;
|
||||
buildPhases = (
|
||||
51554BE6228B6E8F0055115A /* Headers */,
|
||||
51554BE7228B6E8F0055115A /* Sources */,
|
||||
51554BE8228B6E8F0055115A /* Frameworks */,
|
||||
51554BE9228B6E8F0055115A /* Resources */,
|
||||
51C8F349234FB0C40048ED95 /* Run Script: Verfiy No Build Settings */,
|
||||
51B0DEC524D245A2000AD99E /* Embed Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = SyncDatabase;
|
||||
packageProductDependencies = (
|
||||
51B0DF1224D24EA6000AD99E /* RSDatabase */,
|
||||
);
|
||||
productName = SyncDatabase;
|
||||
productReference = 51554BEB228B6E8F0055115A /* SyncDatabase.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
51554BE2228B6E8F0055115A /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1020;
|
||||
ORGANIZATIONNAME = "Ranchero Software";
|
||||
TargetAttributes = {
|
||||
51554BEA228B6E8F0055115A = {
|
||||
CreatedOnToolsVersion = 10.2.1;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 51554BE5228B6E8F0055115A /* Build configuration list for PBXProject "SyncDatabase" */;
|
||||
compatibilityVersion = "Xcode 9.3";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 51554BE1228B6E8F0055115A;
|
||||
packageReferences = (
|
||||
51B0DF1124D24EA6000AD99E /* XCRemoteSwiftPackageReference "RSDatabase" */,
|
||||
);
|
||||
productRefGroup = 51554BEC228B6E8F0055115A /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
51554BEA228B6E8F0055115A /* SyncDatabase */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
51554BE9228B6E8F0055115A /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
51554C21228B701F0055115A /* SyncDatabase_project_release.xcconfig in Resources */,
|
||||
51554C22228B701F0055115A /* SyncDatabase_target.xcconfig in Resources */,
|
||||
51554C1F228B701F0055115A /* SyncDatabase_project_debug.xcconfig in Resources */,
|
||||
51554C1E228B701F0055115A /* SyncDatabase_project.xcconfig in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
51C8F349234FB0C40048ED95 /* Run Script: Verfiy No Build Settings */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Run Script: Verfiy No Build Settings";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "if [ \"$ENABLE_PREVIEWS\" = \"YES\" ]; then exit 0; fi\n\nxcrun -sdk macosx swiftc -target x86_64-macosx10.11 ../../buildscripts/VerifyNoBuildSettings.swift -o $CONFIGURATION_TEMP_DIR/VerifyNoBS\n$CONFIGURATION_TEMP_DIR/VerifyNoBS ${PROJECT_NAME}.xcodeproj/project.pbxproj\n\nif [ $? -ne 0 ]\nthen\n echo \"error: Build Setting were found in the project.pbxproj file. Most likely you didn't intend to change this file and should revert it.\"\n exit 1\nfi\n\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
51554BE7228B6E8F0055115A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
51554C15228B6F0D0055115A /* SyncStatus.swift in Sources */,
|
||||
51554C16228B6F0D0055115A /* SyncStatusTable.swift in Sources */,
|
||||
51554C17228B6F0D0055115A /* SyncDatabase.swift in Sources */,
|
||||
51554C38228B7DAC0055115A /* Constants.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
51554BF1228B6E8F0055115A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 51554C1A228B701F0055115A /* SyncDatabase_project_debug.xcconfig */;
|
||||
buildSettings = {
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
51554BF2228B6E8F0055115A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 51554C1C228B701F0055115A /* SyncDatabase_project_release.xcconfig */;
|
||||
buildSettings = {
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
51554BF4228B6E8F0055115A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 51554C1D228B701F0055115A /* SyncDatabase_target.xcconfig */;
|
||||
buildSettings = {
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
51554BF5228B6E8F0055115A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 51554C1D228B701F0055115A /* SyncDatabase_target.xcconfig */;
|
||||
buildSettings = {
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
51554BE5228B6E8F0055115A /* Build configuration list for PBXProject "SyncDatabase" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
51554BF1228B6E8F0055115A /* Debug */,
|
||||
51554BF2228B6E8F0055115A /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
51554BF3228B6E8F0055115A /* Build configuration list for PBXNativeTarget "SyncDatabase" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
51554BF4228B6E8F0055115A /* Debug */,
|
||||
51554BF5228B6E8F0055115A /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
51B0DF1124D24EA6000AD99E /* XCRemoteSwiftPackageReference "RSDatabase" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/Ranchero-Software/RSDatabase.git";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = "1.0.0-beta1";
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
51B0DF1224D24EA6000AD99E /* RSDatabase */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 51B0DF1124D24EA6000AD99E /* XCRemoteSwiftPackageReference "RSDatabase" */;
|
||||
productName = RSDatabase;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
};
|
||||
rootObject = 51554BE2228B6E8F0055115A /* Project object */;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:SyncDatabase.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -1,8 +0,0 @@
|
||||
<?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>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,48 +0,0 @@
|
||||
//
|
||||
// SyncStatus.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 5/14/19.
|
||||
// Copyright © 2019 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Articles
|
||||
import RSDatabase
|
||||
|
||||
public struct SyncStatus: Hashable, Equatable {
|
||||
|
||||
public enum Key: String {
|
||||
case read = "read"
|
||||
case starred = "starred"
|
||||
case deleted = "deleted"
|
||||
case new = "new"
|
||||
|
||||
public init(_ articleStatusKey: ArticleStatus.Key) {
|
||||
switch articleStatusKey {
|
||||
case .read:
|
||||
self = Self.read
|
||||
case .starred:
|
||||
self = Self.starred
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public let articleID: String
|
||||
public let key: SyncStatus.Key
|
||||
public let flag: Bool
|
||||
public let selected: Bool
|
||||
|
||||
public init(articleID: String, key: SyncStatus.Key, flag: Bool, selected: Bool = false) {
|
||||
self.articleID = articleID
|
||||
self.key = key
|
||||
self.flag = flag
|
||||
self.selected = selected
|
||||
}
|
||||
|
||||
public func databaseDictionary() -> DatabaseDictionary {
|
||||
return [DatabaseKey.articleID: articleID, DatabaseKey.key: key.rawValue, DatabaseKey.flag: flag, DatabaseKey.selected: selected]
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,248 +0,0 @@
|
||||
//
|
||||
// SyncStatusTable.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 5/14/19.
|
||||
// Copyright © 2019 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import RSCore
|
||||
import Articles
|
||||
import RSDatabase
|
||||
import RSDatabaseObjC
|
||||
|
||||
struct SyncStatusTable: DatabaseTable {
|
||||
|
||||
let name = DatabaseTableName.syncStatus
|
||||
private let queue: DatabaseQueue
|
||||
|
||||
init(queue: DatabaseQueue) {
|
||||
self.queue = queue
|
||||
}
|
||||
|
||||
func selectForProcessing(limit: Int?, completion: @escaping SyncStatusesCompletionBlock) {
|
||||
queue.runInTransaction { databaseResult in
|
||||
var statuses = Set<SyncStatus>()
|
||||
var error: DatabaseError?
|
||||
|
||||
func makeDatabaseCall(_ database: FMDatabase) {
|
||||
let updateSQL = "update syncStatus set selected = true"
|
||||
database.executeUpdate(updateSQL, withArgumentsIn: nil)
|
||||
|
||||
var selectSQL = "select * from syncStatus where selected == true"
|
||||
if let limit = limit {
|
||||
selectSQL = "\(selectSQL) limit \(limit)"
|
||||
}
|
||||
if let resultSet = database.executeQuery(selectSQL, withArgumentsIn: nil) {
|
||||
statuses = resultSet.mapToSet(self.statusWithRow)
|
||||
}
|
||||
}
|
||||
|
||||
switch databaseResult {
|
||||
case .success(let database):
|
||||
makeDatabaseCall(database)
|
||||
case .failure(let databaseError):
|
||||
error = databaseError
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
if let error = error {
|
||||
completion(.failure(error))
|
||||
}
|
||||
else {
|
||||
completion(.success(Array(statuses)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func selectPendingCount(_ completion: @escaping DatabaseIntCompletionBlock) {
|
||||
queue.runInDatabase { databaseResult in
|
||||
var count: Int = 0
|
||||
var error: DatabaseError?
|
||||
|
||||
func makeDatabaseCall(_ database: FMDatabase) {
|
||||
let sql = "select count(*) from syncStatus"
|
||||
if let resultSet = database.executeQuery(sql, withArgumentsIn: nil) {
|
||||
count = self.numberWithCountResultSet(resultSet)
|
||||
}
|
||||
}
|
||||
|
||||
switch databaseResult {
|
||||
case .success(let database):
|
||||
makeDatabaseCall(database)
|
||||
case .failure(let databaseError):
|
||||
error = databaseError
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
if let error = error {
|
||||
completion(.failure(error))
|
||||
}
|
||||
else {
|
||||
completion(.success(count))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func selectPendingReadStatusArticleIDs(completion: @escaping SyncStatusArticleIDsCompletionBlock) {
|
||||
selectPendingArticleIDsAsync(.read, completion)
|
||||
}
|
||||
|
||||
func selectPendingStarredStatusArticleIDs(completion: @escaping SyncStatusArticleIDsCompletionBlock) {
|
||||
selectPendingArticleIDsAsync(.starred, completion)
|
||||
}
|
||||
|
||||
func resetAllSelectedForProcessing(completion: DatabaseCompletionBlock? = nil) {
|
||||
queue.runInTransaction { databaseResult in
|
||||
|
||||
func makeDatabaseCall(_ database: FMDatabase) {
|
||||
let updateSQL = "update syncStatus set selected = false"
|
||||
database.executeUpdate(updateSQL, withArgumentsIn: nil)
|
||||
}
|
||||
|
||||
switch databaseResult {
|
||||
case .success(let database):
|
||||
makeDatabaseCall(database)
|
||||
callCompletion(completion, nil)
|
||||
case .failure(let databaseError):
|
||||
callCompletion(completion, databaseError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func resetSelectedForProcessing(_ articleIDs: [String], completion: DatabaseCompletionBlock? = nil) {
|
||||
queue.runInTransaction { databaseResult in
|
||||
|
||||
func makeDatabaseCall(_ database: FMDatabase) {
|
||||
let parameters = articleIDs.map { $0 as AnyObject }
|
||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(articleIDs.count))!
|
||||
let updateSQL = "update syncStatus set selected = false where articleID in \(placeholders)"
|
||||
database.executeUpdate(updateSQL, withArgumentsIn: parameters)
|
||||
}
|
||||
|
||||
switch databaseResult {
|
||||
case .success(let database):
|
||||
makeDatabaseCall(database)
|
||||
callCompletion(completion, nil)
|
||||
case .failure(let databaseError):
|
||||
callCompletion(completion, databaseError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func deleteSelectedForProcessing(_ articleIDs: [String], completion: DatabaseCompletionBlock? = nil) {
|
||||
queue.runInTransaction { databaseResult in
|
||||
|
||||
func makeDatabaseCall(_ database: FMDatabase) {
|
||||
let parameters = articleIDs.map { $0 as AnyObject }
|
||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(articleIDs.count))!
|
||||
let deleteSQL = "delete from syncStatus where selected = true and articleID in \(placeholders)"
|
||||
database.executeUpdate(deleteSQL, withArgumentsIn: parameters)
|
||||
}
|
||||
|
||||
switch databaseResult {
|
||||
case .success(let database):
|
||||
makeDatabaseCall(database)
|
||||
callCompletion(completion, nil)
|
||||
case .failure(let databaseError):
|
||||
callCompletion(completion, databaseError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func insertStatuses(_ statuses: [SyncStatus]) throws {
|
||||
var error: DatabaseError?
|
||||
queue.runInTransactionSync { databaseResult in
|
||||
switch databaseResult {
|
||||
case .success(let database):
|
||||
let statusArray = statuses.map { $0.databaseDictionary() }
|
||||
self.insertRows(statusArray, insertType: .orReplace, in: database)
|
||||
case .failure(let databaseError):
|
||||
error = databaseError
|
||||
}
|
||||
}
|
||||
|
||||
if let error = error {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
func insertStatuses(_ statuses: [SyncStatus], completion: @escaping DatabaseCompletionBlock) {
|
||||
queue.runInTransaction { databaseResult in
|
||||
|
||||
func makeDatabaseCall(_ database: FMDatabase) {
|
||||
let statusArray = statuses.map { $0.databaseDictionary() }
|
||||
self.insertRows(statusArray, insertType: .orReplace, in: database)
|
||||
}
|
||||
|
||||
switch databaseResult {
|
||||
case .success(let database):
|
||||
makeDatabaseCall(database)
|
||||
completion(nil)
|
||||
case .failure(let databaseError):
|
||||
completion(databaseError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private extension SyncStatusTable {
|
||||
|
||||
func statusWithRow(_ row: FMResultSet) -> SyncStatus? {
|
||||
guard let articleID = row.string(forColumn: DatabaseKey.articleID),
|
||||
let rawKey = row.string(forColumn: DatabaseKey.key),
|
||||
let key = SyncStatus.Key(rawValue: rawKey) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let flag = row.bool(forColumn: DatabaseKey.flag)
|
||||
let selected = row.bool(forColumn: DatabaseKey.selected)
|
||||
|
||||
return SyncStatus(articleID: articleID, key: key, flag: flag, selected: selected)
|
||||
}
|
||||
|
||||
func selectPendingArticleIDsAsync(_ statusKey: ArticleStatus.Key, _ completion: @escaping SyncStatusArticleIDsCompletionBlock) {
|
||||
|
||||
queue.runInDatabase { databaseResult in
|
||||
|
||||
func makeDatabaseCall(_ database: FMDatabase) {
|
||||
let sql = "select articleID from syncStatus where selected == false and key = \"\(statusKey.rawValue)\";"
|
||||
|
||||
guard let resultSet = database.executeQuery(sql, withArgumentsIn: nil) else {
|
||||
DispatchQueue.main.async {
|
||||
completion(.success(Set<String>()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
let articleIDs = resultSet.mapToSet{ $0.string(forColumnIndex: 0) }
|
||||
DispatchQueue.main.async {
|
||||
completion(.success(articleIDs))
|
||||
}
|
||||
}
|
||||
|
||||
switch databaseResult {
|
||||
case .success(let database):
|
||||
makeDatabaseCall(database)
|
||||
case .failure(let databaseError):
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(databaseError))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private func callCompletion(_ completion: DatabaseCompletionBlock?, _ databaseError: DatabaseError?) {
|
||||
guard let completion = completion else {
|
||||
return
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
completion(databaseError)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user