GDBManager.m 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953
  1. //
  2. // GDBManager.m
  3. // TUIContact
  4. //
  5. // Created by gan on 2025/3/24.
  6. //
  7. #import <Foundation/Foundation.h>
  8. #import "GDBManager.h"
  9. #import "UDManager.h"
  10. #import "FMDB.h"
  11. #import "config.h"
  12. @interface GDBManager ()
  13. @property (nonatomic, strong) FMDatabase *db;
  14. @property (nonatomic) BOOL isOpen;
  15. @end
  16. @implementation GDBManager
  17. + (GDBManager *_Nonnull)shareInstance{
  18. static id gShareInstance = nil;
  19. static dispatch_once_t onceToken;
  20. dispatch_once(&onceToken, ^{
  21. gShareInstance = [[self alloc] init];
  22. });
  23. return gShareInstance;
  24. }
  25. - (instancetype)init {
  26. if (self = [super init]) {
  27. self.isOpen = false;
  28. }
  29. return self;
  30. }
  31. #pragma mark - Public -
  32. -(void)createDatabase:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  33. // 数据库文件路径,这里使用文档目录下的数据库文件,确保数据持久化
  34. NSString *docsDir;
  35. NSArray *dirPaths;
  36. // 获取文档目录路径
  37. dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  38. docsDir = [dirPaths objectAtIndex:0];
  39. NSString *dbPath = [[docsDir stringByAppendingPathComponent:locateDB] stringByStandardizingPath];
  40. // 创建数据库实例,如果数据库文件不存在,则会自动创建该文件
  41. self.db = [FMDatabase databaseWithPath:dbPath];
  42. if (![self.db open]) {
  43. NSLog(@"数据库打开失败");
  44. if(fail){
  45. fail([NSString stringWithFormat:@"数据库打开失败: %@", [self.db lastErrorMessage]]);
  46. }
  47. } else {
  48. NSLog(@"数据库打开成功");
  49. if(succ){
  50. succ(nil);
  51. }
  52. self.isOpen = true;
  53. }
  54. }
  55. -(void)closeDB{
  56. [self.db close];
  57. self.isOpen = false;
  58. }
  59. -(void)deleteDB{
  60. // 数据库文件路径,这里使用文档目录下的数据库文件,确保数据持久化
  61. [self closeDB];
  62. NSString *docsDir;
  63. NSArray *dirPaths;
  64. // 获取文档目录路径
  65. dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  66. docsDir = [dirPaths objectAtIndex:0];
  67. NSString *dbPath = [[docsDir stringByAppendingPathComponent:locateDB] stringByStandardizingPath];
  68. NSError *error;
  69. NSFileManager *fileManager = [NSFileManager defaultManager];
  70. BOOL success = [fileManager removeItemAtPath:dbPath error:&error];
  71. if (success) {
  72. NSLog(@"文件删除成功");
  73. self.isOpen = false;
  74. } else {
  75. NSLog(@"文件删除失败: %@", error.localizedDescription);
  76. }
  77. }
  78. -(void)replayAllData{
  79. int lowerBound = 10;
  80. int upperBound = 30;
  81. int randomInt = lowerBound + arc4random() % (upperBound - lowerBound + 1);
  82. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  83. for (NSInteger i = 0; i<randomInt; i++) {
  84. [self delLocalmsglistTable:userid];
  85. [self createLocalMSGtable:nil fail:nil];
  86. NSUUID *uid = [NSUUID UUID];
  87. NSDate *now = [NSDate date];
  88. NSTimeInterval trt = [now timeIntervalSince1970];
  89. NSInteger time = trt*1000;
  90. NSString *strtime = [NSString stringWithFormat:@"%ld",(long)time];
  91. NSDictionary *dic =@{
  92. @"id":strtime,
  93. @"messageType":MessageType_image,
  94. @"chatId":[NSString stringWithFormat:@"%d",randomInt],
  95. @"fromId":userid,
  96. @"fromName":userid,
  97. @"fromAvatar":@"Avatar",
  98. @"reSend":[NSNumber numberWithBool:false],
  99. @"content":uid.UUIDString,
  100. @"type":@"0",
  101. @"localtime":strtime,
  102. @"timestamp":strtime,
  103. @"mine":[NSNumber numberWithBool:YES],
  104. @"extend":@{
  105. @"url":uid.UUIDString,
  106. @"time":strtime,
  107. @"localurl":uid.UUIDString,
  108. }
  109. };
  110. [self insertLocalmsg:dic succ:nil fail:nil];
  111. NSLog(@"delLocalmsglistTable:%ld",(long)i);
  112. }
  113. randomInt = lowerBound + arc4random() % (upperBound - lowerBound + 1);
  114. for (NSInteger i = 0; i<randomInt; i++) {
  115. [self delchatlistTable:nil fail:nil];
  116. [self createChattable:nil fail:nil];
  117. NSUUID *uid = [NSUUID UUID];
  118. NSDate *now = [NSDate date];
  119. NSTimeInterval trt = [now timeIntervalSince1970];
  120. NSInteger time = trt*1000;
  121. NSString *strtime = [NSString stringWithFormat:@"%ld",(long)time];
  122. NSDictionary *chatD=@{
  123. @"id":strtime,
  124. @"name":userid,
  125. @"avatar":@"avatar",
  126. @"type":@"0",
  127. @"lastMessage":uid.UUIDString,
  128. @"lastTime":strtime,
  129. @"unreadCount":[NSString stringWithFormat:@"%ld",(long)i],
  130. @"loaded":@"",
  131. @"loading":@"",
  132. @"top":@"true",
  133. };
  134. [self insertLocalchat:chatD succ:nil fail:nil];
  135. NSLog(@"delchatlistTable:%ld",(long)i);
  136. }
  137. randomInt = lowerBound + arc4random() % (upperBound - lowerBound + 1);
  138. for (NSInteger i = 0; i<randomInt; i++) {
  139. [self createLastreadtimetable:nil fail:nil];
  140. [self deleatLastreadtimetable];
  141. NSLog(@"deleatLastreadtimetable:%ld",(long)i);
  142. }
  143. randomInt = lowerBound + arc4random() % (upperBound - lowerBound + 1);
  144. for (NSInteger i = 0; i<randomInt; i++) {
  145. [self deleteDB];
  146. [self createDatabase:nil fail:nil];
  147. NSLog(@"deleteDB:%ld",(long)i);
  148. }
  149. }
  150. //创建消息表
  151. -(void)createLocalMSGtable:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail;{
  152. // 创建表语句
  153. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  154. NSString *sql1=@"create table if not exists lcmsglist_";
  155. NSString *tablejg = @"(id CHAR PRIMARY KEY,chatId CHAR,type CHAR,messageType CHAR,timestamp BIGINT,localtime BIGINT,Message TEXT)";
  156. NSString *sql = [NSString stringWithFormat:@"%@%@ %@",sql1,userid,tablejg];
  157. //NSLog(@"sql:%@",sql);
  158. BOOL success = [self.db executeUpdate:sql];
  159. if (!success) {
  160. NSLog(@"创建消息表失败: %@", [self.db lastErrorMessage]);
  161. if(fail){
  162. fail([NSString stringWithFormat:@"创建消息表失败: %@", [self.db lastErrorMessage]]);
  163. }
  164. } else {
  165. NSLog(@"创建消息表成功");
  166. if (succ) {
  167. succ(nil);
  168. }
  169. }
  170. }
  171. -(void)delLocalmsglistTable:(NSString *)userid{//删除消息表
  172. NSString *sql1=@"DROP TABLE lcmsglist_";
  173. NSString *sql = [NSString stringWithFormat:@"%@%@",sql1,userid];
  174. BOOL success = [self.db executeUpdate:sql];
  175. if (!success) {
  176. NSLog(@"删除消息表失败: %@", [self.db lastErrorMessage]);
  177. } else {
  178. NSLog(@"删除消息表成功");
  179. }
  180. }
  181. -(void)insertLocalmsg:(NSDictionary *_Nonnull)msg succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{//插入消息
  182. NSString *vstr = @"insert into lcmsglist_";
  183. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  184. NSDictionary * safeDict = [self replaceNullsWithEmptyStringInDictionary:msg];
  185. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" ('id','chatId','type','messageType','timestamp','localtime','Message') values ("];
  186. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"id"]];
  187. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"chatId"]];
  188. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"type"]];
  189. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"messageType"]];
  190. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"timestamp"]];
  191. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"localtime"]];
  192. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:msg options:0 error:nil];
  193. NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
  194. vstr=[NSString stringWithFormat:@"%@'%@'%@",vstr,jsonString,@")"];
  195. // NSLog(@"vstr:%@",vstr);
  196. BOOL success = [self.db executeUpdate:vstr];
  197. if (!success) {
  198. if(fail){
  199. fail([NSString stringWithFormat:@"插入消息表失败: %@", [self.db lastErrorMessage]]);
  200. }
  201. NSLog(@"插入消息表失败: %@", [self.db lastErrorMessage]);
  202. } else {
  203. NSLog(@"插入消息表成功");
  204. if (succ) {
  205. succ(nil);
  206. }
  207. }
  208. }
  209. -(void)insertRplaceLocalmsg:(NSDictionary *_Nonnull)msg succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{//插入消息
  210. if (![self.db isOpen]) {
  211. return;
  212. }
  213. // 1. 参数校验
  214. if (!msg || msg.count == 0) {
  215. if (fail) fail(@"消息内容不能为空");
  216. return;
  217. }
  218. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  219. if (userid.length == 0) {
  220. if (fail) fail(@"用户ID获取失败");
  221. return;
  222. }
  223. NSString *tableName = [NSString stringWithFormat:@"lcmsglist_%@", userid];
  224. NSDictionary *safeDict = [self replaceNullsWithEmptyStringInDictionary:msg];
  225. // 2. 处理localtime
  226. NSString *localtime = [NSString stringWithFormat:@"%@", safeDict[@"localtime"]];
  227. // if (localtime.length == 0) {
  228. // localtime = safeDict[@"timestamp"];
  229. // }
  230. // 2. 处理图片文件视频消息可能存在乱序问题
  231. NSString *msgtype = safeDict[@"messageType"];
  232. BOOL urlMark = true;
  233. if([msgtype isEqualToString:MessageType_image]||[msgtype isEqualToString:MessageType_file]||[msgtype isEqualToString:MessageType_video]){
  234. // 文件消息
  235. NSDictionary * extend = [safeDict[@"extend"] isKindOfClass:NSDictionary.class]?safeDict[@"extend"]:@{};
  236. NSString *url=extend[@"url"] ?: @"";
  237. if(url.length==0){
  238. urlMark=false;//不是正式真实消息尝试插入,不能删除已有的信息
  239. }
  240. NSString *fileEER = extend[@"fileError"] ?: @"";
  241. if(fileEER.intValue==1){
  242. urlMark=true;//不是正式真实消息尝试插入,不能删除已有的信息
  243. }
  244. }
  245. // 3. 开启事务
  246. [self.db beginTransaction];
  247. BOOL shouldRollback = NO;
  248. @try {
  249. // NSLog(@"删除旧数据(localtime=%@)", localtime);
  250. NSString *selctSQL = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE localtime = %@ AND (messageType='11' OR messageType='12')",tableName,localtime];
  251. FMResultSet *rs = [self.db executeQuery:selctSQL];
  252. BOOL markesel=NO;
  253. while ([rs next]) {
  254. //NSLog(@"rs:%@",rs);
  255. NSString *msg =[rs stringForColumn:@"Message"];
  256. NSLog(@"--------rsmsg:%@",msg);
  257. markesel=YES;
  258. break;
  259. }
  260. [rs close]; // 关闭结果集
  261. if(markesel){
  262. [self.db commit];
  263. return;
  264. }
  265. if(urlMark){//删除旧数据,以便更新信息
  266. NSLog(@"删除旧数据(2localtime=%@)", localtime);
  267. // 4. 删除相同localtime的旧数据
  268. NSString *deleteSQL = [NSString stringWithFormat:
  269. @"DELETE FROM %@ WHERE localtime = ?",
  270. tableName];
  271. if (![self.db executeUpdate:deleteSQL, localtime]) {
  272. NSLog(@"删除旧数据失败(localtime=%@): %@", localtime, [self.db lastErrorMessage]);
  273. // 不终止,继续尝试插入
  274. }
  275. }
  276. // 5. 准备插入数据
  277. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:safeDict options:0 error:nil];
  278. NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
  279. NSString *insertSQL = [NSString stringWithFormat:
  280. @"INSERT INTO %@ (id,chatId,type,messageType,timestamp,localtime,Message) VALUES (?,?,?,?,?,?,?)",
  281. tableName];
  282. // 6. 执行插入
  283. BOOL success = [self.db executeUpdate:insertSQL,
  284. safeDict[@"id"],
  285. safeDict[@"chatId"],
  286. safeDict[@"type"],
  287. safeDict[@"messageType"],
  288. safeDict[@"timestamp"],
  289. localtime,
  290. jsonString];
  291. if (!success) {
  292. shouldRollback = YES;
  293. NSString *error = [NSString stringWithFormat:@"插入消息失败: %@", [self.db lastErrorMessage]];
  294. if (fail) fail(error);
  295. } else {
  296. [self.db commit];
  297. if (succ) succ(nil);
  298. // NSLog(@"消息插入成功(ID=%@)", safeDict);
  299. }
  300. }
  301. @catch (NSException *exception) {
  302. shouldRollback = YES;
  303. NSString *error = [NSString stringWithFormat:@"操作异常: %@", exception.reason];
  304. if (fail) fail(error);
  305. }
  306. @finally {
  307. if (shouldRollback) {
  308. [self.db rollback];
  309. }
  310. }
  311. }
  312. - (void)batchInsertLocalMessages:(NSArray<NSDictionary *> *)messages
  313. success:(DBSucc _Nullable)succ
  314. failure:(DBFail _Nullable)fail {
  315. if (![self.db isOpen]) {
  316. return;
  317. }
  318. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  319. NSString *tableName = [NSString stringWithFormat:@"lcmsglist_%@", userid];
  320. // 开启事务
  321. [self.db beginTransaction];
  322. NSMutableArray *failedMessages = [NSMutableArray array];
  323. BOOL hasErrors = NO;
  324. @try {
  325. // 准备SQL语句(使用参数化查询,避免SQL注入)
  326. NSString *insertSQL = [NSString stringWithFormat:
  327. @"INSERT INTO %@ ('id','chatId','type','messageType','timestamp','localtime','Message') VALUES (?,?,?,?,?,?,?)",
  328. tableName];
  329. for (NSDictionary *msg in messages) {
  330. NSDictionary *safeDict = [self replaceNullsWithEmptyStringInDictionary:msg];
  331. NSString *localtime = [NSString stringWithFormat:@"%@", safeDict[@"localtime"]];
  332. NSString *selctSQL = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE localtime = %@ AND (messageType='11' OR messageType='12')",tableName,localtime];
  333. FMResultSet *rs = [self.db executeQuery:selctSQL];
  334. BOOL markesel=NO;
  335. while ([rs next]) {
  336. //NSLog(@"rs:%@",rs);
  337. NSString *msg =[rs stringForColumn:@"Message"];
  338. // NSLog(@"--------rsmsg:%@",msg);
  339. markesel=YES;
  340. break;
  341. }
  342. [rs close]; // 关闭结果集
  343. if(markesel){
  344. continue;
  345. }
  346. NSString *deleteSQL = [NSString stringWithFormat:
  347. @"DELETE FROM %@ WHERE localtime = ?",
  348. tableName];
  349. if (![self.db executeUpdate:deleteSQL, localtime]) {
  350. // NSLog(@"batchInsertLocalMessages 删除旧数据失败(localtime=%@): %@", localtime, [self.db lastErrorMessage]);
  351. // 不终止,继续尝试插入
  352. }
  353. else{
  354. // NSLog(@"batchInsertLocalMessages 删除旧数据(localtime=%@): %@", localtime, [self.db lastErrorMessage]);
  355. }
  356. // 准备Message字段的JSON字符串
  357. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:safeDict options:0 error:nil];
  358. NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
  359. // 执行插入(使用参数化查询)
  360. BOOL success = [self.db executeUpdate:insertSQL,
  361. safeDict[@"id"],
  362. safeDict[@"chatId"],
  363. safeDict[@"type"],
  364. safeDict[@"messageType"],
  365. safeDict[@"timestamp"],
  366. safeDict[@"localtime"],
  367. jsonString];
  368. if (!success) {
  369. hasErrors = YES;
  370. // 记录失败的消息
  371. // 继续下一条
  372. continue;
  373. }
  374. }
  375. // 提交事务
  376. [self.db commit];
  377. NSLog(@"批量插入消息完成,成功 %lu 条,失败 %lu 条",
  378. (unsigned long)(messages.count - failedMessages.count),
  379. (unsigned long)failedMessages.count);
  380. if (succ) {
  381. // 如果有失败记录,返回失败信息
  382. if (failedMessages.count > 0) {
  383. succ(@[@{
  384. @"successCount": @(messages.count - failedMessages.count),
  385. @"failedCount": @(failedMessages.count),
  386. @"failedMessages": failedMessages
  387. }]);
  388. } else {
  389. succ(nil);
  390. }
  391. }
  392. }
  393. @catch (NSException *exception) {
  394. [self.db rollback];
  395. NSString *error = [NSString stringWithFormat:@"批量插入本地异常: %@", exception.reason];
  396. if (fail) {
  397. fail(error);
  398. }
  399. NSLog(@"%@", error);
  400. }
  401. }
  402. -(void)selectLocalmsg:(NSString *_Nonnull)chatId page:(NSInteger)page succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{//查询消息
  403. // 查询数据
  404. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  405. NSString *vstr = @"select * from lcmsglist_";
  406. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" where chatId = "];
  407. vstr=[NSString stringWithFormat:@"%@%@",vstr,chatId];
  408. vstr=[NSString stringWithFormat:@"%@ %@",vstr,@"ORDER BY timestamp DESC LIMIT 16;"];
  409. // NSLog(@"vstr:%@",vstr);
  410. FMResultSet *rs = [self.db executeQuery:vstr];
  411. NSMutableArray *array=[[NSMutableArray alloc] init];
  412. while ([rs next]) {
  413. //NSLog(@"rs:%@",rs);
  414. NSString *msg =[rs stringForColumn:@"Message"];
  415. //NSLog(@"msg:%@",msg);
  416. NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
  417. NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
  418. // NSLog(@"%@",jsonDict);
  419. // Message *msgobj = [[Message alloc] init];
  420. // [msgobj setValuesWithDictionary:jsonDict];
  421. [array addObject:jsonDict];
  422. }
  423. [rs close]; // 关闭结果集
  424. if(succ){
  425. succ(array);
  426. }
  427. }
  428. -(void)selectnextmsg:(NSString *_Nonnull)chatId timestp:(NSInteger)timestp succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{//查询消息
  429. // 查询数据
  430. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  431. NSString *vstr = @"select * from lcmsglist_";
  432. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" where chatId = "];
  433. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,chatId,@" AND timestamp < "];
  434. vstr=[NSString stringWithFormat:@"%@%ld",vstr,(long)timestp];
  435. vstr=[NSString stringWithFormat:@"%@ %@",vstr,@"ORDER BY timestamp DESC LIMIT 16;"];
  436. // NSLog(@"vstr:%@",vstr);
  437. FMResultSet *rs = [self.db executeQuery:vstr];
  438. NSMutableArray *array=[[NSMutableArray alloc] init];
  439. while ([rs next]) {
  440. //NSLog(@"rs:%@",rs);
  441. NSString *msg =[rs stringForColumn:@"Message"];
  442. //NSLog(@"msg:%@",msg);
  443. NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
  444. NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
  445. // NSLog(@"%@",jsonDict);
  446. // Message *msgobj = [[Message alloc] init];
  447. // [msgobj setValuesWithDictionary:jsonDict];
  448. [array addObject:jsonDict];
  449. }
  450. [rs close]; // 关闭结果集
  451. if(succ){
  452. succ(array);
  453. }
  454. }
  455. -(void)deleteMyLocalmsg:(NSDictionary *)msg{//删除单个消息 DELETE FROM users WHERE id IN (100, 101);
  456. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  457. NSString *vstr = @"DELETE FROM lcmsglist_";
  458. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" WHERE id=="];
  459. vstr=[NSString stringWithFormat:@"%@%@",vstr,msg[@"localtime"]];
  460. BOOL success = [self.db executeUpdate:vstr];
  461. if (!success) {
  462. NSLog(@"删除消息表失败: %@", [self.db lastErrorMessage]);
  463. } else {
  464. NSLog(@"删除消息表成功");
  465. }
  466. }
  467. -(void)deleteLocalmsg:(NSDictionary *_Nullable)msg{
  468. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  469. NSString *vstr = @"DELETE FROM lcmsglist_";
  470. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" WHERE id=="];
  471. vstr=[NSString stringWithFormat:@"%@%@",vstr,msg[@"id"]];
  472. BOOL success = [self.db executeUpdate:vstr];
  473. if (!success) {
  474. NSLog(@"删除指定消息: %@", [self.db lastErrorMessage]);
  475. } else {
  476. NSLog(@"删除指定消息成功");
  477. }
  478. }
  479. //删除数据指定聊天窗消息
  480. -(void)deletechatLocalmsg:(NSString *_Nullable)chatId{
  481. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  482. // 开启事务
  483. [self.db beginTransaction];
  484. @try {
  485. NSString *updataSQL =[NSString stringWithFormat:@"UPDATE lcmsglist_%@ SET Message=? WHERE chatId = ?",userid];
  486. // 执行插入(使用参数化查询)
  487. NSUUID *uid = [NSUUID UUID];
  488. BOOL success = [self.db executeUpdate:updataSQL,
  489. uid.UUIDString,
  490. chatId];
  491. // 提交事务
  492. [self.db commit];
  493. if (!success) {
  494. NSLog(@"更新数据失败: %@", [self.db lastErrorMessage]);
  495. } else {
  496. NSLog(@"更新数据成功");
  497. }
  498. NSString *vstr = [NSString stringWithFormat:@"DELETE FROM lcmsglist_%@ WHERE chatId=%@",userid,chatId];
  499. success = [self.db executeUpdate:vstr];
  500. if (!success) {
  501. NSLog(@"删除指定消息: %@", [self.db lastErrorMessage]);
  502. } else {
  503. NSLog(@"删除指定消息成功");
  504. }
  505. }
  506. @catch (NSException *exception) {
  507. [self.db rollback];
  508. NSString *error = [NSString stringWithFormat:@"lcUserServer插入本地异常: %@", exception.reason];
  509. NSLog(@"%@", error);
  510. }
  511. }
  512. -(void)selectLocalmsgType:(NSString *)chatId messageType:(NSString *)messageType succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{//按分类查询消息
  513. // 查询数据
  514. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  515. NSString *vstr = @"select * from lcmsglist_";
  516. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" where chatId = "];
  517. vstr=[NSString stringWithFormat:@"%@%@ AND messageType=",vstr,chatId];
  518. vstr=[NSString stringWithFormat:@"%@%@",vstr,messageType];
  519. vstr=[NSString stringWithFormat:@"%@ %@",vstr,@"ORDER BY timestamp DESC LIMIT 16;"];
  520. //NSLog(@"vstr:%@",vstr);
  521. FMResultSet *rs = [self.db executeQuery:vstr];
  522. NSMutableArray *array=[[NSMutableArray alloc] init];
  523. while ([rs next]) {
  524. //NSLog(@"rs:%@",rs);
  525. NSString *msg =[rs stringForColumn:@"Message"];
  526. //NSLog(@"msg:%@",msg);
  527. NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
  528. if (data) {
  529. NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
  530. [array addObject:jsonDict];
  531. }
  532. }
  533. [rs close]; // 关闭结果集
  534. if(succ){
  535. succ(array);
  536. }
  537. }
  538. -(void)selectNextmsgType:(NSString *_Nullable)chatId messageType:(NSString *_Nullable)messageType timestp:(NSInteger)timestp succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  539. // 查询数据
  540. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  541. NSString *vstr = @"select * from lcmsglist_";
  542. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" where chatId = "];
  543. vstr=[NSString stringWithFormat:@"%@%@ AND messageType=",vstr,chatId];
  544. vstr=[NSString stringWithFormat:@"%@%@ AND timestamp < ",vstr,messageType];
  545. vstr=[NSString stringWithFormat:@"%@%ld",vstr,(long)timestp];
  546. vstr=[NSString stringWithFormat:@"%@ %@",vstr,@"ORDER BY timestamp DESC LIMIT 16;"];
  547. NSLog(@"vstr:%@",vstr);
  548. FMResultSet *rs = [self.db executeQuery:vstr];
  549. NSMutableArray *array=[[NSMutableArray alloc] init];
  550. while ([rs next]) {
  551. //NSLog(@"rs:%@",rs);
  552. NSString *msg =[rs stringForColumn:@"Message"];
  553. //NSLog(@"msg:%@",msg);
  554. NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
  555. if (data) {
  556. NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
  557. [array addObject:jsonDict];
  558. }
  559. }
  560. [rs close]; // 关闭结果集
  561. if(succ){
  562. succ(array);
  563. }
  564. }
  565. //根据本地时间查询本地消息
  566. -(void)selectLocalmsgWithLocaltime:(NSString *_Nullable)localtime succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  567. // 查询数据
  568. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  569. NSString *vstr = @"select * from lcmsglist_";
  570. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" where localtime = "];
  571. vstr=[NSString stringWithFormat:@"%@%@",vstr,localtime];;
  572. NSLog(@"vstr:%@",vstr);
  573. FMResultSet *rs = [self.db executeQuery:vstr];
  574. NSMutableArray *array=[[NSMutableArray alloc] init];
  575. while ([rs next]) {
  576. //NSLog(@"rs:%@",rs);
  577. NSString *msg =[rs stringForColumn:@"Message"];
  578. //NSLog(@"msg:%@",msg);
  579. NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
  580. if (data) {
  581. NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
  582. [array addObject:jsonDict];
  583. }
  584. }
  585. [rs close]; // 关闭结果集
  586. if(succ){
  587. succ(array);
  588. }
  589. }
  590. //聊天窗表lcChatlist_
  591. -(void)createChattable:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  592. // 创建表语句
  593. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  594. NSString *sql1=@"create table if not exists lcChatlist_";
  595. NSString *tablejg = @"(id CHAR PRIMARY KEY,name CHAR,avatar CHAR,type CHAR,lastMessage TEXT,lastTime BIGINT,unreadCount int,loaded int,loading int,top int)";
  596. NSString *sql = [NSString stringWithFormat:@"%@%@ %@",sql1,userid,tablejg];
  597. //NSLog(@"sql:%@",sql);
  598. BOOL success = [self.db executeUpdate:sql];
  599. if (!success) {
  600. NSLog(@"创建lcChatlist_表失败: %@", [self.db lastErrorMessage]);
  601. if(fail){
  602. fail([NSString stringWithFormat:@"创建消息表失败: %@", [self.db lastErrorMessage]]);
  603. }
  604. } else {
  605. NSLog(@"创建lcChatlist_表成功");
  606. if (succ) {
  607. succ(nil);
  608. }
  609. }
  610. }
  611. -(void)delchatlistTable:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{//删除聊天窗表lcChatlist_
  612. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  613. NSString *sql1=@"DROP TABLE lcChatlist_";
  614. NSString *sql = [NSString stringWithFormat:@"%@%@",sql1,userid];
  615. BOOL success = [self.db executeUpdate:sql];
  616. if (!success) {
  617. NSLog(@"删除lcChatlist_表失败: %@", [self.db lastErrorMessage]);
  618. if(fail){
  619. fail([NSString stringWithFormat:@"创建消息表失败: %@", [self.db lastErrorMessage]]);
  620. }
  621. } else {
  622. NSLog(@"删除lcChatlist_表成功");
  623. if (succ) {
  624. succ(nil);
  625. }
  626. }
  627. }
  628. -(void)insertLocalchat:(NSDictionary *_Nonnull)msg succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  629. NSString *vstr = @"INSERT OR REPLACE INTO lcChatlist_";
  630. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  631. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" ('id','name','avatar','type','lastMessage','lastTime','unreadCount','loaded','loading','top') values ("];
  632. NSDictionary * safeDict = [self replaceNullsWithEmptyStringInDictionary:msg];
  633. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,safeDict[@"id"]];
  634. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,safeDict[@"name"]];
  635. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,safeDict[@"avatar"]];
  636. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"type"]];
  637. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,safeDict[@"lastMessage"]];
  638. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,safeDict[@"lastTime"]];
  639. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"unreadCount"]];
  640. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,safeDict[@"loaded"]];
  641. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,safeDict[@"loading"]];
  642. vstr=[NSString stringWithFormat:@"%@'%@')",vstr,safeDict[@"top"]];
  643. // NSLog(@"vstr:%@",vstr);
  644. BOOL success = [self.db executeUpdate:vstr];
  645. if (!success) {
  646. if(fail){
  647. fail([NSString stringWithFormat:@"插入消息表失败: %@", [self.db lastErrorMessage]]);
  648. }
  649. //NSLog(@"插入消息表失败: %@", [self.db lastErrorMessage]);
  650. } else {
  651. // NSLog(@"插入消息表成功 insertLocalchat");
  652. if (succ) {
  653. succ(nil);
  654. }
  655. }
  656. }
  657. -(void)selectLocalchats:(NSString *)top succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  658. // 查询数据
  659. NSString *vstr = @"select * from lcChatlist_";
  660. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  661. vstr=[NSString stringWithFormat:@"%@%@",vstr,userid];
  662. vstr=[NSString stringWithFormat:@"%@ %@",vstr,@"where top="];
  663. vstr=[NSString stringWithFormat:@"%@%@",vstr,top];
  664. vstr=[NSString stringWithFormat:@"%@ %@",vstr,@"ORDER BY 'lastTime' ASC"];
  665. NSLog(@"vstr:%@",vstr);
  666. FMResultSet *rs = [self.db executeQuery:vstr];
  667. NSMutableArray *array=[[NSMutableArray alloc] init];
  668. while ([rs next]) {
  669. NSDictionary *chatD=@{
  670. @"id":[rs stringForColumn:@"id"],
  671. @"name":[rs stringForColumn:@"name"],
  672. @"avatar":[rs stringForColumn:@"avatar"],
  673. @"type":[rs stringForColumn:@"type"],
  674. @"lastMessage":[rs stringForColumn:@"lastMessage"],
  675. @"lastTime":[rs stringForColumn:@"lastTime"],
  676. @"unreadCount":[rs stringForColumn:@"unreadCount"],
  677. @"loaded":[rs stringForColumn:@"loaded"],
  678. @"loading":[rs stringForColumn:@"loading"],
  679. @"top":[rs stringForColumn:@"top"]
  680. };
  681. [array addObject:chatD];
  682. }
  683. [rs close]; // 关闭结果集
  684. if(succ){
  685. succ(array);
  686. }
  687. }
  688. - (void)deleteChatListItem:(NSDictionary *_Nonnull)item succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  689. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  690. NSString *vstr = @"DELETE FROM lcChatlist_";
  691. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" WHERE id="];
  692. vstr=[NSString stringWithFormat:@"%@%@",vstr,item[@"id"]];
  693. BOOL success = [self.db executeUpdate:vstr];
  694. if (!success) {
  695. NSLog(@"删除消息表失败: %@", [self.db lastErrorMessage]);
  696. if(fail){
  697. fail([NSString stringWithFormat:@"删除消息表失败: %@", [self.db lastErrorMessage]]);
  698. }
  699. } else {
  700. int changes = [self.db changes];
  701. if (changes > 0) {
  702. NSLog(@"成功删除 %d 条记录", changes);
  703. if (succ) {
  704. succ(nil);
  705. }
  706. } else {
  707. NSLog(@"没有匹配的记录被删除");
  708. }
  709. }
  710. }
  711. //聊天窗最后已读时间表
  712. -(void)createLastreadtimetable:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  713. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  714. NSString *sql1=@"create table if not exists lcChatlasttime_";
  715. NSString *tablejg = @"(chatId CHAR PRIMARY KEY,userId CHAR,timestamp BIGINT,type CHAR)";
  716. NSString *sql = [NSString stringWithFormat:@"%@%@ %@",sql1,userid,tablejg];
  717. //NSLog(@"sql:%@",sql);
  718. BOOL success = [self.db executeUpdate:sql];
  719. if (!success) {
  720. NSLog(@"创建lcChatlasttime_表失败: %@", [self.db lastErrorMessage]);
  721. if(fail){
  722. fail([NSString stringWithFormat:@"创建消息表失败: %@", [self.db lastErrorMessage]]);
  723. }
  724. } else {
  725. NSLog(@"创建lcChatlasttime_表成功");
  726. if (succ) {
  727. succ(nil);
  728. }
  729. }
  730. }
  731. -(void)deleatLastreadtimetable{
  732. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  733. NSString *sql1=@"DROP TABLE lcChatlasttime_";
  734. NSString *sql = [NSString stringWithFormat:@"%@%@",sql1,userid];
  735. BOOL success = [self.db executeUpdate:sql];
  736. if (!success) {
  737. NSLog(@"删除lcChatlasttime_表失败: %@", [self.db lastErrorMessage]);
  738. } else {
  739. NSLog(@"删除lcChatlasttime_表成功");
  740. }
  741. }
  742. -(void)insertLastreadtime:(NSDictionary *_Nonnull)msg succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  743. NSString *vstr = @"INSERT OR REPLACE INTO lcChatlasttime_";
  744. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  745. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" ('chatId','userId','timestamp','type') values ("];
  746. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,msg[@"chatId"]];
  747. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,msg[@"userId"]];
  748. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,msg[@"timestamp"]];
  749. vstr=[NSString stringWithFormat:@"%@'%@')",vstr,msg[@"type"]];
  750. NSLog(@"vstr:%@",vstr);
  751. BOOL success = [self.db executeUpdate:vstr];
  752. if (!success) {
  753. if(fail){
  754. fail([NSString stringWithFormat:@"插入Lastreadtime表失败: %@", [self.db lastErrorMessage]]);
  755. }
  756. NSLog(@"插入消息表失败: %@", [self.db lastErrorMessage]);
  757. } else {
  758. NSLog(@"插入Lastreadtime表成功 insertLocalchat");
  759. if (succ) {
  760. succ(nil);
  761. }
  762. }
  763. }
  764. -(void)selectchatLastreadtime:(NSString *_Nonnull)chatId succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  765. // 查询数据
  766. NSString *vstr = @"select * from lcChatlasttime_";
  767. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  768. vstr=[NSString stringWithFormat:@"%@%@",vstr,userid];
  769. vstr=[NSString stringWithFormat:@"%@ %@%@",vstr,@"where userId=",chatId];
  770. NSLog(@"vstr:%@",vstr);
  771. FMResultSet *rs = [self.db executeQuery:vstr];
  772. NSMutableArray *array=[[NSMutableArray alloc] init];
  773. while ([rs next]) {
  774. NSDictionary *chatD=@{
  775. @"chatId":[rs stringForColumn:@"chatId"],
  776. @"userId":[rs stringForColumn:@"userId"],
  777. @"timestamp":[rs stringForColumn:@"timestamp"],
  778. @"type":[rs stringForColumn:@"type"]
  779. };
  780. [array addObject:chatD];
  781. }
  782. [rs close]; // 关闭结果集
  783. if(succ){
  784. succ(array);
  785. }
  786. }
  787. // 递归替换字典中的 NSNull 为 @""
  788. - (NSDictionary *)replaceNullsWithEmptyStringInDictionary:(NSDictionary *)dictionary {
  789. NSMutableDictionary *mutableDict = [NSMutableDictionary dictionaryWithDictionary:dictionary];
  790. for (id key in [mutableDict allKeys]) {
  791. id value = [mutableDict objectForKey:key];
  792. if ([value isKindOfClass:[NSNull class]]) {
  793. [mutableDict setObject:@"" forKey:key];
  794. } else if ([value isKindOfClass:[NSDictionary class]]) {
  795. // 递归处理子字典
  796. [mutableDict setObject:[self replaceNullsWithEmptyStringInDictionary:value] forKey:key];
  797. } else if ([value isKindOfClass:[NSArray class]]) {
  798. // 递归处理数组
  799. [mutableDict setObject:[self replaceNullsWithEmptyStringInArray:value] forKey:key];
  800. }
  801. }
  802. return [NSDictionary dictionaryWithDictionary:mutableDict];
  803. }
  804. // 递归替换数组中的 NSNull 为 @""
  805. - (NSArray *)replaceNullsWithEmptyStringInArray:(NSArray *)array {
  806. NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:array];
  807. for (NSInteger i = 0; i < [mutableArray count]; i++) {
  808. id value = [mutableArray objectAtIndex:i];
  809. if ([value isKindOfClass:[NSNull class]]) {
  810. [mutableArray replaceObjectAtIndex:i withObject:@""];
  811. } else if ([value isKindOfClass:[NSDictionary class]]) {
  812. // 递归处理子字典
  813. [mutableArray replaceObjectAtIndex:i withObject:[self replaceNullsWithEmptyStringInDictionary:value]];
  814. } else if ([value isKindOfClass:[NSArray class]]) {
  815. // 递归处理子数组
  816. [mutableArray replaceObjectAtIndex:i withObject:[self replaceNullsWithEmptyStringInArray:value]];
  817. }
  818. }
  819. return [NSArray arrayWithArray:mutableArray];
  820. }
  821. @end