mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Disable removing corrupt database in non-main processes
This commit is contained in:
parent
6738428f60
commit
5f66e325a7
@ -613,7 +613,7 @@ private final class NotificationServiceHandler {
|
||||
|
||||
let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown"
|
||||
|
||||
self.accountManager = AccountManager<TelegramAccountManagerTypes>(basePath: rootPath + "/accounts-metadata", isTemporary: true, isReadOnly: false, useCaches: false)
|
||||
self.accountManager = AccountManager<TelegramAccountManagerTypes>(basePath: rootPath + "/accounts-metadata", isTemporary: true, isReadOnly: false, useCaches: false, removeDatabaseOnError: false)
|
||||
|
||||
let deviceSpecificEncryptionParameters = BuildConfig.deviceSpecificEncryptionParameters(rootPath, baseAppBundleId: baseAppBundleId)
|
||||
self.encryptionParameters = ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: deviceSpecificEncryptionParameters.key)!, salt: ValueBoxEncryptionParameters.Salt(data: deviceSpecificEncryptionParameters.salt)!)
|
||||
|
@ -121,7 +121,7 @@ class DefaultIntentHandler: INExtension, INSendMessageIntentHandling, INSearchFo
|
||||
let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown"
|
||||
|
||||
initializeAccountManagement()
|
||||
let accountManager = AccountManager<TelegramAccountManagerTypes>(basePath: rootPath + "/accounts-metadata", isTemporary: true, isReadOnly: false, useCaches: false)
|
||||
let accountManager = AccountManager<TelegramAccountManagerTypes>(basePath: rootPath + "/accounts-metadata", isTemporary: true, isReadOnly: false, useCaches: false, removeDatabaseOnError: false)
|
||||
self.accountManager = accountManager
|
||||
|
||||
let deviceSpecificEncryptionParameters = BuildConfig.deviceSpecificEncryptionParameters(rootPath, baseAppBundleId: baseAppBundleId)
|
||||
|
@ -1170,7 +1170,7 @@ func debugRestoreState(basePath:String, name: String) {
|
||||
|
||||
private let sharedQueue = Queue(name: "org.telegram.postbox.Postbox")
|
||||
|
||||
public func openPostbox(basePath: String, seedConfiguration: SeedConfiguration, encryptionParameters: ValueBoxEncryptionParameters, timestampForAbsoluteTimeBasedOperations: Int32, isTemporary: Bool, isReadOnly: Bool, useCopy: Bool, useCaches: Bool) -> Signal<PostboxResult, NoError> {
|
||||
public func openPostbox(basePath: String, seedConfiguration: SeedConfiguration, encryptionParameters: ValueBoxEncryptionParameters, timestampForAbsoluteTimeBasedOperations: Int32, isTemporary: Bool, isReadOnly: Bool, useCopy: Bool, useCaches: Bool, removeDatabaseOnError: Bool) -> Signal<PostboxResult, NoError> {
|
||||
let queue = sharedQueue
|
||||
return Signal { subscriber in
|
||||
queue.async {
|
||||
@ -1214,7 +1214,7 @@ public func openPostbox(basePath: String, seedConfiguration: SeedConfiguration,
|
||||
|
||||
postboxLog("openPostbox, initialize SqliteValueBox")
|
||||
|
||||
guard var valueBox = SqliteValueBox(basePath: dbBasePath, queue: queue, isTemporary: isTemporary, isReadOnly: isReadOnly, useCaches: useCaches, encryptionParameters: encryptionParameters, upgradeProgress: { progress in
|
||||
guard var valueBox = SqliteValueBox(basePath: dbBasePath, queue: queue, isTemporary: isTemporary, isReadOnly: isReadOnly, useCaches: useCaches, removeDatabaseOnError: removeDatabaseOnError, encryptionParameters: encryptionParameters, upgradeProgress: { progress in
|
||||
postboxLog("openPostbox, SqliteValueBox upgrading progress \(progress)")
|
||||
subscriber.putNext(.upgrading(progress))
|
||||
}) else {
|
||||
@ -1242,7 +1242,7 @@ public func openPostbox(basePath: String, seedConfiguration: SeedConfiguration,
|
||||
postboxLog("Version \(userVersion) is newer than supported")
|
||||
assertionFailure("Version \(userVersion) is newer than supported")
|
||||
valueBox.drop()
|
||||
guard let updatedValueBox = SqliteValueBox(basePath: dbBasePath, queue: queue, isTemporary: isTemporary, isReadOnly: isReadOnly, useCaches: useCaches, encryptionParameters: encryptionParameters, upgradeProgress: { progress in
|
||||
guard let updatedValueBox = SqliteValueBox(basePath: dbBasePath, queue: queue, isTemporary: isTemporary, isReadOnly: isReadOnly, useCaches: useCaches, removeDatabaseOnError: removeDatabaseOnError, encryptionParameters: encryptionParameters, upgradeProgress: { progress in
|
||||
subscriber.putNext(.upgrading(progress))
|
||||
}) else {
|
||||
subscriber.putNext(.error)
|
||||
@ -1266,7 +1266,7 @@ public func openPostbox(basePath: String, seedConfiguration: SeedConfiguration,
|
||||
valueBox.internalClose()
|
||||
let _ = try? FileManager.default.removeItem(atPath: dbBasePath)
|
||||
let _ = try? FileManager.default.moveItem(atPath: updatedPath, toPath: dbBasePath)
|
||||
guard let updatedValueBox = SqliteValueBox(basePath: dbBasePath, queue: queue, isTemporary: isTemporary, isReadOnly: isReadOnly, useCaches: useCaches, encryptionParameters: encryptionParameters, upgradeProgress: { progress in
|
||||
guard let updatedValueBox = SqliteValueBox(basePath: dbBasePath, queue: queue, isTemporary: isTemporary, isReadOnly: isReadOnly, useCaches: useCaches, removeDatabaseOnError: removeDatabaseOnError, encryptionParameters: encryptionParameters, upgradeProgress: { progress in
|
||||
subscriber.putNext(.upgrading(progress))
|
||||
}) else {
|
||||
subscriber.putNext(.error)
|
||||
@ -1280,7 +1280,7 @@ public func openPostbox(basePath: String, seedConfiguration: SeedConfiguration,
|
||||
assertionFailure("Couldn't find any upgrade for \(userVersion)")
|
||||
postboxLog("Couldn't find any upgrade for \(userVersion)")
|
||||
valueBox.drop()
|
||||
guard let updatedValueBox = SqliteValueBox(basePath: dbBasePath, queue: queue, isTemporary: isTemporary, isReadOnly: isReadOnly, useCaches: useCaches, encryptionParameters: encryptionParameters, upgradeProgress: { progress in
|
||||
guard let updatedValueBox = SqliteValueBox(basePath: dbBasePath, queue: queue, isTemporary: isTemporary, isReadOnly: isReadOnly, useCaches: useCaches, removeDatabaseOnError: removeDatabaseOnError, encryptionParameters: encryptionParameters, upgradeProgress: { progress in
|
||||
subscriber.putNext(.upgrading(progress))
|
||||
}) else {
|
||||
subscriber.putNext(.error)
|
||||
|
@ -46,7 +46,7 @@ struct SqlitePreparedStatement {
|
||||
sqlite3_clear_bindings(statement)
|
||||
}
|
||||
|
||||
func step(handle: OpaquePointer?, _ initial: Bool = false, path: String?) -> Bool {
|
||||
func step(handle: OpaquePointer?, _ initial: Bool = false, pathToRemoveOnError: String?) -> Bool {
|
||||
let res = sqlite3_step(statement)
|
||||
if res != SQLITE_ROW && res != SQLITE_DONE {
|
||||
if let error = sqlite3_errmsg(handle), let str = NSString(utf8String: error) {
|
||||
@ -56,7 +56,7 @@ struct SqlitePreparedStatement {
|
||||
}
|
||||
|
||||
if res == SQLITE_CORRUPT {
|
||||
if let path = path {
|
||||
if let path = pathToRemoveOnError {
|
||||
postboxLog("Corrupted DB at step, dropping")
|
||||
try? FileManager.default.removeItem(atPath: path)
|
||||
preconditionFailure()
|
||||
@ -70,7 +70,7 @@ struct SqlitePreparedStatement {
|
||||
var code: Int32
|
||||
}
|
||||
|
||||
func tryStep(handle: OpaquePointer?, _ initial: Bool = false, path: String?) -> Result<Void, SqlError> {
|
||||
func tryStep(handle: OpaquePointer?, _ initial: Bool = false, pathToRemoveOnError: String?) -> Result<Void, SqlError> {
|
||||
let res = sqlite3_step(statement)
|
||||
if res != SQLITE_ROW && res != SQLITE_DONE {
|
||||
if let error = sqlite3_errmsg(handle), let str = NSString(utf8String: error) {
|
||||
@ -80,7 +80,7 @@ struct SqlitePreparedStatement {
|
||||
}
|
||||
|
||||
if res == SQLITE_CORRUPT {
|
||||
if let path = path {
|
||||
if let path = pathToRemoveOnError {
|
||||
postboxLog("Corrupted DB at step, dropping")
|
||||
try? FileManager.default.removeItem(atPath: path)
|
||||
preconditionFailure()
|
||||
@ -167,6 +167,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
private let inMemory: Bool
|
||||
private let encryptionParameters: ValueBoxEncryptionParameters?
|
||||
private let databasePath: String
|
||||
private let removeDatabaseOnError: Bool
|
||||
private var database: Database!
|
||||
private var tables: [Int32: SqliteValueBoxTable] = [:]
|
||||
private var fullTextTables: [Int32: ValueBoxFullTextTable] = [:]
|
||||
@ -202,11 +203,12 @@ public final class SqliteValueBox: ValueBox {
|
||||
|
||||
private let queue: Queue
|
||||
|
||||
public init?(basePath: String, queue: Queue, isTemporary: Bool, isReadOnly: Bool, useCaches: Bool, encryptionParameters: ValueBoxEncryptionParameters?, upgradeProgress: (Float) -> Void, inMemory: Bool = false) {
|
||||
public init?(basePath: String, queue: Queue, isTemporary: Bool, isReadOnly: Bool, useCaches: Bool, removeDatabaseOnError: Bool, encryptionParameters: ValueBoxEncryptionParameters?, upgradeProgress: (Float) -> Void, inMemory: Bool = false) {
|
||||
self.basePath = basePath
|
||||
self.isTemporary = isTemporary
|
||||
self.isReadOnly = isReadOnly
|
||||
self.useCaches = useCaches
|
||||
self.removeDatabaseOnError = removeDatabaseOnError
|
||||
self.inMemory = inMemory
|
||||
self.encryptionParameters = encryptionParameters
|
||||
self.databasePath = basePath + "/db_sqlite"
|
||||
@ -294,7 +296,9 @@ public final class SqliteValueBox: ValueBox {
|
||||
preconditionFailure("Don't have write access to database folder")
|
||||
}
|
||||
|
||||
if self.removeDatabaseOnError {
|
||||
let _ = try? FileManager.default.removeItem(atPath: path)
|
||||
}
|
||||
preconditionFailure("Couldn't open database")
|
||||
}
|
||||
|
||||
@ -328,7 +332,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
if self.isEncrypted(database) {
|
||||
postboxLog("Encryption key is invalid")
|
||||
|
||||
if isTemporary || isReadOnly {
|
||||
if isTemporary || isReadOnly || !self.removeDatabaseOnError {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -347,7 +351,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
}
|
||||
} else {
|
||||
postboxLog("Encryption key is required")
|
||||
if isReadOnly {
|
||||
if isReadOnly || !self.removeDatabaseOnError {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -548,13 +552,16 @@ public final class SqliteValueBox: ValueBox {
|
||||
postboxLog("isEncrypted prepare...")
|
||||
|
||||
let allIsOk = Atomic<Bool>(value: false)
|
||||
let removeDatabaseOnError = self.removeDatabaseOnError
|
||||
let databasePath = self.databasePath
|
||||
DispatchQueue.global().asyncAfter(deadline: .now() + 5.0, execute: {
|
||||
if allIsOk.with({ $0 }) == false {
|
||||
postboxLog("Timeout reached, discarding database")
|
||||
if removeDatabaseOnError {
|
||||
try? FileManager.default.removeItem(atPath: databasePath)
|
||||
}
|
||||
|
||||
exit(0)
|
||||
preconditionFailure()
|
||||
}
|
||||
})
|
||||
let status = sqlite3_prepare_v2(database.handle, "SELECT * FROM sqlite_master LIMIT 1", -1, &statement, nil)
|
||||
@ -569,7 +576,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
return true
|
||||
}
|
||||
let preparedStatement = SqlitePreparedStatement(statement: statement)
|
||||
switch preparedStatement.tryStep(handle: database.handle, path: self.databasePath) {
|
||||
switch preparedStatement.tryStep(handle: database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
case .success:
|
||||
break
|
||||
case let .failure(error):
|
||||
@ -588,7 +595,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
let status = sqlite3_prepare_v2(database.handle, "PRAGMA user_version", -1, &statement, nil)
|
||||
precondition(status == SQLITE_OK)
|
||||
let preparedStatement = SqlitePreparedStatement(statement: statement)
|
||||
let _ = preparedStatement.step(handle: database.handle, path: self.databasePath)
|
||||
let _ = preparedStatement.step(handle: database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil)
|
||||
let value = preparedStatement.int64At(0)
|
||||
preparedStatement.destroy()
|
||||
return value
|
||||
@ -601,7 +608,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
precondition(status == SQLITE_OK)
|
||||
let preparedStatement = SqlitePreparedStatement(statement: statement)
|
||||
var result: String?
|
||||
if preparedStatement.step(handle: database.handle, path: self.databasePath) {
|
||||
if preparedStatement.step(handle: database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
result = preparedStatement.stringAt(0)
|
||||
}
|
||||
preparedStatement.destroy()
|
||||
@ -616,7 +623,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
let preparedStatement = SqlitePreparedStatement(statement: statement)
|
||||
var tables: [SqliteValueBoxTable] = []
|
||||
|
||||
while preparedStatement.step(handle: database.handle, true, path: self.databasePath) {
|
||||
while preparedStatement.step(handle: database.handle, true, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
guard let name = preparedStatement.stringAt(0) else {
|
||||
assertionFailure()
|
||||
continue
|
||||
@ -663,7 +670,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
let preparedStatement = SqlitePreparedStatement(statement: statement)
|
||||
var tables: [ValueBoxFullTextTable] = []
|
||||
|
||||
while preparedStatement.step(handle: database.handle, true, path: self.databasePath) {
|
||||
while preparedStatement.step(handle: database.handle, true, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
let value = preparedStatement.int64At(0)
|
||||
tables.append(ValueBoxFullTextTable(id: Int32(value)))
|
||||
}
|
||||
@ -1475,7 +1482,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
|
||||
var buffer: ReadBuffer?
|
||||
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
buffer = statement.valueAt(0)
|
||||
break
|
||||
}
|
||||
@ -1495,7 +1502,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
if let _ = self.tables[table.id] {
|
||||
let statement = self.getRowIdStatement(table, key: key)
|
||||
|
||||
if statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
if statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
let rowId = statement.int64At(0)
|
||||
var blobHandle: OpaquePointer?
|
||||
sqlite3_blob_open(database.handle, "main", "t\(table.id)", "value", rowId, 0, &blobHandle)
|
||||
@ -1515,7 +1522,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
if let _ = self.tables[table.id] {
|
||||
let statement = self.getRowIdStatement(table, key: key)
|
||||
|
||||
if statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
if statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
let rowId = statement.int64At(0)
|
||||
var blobHandle: OpaquePointer?
|
||||
sqlite3_blob_open(database.handle, "main", "t\(table.id)", "value", rowId, 1, &blobHandle)
|
||||
@ -1566,7 +1573,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
}
|
||||
}
|
||||
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
let key = statement.keyAt(0)
|
||||
let value = statement.valueAt(1)
|
||||
|
||||
@ -1591,7 +1598,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
}
|
||||
}
|
||||
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
let key = statement.int64KeyAt(0)
|
||||
let value = statement.valueAt(1)
|
||||
|
||||
@ -1702,7 +1709,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
}
|
||||
}
|
||||
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
let key = statement.keyAt(0)
|
||||
|
||||
if !keys(key) {
|
||||
@ -1726,7 +1733,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
}
|
||||
}
|
||||
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
let key = statement.int64KeyAt(0)
|
||||
|
||||
if !keys(key) {
|
||||
@ -1748,7 +1755,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
if let _ = self.tables[table.id] {
|
||||
let statement: SqlitePreparedStatement = self.scanStatement(table)
|
||||
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
let key = statement.keyAt(0)
|
||||
let value = statement.valueAt(1)
|
||||
|
||||
@ -1767,7 +1774,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
if let _ = self.tables[table.id] {
|
||||
let statement: SqlitePreparedStatement = self.scanKeysStatement(table)
|
||||
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
let key = statement.keyAt(0)
|
||||
|
||||
if !keys(key) {
|
||||
@ -1785,7 +1792,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
if let _ = self.tables[table.id] {
|
||||
let statement: SqlitePreparedStatement = self.scanStatement(table)
|
||||
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
let key = statement.int64KeyValueAt(0)
|
||||
let value = statement.valueAt(1)
|
||||
|
||||
@ -1804,7 +1811,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
if let _ = self.tables[table.id] {
|
||||
let statement: SqlitePreparedStatement = self.scanKeysStatement(table)
|
||||
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
let key = statement.int64KeyValueAt(0)
|
||||
|
||||
if !keys(key) {
|
||||
@ -1822,18 +1829,18 @@ public final class SqliteValueBox: ValueBox {
|
||||
|
||||
if sqliteTable.hasPrimaryKey {
|
||||
let statement = self.insertOrReplaceStatement(sqliteTable, key: key, value: value)
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
}
|
||||
statement.reset()
|
||||
} else {
|
||||
if self.exists(table, key: key) {
|
||||
let statement = self.updateStatement(table, key: key, value: value)
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
}
|
||||
statement.reset()
|
||||
} else {
|
||||
let statement = self.insertOrReplaceStatement(sqliteTable, key: key, value: value)
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
}
|
||||
statement.reset()
|
||||
}
|
||||
@ -1850,7 +1857,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
}
|
||||
|
||||
let statement = self.deleteStatement(table, key: key)
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
}
|
||||
statement.reset()
|
||||
}
|
||||
@ -1860,7 +1867,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
precondition(self.queue.isCurrent())
|
||||
if let _ = self.tables[table.id] {
|
||||
let statement = self.rangeDeleteStatement(table, start: min(start, end), end: max(start, end))
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
}
|
||||
statement.reset()
|
||||
}
|
||||
@ -1870,7 +1877,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
precondition(self.queue.isCurrent())
|
||||
if let _ = self.tables[table.id] {
|
||||
let statement = self.moveStatement(table, from: previousKey, to: updatedKey)
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
}
|
||||
statement.reset()
|
||||
}
|
||||
@ -1880,7 +1887,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
precondition(self.queue.isCurrent())
|
||||
if let _ = self.tables[fromTable.id] {
|
||||
let statement = self.copyStatement(fromTable: fromTable, fromKey: fromKey, toTable: toTable, toKey: toKey)
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
}
|
||||
statement.reset()
|
||||
}
|
||||
@ -1916,7 +1923,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
}
|
||||
|
||||
if let statement = statement {
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
let resultCollectionId = statement.stringAt(0)
|
||||
let resultItemId = statement.stringAt(1)
|
||||
|
||||
@ -1942,7 +1949,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
}
|
||||
|
||||
let statement = self.fullTextInsertStatement(table, collectionId: collectionIdData, itemId: itemIdData, contents: contentsData, tags: tagsData)
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
}
|
||||
statement.reset()
|
||||
}
|
||||
@ -1960,7 +1967,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
}
|
||||
|
||||
let statement = self.fullTextDeleteStatement(table, itemId: itemIdData)
|
||||
while statement.step(handle: self.database.handle, path: self.databasePath) {
|
||||
while statement.step(handle: self.database.handle, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
}
|
||||
statement.reset()
|
||||
}
|
||||
@ -1987,7 +1994,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
}
|
||||
|
||||
var result = 0
|
||||
while statement.step(handle: database.handle, true, path: self.databasePath) {
|
||||
while statement.step(handle: database.handle, true, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
let value = statement.int32At(0)
|
||||
result = Int(value)
|
||||
}
|
||||
@ -2005,7 +2012,7 @@ public final class SqliteValueBox: ValueBox {
|
||||
let statement = SqlitePreparedStatement(statement: statementImpl)
|
||||
|
||||
var result = 0
|
||||
while statement.step(handle: database.handle, true, path: self.databasePath) {
|
||||
while statement.step(handle: database.handle, true, pathToRemoveOnError: self.removeDatabaseOnError ? self.databasePath : nil) {
|
||||
let value = statement.int32At(0)
|
||||
result = Int(value)
|
||||
}
|
||||
|
@ -173,7 +173,8 @@ public func accountWithId(accountManager: AccountManager<TelegramAccountManagerT
|
||||
isTemporary: false,
|
||||
isReadOnly: false,
|
||||
useCopy: false,
|
||||
useCaches: !supplementary
|
||||
useCaches: !supplementary,
|
||||
removeDatabaseOnError: !supplementary
|
||||
)
|
||||
|
||||
return postbox
|
||||
@ -1295,7 +1296,8 @@ public func standaloneStateManager(
|
||||
isTemporary: false,
|
||||
isReadOnly: false,
|
||||
useCopy: false,
|
||||
useCaches: false
|
||||
useCaches: false,
|
||||
removeDatabaseOnError: false
|
||||
)
|
||||
|
||||
return postbox
|
||||
|
@ -73,7 +73,7 @@ final class AccountManagerImpl<Types: AccountManagerTypes> {
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate init?(queue: Queue, basePath: String, isTemporary: Bool, isReadOnly: Bool, useCaches: Bool, temporarySessionId: Int64) {
|
||||
fileprivate init?(queue: Queue, basePath: String, isTemporary: Bool, isReadOnly: Bool, useCaches: Bool, removeDatabaseOnError: Bool, temporarySessionId: Int64) {
|
||||
let startTime = CFAbsoluteTimeGetCurrent()
|
||||
|
||||
self.queue = queue
|
||||
@ -82,11 +82,11 @@ final class AccountManagerImpl<Types: AccountManagerTypes> {
|
||||
self.loginTokensPath = "\(basePath)/login-tokens"
|
||||
self.temporarySessionId = temporarySessionId
|
||||
let _ = try? FileManager.default.createDirectory(atPath: basePath, withIntermediateDirectories: true, attributes: nil)
|
||||
guard let guardValueBox = SqliteValueBox(basePath: basePath + "/guard_db", queue: queue, isTemporary: isTemporary, isReadOnly: false, useCaches: useCaches, encryptionParameters: nil, upgradeProgress: { _ in }) else {
|
||||
guard let guardValueBox = SqliteValueBox(basePath: basePath + "/guard_db", queue: queue, isTemporary: isTemporary, isReadOnly: false, useCaches: useCaches, removeDatabaseOnError: removeDatabaseOnError, encryptionParameters: nil, upgradeProgress: { _ in }) else {
|
||||
return nil
|
||||
}
|
||||
self.guardValueBox = guardValueBox
|
||||
guard let valueBox = SqliteValueBox(basePath: basePath + "/db", queue: queue, isTemporary: isTemporary, isReadOnly: isReadOnly, useCaches: useCaches, encryptionParameters: nil, upgradeProgress: { _ in }) else {
|
||||
guard let valueBox = SqliteValueBox(basePath: basePath + "/db", queue: queue, isTemporary: isTemporary, isReadOnly: isReadOnly, useCaches: useCaches, removeDatabaseOnError: removeDatabaseOnError, encryptionParameters: nil, upgradeProgress: { _ in }) else {
|
||||
return nil
|
||||
}
|
||||
self.valueBox = valueBox
|
||||
@ -510,7 +510,7 @@ public final class AccountManager<Types: AccountManagerTypes> {
|
||||
return AccountManagerImpl<Types>.getCurrentRecords(basePath: basePath)
|
||||
}
|
||||
|
||||
public init(basePath: String, isTemporary: Bool, isReadOnly: Bool, useCaches: Bool) {
|
||||
public init(basePath: String, isTemporary: Bool, isReadOnly: Bool, useCaches: Bool, removeDatabaseOnError: Bool) {
|
||||
self.queue = sharedQueue
|
||||
self.basePath = basePath
|
||||
var temporarySessionId: Int64 = 0
|
||||
@ -518,7 +518,7 @@ public final class AccountManager<Types: AccountManagerTypes> {
|
||||
self.temporarySessionId = temporarySessionId
|
||||
let queue = self.queue
|
||||
self.impl = QueueLocalObject(queue: queue, generate: {
|
||||
if let value = AccountManagerImpl<Types>(queue: queue, basePath: basePath, isTemporary: isTemporary, isReadOnly: isReadOnly, useCaches: useCaches, temporarySessionId: temporarySessionId) {
|
||||
if let value = AccountManagerImpl<Types>(queue: queue, basePath: basePath, isTemporary: isTemporary, isReadOnly: isReadOnly, useCaches: useCaches, removeDatabaseOnError: removeDatabaseOnError, temporarySessionId: temporarySessionId) {
|
||||
return value
|
||||
} else {
|
||||
preconditionFailure()
|
||||
|
@ -97,9 +97,9 @@ public enum AccountTransactionError {
|
||||
case couldNotOpen
|
||||
}
|
||||
|
||||
public func accountTransaction<T>(rootPath: String, id: AccountRecordId, encryptionParameters: ValueBoxEncryptionParameters, isReadOnly: Bool, useCopy: Bool = false, useCaches: Bool = true, transaction: @escaping (Postbox, Transaction) -> T) -> Signal<T, AccountTransactionError> {
|
||||
public func accountTransaction<T>(rootPath: String, id: AccountRecordId, encryptionParameters: ValueBoxEncryptionParameters, isReadOnly: Bool, useCopy: Bool = false, useCaches: Bool = true, removeDatabaseOnError: Bool = true, transaction: @escaping (Postbox, Transaction) -> T) -> Signal<T, AccountTransactionError> {
|
||||
let path = "\(rootPath)/\(accountRecordIdPathName(id))"
|
||||
let postbox = openPostbox(basePath: path + "/postbox", seedConfiguration: telegramPostboxSeedConfiguration, encryptionParameters: encryptionParameters, timestampForAbsoluteTimeBasedOperations: Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970), isTemporary: true, isReadOnly: isReadOnly, useCopy: useCopy, useCaches: useCaches)
|
||||
let postbox = openPostbox(basePath: path + "/postbox", seedConfiguration: telegramPostboxSeedConfiguration, encryptionParameters: encryptionParameters, timestampForAbsoluteTimeBasedOperations: Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970), isTemporary: true, isReadOnly: isReadOnly, useCopy: useCopy, useCaches: useCaches, removeDatabaseOnError: removeDatabaseOnError)
|
||||
return postbox
|
||||
|> castError(AccountTransactionError.self)
|
||||
|> mapToSignal { value -> Signal<T, AccountTransactionError> in
|
||||
|
@ -705,7 +705,7 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
||||
UINavigationController.attemptRotationToDeviceOrientation()
|
||||
})
|
||||
|
||||
let accountManager = AccountManager<TelegramAccountManagerTypes>(basePath: rootPath + "/accounts-metadata", isTemporary: false, isReadOnly: false, useCaches: true)
|
||||
let accountManager = AccountManager<TelegramAccountManagerTypes>(basePath: rootPath + "/accounts-metadata", isTemporary: false, isReadOnly: false, useCaches: true, removeDatabaseOnError: true)
|
||||
self.accountManager = accountManager
|
||||
|
||||
telegramUIDeclareEncodables()
|
||||
|
@ -94,7 +94,7 @@ public final class NotificationViewControllerImpl {
|
||||
|
||||
if sharedAccountContext == nil {
|
||||
initializeAccountManagement()
|
||||
let accountManager = AccountManager<TelegramAccountManagerTypes>(basePath: rootPath + "/accounts-metadata", isTemporary: true, isReadOnly: false, useCaches: false)
|
||||
let accountManager = AccountManager<TelegramAccountManagerTypes>(basePath: rootPath + "/accounts-metadata", isTemporary: true, isReadOnly: false, useCaches: false, removeDatabaseOnError: false)
|
||||
|
||||
var initialPresentationDataAndSettings: InitialPresentationDataAndSettings?
|
||||
let semaphore = DispatchSemaphore(value: 0)
|
||||
|
@ -205,7 +205,7 @@ public class ShareRootControllerImpl {
|
||||
|
||||
let internalContext: InternalContext
|
||||
|
||||
let accountManager = AccountManager<TelegramAccountManagerTypes>(basePath: rootPath + "/accounts-metadata", isTemporary: true, isReadOnly: false, useCaches: false)
|
||||
let accountManager = AccountManager<TelegramAccountManagerTypes>(basePath: rootPath + "/accounts-metadata", isTemporary: true, isReadOnly: false, useCaches: false, removeDatabaseOnError: false)
|
||||
|
||||
if let globalInternalContext = globalInternalContext {
|
||||
internalContext = globalInternalContext
|
||||
|
Loading…
x
Reference in New Issue
Block a user