diff --git a/.version b/.version index d41dfb3..be13f15 100644 --- a/.version +++ b/.version @@ -1,6 +1,6 @@ { - "latestVersionNum": 20, - "latestVersion": "2.5.1", + "latestVersionNum": 22, + "latestVersion": "2.5.2", "updateType": "hint", - "releaseNotes": "1. 修复低版本用户名问题。" + "releaseNotes": "1. 增加字符串长度查询设置,对于超长字符通守getrange改善性能。\n2. 优化线程池关闭方式。" } diff --git a/redis-pro.xcodeproj/project.pbxproj b/redis-pro.xcodeproj/project.pbxproj index 04b55d8..775b654 100644 --- a/redis-pro.xcodeproj/project.pbxproj +++ b/redis-pro.xcodeproj/project.pbxproj @@ -64,7 +64,7 @@ 4382204026574E3F00DA7F9E /* MSpin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4382203F26574E3F00DA7F9E /* MSpin.swift */; }; 43822042265763D400DA7F9E /* RedisProCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43822041265763D400DA7F9E /* RedisProCommands.swift */; }; 4385D32E261ED26200BA8ED1 /* IndexView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4385D32D261ED26200BA8ED1 /* IndexView.swift */; }; - 4397288C2643E43800803BE9 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4397288B2643E43800803BE9 /* Constants.swift */; }; + 4397288C2643E43800803BE9 /* Const.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4397288B2643E43800803BE9 /* Const.swift */; }; 43BB012326390BC20039565E /* ModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43BB012226390BC20039565E /* ModalView.swift */; }; 43BCCD3526A919B8000BE45F /* MSecureField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43BCCD3426A919B8000BE45F /* MSecureField.swift */; }; 43BCCD3726A91E85000BE45F /* FormItemPassword.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43BCCD3626A91E85000BE45F /* FormItemPassword.swift */; }; @@ -131,7 +131,7 @@ 627E1BC4282F462C00163D6B /* RenameStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 627E1BC3282F462C00163D6B /* RenameStore.swift */; }; 627E1BC6282FC72B00163D6B /* HashValueStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 627E1BC5282FC72B00163D6B /* HashValueStore.swift */; }; 627E1BC8282FCEE300163D6B /* ScanStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 627E1BC7282FCEE300163D6B /* ScanStore.swift */; }; - 6280596828B218D800126E81 /* RediStackClientString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6280596728B218D800126E81 /* RediStackClientString.swift */; }; + 6280596828B218D800126E81 /* RedisClientString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6280596728B218D800126E81 /* RedisClientString.swift */; }; 6280596A28B23DBB00126E81 /* RediStackClientStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6280596928B23DBB00126E81 /* RediStackClientStream.swift */; }; 628F9AA02896A3FB0003B6C0 /* RedisCommandExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 628F9A9F2896A3FB0003B6C0 /* RedisCommandExt.swift */; }; 628F9AA2289EA7C50003B6C0 /* SSHTunnel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 628F9AA1289EA7C50003B6C0 /* SSHTunnel.swift */; }; @@ -267,7 +267,7 @@ 4382203F26574E3F00DA7F9E /* MSpin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MSpin.swift; sourceTree = ""; }; 43822041265763D400DA7F9E /* RedisProCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedisProCommands.swift; sourceTree = ""; }; 4385D32D261ED26200BA8ED1 /* IndexView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IndexView.swift; sourceTree = ""; }; - 4397288B2643E43800803BE9 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; + 4397288B2643E43800803BE9 /* Const.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Const.swift; sourceTree = ""; }; 43BB012226390BC20039565E /* ModalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalView.swift; sourceTree = ""; }; 43BCCD3426A919B8000BE45F /* MSecureField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MSecureField.swift; sourceTree = ""; }; 43BCCD3626A91E85000BE45F /* FormItemPassword.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormItemPassword.swift; sourceTree = ""; }; @@ -331,7 +331,7 @@ 627E1BC3282F462C00163D6B /* RenameStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RenameStore.swift; sourceTree = ""; }; 627E1BC5282FC72B00163D6B /* HashValueStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashValueStore.swift; sourceTree = ""; }; 627E1BC7282FCEE300163D6B /* ScanStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanStore.swift; sourceTree = ""; }; - 6280596728B218D800126E81 /* RediStackClientString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RediStackClientString.swift; sourceTree = ""; }; + 6280596728B218D800126E81 /* RedisClientString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedisClientString.swift; sourceTree = ""; }; 6280596928B23DBB00126E81 /* RediStackClientStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RediStackClientStream.swift; sourceTree = ""; }; 628F9A9F2896A3FB0003B6C0 /* RedisCommandExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedisCommandExt.swift; sourceTree = ""; }; 628F9AA1289EA7C50003B6C0 /* SSHTunnel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSHTunnel.swift; sourceTree = ""; }; @@ -560,7 +560,7 @@ 62D1BA9428435C0C00F41CAD /* Helpers */, 431266D7261C66E100FB6B69 /* MTheme.swift */, 4373C50025C2E75B002B700E /* BizError.swift */, - 4397288B2643E43800803BE9 /* Constants.swift */, + 4397288B2643E43800803BE9 /* Const.swift */, 437BC2442645272E00E2C84D /* DoubleFormatter.swift */, 437BC24626452AE400E2C84D /* StringFormatter.swift */, 43CD286D2670A03800E11876 /* VersionManager.swift */, @@ -638,7 +638,7 @@ isa = PBXGroup; children = ( 4314A34E2625B46E00053FEE /* RediStackClient.swift */, - 6280596728B218D800126E81 /* RediStackClientString.swift */, + 6280596728B218D800126E81 /* RedisClientString.swift */, 620AF6B727D486F5002D6895 /* RedisClientScan.swift */, 620AF6B527D485EB002D6895 /* RedisClientKeys.swift */, 620AF6B927D48848002D6895 /* RedisClientHash.swift */, @@ -972,7 +972,7 @@ 436BB6932644D126008B4866 /* SetEditorView.swift in Sources */, 4373C50525C3F0B6002B700E /* UserDefaultsKeysEnum.swift in Sources */, 4340E2CA2666494300F51F19 /* ScanModel.swift in Sources */, - 4397288C2643E43800803BE9 /* Constants.swift in Sources */, + 4397288C2643E43800803BE9 /* Const.swift in Sources */, 620AF6C627D48996002D6895 /* RedisClientSlowLog.swift in Sources */, 62BDAB3E293B7C0000ADA406 /* AbountCommand.swift in Sources */, 43F22F1326A5546000A00F97 /* RedisInfoItemModel.swift in Sources */, @@ -995,7 +995,7 @@ 4382204026574E3F00DA7F9E /* MSpin.swift in Sources */, 626C4C622820376700B7A542 /* RedisFavoriteDefaultSelectTypeEnum.swift in Sources */, 62D741C1288415180049AB3C /* LuaStore.swift in Sources */, - 6280596828B218D800126E81 /* RediStackClientString.swift in Sources */, + 6280596828B218D800126E81 /* RedisClientString.swift in Sources */, 62D741B9284B776D0049AB3C /* RedisConfigStore.swift in Sources */, 62E9F13F2849DA9F00F4FABF /* SystemEnvironment.swift in Sources */, 627E1BC8282FCEE300163D6B /* ScanStore.swift in Sources */, @@ -1400,7 +1400,7 @@ repositoryURL = "https://github.com/apple/swift-log.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 1.4.2; + minimumVersion = 1.5.2; }; }; 625B41B7293AEBD700C7766D /* XCRemoteSwiftPackageReference "RediStack" */ = { @@ -1432,7 +1432,7 @@ repositoryURL = "https://github.com/sushichop/Puppy.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + minimumVersion = 0.7.0; }; }; CEA1EF48277C56B100D300E9 /* XCRemoteSwiftPackageReference "swift-nio-ssh" */ = { @@ -1440,7 +1440,7 @@ repositoryURL = "https://github.com/apple/swift-nio-ssh"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.4.1; + minimumVersion = 0.6.1; }; }; CEA1EF4B277C56DD00D300E9 /* XCRemoteSwiftPackageReference "swift-nio" */ = { diff --git a/redis-pro.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/redis-pro.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 2416c41..7fec572 100644 --- a/redis-pro.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/redis-pro.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/sushichop/Puppy.git", "state" : { - "revision" : "9f3cf02dc92bc233e40ba8a66af20abb97978929", - "version" : "0.6.0" + "revision" : "b5af02a72a5a1f92a68e6eceee19cac804067ad9", + "version" : "0.7.0" } }, { @@ -113,8 +113,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-log.git", "state" : { - "revision" : "6fe203dc33195667ce1759bf0182975e4653ba1c", - "version" : "1.4.4" + "revision" : "32e8d724467f8fe623624570367e3d50c5638e46", + "version" : "1.5.2" } }, { @@ -140,8 +140,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio-ssh", "state" : { - "revision" : "fe02717fa9f7eb8d82957d6784bc3d1793f9c1e6", - "version" : "0.4.1" + "revision" : "baa05dc6ff3de89c589a9d582659f0f6699f62ab", + "version" : "0.6.1" } }, { diff --git a/redis-pro.xcodeproj/project.xcworkspace/xcuserdata/chengpan.xcuserdatad/UserInterfaceState.xcuserstate b/redis-pro.xcodeproj/project.xcworkspace/xcuserdata/chengpan.xcuserdatad/UserInterfaceState.xcuserstate index 6d7bb5f..a3531ce 100644 Binary files a/redis-pro.xcodeproj/project.xcworkspace/xcuserdata/chengpan.xcuserdatad/UserInterfaceState.xcuserstate and b/redis-pro.xcodeproj/project.xcworkspace/xcuserdata/chengpan.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/redis-pro.xcodeproj/project.xcworkspace/xcuserdata/chengpanwang.xcuserdatad/UserInterfaceState.xcuserstate b/redis-pro.xcodeproj/project.xcworkspace/xcuserdata/chengpanwang.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..b5aa7ba Binary files /dev/null and b/redis-pro.xcodeproj/project.xcworkspace/xcuserdata/chengpanwang.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/redis-pro.xcodeproj/xcuserdata/chengpan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/redis-pro.xcodeproj/xcuserdata/chengpan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index e731352..b74826b 100644 --- a/redis-pro.xcodeproj/xcuserdata/chengpan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/redis-pro.xcodeproj/xcuserdata/chengpan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -62,8 +62,8 @@ filePath = "redis-pro/Common/RedisClient/RediStackClient.swift" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "208" - endingLineNumber = "208" + startingLineNumber = "204" + endingLineNumber = "204" landmarkName = "getConnPool()" landmarkType = "7"> @@ -78,11 +78,43 @@ filePath = "redis-pro/Common/RedisClient/RediStackClient.swift" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "218" - endingLineNumber = "218" + startingLineNumber = "214" + endingLineNumber = "214" landmarkName = "getConnPool()" landmarkType = "7"> + + + + + + + + diff --git a/redis-pro.xcodeproj/xcuserdata/chengpanwang.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/redis-pro.xcodeproj/xcuserdata/chengpanwang.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index b0ec863..f6e3871 100644 --- a/redis-pro.xcodeproj/xcuserdata/chengpanwang.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/redis-pro.xcodeproj/xcuserdata/chengpanwang.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -34,6 +34,38 @@ endingLineNumber = "46" landmarkName = "getSSHConnection()" landmarkType = "7"> + + + + + + SchemeUserState + CustomDump (Playground) 1.xcscheme + + isShown + + orderHint + 20 + + CustomDump (Playground) 2.xcscheme + + isShown + + orderHint + 21 + + CustomDump (Playground).xcscheme + + isShown + + orderHint + 19 + Playground (Playground) 1.xcscheme isShown diff --git a/redis-pro/Command/HomeCommand.swift b/redis-pro/Command/HomeCommand.swift index c0c1bbd..76cef29 100644 --- a/redis-pro/Command/HomeCommand.swift +++ b/redis-pro/Command/HomeCommand.swift @@ -13,7 +13,7 @@ struct HomeCommands: View { var body: some View { Button("Home") { - guard let url = URL(string: Constants.REPO_URL) else { + guard let url = URL(string: Const.REPO_URL) else { return } openURL(url) diff --git a/redis-pro/Common/Constants.swift b/redis-pro/Common/Const.swift similarity index 65% rename from redis-pro/Common/Constants.swift rename to redis-pro/Common/Const.swift index 52e9ccb..5d1872c 100644 --- a/redis-pro/Common/Constants.swift +++ b/redis-pro/Common/Const.swift @@ -1,5 +1,5 @@ // -// Constants.swift +// Const.swift // redis-pro // // Created by chengpanwang on 2021/5/6. @@ -7,9 +7,14 @@ import Foundation -struct Constants { +struct Const { + static let EMPTY_STRING = "" + static let LIST_VALUE_DELETE_MARK = "__REDIS_LIST_VALUE_DELETE_BY_REDIS_PRO__" static let REPO_URL = "https://github.com/cmushroom/redis-pro" static let RELEASE_URL = "https://github.com/cmushroom/redis-pro/releases" + + // 最大字符串展示长度默认值 + static let DEFAULT_STRING_MAX_LENGTH = 10240 } diff --git a/redis-pro/Common/PuppyLogger.swift b/redis-pro/Common/PuppyLogger.swift index 3aaed7a..1b0b19a 100644 --- a/redis-pro/Common/PuppyLogger.swift +++ b/redis-pro/Common/PuppyLogger.swift @@ -12,7 +12,7 @@ final class LogFormatter: LogFormattable { func formatMessage(_ level: LogLevel, message: String, tag: String, function: String, file: String, line: UInt, swiftLogInfo: [String : String], label: String, date: Date, threadID: UInt64) -> String { - let date = dateFormatter(date, dateFormat: "yyyy-MM-dd'T'HH:mm:ss.SSSZ") + let date = dateFormatter(date, withFormatter: .init(), dateFormat: "yyyy-MM-dd'T'HH:mm:ss.SSSZ") let file = fileName(file) return "\(date) [\(level.emoji) \(level)] \(file)#L.\(line) \(function) \(message)" } diff --git a/redis-pro/Common/RedisClient/RediStackClient.swift b/redis-pro/Common/RedisClient/RediStackClient.swift index 7755e40..843d903 100644 --- a/redis-pro/Common/RedisClient/RediStackClient.swift +++ b/redis-pro/Common/RedisClient/RediStackClient.swift @@ -13,10 +13,6 @@ import NIOSSH import Swift import ComposableArchitecture -class Cons { - static let EMPTY_STRING = "" -} - class RediStackClient { let logger = Logger(label: "redis-client") var redisModel:RedisModel @@ -114,7 +110,7 @@ class RediStackClient { conn.send(command, eventLoop: nil, logger: self.logger) .whenComplete({completion in if case .success(let r) = completion { - self.logger.info("string operator, setex complete") + self.logger.info("send redis command: \(command) complete") continuation.resume(returning: r) } else if case .failure(let error) = completion { @@ -124,9 +120,8 @@ class RediStackClient { } } - /** - 公共底层请求redis 数据方法, 不处理任何异常, 使用者需要自己行处理异常信息 - */ + + // 公共底层请求redis 数据方法, 不处理任何异常, 使用者需要自己行处理异常信息 func _send(_ command: RedisCommand) async throws -> R { let conn = try await getConn() return try await _send(conn, command) @@ -320,11 +315,9 @@ class RediStackClient { self.logger.info("redis client- connection pool close") self.closeSSH() - -// self.keepaliveTask?.cancel() } - deinit { + func shutdown() { do { logger.info("gracefully shutdown event loop group start...") try self.eventLoopGroup.syncShutdownGracefully() diff --git a/redis-pro/Common/RedisClient/RedisClientList.swift b/redis-pro/Common/RedisClient/RedisClientList.swift index 9f845bb..f0e897c 100644 --- a/redis-pro/Common/RedisClient/RedisClientList.swift +++ b/redis-pro/Common/RedisClient/RedisClientList.swift @@ -61,9 +61,9 @@ extension RediStackClient { throw BizError("list value: \(value), index: \(index) have changed, please check!") } - try await _lset(key, index: index, value: Constants.LIST_VALUE_DELETE_MARK) + try await _lset(key, index: index, value: Const.LIST_VALUE_DELETE_MARK) - return try await _lrem(key,value: Constants.LIST_VALUE_DELETE_MARK) + return try await _lrem(key,value: Const.LIST_VALUE_DELETE_MARK) } catch { handleError(error) } diff --git a/redis-pro/Common/RedisClient/RediStackClientString.swift b/redis-pro/Common/RedisClient/RedisClientString.swift similarity index 85% rename from redis-pro/Common/RedisClient/RediStackClientString.swift rename to redis-pro/Common/RedisClient/RedisClientString.swift index b6cb9a4..d1a6139 100644 --- a/redis-pro/Common/RedisClient/RediStackClientString.swift +++ b/redis-pro/Common/RedisClient/RedisClientString.swift @@ -33,7 +33,23 @@ extension RediStackClient { let command:RedisCommand = .get(RedisKey(key)) let r = await send(command) - return r??.description ?? Cons.EMPTY_STRING + return r??.description ?? Const.EMPTY_STRING + } + + func getRange(_ key:String, start:Int = 0, end:Int) async -> String { + logger.info("get value range, key:\(key), start:\(start), end:\(end)") + + let command:RedisCommand = .getRange(key, start: start, end: end) + let r = await send(command) + return r?.description ?? Const.EMPTY_STRING + } + + func strLen(_ key:String) async -> Int { + logger.info("get value length, key:\(key)") + + let command:RedisCommand = .strln(RedisKey(key)) + let r = await send(command) + return r ?? 0 } func del(_ key:String) async -> Int { diff --git a/redis-pro/Common/RedisClient/RedisClientZSet.swift b/redis-pro/Common/RedisClient/RedisClientZSet.swift index 497353e..ae3a4f5 100644 --- a/redis-pro/Common/RedisClient/RedisClientZSet.swift +++ b/redis-pro/Common/RedisClient/RedisClientZSet.swift @@ -128,7 +128,7 @@ extension RediStackClient { let command: RedisCommand<(Int, [(RESPValue, Double)])> = .zscan(RedisKey(key), startingFrom: cursor, matching: keywords, count: count) let r = try await _send(command) - return (r.0, r.1.map { ($0.0.string ?? Cons.EMPTY_STRING, $0.1) }) + return (r.0, r.1.map { ($0.0.string ?? Const.EMPTY_STRING, $0.1) }) } func zupdate(_ key:String, from:String, to:String, score:Double) async -> Bool { @@ -203,7 +203,7 @@ extension RediStackClient { let command: RedisCommand<[(RESPValue, Double)]> = .zrangebyscore(from: RedisKey(key), withMinimumScoreOf: .inclusive(Double.min), limitBy: (offset: page.start, count: page.size), returning: .valuesAndScores) let r:[(RESPValue, Double)] = try await _send(command) - return r.map { ($0.string ?? Cons.EMPTY_STRING, "\($1)") } + return r.map { ($0.string ?? Const.EMPTY_STRING, "\($1)") } } diff --git a/redis-pro/Common/RedisClient/RedisCommandExt.swift b/redis-pro/Common/RedisClient/RedisCommandExt.swift index 2b5bba9..66c3ab9 100644 --- a/redis-pro/Common/RedisClient/RedisCommandExt.swift +++ b/redis-pro/Common/RedisClient/RedisCommandExt.swift @@ -90,6 +90,10 @@ extension RedisCommand where ResultType == String { }) } + public static func getRange(_ key: String, start:Int = 0, end:Int) -> RedisCommand { + return .init(keyword: "GETRANGE", arguments: [.init(from: key), .init(from: start), .init(from: end)]) + } + public static func type(_ key: String) -> RedisCommand { return .init(keyword: "TYPE", arguments: [.init(from: key)]) } diff --git a/redis-pro/Common/UserDefaults/RedisDefaults.swift b/redis-pro/Common/UserDefaults/RedisDefaults.swift index b939d83..4ec9738 100644 --- a/redis-pro/Common/UserDefaults/RedisDefaults.swift +++ b/redis-pro/Common/UserDefaults/RedisDefaults.swift @@ -47,31 +47,21 @@ class RedisDefaults { return userDefaults.string(forKey: UserDefaulsKeysEnum.RedisLastUseIdKey.rawValue) } + // string 最大显示长度 + static func getStringMaxLength() -> Int { + let string:String? = userDefaults.string(forKey: UserDefaulsKeysEnum.AppStringMaxLength.rawValue) + if let string = string { + return Int(string) ?? Const.DEFAULT_STRING_MAX_LENGTH + } + + return Const.DEFAULT_STRING_MAX_LENGTH + } + private static func getAllDict() -> [Dictionary]? { return userDefaults.array(forKey: UserDefaulsKeysEnum.RedisFavoriteListKey.rawValue) as? [Dictionary] } - -// func loadAll() -> Void { -// redisModels.removeAll() -// -// let redisDicts = getAll() -// -// redisDicts.forEach{ (element) in -// let item = RedisModel(dictionary: element) -// redisModels.append(item) -// } -// -// if redisModels.count == 0 { -// let item = RedisModel() -// redisModels.append(item) -// } -// -// self.lastRedisModelId = userDefaults.string(forKey: UserDefaulsKeysEnum.RedisLastUseIdKey.rawValue) -// logger.info("last select redis model id: \(String(describing: lastRedisModelId))") -// } - static func saveLastUse(_ redisModel:RedisModel) -> Void { userDefaults.setValue(redisModel.id, forKey: UserDefaulsKeysEnum.RedisLastUseIdKey.rawValue) } diff --git a/redis-pro/Common/UserDefaults/UserDefaultsKeysEnum.swift b/redis-pro/Common/UserDefaults/UserDefaultsKeysEnum.swift index 3e95c1c..c0802d7 100644 --- a/redis-pro/Common/UserDefaults/UserDefaultsKeysEnum.swift +++ b/redis-pro/Common/UserDefaults/UserDefaultsKeysEnum.swift @@ -15,6 +15,8 @@ enum UserDefaulsKeysEnum: String { case RedisFavoriteDefaultSelectType = "User.defaultFavorite" // color scheme case AppColorScheme = "App.ColorScheme" + // string editor default max length + case AppStringMaxLength = "App.StringMaxLength" // keepalive second case AppKeepalive = "App.Keepalive" diff --git a/redis-pro/Common/VersionManager.swift b/redis-pro/Common/VersionManager.swift index e48fa24..7373184 100644 --- a/redis-pro/Common/VersionManager.swift +++ b/redis-pro/Common/VersionManager.swift @@ -48,7 +48,7 @@ struct VersionManager { Messages.confirm("New version \(latestVersion) is available", message: releaseNotes, primaryButton: "Upgrade", action: { - if let url = URL(string: Constants.RELEASE_URL) { + if let url = URL(string: Const.RELEASE_URL) { NSWorkspace.shared.open(url) } } diff --git a/redis-pro/Model/RedisInsanceModel.swift b/redis-pro/Model/RedisInsanceModel.swift index 8e2226b..0e4d8f8 100644 --- a/redis-pro/Model/RedisInsanceModel.swift +++ b/redis-pro/Model/RedisInsanceModel.swift @@ -29,6 +29,8 @@ class RedisInstanceModel:ObservableObject, Identifiable { NotificationCenter.default.addObserver(forName: NSApplication.willTerminateNotification, object: nil, queue: .main) { [self] _ in logger.info("redis pro will exit...") close() + + shutdown() } ) } @@ -88,4 +90,8 @@ class RedisInstanceModel:ObservableObject, Identifiable { rediStackClient?.close() rediStackClient = nil } + + func shutdown() -> Void { + rediStackClient?.shutdown() + } } diff --git a/redis-pro/Store/SettingsStore.swift b/redis-pro/Store/SettingsStore.swift index 67bda56..b61f83a 100644 --- a/redis-pro/Store/SettingsStore.swift +++ b/redis-pro/Store/SettingsStore.swift @@ -15,6 +15,7 @@ private let userDefaults = UserDefaults.standard struct SettingsState: Equatable { var colorSchemeValue:String? var defaultFavorite:String = "last" + var stringMaxLength:Int = Const.DEFAULT_STRING_MAX_LENGTH var keepalive:Int = 30 var redisModels: [RedisModel] = [] @@ -27,6 +28,7 @@ enum SettingsAction:Equatable { case initial case setColorScheme(String) case setDefaultFavorite(String) + case setStringMaxLength(Int) case setKeepalive(Int) } @@ -42,8 +44,12 @@ let settingsReducer = Reducer Void)? @@ -24,7 +25,10 @@ struct FormItemInt: View { } // NIntField(value: $value, placeholder: placeholder ?? label, onCommit: onCommit) // MTextField(value: valueProxy, placeholder: placeholder ?? label, suffix: suffix, onCommit: onCommit, autoCommit: autoCommit) - MIntField(value: $value, placeholder: placeholder ?? label, onCommit: onCommit) + MIntField(value: $value, placeholder: placeholder ?? label, onCommit: onCommit).help(tips ?? "") + if(tips != nil) { + MIcon(icon: "questionmark.circle", fontSize: 12).help(tips!) + } } } } diff --git a/redis-pro/Views/Login/LoginForm.swift b/redis-pro/Views/Login/LoginForm.swift index a4d7f42..0ac17cd 100644 --- a/redis-pro/Views/Login/LoginForm.swift +++ b/redis-pro/Views/Login/LoginForm.swift @@ -25,7 +25,7 @@ struct LoginForm: View { HStack(alignment: .center){ if !viewStore.loading { Button(action: { - guard let url = URL(string: Constants.REPO_URL) else { + guard let url = URL(string: Const.REPO_URL) else { return } openURL(url) diff --git a/redis-pro/Views/RedisEditorView/StringEditorView.swift b/redis-pro/Views/RedisEditorView/StringEditorView.swift index f8034b5..d807fc8 100644 --- a/redis-pro/Views/RedisEditorView/StringEditorView.swift +++ b/redis-pro/Views/RedisEditorView/StringEditorView.swift @@ -24,10 +24,17 @@ struct StringEditorView: View { // footer HStack(alignment: .center, spacing: MTheme.H_SPACING) { + if (viewStore.isIntactString) { + Text("lenth: \(viewStore.length)") + } else { + Text("range: 0~\(viewStore.stringMaxLength + 1) / \(viewStore.length)") + MButton(text: "Show Intact", action: {viewStore.send(.getIntactString)}) + } + Spacer() MButton(text: "Pretty Json", action: {viewStore.send(.jsonFormat)}) IconButton(icon: "arrow.clockwise", name: "Refresh", action: {viewStore.send(.refresh)}) - IconButton(icon: "checkmark", name: "Submit", action: {viewStore.send(.submit)}) + IconButton(icon: "checkmark", name: "Submit", disabled: !viewStore.isIntactString, action: {viewStore.send(.submit)}) } .padding(EdgeInsets(top: 6, leading: 0, bottom: 6, trailing: 0)) diff --git a/redis-pro/en.lproj/Localizable.strings b/redis-pro/en.lproj/Localizable.strings index 4fed170..7292060 100644 --- a/redis-pro/en.lproj/Localizable.strings +++ b/redis-pro/en.lproj/Localizable.strings @@ -14,7 +14,12 @@ // -------------------------------------------------- redis help message end ----------------------------------------------------- -// -------------------------------------------------- redis confirm message start --------------------------------------------------- +// -------------------------------------------------- redis string message start ------------------------------------------------- +"HELP_STRING_GET_RANGE_LENGTH" = "查询redis string类型数据时最大长度, 用于控制在查询超大字符串时引起的性能问题, -1表过查询整个字符串, 大于-1使用GETRANGE方法查询"; +// -------------------------------------------------- redis string message end --------------------------------------------------- + + +// -------------------------------------------------- redis confirm message start ------------------------------------------------ "ZSET_DELETE_CONFIRM_TITLE" = "Delete zset element, value: '%@'?"; "ZSET_DELETE_CONFIRM_MESSAGE" = "Are you sure you want to delete the zset element, value: '%@'? This operation cannot be undone."; @@ -27,31 +32,31 @@ "HASH_DELETE_CONFIRM_TITLE'%@'" = "Delete hash field '%@'?"; "HASH_DELETE_CONFIRM_MESSAGE'%@'" = "Are you sure you want to delete the hash field '%@'? This operation cannot be undone."; -// -------------------------------------------------- redis confirm message end ----------------------------------------------------- +// -------------------------------------------------- redis confirm message end -------------------------------------------------- -// -------------------------------------------------- redis key message start --------------------------------------------------- +// -------------------------------------------------- redis key message start ---------------------------------------------------- "REDIS_KEY_DELETE_CONFIRM_TITLE'%@'" = "Delete key '%@'?"; "REDIS_KEY_DELETE_CONFIRM_MESSAGE'%@'" = "Are you sure you want to delete the key '%@'? This operation cannot be undone."; -// -------------------------------------------------- redis key message end ----------------------------------------------------- +// -------------------------------------------------- redis key message end ------------------------------------------------------ -// ------------------------------------------------ system confirm message start ------------------------------------------------ +// ------------------------------------------------ system confirm message start ------------------------------------------------- "CONFIRM_FAVORITE_REDIS_TITLE'%@'" = "Delete list item '%@'?"; "CONFIRM_FAVORITE_REDIS_MESSAGE'%@'" = "Are you sure you want to delete the item '%@'? This operation cannot be undone."; -// ------------------------------------------------ system confirm message end -------------------------------------------------- +// ------------------------------------------------ system confirm message end --------------------------------------------------- -// ------------------------------------------------ system start ---------------------------------------------------------------- +// ------------------------------------------------ system start ----------------------------------------------------------------- "UNIT_MICROSECOND" = "1 second = 1,000,000 microsecond"; -// ------------------------------------------------ system start ---------------------------------------------------------------- +// ------------------------------------------------ system start ----------------------------------------------------------------- -// ------------------------------------------------ Redis Config Start...-------------------------------------------------------- +// ------------------------------------------------ Redis Config Start...--------------------------------------------------------- "REDIS_CONFIG_REWRITE" = "The CONFIG REWRITE command rewrites the redis.conf file the server was started with, applying the minimal changes needed to make it reflect the configuration currently used by the server, which may be different compared to the original one because of the use of the CONFIG SET command."; -// ------------------------------------------------ Redis Config End...---------------------------------------------------------- +// ------------------------------------------------ Redis Config End...----------------------------------------------------------- -// ------------------------------------------------ Redis Slow Log Start...------------------------------------------------------ +// ------------------------------------------------ Redis Slow Log Start...------------------------------------------------------- "REDIS_SLOW_LOG_ID" = "A unique progressive identifier for every slow log entry, The ID is never reset in the course of the Redis server execution, only a server restart will reset it"; "REDIS_SLOW_LOG_TIMESTAMP" = "The timestamp at which the logged command was processed"; "REDIS_SLOW_LOG_EXEC_TIME" = "The amount of time needed for its execution, in microseconds"; diff --git a/redis-pro/zh-Hans.lproj/Localizable.strings b/redis-pro/zh-Hans.lproj/Localizable.strings index 24656ea..7c859af 100644 --- a/redis-pro/zh-Hans.lproj/Localizable.strings +++ b/redis-pro/zh-Hans.lproj/Localizable.strings @@ -13,7 +13,11 @@ "HELP_REFRESH" = "刷新"; // -------------------------------------------------- redis help message end ----------------------------------------------------- -// -------------------------------------------------- redis confirm message start --------------------------------------------------- +// -------------------------------------------------- redis string message start ------------------------------------------------- +"HELP_STRING_GET_RANGE_LENGTH" = "查询redis string类型数据时最大长度, 用于控制在查询超大字符串时引起的性能问题, -1表过查询整个字符串, 大于-1使用GETRANGE方法查询"; +// -------------------------------------------------- redis string message end --------------------------------------------------- + +// -------------------------------------------------- redis confirm message start ------------------------------------------------ "ZSET_DELETE_CONFIRM_TITLE" = "Delete zset element, value: '%@'?"; "ZSET_DELETE_CONFIRM_MESSAGE" = "Are you sure you want to delete the zset element, value: '%@'? This operation cannot be undone."; @@ -26,10 +30,10 @@ "HASH_DELETE_CONFIRM_TITLE'%@'" = "Delete hash field '%@'?"; "HASH_DELETE_CONFIRM_MESSAGE'%@'" = "Are you sure you want to delete the hash field '%@'? This operation cannot be undone."; -// -------------------------------------------------- redis confirm message end ----------------------------------------------------- +// -------------------------------------------------- redis confirm message end -------------------------------------------------- -// -------------------------------------------------- redis key message start --------------------------------------------------- +// -------------------------------------------------- redis key message start ---------------------------------------------------- "REDIS_KEY_DELETE_CONFIRM_TITLE'%@'" = "Delete key '%@'?"; "REDIS_KEY_DELETE_CONFIRM_MESSAGE'%@'" = "Are you sure you want to delete the key '%@'? This operation cannot be undone.";