BGDB.m 87 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204
  1. //
  2. // BGDB.m
  3. // BGFMDB
  4. //
  5. // Created by biao on 2017/10/18.
  6. // Copyright © 2017年 Biao. All rights reserved.
  7. //
  8. #import "BGDB.h"
  9. #import "BGTool.h"
  10. #import "NSCache+BGCache.h"
  11. /**
  12. 默认数据库名称
  13. */
  14. #define SQLITE_NAME @"BGFMDB.db"
  15. #define bg_debug(param) do{\
  16. if(self.debug){bg_log(@"调试输出: %@",param);}\
  17. }while(0)
  18. #define MaxQueryPageNum 50
  19. #define CachePath(name) [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:name]
  20. static const void * const BGFMDBDispatchQueueSpecificKey = &BGFMDBDispatchQueueSpecificKey;
  21. @interface BGDB()
  22. /**
  23. 数据库队列
  24. */
  25. @property (nonatomic, strong) FMDatabaseQueue *queue;
  26. @property (nonatomic, strong) FMDatabase* db;
  27. @property (nonatomic, assign) BOOL inTransaction;
  28. /**
  29. 多线程池
  30. */
  31. @property(nonatomic,strong)NSMutableArray* _Nullable mulThreadPool;
  32. @property(nonatomic,strong)dispatch_queue_t mulThreadPoolQueue;
  33. /**
  34. 线程池执行状态标识
  35. */
  36. @property(nonatomic,assign)BOOL threadPoolFlag;
  37. /**
  38. 递归锁.
  39. */
  40. //@property (nonatomic, strong) NSRecursiveLock *threadLock;
  41. /**
  42. 记录注册监听数据变化的block.
  43. */
  44. @property (nonatomic,strong) NSMutableDictionary* changeBlocks;
  45. /**
  46. 存放当队列处于忙时的事务block
  47. */
  48. @property (nonatomic,strong) NSMutableArray* transactionBlocks;
  49. @end
  50. static BGDB* BGdb = nil;
  51. @implementation BGDB
  52. -(void)dealloc{
  53. //烧毁数据.
  54. [self destroy];
  55. }
  56. -(void)destroy{
  57. if (self.changeBlocks){
  58. [self.changeBlocks removeAllObjects];//清除所有注册列表.
  59. _changeBlocks = nil;
  60. }
  61. if (_semaphore) {
  62. _semaphore = 0x00;
  63. }
  64. [self closeDB];
  65. if (BGdb) {
  66. BGdb = nil;
  67. }
  68. }
  69. -(NSMutableArray *)mulThreadPool{
  70. if (_mulThreadPool == nil) {
  71. _mulThreadPool = [NSMutableArray array];
  72. }
  73. return _mulThreadPool;
  74. }
  75. -(dispatch_queue_t)mulThreadPoolQueue{
  76. if (_mulThreadPoolQueue == nil) {
  77. _mulThreadPoolQueue = dispatch_queue_create("BGFMDB.excuteThreadPool", DISPATCH_QUEUE_SERIAL);
  78. }
  79. return _mulThreadPoolQueue;
  80. }
  81. /**
  82. 关闭数据库.
  83. */
  84. -(void)closeDB{
  85. if(_disableCloseDB)return;//不关闭数据库
  86. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  87. if(!_inTransaction && _queue) {//没有事务的情况下就关闭数据库.
  88. [_queue close];//关闭数据库.
  89. _queue = nil;
  90. }
  91. dispatch_semaphore_signal(self.semaphore);
  92. }
  93. /**
  94. 删除数据库文件.
  95. */
  96. +(BOOL)deleteSqlite:(NSString*)sqliteName{
  97. NSString* filePath = CachePath(([NSString stringWithFormat:@"%@.db",sqliteName]));
  98. NSFileManager * file_manager = [NSFileManager defaultManager];
  99. NSError* error;
  100. if ([file_manager fileExistsAtPath:filePath]) {
  101. [file_manager removeItemAtPath:filePath error:&error];
  102. }
  103. return error==nil;
  104. }
  105. -(instancetype)init{
  106. self = [super init];
  107. if (self) {
  108. //创建递归锁.
  109. //self.threadLock = [[NSRecursiveLock alloc] init];
  110. //创建信号量.
  111. self.semaphore = dispatch_semaphore_create(1);
  112. }
  113. return self;
  114. }
  115. -(FMDatabaseQueue *)queue{
  116. if(_queue)return _queue;
  117. //获得沙盒中的数据库文件名
  118. NSString* name;
  119. if(_sqliteName) {
  120. name = [NSString stringWithFormat:@"%@.db",_sqliteName];
  121. }else{
  122. name = SQLITE_NAME;
  123. }
  124. NSString *filename = CachePath(name);
  125. //HLog(@"数据库路径 = %@",filename);
  126. _queue = [FMDatabaseQueue databaseQueueWithPath:filename];
  127. return _queue;
  128. }
  129. -(NSMutableDictionary *)changeBlocks{
  130. if (_changeBlocks == nil) {
  131. @synchronized(self){
  132. if(_changeBlocks == nil){
  133. _changeBlocks = [NSMutableDictionary dictionary];
  134. }
  135. }
  136. }
  137. return _changeBlocks;
  138. }
  139. -(NSMutableArray *)transactionBlocks{
  140. if (_transactionBlocks == nil){
  141. @synchronized(self){
  142. if(_transactionBlocks == nil){
  143. _transactionBlocks = [NSMutableArray array];
  144. }
  145. }
  146. }
  147. return _transactionBlocks;
  148. }
  149. /**
  150. 获取单例函数.
  151. */
  152. +(_Nonnull instancetype)shareManager{
  153. static dispatch_once_t onceToken;
  154. dispatch_once(&onceToken, ^{
  155. BGdb = [[BGDB alloc] init];
  156. });
  157. return BGdb;
  158. }
  159. /**
  160. 添加操作到线程池
  161. */
  162. -(void)addToThreadPool:(void (^_Nonnull)())block{
  163. NSAssert(block, @"block is nil!");
  164. if(!self.mulThreadPoolQueue || !self.mulThreadPool || !block){
  165. HLog(@"\n\n\n\n\n\n\n addToThreadPool error");
  166. [cachesFileManager writeLogsWithMsg:@"addToThreadPool error"];
  167. //return;
  168. }
  169. dispatch_async(self.mulThreadPoolQueue, ^{
  170. NSString* key = [NSString stringWithFormat:@"b_%@_%@",@([[NSDate new] timeIntervalSince1970]),@(random())];
  171. NSDictionary* dict = @{key:block};
  172. [self.mulThreadPool addObject:dict];
  173. [self excuteThreadPool];
  174. });
  175. }
  176. /**
  177. 执行线程池操作
  178. */
  179. -(void)excuteThreadPool{
  180. if (!_threadPoolFlag) {
  181. _threadPoolFlag = YES;
  182. do{
  183. if(self.mulThreadPool.count>0){
  184. NSDictionary* dict = self.mulThreadPool.firstObject;
  185. NSString* key = [dict.allKeys firstObject];
  186. void(^block)(void) = dict[key];
  187. if(block){
  188. block();
  189. }
  190. if(self.mulThreadPool.count>0){//hxd add 20240305 推测线程没保护好
  191. [self.mulThreadPool removeObjectAtIndex:0];//移除任务
  192. }
  193. }
  194. }while(self.mulThreadPool.count>0);
  195. _threadPoolFlag = NO;
  196. }
  197. }
  198. //事务操作
  199. -(void)inTransaction:(BOOL (^_Nonnull)())block{
  200. NSAssert(block, @"block is nil!");
  201. if([NSThread currentThread].isMainThread){//主线程直接执行
  202. [self executeTransation:block];
  203. }else{//子线程则延迟执行
  204. [self.transactionBlocks addObject:block];
  205. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.2*NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  206. [self executeTransationBlocks];
  207. });
  208. }
  209. }
  210. /*
  211. 执行事务操作
  212. */
  213. -(void)executeTransation:(BOOL (^_Nonnull)())block{
  214. [self executeDB:^(FMDatabase * _Nonnull db) {
  215. _inTransaction = db.isInTransaction;
  216. if (!_inTransaction) {
  217. _inTransaction = [db beginTransaction];
  218. }
  219. BOOL isCommit = NO;
  220. isCommit = block();
  221. if (_inTransaction){
  222. if (isCommit) {
  223. [db commit];
  224. }else {
  225. [db rollback];
  226. }
  227. _inTransaction = NO;
  228. }
  229. }];
  230. }
  231. -(void)executeTransationBlocks{
  232. //[self.threadLock lock];
  233. @synchronized(self){
  234. if(_inTransaction || _queue){
  235. if(self.transactionBlocks.count) {
  236. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.2*NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  237. [self executeTransationBlocks];
  238. });
  239. }
  240. return;
  241. }
  242. while(self.transactionBlocks.count) {
  243. BOOL (^block)() = [self.transactionBlocks lastObject];
  244. [self executeTransation:block];
  245. [self.transactionBlocks removeLastObject];
  246. }
  247. }
  248. //[self.threadLock unlock];
  249. }
  250. /**
  251. 为了对象层的事物操作而封装的函数.
  252. */
  253. -(void)executeDB:(void (^_Nonnull)(FMDatabase *_Nonnull db))block{
  254. NSAssert(block, @"block is nil!");
  255. if (_db){//为了事务操作防止死锁而设置.
  256. block(_db);
  257. return;
  258. }
  259. __weak typeof(self) weakSelf = self;
  260. [self.queue inDatabase:^(FMDatabase *db){
  261. __strong typeof(weakSelf) strongSelf = weakSelf;
  262. strongSelf.db = db;
  263. block(db);
  264. strongSelf.db = nil;
  265. }];
  266. }
  267. /**
  268. 注册数据变化监听.
  269. */
  270. -(BOOL)registerChangeWithName:(NSString* const _Nonnull)name block:(bg_changeBlock)block{
  271. if ([self.changeBlocks.allKeys containsObject:name]){
  272. NSString* reason = [NSString stringWithFormat:@"%@表注册监听重复,注册监听失败!",name];
  273. bg_debug(reason);
  274. return NO;
  275. }else{
  276. [self.changeBlocks setObject:block forKey:name];
  277. return YES;
  278. }
  279. }
  280. /**
  281. 移除数据变化监听.
  282. */
  283. -(BOOL)removeChangeWithName:(NSString* const _Nonnull)name{
  284. if ([self.changeBlocks.allKeys containsObject:name]){
  285. [self.changeBlocks removeObjectForKey:name];
  286. return YES;
  287. }else{
  288. NSString* reason = [NSString stringWithFormat:@"%@表还没有注册监听,移除监听失败!",name];
  289. bg_debug(reason);
  290. return NO;
  291. }
  292. }
  293. -(void)doChangeWithName:(NSString* const _Nonnull)name flag:(BOOL)flag state:(bg_changeState)state{
  294. if(flag && self.changeBlocks.count>0){
  295. //开一个子线程去执行block,防止死锁.
  296. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0), ^{
  297. [self.changeBlocks enumerateKeysAndObjectsUsingBlock:^(NSString* _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop){
  298. NSString* tablename = [key componentsSeparatedByString:@"*"].firstObject;
  299. if([name isEqualToString:tablename]){
  300. void(^block)(bg_changeState) = obj;
  301. //返回主线程回调.
  302. dispatch_sync(dispatch_get_main_queue(), ^{
  303. block(state);
  304. });
  305. }
  306. }];
  307. });
  308. }
  309. }
  310. /**
  311. 数据库中是否存在表.
  312. */
  313. -(void)isExistWithTableName:(NSString* _Nonnull)name complete:(bg_complete_B)complete{
  314. NSAssert(name,@"表名不能为空!");
  315. __block BOOL result;
  316. [self executeDB:^(FMDatabase * _Nonnull db) {
  317. result = [db tableExists:name];
  318. }];
  319. bg_completeBlock(result);
  320. }
  321. /**
  322. 对用户暴露的
  323. */
  324. -(BOOL)bg_isExistWithTableName:( NSString* _Nonnull)name{
  325. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  326. NSAssert(name,@"表名不能为空!");
  327. __block BOOL result;
  328. [self executeDB:^(FMDatabase * _Nonnull db) {
  329. result = [db tableExists:name];
  330. }];
  331. dispatch_semaphore_signal(self.semaphore);
  332. return result;
  333. }
  334. /**
  335. 创建表(如果存在则不创建).
  336. */
  337. -(void)createTableWithTableName:(NSString* _Nonnull)name keys:(NSArray<NSString*>* _Nonnull)keys unionPrimaryKeys:(NSArray* _Nullable)unionPrimaryKeys uniqueKeys:(NSArray* _Nullable)uniqueKeys complete:(bg_complete_B)complete{
  338. NSAssert(name,@"表名不能为空!");
  339. NSAssert(keys,@"字段数组不能为空!");
  340. //创表
  341. __block BOOL result;
  342. [self executeDB:^(FMDatabase * _Nonnull db) {
  343. NSString* header = [NSString stringWithFormat:@"create table if not exists %@ (",name];
  344. NSMutableString* sql = [[NSMutableString alloc] init];
  345. [sql appendString:header];
  346. NSInteger uniqueKeyFlag = uniqueKeys.count;
  347. NSMutableArray* tempUniqueKeys = [NSMutableArray arrayWithArray:uniqueKeys];
  348. for(int i=0;i<keys.count;i++){
  349. NSString* key = [keys[i] componentsSeparatedByString:@"*"][0];
  350. if(tempUniqueKeys.count && [tempUniqueKeys containsObject:key]){
  351. for(NSString* uniqueKey in tempUniqueKeys){
  352. if([BGTool isUniqueKey:uniqueKey with:keys[i]]){
  353. [sql appendFormat:@"%@ unique",[BGTool keyAndType:keys[i]]];
  354. [tempUniqueKeys removeObject:uniqueKey];
  355. uniqueKeyFlag--;
  356. break;
  357. }
  358. }
  359. }else{
  360. if ([key isEqualToString:bg_primaryKey] && !unionPrimaryKeys.count){
  361. [sql appendFormat:@"%@ primary key autoincrement",[BGTool keyAndType:keys[i]]];
  362. }else{
  363. [sql appendString:[BGTool keyAndType:keys[i]]];
  364. }
  365. }
  366. if (i == (keys.count-1)) {
  367. if(unionPrimaryKeys.count){
  368. [sql appendString:@",primary key ("];
  369. [unionPrimaryKeys enumerateObjectsUsingBlock:^(id _Nonnull unionKey, NSUInteger idx, BOOL * _Nonnull stop) {
  370. if(idx == 0){
  371. [sql appendString:bg_sqlKey(unionKey)];
  372. }else{
  373. [sql appendFormat:@",%@",bg_sqlKey(unionKey)];
  374. }
  375. }];
  376. [sql appendString:@")"];
  377. }
  378. [sql appendString:@");"];
  379. }else{
  380. [sql appendString:@","];
  381. }
  382. }//for over
  383. if(uniqueKeys.count){
  384. NSAssert(!uniqueKeyFlag,@"没有找到设置的'唯一约束',请检查模型类.m文件的bg_uniqueKeys函数返回值是否正确!");
  385. }
  386. bg_debug(sql);
  387. result = [db executeUpdate:sql];
  388. }];
  389. bg_completeBlock(result);
  390. }
  391. -(NSInteger)getKeyMaxForTable:(NSString*)name key:(NSString*)key db:(FMDatabase*)db{
  392. __block NSInteger num = 0;
  393. [db executeStatements:[NSString stringWithFormat:@"select max(%@) from %@",key,name] withResultBlock:^int(NSDictionary *resultsDictionary){
  394. id dbResult = [resultsDictionary.allValues lastObject];
  395. if(dbResult && ![dbResult isKindOfClass:[NSNull class]]) {
  396. num = [dbResult integerValue];
  397. }
  398. return 0;
  399. }];
  400. return num;
  401. }
  402. /**
  403. 插入数据.
  404. */
  405. -(void)insertIntoTableName:(NSString* _Nonnull)name Dict:(NSDictionary* _Nonnull)dict complete:(bg_complete_B)complete{
  406. NSAssert(name,@"表名不能为空!");
  407. NSAssert(dict,@"插入值字典不能为空!");
  408. __block BOOL result;
  409. [self executeDB:^(FMDatabase * _Nonnull db) {
  410. NSArray* keys = dict.allKeys;
  411. if([keys containsObject:bg_sqlKey(bg_primaryKey)]){
  412. NSInteger num = [self getKeyMaxForTable:name key:bg_sqlKey(bg_primaryKey) db:db];
  413. [dict setValue:@(num+1) forKey:bg_sqlKey(bg_primaryKey)];
  414. }
  415. NSArray* values = dict.allValues;
  416. NSMutableString* SQL = [[NSMutableString alloc] init];
  417. [SQL appendFormat:@"insert into %@(",name];
  418. for(int i=0;i<keys.count;i++){
  419. [SQL appendFormat:@"%@",keys[i]];
  420. if(i == (keys.count-1)){
  421. [SQL appendString:@") "];
  422. }else{
  423. [SQL appendString:@","];
  424. }
  425. }
  426. [SQL appendString:@"values("];
  427. for(int i=0;i<values.count;i++){
  428. [SQL appendString:@"?"];
  429. if(i == (keys.count-1)){
  430. [SQL appendString:@");"];
  431. }else{
  432. [SQL appendString:@","];
  433. }
  434. }
  435. bg_debug(SQL);
  436. result = [db executeUpdate:SQL withArgumentsInArray:values];
  437. }];
  438. //数据监听执行函数
  439. [self doChangeWithName:name flag:result state:bg_insert];
  440. bg_completeBlock(result);
  441. }
  442. /**
  443. 批量插入
  444. */
  445. -(void)insertIntoTableName:(NSString* _Nonnull)name DictArray:(NSArray<NSDictionary*>* _Nonnull)dictArray complete:(bg_complete_B)complete{
  446. NSAssert(name,@"表名不能为空!");
  447. __block BOOL result;
  448. [self executeDB:^(FMDatabase * _Nonnull db) {
  449. [db beginTransaction];
  450. __block NSInteger counter = 0;
  451. [dictArray enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull dict, NSUInteger idx, BOOL * _Nonnull stop) {
  452. @autoreleasepool {
  453. NSArray* keys = dict.allKeys;
  454. NSArray* values = dict.allValues;
  455. NSMutableString* SQL = [[NSMutableString alloc] init];
  456. [SQL appendFormat:@"insert into %@(",name];
  457. for(int i=0;i<keys.count;i++){
  458. [SQL appendFormat:@"%@",keys[i]];
  459. if(i == (keys.count-1)){
  460. [SQL appendString:@") "];
  461. }else{
  462. [SQL appendString:@","];
  463. }
  464. }
  465. [SQL appendString:@"values("];
  466. for(int i=0;i<values.count;i++){
  467. [SQL appendString:@"?"];
  468. if(i == (keys.count-1)){
  469. [SQL appendString:@");"];
  470. }else{
  471. [SQL appendString:@","];
  472. }
  473. }
  474. bg_debug(SQL);
  475. BOOL flag = [db executeUpdate:SQL withArgumentsInArray:values];
  476. if(flag){
  477. counter++;
  478. }else{
  479. *stop=YES;
  480. }
  481. }
  482. }];
  483. if(dictArray.count == counter){
  484. result = YES;
  485. [db commit];
  486. }else{
  487. result = NO;
  488. [db rollback];
  489. }
  490. }];
  491. //数据监听执行函数
  492. [self doChangeWithName:name flag:result state:bg_insert];
  493. bg_completeBlock(result);
  494. }
  495. /**
  496. 批量更新
  497. over
  498. */
  499. -(void)updateSetTableName:(NSString* _Nonnull)name class:(__unsafe_unretained _Nonnull Class)cla DictArray:(NSArray<NSDictionary*>* _Nonnull)dictArray complete:(bg_complete_B)complete{
  500. __block BOOL result;
  501. [self executeDB:^(FMDatabase * _Nonnull db) {
  502. [db beginTransaction];
  503. __block NSInteger counter = 0;
  504. [dictArray enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull dict, NSUInteger idx, BOOL * _Nonnull stop) {
  505. @autoreleasepool {
  506. NSArray* uniqueKeys = [BGTool executeSelector:bg_uniqueKeysSelector forClass:cla];
  507. NSMutableDictionary* tempDict = [[NSMutableDictionary alloc] initWithDictionary:dict];
  508. NSMutableString* where = [NSMutableString new];
  509. if(uniqueKeys.count > 1){
  510. [where appendString:@" where"];
  511. [uniqueKeys enumerateObjectsUsingBlock:^(NSString* _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop){
  512. NSString* uniqueKey = bg_sqlKey(obj);
  513. id uniqueKeyVlaue = tempDict[uniqueKey];
  514. if(idx < (uniqueKeys.count-1)){
  515. [where appendFormat:@" %@=%@ or",uniqueKey,bg_sqlValue(uniqueKeyVlaue)];
  516. }else{
  517. [where appendFormat:@" %@=%@",uniqueKey,bg_sqlValue(uniqueKeyVlaue)];
  518. }
  519. [tempDict removeObjectForKey:uniqueKey];
  520. }];
  521. }else if(uniqueKeys.count == 1){
  522. NSString* uniqueKey = bg_sqlKey([uniqueKeys firstObject]);
  523. id uniqueKeyVlaue = tempDict[uniqueKey];
  524. [where appendFormat:@" where %@=%@",uniqueKey,bg_sqlValue(uniqueKeyVlaue)];
  525. [tempDict removeObjectForKey:uniqueKey];
  526. }else if([dict.allKeys containsObject:bg_sqlKey(bg_primaryKey)]){
  527. NSString* primaryKey = bg_sqlKey(bg_primaryKey);
  528. id primaryKeyVlaue = tempDict[primaryKey];
  529. [where appendFormat:@" where %@=%@",primaryKey,bg_sqlValue(primaryKeyVlaue)];
  530. [tempDict removeObjectForKey:primaryKey];
  531. }else;
  532. NSMutableArray* arguments = [NSMutableArray array];
  533. NSMutableString* SQL = [[NSMutableString alloc] init];
  534. [SQL appendFormat:@"update %@ set ",name];
  535. [tempDict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
  536. [SQL appendFormat:@"%@=?,",key];
  537. [arguments addObject:obj];
  538. }];
  539. SQL = [NSMutableString stringWithString:[SQL substringToIndex:SQL.length-1]];
  540. if(where.length) {
  541. [SQL appendString:where];
  542. }
  543. bg_debug(SQL);
  544. BOOL flag = [db executeUpdate:SQL withArgumentsInArray:arguments];
  545. if(flag){
  546. counter++;
  547. }
  548. }
  549. }];
  550. if (dictArray.count == counter){
  551. result = YES;
  552. [db commit];
  553. }else{
  554. result = NO;
  555. [db rollback];
  556. }
  557. }];
  558. //数据监听执行函数
  559. [self doChangeWithName:name flag:result state:bg_update];
  560. bg_completeBlock(result);
  561. }
  562. /**
  563. 批量插入或更新.
  564. */
  565. -(void)bg_saveOrUpdateWithTableName:(NSString* _Nonnull)tablename class:(__unsafe_unretained _Nonnull Class)cla DictArray:(NSArray<NSDictionary*>* _Nonnull)dictArray complete:(bg_complete_B)complete{
  566. __block BOOL result;
  567. [self executeDB:^(FMDatabase * _Nonnull db) {
  568. [db beginTransaction];
  569. __block NSInteger counter = 0;
  570. [dictArray enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull dict, NSUInteger idx, BOOL * _Nonnull stop) {
  571. @autoreleasepool {
  572. NSString* bg_id = bg_sqlKey(bg_primaryKey);
  573. //获得"唯一约束"
  574. NSArray* uniqueKeys = [BGTool executeSelector:bg_uniqueKeysSelector forClass:cla];
  575. //获得"联合主键"
  576. NSArray* unionPrimaryKeys =[BGTool executeSelector:bg_unionPrimaryKeysSelector forClass:cla];
  577. NSMutableDictionary* tempDict = [[NSMutableDictionary alloc] initWithDictionary:dict];
  578. NSMutableString* where = [NSMutableString new];
  579. BOOL isSave = NO;//是否存储还是更新.
  580. if(uniqueKeys.count || unionPrimaryKeys.count){
  581. NSArray* tempKeys;
  582. NSString* orAnd;
  583. if(unionPrimaryKeys.count){
  584. tempKeys = unionPrimaryKeys;
  585. orAnd = @"and";
  586. }else{
  587. tempKeys = uniqueKeys;
  588. orAnd = @"or";
  589. }
  590. if(tempKeys.count == 1){
  591. NSString* tempkey = bg_sqlKey([tempKeys firstObject]);
  592. id tempkeyVlaue = tempDict[tempkey];
  593. [where appendFormat:@" where %@=%@",tempkey,bg_sqlValue(tempkeyVlaue)];
  594. }else{
  595. [where appendString:@" where"];
  596. [tempKeys enumerateObjectsUsingBlock:^(NSString* _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop){
  597. NSString* tempkey = bg_sqlKey(obj);
  598. id tempkeyVlaue = tempDict[tempkey];
  599. if(idx < (tempKeys.count-1)){
  600. [where appendFormat:@" %@=%@ %@",tempkey,bg_sqlValue(tempkeyVlaue),orAnd];
  601. }else{
  602. [where appendFormat:@" %@=%@",tempkey,bg_sqlValue(tempkeyVlaue)];
  603. }
  604. }];
  605. }
  606. NSString* dataCountSql = [NSString stringWithFormat:@"select count(*) from %@%@",tablename,where];
  607. __block NSInteger dataCount = 0;
  608. [db executeStatements:dataCountSql withResultBlock:^int(NSDictionary *resultsDictionary) {
  609. dataCount = [[resultsDictionary.allValues lastObject] integerValue];
  610. return 0;
  611. }];
  612. bg_debug(dataCountSql);
  613. if(dataCount){
  614. //更新操作
  615. [tempKeys enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  616. [tempDict removeObjectForKey:bg_sqlKey(obj)];
  617. }];
  618. }else{
  619. //插入操作
  620. isSave = YES;
  621. }
  622. }else{
  623. if([tempDict.allKeys containsObject:bg_id]){
  624. //更新操作
  625. id primaryKeyVlaue = tempDict[bg_id];
  626. [where appendFormat:@" where %@=%@",bg_id,bg_sqlValue(primaryKeyVlaue)];
  627. }else{
  628. //插入操作
  629. isSave = YES;
  630. }
  631. }
  632. NSMutableString* SQL = [[NSMutableString alloc] init];
  633. NSMutableArray* arguments = [NSMutableArray array];
  634. if(isSave){//存储操作
  635. NSInteger num = [self getKeyMaxForTable:tablename key:bg_id db:db];
  636. [tempDict setValue:@(num+1) forKey:bg_id];
  637. [SQL appendFormat:@"insert into %@(",tablename];
  638. NSArray* keys = tempDict.allKeys;
  639. NSArray* values = tempDict.allValues;
  640. for(int i=0;i<keys.count;i++){
  641. [SQL appendFormat:@"%@",keys[i]];
  642. if(i == (keys.count-1)){
  643. [SQL appendString:@") "];
  644. }else{
  645. [SQL appendString:@","];
  646. }
  647. }
  648. [SQL appendString:@"values("];
  649. for(int i=0;i<values.count;i++){
  650. [SQL appendString:@"?"];
  651. if(i == (keys.count-1)){
  652. [SQL appendString:@");"];
  653. }else{
  654. [SQL appendString:@","];
  655. }
  656. [arguments addObject:values[i]];
  657. }
  658. }else{//更新操作
  659. if([tempDict.allKeys containsObject:bg_id]){
  660. [tempDict removeObjectForKey:bg_id];//移除主键
  661. }
  662. [tempDict removeObjectForKey:bg_sqlKey(bg_createTimeKey)];//移除创建时间
  663. [SQL appendFormat:@"update %@ set ",tablename];
  664. [tempDict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
  665. [SQL appendFormat:@"%@=?,",key];
  666. [arguments addObject:obj];
  667. }];
  668. SQL = [NSMutableString stringWithString:[SQL substringToIndex:SQL.length-1]];
  669. if(where.length) {
  670. [SQL appendString:where];
  671. }
  672. }
  673. bg_debug(SQL);
  674. BOOL flag = [db executeUpdate:SQL withArgumentsInArray:arguments];
  675. if(flag){
  676. counter++;
  677. }
  678. }
  679. }];
  680. if (dictArray.count == counter){
  681. result = YES;
  682. [db commit];
  683. }else{
  684. result = NO;
  685. [db rollback];
  686. }
  687. }];
  688. //数据监听执行函数
  689. [self doChangeWithName:tablename flag:result state:bg_update];
  690. bg_completeBlock(result);
  691. }
  692. -(void)queryQueueWithTableName:(NSString* _Nonnull)name conditions:(NSString* _Nullable)conditions complete:(bg_complete_A)complete{
  693. NSAssert(name,@"表名不能为空!");
  694. __block NSMutableArray* arrM = nil;
  695. [self executeDB:^(FMDatabase * _Nonnull db){
  696. NSString* SQL = conditions?[NSString stringWithFormat:@"select * from %@ %@",name,conditions]:[NSString stringWithFormat:@"select * from %@",name];
  697. bg_debug(SQL);
  698. // 1.查询数据
  699. FMResultSet *rs = [db executeQuery:SQL];
  700. if (rs == nil) {
  701. bg_debug(@"查询错误,可能是'类变量名'发生了改变或'字段','表格'不存在!,请存储后再读取!");
  702. }else{
  703. arrM = [[NSMutableArray alloc] init];
  704. }
  705. // 2.遍历结果集
  706. while (rs.next) {
  707. NSMutableDictionary* dictM = [[NSMutableDictionary alloc] init];
  708. for (int i=0;i<[[[rs columnNameToIndexMap] allKeys] count];i++) {
  709. dictM[[rs columnNameForIndex:i]] = [rs objectForColumnIndex:i];
  710. }
  711. [arrM addObject:dictM];
  712. }
  713. //查询完后要关闭rs,不然会报@"Warning: there is at least one open result set around after performing
  714. [rs close];
  715. }];
  716. bg_completeBlock(arrM);
  717. }
  718. /**
  719. 直接传入条件sql语句查询
  720. */
  721. -(void)queryWithTableName:(NSString* _Nonnull)name conditions:(NSString* _Nullable)conditions complete:(bg_complete_A)complete{
  722. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  723. @autoreleasepool {
  724. [self queryQueueWithTableName:name conditions:conditions complete:complete];
  725. }
  726. dispatch_semaphore_signal(self.semaphore);
  727. }
  728. /**
  729. 根据条件查询字段.
  730. */
  731. -(void)queryWithTableName:(NSString* _Nonnull)name keys:(NSArray<NSString*>* _Nullable)keys where:(NSArray* _Nullable)where complete:(bg_complete_A)complete{
  732. NSAssert(name,@"表名不能为空!");
  733. NSMutableArray* arrM = [[NSMutableArray alloc] init];
  734. __block NSArray* arguments;
  735. [self executeDB:^(FMDatabase * _Nonnull db) {
  736. NSMutableString* SQL = [[NSMutableString alloc] init];
  737. [SQL appendString:@"select"];
  738. if ((keys!=nil)&&(keys.count>0)) {
  739. [SQL appendString:@" "];
  740. for(int i=0;i<keys.count;i++){
  741. [SQL appendFormat:@"%@%@",BG,keys[i]];
  742. if (i != (keys.count-1)) {
  743. [SQL appendString:@","];
  744. }
  745. }
  746. }else{
  747. [SQL appendString:@" *"];
  748. }
  749. [SQL appendFormat:@" from %@",name];
  750. if(where && (where.count>0)){
  751. NSArray* results = [BGTool where:where];
  752. [SQL appendString:results[0]];
  753. arguments = results[1];
  754. }
  755. bg_debug(SQL);
  756. // 1.查询数据
  757. FMResultSet *rs = [db executeQuery:SQL withArgumentsInArray:arguments];
  758. if (rs == nil) {
  759. bg_debug(@"查询错误,可能是'类变量名'发生了改变或'字段','表格'不存在!,请存储后再读取,或检查条件数组'字段名称'是否正确");
  760. }
  761. // 2.遍历结果集
  762. while (rs.next) {
  763. NSMutableDictionary* dictM = [[NSMutableDictionary alloc] init];
  764. for (int i=0;i<[[[rs columnNameToIndexMap] allKeys] count];i++) {
  765. dictM[[rs columnNameForIndex:i]] = [rs objectForColumnIndex:i];
  766. }
  767. [arrM addObject:dictM];
  768. }
  769. //查询完后要关闭rs,不然会报@"Warning: there is at least one open result set around after performing
  770. [rs close];
  771. }];
  772. bg_completeBlock(arrM);
  773. }
  774. /**
  775. 查询对象.
  776. */
  777. -(void)queryWithTableName:(NSString* _Nonnull)name where:(NSString* _Nullable)where complete:(bg_complete_A)complete{
  778. NSAssert(name,@"表名不能为空!");
  779. NSMutableArray* arrM = [[NSMutableArray alloc] init];
  780. [self executeDB:^(FMDatabase * _Nonnull db) {
  781. NSMutableString* SQL = [NSMutableString string];
  782. [SQL appendFormat:@"select * from %@",name];
  783. !where?:[SQL appendFormat:@" %@",where];
  784. bg_debug(SQL);
  785. // 1.查询数据
  786. FMResultSet *rs = [db executeQuery:SQL];
  787. if (rs == nil) {
  788. bg_debug(@"查询错误,'表格'不存在!,请存储后再读取!");
  789. }
  790. // 2.遍历结果集
  791. while (rs.next) {
  792. NSMutableDictionary* dictM = [[NSMutableDictionary alloc] init];
  793. for (int i=0;i<[[[rs columnNameToIndexMap] allKeys] count];i++) {
  794. dictM[[rs columnNameForIndex:i]] = [rs objectForColumnIndex:i];
  795. }
  796. [arrM addObject:dictM];
  797. }
  798. //查询完后要关闭rs,不然会报@"Warning: there is at least one open result set around after performing
  799. [rs close];
  800. }];
  801. bg_completeBlock(arrM);
  802. }
  803. /**
  804. 更新数据.
  805. */
  806. -(void)updateWithTableName:(NSString* _Nonnull)name valueDict:(NSDictionary* _Nonnull)valueDict where:(NSArray* _Nullable)where complete:(bg_complete_B)complete{
  807. NSAssert(name,@"表名不能为空!");
  808. NSAssert(valueDict,@"更新数据集合不能为空!");
  809. __block BOOL result;
  810. NSMutableArray* arguments = [NSMutableArray array];
  811. [self executeDB:^(FMDatabase * _Nonnull db) {
  812. NSMutableString* SQL = [[NSMutableString alloc] init];
  813. [SQL appendFormat:@"update %@ set ",name];
  814. for(int i=0;i<valueDict.allKeys.count;i++){
  815. [SQL appendFormat:@"%@=?",valueDict.allKeys[i]];
  816. [arguments addObject:valueDict[valueDict.allKeys[i]]];
  817. if (i != (valueDict.allKeys.count-1)) {
  818. [SQL appendString:@","];
  819. }
  820. }
  821. if(where && (where.count>0)){
  822. NSArray* results = [BGTool where:where];
  823. [SQL appendString:results[0]];
  824. [arguments addObjectsFromArray:results[1]];
  825. }
  826. bg_debug(SQL);
  827. result = [db executeUpdate:SQL withArgumentsInArray:arguments];
  828. }];
  829. //数据监听执行函数
  830. [self doChangeWithName:name flag:result state:bg_update];
  831. bg_completeBlock(result);
  832. }
  833. -(void)updateQueueWithTableName:(NSString* _Nonnull)name valueDict:(NSDictionary* _Nullable)valueDict conditions:(NSString* _Nonnull)conditions complete:(bg_complete_B)complete{
  834. NSAssert(name,@"表名不能为空!");
  835. __block BOOL result;
  836. [self executeDB:^(FMDatabase * _Nonnull db){
  837. NSString* SQL;
  838. if (!valueDict || !valueDict.count) {
  839. SQL = [NSString stringWithFormat:@"update %@ %@",name,conditions];
  840. }else{
  841. NSMutableString* param = [NSMutableString stringWithFormat:@"update %@ set ",name];
  842. for(int i=0;i<valueDict.allKeys.count;i++){
  843. NSString* key = valueDict.allKeys[i];
  844. [param appendFormat:@"%@=?",key];
  845. if(i != (valueDict.allKeys.count-1)) {
  846. [param appendString:@","];
  847. }
  848. }
  849. [param appendFormat:@" %@",conditions];
  850. SQL = param;
  851. }
  852. bg_debug(SQL);
  853. result = [db executeUpdate:SQL withArgumentsInArray:valueDict.allValues];
  854. }];
  855. //数据监听执行函数
  856. [self doChangeWithName:name flag:result state:bg_update];
  857. bg_completeBlock(result);
  858. }
  859. /**
  860. 直接传入条件sql语句更新.
  861. */
  862. -(void)updateWithObject:(id _Nonnull)object valueDict:(NSDictionary* _Nullable)valueDict conditions:(NSString* _Nonnull)conditions complete:(bg_complete_B)complete{
  863. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  864. @autoreleasepool {
  865. //自动判断是否有字段改变,自动刷新数据库.
  866. [self ifIvarChangeForObject:object ignoredKeys:[BGTool executeSelector:bg_ignoreKeysSelector forClass:[object class]]];
  867. NSString* tablename = [BGTool getTableNameWithObject:object];
  868. [self updateQueueWithTableName:tablename valueDict:valueDict conditions:conditions complete:complete];
  869. }
  870. dispatch_semaphore_signal(self.semaphore);
  871. }
  872. /**
  873. 直接传入条件sql语句更新对象.
  874. */
  875. -(void)updateObject:(id _Nonnull)object ignoreKeys:(NSArray* const _Nullable)ignoreKeys conditions:(NSString* _Nonnull)conditions complete:(bg_complete_B)complete{
  876. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  877. @autoreleasepool {
  878. NSString* tableName = [BGTool getTableNameWithObject:object];
  879. //自动判断是否有字段改变,自动刷新数据库.
  880. [self ifIvarChangeForObject:object ignoredKeys:ignoreKeys];
  881. NSDictionary* valueDict = [BGTool getDictWithObject:self ignoredKeys:ignoreKeys filtModelInfoType:bg_ModelInfoSingleUpdate];
  882. [self updateQueueWithTableName:tableName valueDict:valueDict conditions:conditions complete:complete];
  883. }
  884. dispatch_semaphore_signal(self.semaphore);
  885. }
  886. /**
  887. 根据keypath更新数据
  888. */
  889. -(void)updateWithTableName:(NSString* _Nonnull)name forKeyPathAndValues:(NSArray* _Nonnull)keyPathValues valueDict:(NSDictionary* _Nonnull)valueDict complete:(bg_complete_B)complete{
  890. NSString* like = [BGTool getLikeWithKeyPathAndValues:keyPathValues where:YES];
  891. NSMutableArray* arguments = [NSMutableArray array];
  892. __block BOOL result;
  893. [self executeDB:^(FMDatabase * _Nonnull db){
  894. NSMutableString* SQL = [[NSMutableString alloc] init];
  895. [SQL appendFormat:@"update %@ set ",name];
  896. for(int i=0;i<valueDict.allKeys.count;i++){
  897. [SQL appendFormat:@"%@=?",valueDict.allKeys[i]];
  898. [arguments addObject:valueDict[valueDict.allKeys[i]]];
  899. if (i != (valueDict.allKeys.count-1)) {
  900. [SQL appendString:@","];
  901. }
  902. }
  903. [SQL appendString:like];
  904. result = [db executeUpdate:SQL withArgumentsInArray:arguments];
  905. bg_debug(SQL);
  906. }];
  907. //数据监听执行函数
  908. [self doChangeWithName:name flag:result state:bg_update];
  909. bg_completeBlock(result);
  910. }
  911. /**
  912. 根据条件删除数据.
  913. */
  914. -(void)deleteWithTableName:(NSString* _Nonnull)name where:(NSArray* _Nonnull)where complete:(bg_complete_B)complete{
  915. NSAssert(name,@"表名不能为空!");
  916. NSAssert(where,@"条件数组错误! 不能为空");
  917. __block BOOL result;
  918. NSMutableArray* arguments = [NSMutableArray array];
  919. [self executeDB:^(FMDatabase * _Nonnull db) {
  920. NSMutableString* SQL = [[NSMutableString alloc] init];
  921. [SQL appendFormat:@"delete from %@",name];
  922. if(where && (where.count>0)){
  923. NSArray* results = [BGTool where:where];
  924. [SQL appendString:results[0]];
  925. [arguments addObjectsFromArray:results[1]];
  926. }
  927. bg_debug(SQL);
  928. result = [db executeUpdate:SQL withArgumentsInArray:arguments];
  929. }];
  930. //数据监听执行函数
  931. [self doChangeWithName:name flag:result state:bg_delete];
  932. bg_completeBlock(result);
  933. }
  934. -(void)deleteQueueWithTableName:(NSString* _Nonnull)name conditions:(NSString* _Nullable)conditions complete:(bg_complete_B)complete{
  935. NSAssert(name,@"表名不能为空!");
  936. __block BOOL result;
  937. [self executeDB:^(FMDatabase * _Nonnull db) {
  938. NSString* SQL = conditions?[NSString stringWithFormat:@"delete from %@ %@",name,conditions]:[NSString stringWithFormat:@"delete from %@",name];
  939. bg_debug(SQL);
  940. result = [db executeUpdate:SQL];
  941. }];
  942. //数据监听执行函数
  943. [self doChangeWithName:name flag:result state:bg_delete];
  944. bg_completeBlock(result);
  945. }
  946. /**
  947. 直接传入条件sql语句删除.
  948. */
  949. -(void)deleteWithTableName:(NSString* _Nonnull)name conditions:(NSString* _Nullable)conditions complete:(bg_complete_B)complete{
  950. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  951. [self deleteQueueWithTableName:name conditions:conditions complete:complete];
  952. dispatch_semaphore_signal(self.semaphore);
  953. }
  954. -(void)deleteQueueWithTableName:(NSString* _Nonnull)name forKeyPathAndValues:(NSArray* _Nonnull)keyPathValues complete:(bg_complete_B)complete{
  955. NSAssert(name,@"表名不能为空!");
  956. NSString* like = [BGTool getLikeWithKeyPathAndValues:keyPathValues where:YES];
  957. __block BOOL result;
  958. [self executeDB:^(FMDatabase * _Nonnull db) {
  959. NSMutableString* SQL = [[NSMutableString alloc] init];
  960. [SQL appendFormat:@"delete from %@%@",name,like];
  961. bg_debug(SQL);
  962. result = [db executeUpdate:SQL];
  963. }];
  964. //数据监听执行函数
  965. [self doChangeWithName:name flag:result state:bg_delete];
  966. bg_completeBlock(result);
  967. }
  968. //根据keypath删除表内容.
  969. -(void)deleteWithTableName:(NSString* _Nonnull)name forKeyPathAndValues:(NSArray* _Nonnull)keyPathValues complete:(bg_complete_B)complete{
  970. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  971. [self deleteQueueWithTableName:name forKeyPathAndValues:keyPathValues complete:complete];
  972. dispatch_semaphore_signal(self.semaphore);
  973. }
  974. /**
  975. 根据表名删除表格全部内容.
  976. */
  977. -(void)clearTable:(NSString* _Nonnull)name complete:(bg_complete_B)complete{
  978. NSAssert(name,@"表名不能为空!");
  979. __block BOOL result;
  980. [self executeDB:^(FMDatabase * _Nonnull db) {
  981. NSString* SQL = [NSString stringWithFormat:@"delete from %@",name];
  982. bg_debug(SQL);
  983. result = [db executeUpdate:SQL];
  984. }];
  985. //数据监听执行函数
  986. [self doChangeWithName:name flag:result state:bg_delete];
  987. bg_completeBlock(result);
  988. }
  989. /**
  990. 删除表.
  991. */
  992. -(void)dropTable:(NSString* _Nonnull)name complete:(bg_complete_B)complete{
  993. NSAssert(name,@"表名不能为空!");
  994. __block BOOL result;
  995. [self executeDB:^(FMDatabase * _Nonnull db) {
  996. NSString* SQL = [NSString stringWithFormat:@"drop table %@",name];
  997. bg_debug(SQL);
  998. result = [db executeUpdate:SQL];
  999. }];
  1000. //数据监听执行函数
  1001. [self doChangeWithName:name flag:result state:bg_drop];
  1002. bg_completeBlock(result);
  1003. }
  1004. /**
  1005. 删除表(线程安全).
  1006. */
  1007. -(void)dropSafeTable:(NSString* _Nonnull)name complete:(bg_complete_B)complete{
  1008. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1009. @autoreleasepool {
  1010. [self dropTable:name complete:complete];
  1011. }
  1012. dispatch_semaphore_signal(self.semaphore);
  1013. }
  1014. /**
  1015. 动态添加表字段.
  1016. */
  1017. -(void)addTable:(NSString* _Nonnull)name key:(NSString* _Nonnull)key complete:(bg_complete_B)complete{
  1018. NSAssert(name,@"表名不能为空!");
  1019. __block BOOL result;
  1020. [self executeDB:^(FMDatabase * _Nonnull db) {
  1021. NSString* SQL = [NSString stringWithFormat:@"alter table %@ add %@;",name,[BGTool keyAndType:key]];
  1022. bg_debug(SQL);
  1023. result = [db executeUpdate:SQL];
  1024. }];
  1025. bg_completeBlock(result);
  1026. }
  1027. /**
  1028. 查询该表中有多少条数据
  1029. */
  1030. -(NSInteger)countQueueForTable:(NSString* _Nonnull)name where:(NSArray* _Nullable)where{
  1031. NSAssert(name,@"表名不能为空!");
  1032. NSAssert(!(where.count%3),@"条件数组错误!");
  1033. NSMutableString* strM = [NSMutableString string];
  1034. !where?:[strM appendString:@" where "];
  1035. for(int i=0;i<where.count;i+=3){
  1036. if ([where[i+2] isKindOfClass:[NSString class]]) {
  1037. [strM appendFormat:@"%@%@%@'%@'",BG,where[i],where[i+1],where[i+2]];
  1038. }else{
  1039. [strM appendFormat:@"%@%@%@%@",BG,where[i],where[i+1],where[i+2]];
  1040. }
  1041. if (i != (where.count-3)) {
  1042. [strM appendString:@" and "];
  1043. }
  1044. }
  1045. __block NSUInteger count=0;
  1046. [self executeDB:^(FMDatabase * _Nonnull db) {
  1047. NSString* SQL = [NSString stringWithFormat:@"select count(*) from %@%@",name,strM];
  1048. bg_debug(SQL);
  1049. [db executeStatements:SQL withResultBlock:^int(NSDictionary *resultsDictionary) {
  1050. count = [[resultsDictionary.allValues lastObject] integerValue];
  1051. return 0;
  1052. }];
  1053. }];
  1054. return count;
  1055. }
  1056. /**
  1057. 查询该表中有多少条数据
  1058. */
  1059. -(NSInteger)countForTable:(NSString* _Nonnull)name where:(NSArray* _Nullable)where{
  1060. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1061. NSInteger count = 0;
  1062. @autoreleasepool {
  1063. count = [self countQueueForTable:name where:where];
  1064. }
  1065. dispatch_semaphore_signal(self.semaphore);
  1066. return count;
  1067. }
  1068. /**
  1069. 直接传入条件sql语句查询数据条数.
  1070. */
  1071. -(NSInteger)countQueueForTable:(NSString* _Nonnull)name conditions:(NSString* _Nullable)conditions{
  1072. NSAssert(name,@"表名不能为空!");
  1073. __block NSUInteger count=0;
  1074. [self executeDB:^(FMDatabase * _Nonnull db) {
  1075. NSString* SQL = conditions?[NSString stringWithFormat:@"select count(*) from %@ %@",name,conditions]:[NSString stringWithFormat:@"select count(*) from %@",name];
  1076. bg_debug(SQL);
  1077. [db executeStatements:SQL withResultBlock:^int(NSDictionary *resultsDictionary) {
  1078. count = [[resultsDictionary.allValues lastObject] integerValue];
  1079. return 0;
  1080. }];
  1081. }];
  1082. return count;
  1083. }
  1084. /**
  1085. 直接传入条件sql语句查询数据条数.
  1086. */
  1087. -(NSInteger)countForTable:(NSString* _Nonnull)name conditions:(NSString* _Nullable)conditions{
  1088. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1089. NSInteger count = 0;
  1090. @autoreleasepool {
  1091. count = [self countQueueForTable:name conditions:conditions];
  1092. }
  1093. dispatch_semaphore_signal(self.semaphore);
  1094. return count;
  1095. }
  1096. /**
  1097. 直接调用sqliteb的原生函数计算sun,min,max,avg等.
  1098. */
  1099. -(double)sqliteMethodQueueForTable:(NSString* _Nonnull)name type:(bg_sqliteMethodType)methodType key:(NSString*)key where:(NSString* _Nullable)where{
  1100. NSAssert(name,@"表名不能为空!");
  1101. NSAssert(key,@"属性名不能为空!");
  1102. __block double num = 0.0;
  1103. NSString* method;
  1104. switch (methodType) {
  1105. case bg_min:
  1106. method = [NSString stringWithFormat:@"min(%@%@)",BG,key];
  1107. break;
  1108. case bg_max:
  1109. method = [NSString stringWithFormat:@"max(%@%@)",BG,key];
  1110. break;
  1111. case bg_sum:
  1112. method = [NSString stringWithFormat:@"sum(%@%@)",BG,key];
  1113. break;
  1114. case bg_avg:
  1115. method = [NSString stringWithFormat:@"avg(%@%@)",BG,key];
  1116. break;
  1117. default:
  1118. NSAssert(NO,@"请传入方法类型!");
  1119. break;
  1120. }
  1121. [self executeDB:^(FMDatabase * _Nonnull db){
  1122. NSString* SQL;
  1123. if(where){
  1124. SQL = [NSString stringWithFormat:@"select %@ from %@ %@",method,name,where];
  1125. }else{
  1126. SQL = [NSString stringWithFormat:@"select %@ from %@",method,name];
  1127. }
  1128. bg_debug(SQL);
  1129. [db executeStatements:SQL withResultBlock:^int(NSDictionary *resultsDictionary){
  1130. id dbResult = [resultsDictionary.allValues lastObject];
  1131. if(dbResult && ![dbResult isKindOfClass:[NSNull class]]) {
  1132. num = [dbResult doubleValue];
  1133. }
  1134. return 0;
  1135. }];
  1136. }];
  1137. return num;
  1138. }
  1139. /**
  1140. 直接调用sqliteb的原生函数计算sun,min,max,avg等.
  1141. */
  1142. -(double)sqliteMethodForTable:(NSString* _Nonnull)name type:(bg_sqliteMethodType)methodType key:(NSString*)key where:(NSString* _Nullable)where{
  1143. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1144. double num = 0.0;
  1145. @autoreleasepool {
  1146. num = [self sqliteMethodQueueForTable:name type:methodType key:key where:where];
  1147. }
  1148. dispatch_semaphore_signal(self.semaphore);
  1149. return num;
  1150. }
  1151. /**
  1152. keyPath查询数据条数.
  1153. */
  1154. -(NSInteger)countQueueForTable:(NSString* _Nonnull)name forKeyPathAndValues:(NSArray* _Nonnull)keyPathValues{
  1155. NSString* like = [BGTool getLikeWithKeyPathAndValues:keyPathValues where:YES];
  1156. __block NSUInteger count=0;
  1157. [self executeDB:^(FMDatabase * _Nonnull db) {
  1158. NSString* SQL = [NSString stringWithFormat:@"select count(*) from %@%@",name,like];
  1159. bg_debug(SQL);
  1160. [db executeStatements:SQL withResultBlock:^int(NSDictionary *resultsDictionary) {
  1161. count = [[resultsDictionary.allValues lastObject] integerValue];
  1162. return 0;
  1163. }];
  1164. }];
  1165. return count;
  1166. }
  1167. /**
  1168. keyPath查询数据条数.
  1169. */
  1170. -(NSInteger)countForTable:(NSString* _Nonnull)name forKeyPathAndValues:(NSArray* _Nonnull)keyPathValues{
  1171. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1172. NSInteger count = 0;
  1173. @autoreleasepool {
  1174. count = [self countQueueForTable:name forKeyPathAndValues:keyPathValues];
  1175. }
  1176. dispatch_semaphore_signal(self.semaphore);
  1177. return count;
  1178. }
  1179. -(void)copyA:(NSString* _Nonnull)A toB:(NSString* _Nonnull)B class:(__unsafe_unretained _Nonnull Class)cla keys:(NSArray<NSString*>* const _Nonnull)keys complete:(bg_complete_I)complete{
  1180. //获取"唯一约束"字段名
  1181. NSArray* uniqueKeys = [BGTool executeSelector:bg_uniqueKeysSelector forClass:cla];
  1182. //获取“联合主键”字段名
  1183. NSArray* unionPrimaryKeys = [BGTool executeSelector:bg_unionPrimaryKeysSelector forClass:cla];
  1184. //建立一张临时表
  1185. __block BOOL createFlag;
  1186. [self createTableWithTableName:B keys:keys unionPrimaryKeys:unionPrimaryKeys uniqueKeys:uniqueKeys complete:^(BOOL isSuccess) {
  1187. createFlag = isSuccess;
  1188. }];
  1189. if (!createFlag){
  1190. bg_debug(@"数据库更新失败!");
  1191. bg_completeBlock(bg_error);
  1192. return;
  1193. }
  1194. __block bg_dealState refreshstate = bg_error;
  1195. __block BOOL recordError = NO;
  1196. __block BOOL recordSuccess = NO;
  1197. __weak typeof(self) BGSelf = self;
  1198. NSInteger count = [self countQueueForTable:A where:nil];
  1199. for(NSInteger i=0;i<count;i+=MaxQueryPageNum){
  1200. @autoreleasepool{//由于查询出来的数据量可能巨大,所以加入自动释放池.
  1201. NSString* param = [NSString stringWithFormat:@"limit %@,%@",@(i),@(MaxQueryPageNum)];
  1202. [self queryWithTableName:A where:param complete:^(NSArray * _Nullable array) {
  1203. for(NSDictionary* oldDict in array){
  1204. NSMutableDictionary* newDict = [NSMutableDictionary dictionary];
  1205. for(NSString* keyAndType in keys){
  1206. NSString* key = [keyAndType componentsSeparatedByString:@"*"][0];
  1207. //字段名前加上 @"BG_"
  1208. key = [NSString stringWithFormat:@"%@%@",BG,key];
  1209. if (oldDict[key]){
  1210. newDict[key] = oldDict[key];
  1211. }
  1212. }
  1213. //将旧表的数据插入到新表
  1214. [BGSelf insertIntoTableName:B Dict:newDict complete:^(BOOL isSuccess){
  1215. if (isSuccess){
  1216. if (!recordSuccess) {
  1217. recordSuccess = YES;
  1218. }
  1219. }else{
  1220. if (!recordError) {
  1221. recordError = YES;
  1222. }
  1223. }
  1224. }];
  1225. }
  1226. }];
  1227. }
  1228. }
  1229. if (complete){
  1230. if (recordError && recordSuccess) {
  1231. refreshstate = bg_incomplete;
  1232. }else if(recordError && !recordSuccess){
  1233. refreshstate = bg_error;
  1234. }else if (recordSuccess && !recordError){
  1235. refreshstate = bg_complete;
  1236. }else;
  1237. complete(refreshstate);
  1238. }
  1239. }
  1240. -(void)refreshQueueTable:(NSString* _Nonnull)name class:(__unsafe_unretained _Nonnull Class)cla keys:(NSArray<NSString*>* const _Nonnull)keys complete:(bg_complete_I)complete{
  1241. NSAssert(name,@"表名不能为空!");
  1242. NSAssert(keys,@"字段数组不能为空!");
  1243. [self isExistWithTableName:name complete:^(BOOL isSuccess){
  1244. if (!isSuccess){
  1245. bg_debug(@"没有数据存在,数据库更新失败!");
  1246. bg_completeBlock(bg_error);
  1247. return;
  1248. }
  1249. }];
  1250. NSString* BGTempTable = @"BGTempTable";
  1251. //事务操作.
  1252. __block int recordFailCount = 0;
  1253. [self executeTransation:^BOOL{
  1254. [self copyA:name toB:BGTempTable class:cla keys:keys complete:^(bg_dealState result) {
  1255. if(result == bg_complete){
  1256. recordFailCount++;
  1257. }
  1258. }];
  1259. [self dropTable:name complete:^(BOOL isSuccess) {
  1260. if(isSuccess)recordFailCount++;
  1261. }];
  1262. [self copyA:BGTempTable toB:name class:cla keys:keys complete:^(bg_dealState result) {
  1263. if(result == bg_complete){
  1264. recordFailCount++;
  1265. }
  1266. }];
  1267. [self dropTable:BGTempTable complete:^(BOOL isSuccess) {
  1268. if(isSuccess)recordFailCount++;
  1269. }];
  1270. if(recordFailCount != 4){
  1271. bg_debug(@"发生错误,更新数据库失败!");
  1272. }
  1273. return recordFailCount==4;
  1274. }];
  1275. //回调结果.
  1276. if (recordFailCount==0) {
  1277. bg_completeBlock(bg_error);
  1278. }else if (recordFailCount>0&&recordFailCount<4){
  1279. bg_completeBlock(bg_incomplete);
  1280. }else{
  1281. bg_completeBlock(bg_complete);
  1282. }
  1283. }
  1284. /**
  1285. 刷新数据库,即将旧数据库的数据复制到新建的数据库,这是为了去掉没用的字段.
  1286. */
  1287. -(void)refreshTable:(NSString* _Nonnull)name class:(__unsafe_unretained _Nonnull Class)cla keys:(NSArray<NSString*>* const _Nonnull)keys complete:(bg_complete_I)complete{
  1288. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1289. @autoreleasepool {
  1290. [self refreshQueueTable:name class:cla keys:keys complete:complete];
  1291. }
  1292. dispatch_semaphore_signal(self.semaphore);
  1293. }
  1294. -(void)copyA:(NSString* _Nonnull)A toB:(NSString* _Nonnull)B keyDict:(NSDictionary* const _Nullable)keyDict complete:(bg_complete_I)complete{
  1295. //获取"唯一约束"字段名
  1296. NSArray* uniqueKeys = [BGTool executeSelector:bg_uniqueKeysSelector forClass:NSClassFromString(A)];
  1297. //获取“联合主键”字段名
  1298. NSArray* unionPrimaryKeys = [BGTool executeSelector:bg_unionPrimaryKeysSelector forClass:NSClassFromString(A)];
  1299. __block NSArray* keys = [BGTool getClassIvarList:NSClassFromString(A) Object:nil onlyKey:NO];
  1300. NSArray* newKeys = keyDict.allKeys;
  1301. NSArray* oldKeys = keyDict.allValues;
  1302. //建立一张临时表
  1303. __block BOOL createFlag;
  1304. [self createTableWithTableName:B keys:keys unionPrimaryKeys:unionPrimaryKeys uniqueKeys:uniqueKeys complete:^(BOOL isSuccess) {
  1305. createFlag = isSuccess;
  1306. }];
  1307. if (!createFlag){
  1308. bg_debug(@"数据库更新失败!");
  1309. bg_completeBlock(bg_error);
  1310. return;
  1311. }
  1312. __block bg_dealState refreshstate = bg_error;
  1313. __block BOOL recordError = NO;
  1314. __block BOOL recordSuccess = NO;
  1315. __weak typeof(self) BGSelf = self;
  1316. NSInteger count = [self countQueueForTable:A where:nil];
  1317. for(NSInteger i=0;i<count;i+=MaxQueryPageNum){
  1318. @autoreleasepool{//由于查询出来的数据量可能巨大,所以加入自动释放池.
  1319. NSString* param = [NSString stringWithFormat:@"limit %@,%@",@(i),@(MaxQueryPageNum)];
  1320. [self queryWithTableName:A where:param complete:^(NSArray * _Nullable array) {
  1321. __strong typeof(BGSelf) strongSelf = BGSelf;
  1322. for(NSDictionary* oldDict in array){
  1323. NSMutableDictionary* newDict = [NSMutableDictionary dictionary];
  1324. for(NSString* keyAndType in keys){
  1325. NSString* key = [keyAndType componentsSeparatedByString:@"*"][0];
  1326. //字段名前加上 @"BG_"
  1327. key = [NSString stringWithFormat:@"%@%@",BG,key];
  1328. if (oldDict[key]){
  1329. newDict[key] = oldDict[key];
  1330. }
  1331. }
  1332. for(int i=0;i<oldKeys.count;i++){
  1333. //字段名前加上 @"BG_"
  1334. NSString* oldkey = [NSString stringWithFormat:@"%@%@",BG,oldKeys[i]];
  1335. NSString* newkey = [NSString stringWithFormat:@"%@%@",BG,newKeys[i]];
  1336. if (oldDict[oldkey]){
  1337. newDict[newkey] = oldDict[oldkey];
  1338. }
  1339. }
  1340. //将旧表的数据插入到新表
  1341. [strongSelf insertIntoTableName:B Dict:newDict complete:^(BOOL isSuccess){
  1342. if (isSuccess){
  1343. if (!recordSuccess) {
  1344. recordSuccess = YES;
  1345. }
  1346. }else{
  1347. if (!recordError) {
  1348. recordError = YES;
  1349. }
  1350. }
  1351. }];
  1352. }
  1353. }];
  1354. }
  1355. }
  1356. if (complete){
  1357. if (recordError && recordSuccess) {
  1358. refreshstate = bg_incomplete;
  1359. }else if(recordError && !recordSuccess){
  1360. refreshstate = bg_error;
  1361. }else if (recordSuccess && !recordError){
  1362. refreshstate = bg_complete;
  1363. }else;
  1364. complete(refreshstate);
  1365. }
  1366. }
  1367. -(void)refreshQueueTable:(NSString* _Nonnull)tablename class:(__unsafe_unretained _Nonnull Class)cla keys:(NSArray* const _Nonnull)keys keyDict:(NSDictionary* const _Nonnull)keyDict complete:(bg_complete_I)complete{
  1368. NSAssert(tablename,@"表名不能为空!");
  1369. NSAssert(keyDict,@"变量名影射集合不能为空!");
  1370. [self isExistWithTableName:tablename complete:^(BOOL isSuccess){
  1371. if (!isSuccess){
  1372. bg_debug(@"没有数据存在,数据库更新失败!");
  1373. bg_completeBlock(bg_error);
  1374. return;
  1375. }
  1376. }];
  1377. //事务操作.
  1378. NSString* BGTempTable = @"BGTempTable";
  1379. __block int recordFailCount = 0;
  1380. [self executeTransation:^BOOL{
  1381. [self copyA:tablename toB:BGTempTable keyDict:keyDict complete:^(bg_dealState result) {
  1382. if(result == bg_complete){
  1383. recordFailCount++;
  1384. }
  1385. }];
  1386. [self dropTable:tablename complete:^(BOOL isSuccess) {
  1387. if(isSuccess)recordFailCount++;
  1388. }];
  1389. [self copyA:BGTempTable toB:tablename class:cla keys:keys complete:^(bg_dealState result) {
  1390. if(result == bg_complete){
  1391. recordFailCount++;
  1392. }
  1393. }];
  1394. [self dropTable:BGTempTable complete:^(BOOL isSuccess) {
  1395. if(isSuccess)recordFailCount++;
  1396. }];
  1397. if (recordFailCount != 4) {
  1398. bg_debug(@"发生错误,更新数据库失败!");
  1399. }
  1400. return recordFailCount==4;
  1401. }];
  1402. //回调结果.
  1403. if(recordFailCount==0){
  1404. bg_completeBlock(bg_error);
  1405. }else if (recordFailCount>0&&recordFailCount<4){
  1406. bg_completeBlock(bg_incomplete);
  1407. }else{
  1408. bg_completeBlock(bg_complete);
  1409. }
  1410. }
  1411. -(void)refreshTable:(NSString* _Nonnull)name class:(__unsafe_unretained _Nonnull Class)cla keys:(NSArray* const _Nonnull)keys keyDict:(NSDictionary* const _Nonnull)keyDict complete:(bg_complete_I)complete{
  1412. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1413. @autoreleasepool {
  1414. [self refreshQueueTable:name class:cla keys:keys keyDict:keyDict complete:complete];
  1415. }
  1416. dispatch_semaphore_signal(self.semaphore);
  1417. }
  1418. /**
  1419. 判断类属性是否有改变,智能刷新.
  1420. */
  1421. -(void)ifIvarChangeForObject:(id)object ignoredKeys:(NSArray*)ignoredkeys{
  1422. //获取缓存的属性信息
  1423. NSCache* cache = [NSCache bg_cache];
  1424. NSString *tableName = [object valueForKey:bg_tableNameKey];
  1425. tableName = tableName.length ? tableName : NSStringFromClass([object class]);
  1426. NSString* cacheKey = [NSString stringWithFormat:@"%@_IvarChangeState",tableName];
  1427. id IvarChangeState = [cache objectForKey:cacheKey];
  1428. if(IvarChangeState){
  1429. return;
  1430. }else{
  1431. [cache setObject:@(YES) forKey:cacheKey];
  1432. }
  1433. @autoreleasepool {
  1434. //获取表名
  1435. NSString* tableName = [BGTool getTableNameWithObject:object];
  1436. NSMutableArray* newKeys = [NSMutableArray array];
  1437. NSMutableArray* sqlKeys = [NSMutableArray array];
  1438. [self executeDB:^(FMDatabase * _Nonnull db) {
  1439. NSString* SQL = [NSString stringWithFormat:@"select sql from sqlite_master where tbl_name='%@' and type='table';",tableName];
  1440. NSMutableArray* tempArrayM = [NSMutableArray array];
  1441. //获取表格所有列名.
  1442. [db executeStatements:SQL withResultBlock:^int(NSDictionary *resultsDictionary) {
  1443. NSString* allName = [resultsDictionary.allValues lastObject];
  1444. allName = [allName stringByReplacingOccurrencesOfString:@"\"" withString:@""];
  1445. NSRange range1 = [allName rangeOfString:@"("];
  1446. allName = [allName substringFromIndex:range1.location+1];
  1447. NSRange range2 = [allName rangeOfString:@")"];
  1448. allName = [allName substringToIndex:range2.location];
  1449. NSArray* sqlNames = [allName componentsSeparatedByString:@","];
  1450. for(NSString* sqlName in sqlNames){
  1451. NSString* columnName = [[sqlName componentsSeparatedByString:@" "] firstObject];
  1452. [tempArrayM addObject:columnName];
  1453. }
  1454. return 0;
  1455. }];
  1456. NSArray* columNames = tempArrayM.count?tempArrayM:nil;
  1457. NSArray* keyAndtypes = [BGTool getClassIvarList:[object class] Object:object onlyKey:NO];
  1458. for(NSString* keyAndtype in keyAndtypes){
  1459. NSString* key = [[keyAndtype componentsSeparatedByString:@"*"] firstObject];
  1460. if(ignoredkeys && [ignoredkeys containsObject:key])continue;
  1461. key = [NSString stringWithFormat:@"%@%@",BG,key];
  1462. if (![columNames containsObject:key]) {
  1463. [newKeys addObject:keyAndtype];
  1464. }
  1465. }
  1466. NSMutableArray* keys = [NSMutableArray arrayWithArray:[BGTool getClassIvarList:[object class] Object:nil onlyKey:YES]];
  1467. if (ignoredkeys) {
  1468. [keys removeObjectsInArray:ignoredkeys];
  1469. }
  1470. [columNames enumerateObjectsUsingBlock:^(NSString* _Nonnull columName, NSUInteger idx, BOOL * _Nonnull stop) {
  1471. NSString* propertyName = [columName stringByReplacingOccurrencesOfString:BG withString:@""];
  1472. if(![keys containsObject:propertyName]){
  1473. [sqlKeys addObject:columName];
  1474. }
  1475. }];
  1476. }];
  1477. if((sqlKeys.count==0) && (newKeys.count>0)){
  1478. //此处只是增加了新的列.
  1479. for(NSString* key in newKeys){
  1480. //添加新字段
  1481. [self addTable:tableName key:key complete:^(BOOL isSuccess){}];
  1482. }
  1483. }else if(sqlKeys.count>0){
  1484. //字段发生改变,减少或名称变化,实行刷新数据库.
  1485. NSMutableArray* newTableKeys = [[NSMutableArray alloc] initWithArray:[BGTool getClassIvarList:[object class] Object:nil onlyKey:NO]];
  1486. NSMutableArray* tempIgnoreKeys = [[NSMutableArray alloc] initWithArray:ignoredkeys];
  1487. for(int i=0;i<newTableKeys.count;i++){
  1488. NSString* key = [[newTableKeys[i] componentsSeparatedByString:@"*"] firstObject];
  1489. if([tempIgnoreKeys containsObject:key]) {
  1490. [newTableKeys removeObject:newTableKeys[i]];
  1491. [tempIgnoreKeys removeObject:key];
  1492. i--;
  1493. }
  1494. if(tempIgnoreKeys.count == 0){
  1495. break;
  1496. }
  1497. }
  1498. [self refreshQueueTable:tableName class:[object class] keys:newTableKeys complete:nil];
  1499. }else;
  1500. }
  1501. }
  1502. /**
  1503. 处理插入的字典数据并返回
  1504. */
  1505. -(void)insertWithObject:(id)object ignoredKeys:(NSArray* const _Nullable)ignoredKeys complete:(bg_complete_B)complete{
  1506. NSDictionary* dictM = [BGTool getDictWithObject:object ignoredKeys:ignoredKeys filtModelInfoType:bg_ModelInfoInsert];
  1507. //自动判断是否有字段改变,自动刷新数据库.
  1508. [self ifIvarChangeForObject:object ignoredKeys:ignoredKeys];
  1509. NSString* tableName = [BGTool getTableNameWithObject:object];
  1510. [self insertIntoTableName:tableName Dict:dictM complete:complete];
  1511. }
  1512. -(NSArray*)getArray:(NSArray*)array ignoredKeys:(NSArray* const _Nullable)ignoredKeys filtModelInfoType:(bg_getModelInfoType)filtModelInfoType{
  1513. NSMutableArray* dictArray = [NSMutableArray array];
  1514. [array enumerateObjectsUsingBlock:^(id _Nonnull object, NSUInteger idx, BOOL * _Nonnull stop) {
  1515. NSDictionary* dict = [BGTool getDictWithObject:object ignoredKeys:ignoredKeys filtModelInfoType:filtModelInfoType];
  1516. [dictArray addObject:dict];
  1517. }];
  1518. return dictArray;
  1519. }
  1520. /**
  1521. 批量插入数据
  1522. */
  1523. -(void)insertWithObjects:(NSArray*)array ignoredKeys:(NSArray* const _Nullable)ignoredKeys complete:(bg_complete_B)complete{
  1524. NSArray* dictArray = [self getArray:array ignoredKeys:ignoredKeys filtModelInfoType:bg_ModelInfoInsert];
  1525. //自动判断是否有字段改变,自动刷新数据库.
  1526. [self ifIvarChangeForObject:array.firstObject ignoredKeys:ignoredKeys];
  1527. NSString* tableName = [BGTool getTableNameWithObject:array.firstObject];
  1528. [self insertIntoTableName:tableName DictArray:dictArray complete:complete];
  1529. }
  1530. /**
  1531. 批量更新数据.
  1532. over
  1533. */
  1534. -(void)updateSetWithObjects:(NSArray*)array ignoredKeys:(NSArray* const _Nullable)ignoredKeys complete:(bg_complete_B)complete{
  1535. NSArray* dictArray = [self getArray:array ignoredKeys:ignoredKeys filtModelInfoType:bg_ModelInfoArrayUpdate];
  1536. NSString* tableName = [BGTool getTableNameWithObject:array.firstObject];
  1537. [self updateSetTableName:tableName class:[array.firstObject class] DictArray:dictArray complete:complete];
  1538. }
  1539. /**
  1540. 批量存储.
  1541. */
  1542. -(void)saveObjects:(NSArray* _Nonnull)array ignoredKeys:(NSArray* const _Nullable)ignoredKeys complete:(bg_complete_B)complete{
  1543. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1544. @autoreleasepool {
  1545. [BGTool ifNotExistWillCreateTableWithObject:array.firstObject ignoredKeys:ignoredKeys];
  1546. [self insertWithObjects:array ignoredKeys:ignoredKeys complete:complete];
  1547. }
  1548. dispatch_semaphore_signal(self.semaphore);
  1549. }
  1550. /**
  1551. 批量更新.
  1552. over
  1553. */
  1554. -(void)updateObjects:(NSArray* _Nonnull)array ignoredKeys:(NSArray* const _Nullable)ignoredKeys complete:(bg_complete_B)complete{
  1555. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1556. @autoreleasepool {
  1557. [self updateSetWithObjects:array ignoredKeys:ignoredKeys complete:complete];
  1558. }
  1559. dispatch_semaphore_signal(self.semaphore);
  1560. }
  1561. /**
  1562. 批量插入或更新.
  1563. */
  1564. -(void)bg_saveOrUpateArray:(NSArray* _Nonnull)array ignoredKeys:(NSArray* const _Nullable)ignoredKeys complete:(bg_complete_B)complete{
  1565. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1566. @autoreleasepool {
  1567. //判断是否建表.
  1568. [BGTool ifNotExistWillCreateTableWithObject:array.firstObject ignoredKeys:ignoredKeys];
  1569. //自动判断是否有字段改变,自动刷新数据库.
  1570. [self ifIvarChangeForObject:array.firstObject ignoredKeys:ignoredKeys];
  1571. //转换模型数据
  1572. NSArray* dictArray = [self getArray:array ignoredKeys:ignoredKeys filtModelInfoType:bg_ModelInfoNone];
  1573. //获取自定义表名
  1574. NSString* tableName = [BGTool getTableNameWithObject:array.firstObject];
  1575. [self bg_saveOrUpdateWithTableName:tableName class:[array.firstObject class] DictArray:dictArray complete:complete];
  1576. }
  1577. dispatch_semaphore_signal(self.semaphore);
  1578. }
  1579. /**
  1580. 存储一个对象.
  1581. */
  1582. -(void)saveObject:(id _Nonnull)object ignoredKeys:(NSArray* const _Nullable)ignoredKeys complete:(bg_complete_B)complete{
  1583. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1584. @autoreleasepool {
  1585. [BGTool ifNotExistWillCreateTableWithObject:object ignoredKeys:ignoredKeys];
  1586. [self insertWithObject:object ignoredKeys:ignoredKeys complete:complete];
  1587. }
  1588. dispatch_semaphore_signal(self.semaphore);
  1589. }
  1590. -(void)queryObjectQueueWithTableName:(NSString* _Nonnull)tablename class:(__unsafe_unretained _Nonnull Class)cla where:(NSString* _Nullable)where complete:(bg_complete_A)complete{
  1591. //检查是否建立了跟对象相对应的数据表
  1592. __weak typeof(self) BGSelf = self;
  1593. [self isExistWithTableName:tablename complete:^(BOOL isExist) {
  1594. __strong typeof(BGSelf) strongSelf = BGSelf;
  1595. if (!isExist){//如果不存在就返回空
  1596. bg_completeBlock(nil);
  1597. }else{
  1598. [strongSelf queryWithTableName:tablename where:where complete:^(NSArray * _Nullable array) {
  1599. NSArray* resultArray = [BGTool tansformDataFromSqlDataWithTableName:tablename class:cla array:array];
  1600. bg_completeBlock(resultArray);
  1601. }];
  1602. }
  1603. }];
  1604. }
  1605. /**
  1606. 查询对象.
  1607. */
  1608. -(void)queryObjectWithTableName:(NSString* _Nonnull)tablename class:(__unsafe_unretained _Nonnull Class)cla where:(NSString* _Nullable)where complete:(bg_complete_A)complete{
  1609. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1610. @autoreleasepool {
  1611. [self queryObjectQueueWithTableName:tablename class:cla where:where complete:complete];
  1612. }
  1613. dispatch_semaphore_signal(self.semaphore);
  1614. }
  1615. -(void)updateQueueWithObject:(id _Nonnull)object where:(NSArray* _Nullable)where ignoreKeys:(NSArray* const _Nullable)ignoreKeys complete:(bg_complete_B)complete{
  1616. NSDictionary* valueDict = [BGTool getDictWithObject:object ignoredKeys:ignoreKeys filtModelInfoType:bg_ModelInfoSingleUpdate];
  1617. NSString* tableName = [BGTool getTableNameWithObject:object];
  1618. __block BOOL result = NO;
  1619. [self isExistWithTableName:tableName complete:^(BOOL isExist){
  1620. result = isExist;
  1621. }];
  1622. if (!result){
  1623. //如果不存在就返回NO
  1624. bg_completeBlock(NO);
  1625. }else{
  1626. //自动判断是否有字段改变,自动刷新数据库.
  1627. [self ifIvarChangeForObject:object ignoredKeys:ignoreKeys];
  1628. [self updateWithTableName:tableName valueDict:valueDict where:where complete:complete];
  1629. }
  1630. }
  1631. /**
  1632. 根据条件改变对象数据.
  1633. */
  1634. -(void)updateWithObject:(id _Nonnull)object where:(NSArray* _Nullable)where ignoreKeys:(NSArray* const _Nullable)ignoreKeys complete:(bg_complete_B)complete{
  1635. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1636. @autoreleasepool {
  1637. [self updateQueueWithObject:object where:where ignoreKeys:ignoreKeys complete:complete];
  1638. }
  1639. dispatch_semaphore_signal(self.semaphore);
  1640. }
  1641. -(void)updateQueueWithObject:(id _Nonnull)object forKeyPathAndValues:(NSArray* _Nonnull)keyPathValues ignoreKeys:(NSArray* const _Nullable)ignoreKeys complete:(bg_complete_B)complete{
  1642. NSDictionary* valueDict = [BGTool getDictWithObject:object ignoredKeys:ignoreKeys filtModelInfoType:bg_ModelInfoSingleUpdate];
  1643. NSString* tableName = [BGTool getTableNameWithObject:object];
  1644. __weak typeof(self) BGSelf = self;
  1645. [self isExistWithTableName:tableName complete:^(BOOL isExist){
  1646. __strong typeof(BGSelf) strongSelf = BGSelf;
  1647. if (!isExist){//如果不存在就返回NO
  1648. bg_completeBlock(NO);
  1649. }else{
  1650. [strongSelf updateWithTableName:tableName forKeyPathAndValues:keyPathValues valueDict:valueDict complete:complete];
  1651. }
  1652. }];
  1653. }
  1654. /**
  1655. 根据keyPath改变对象数据.
  1656. */
  1657. -(void)updateWithObject:(id _Nonnull)object forKeyPathAndValues:(NSArray* _Nonnull)keyPathValues ignoreKeys:(NSArray* const _Nullable)ignoreKeys complete:(bg_complete_B)complete{
  1658. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1659. @autoreleasepool {
  1660. //自动判断是否有字段改变,自动刷新数据库.
  1661. [self ifIvarChangeForObject:object ignoredKeys:ignoreKeys];
  1662. [self updateQueueWithObject:object forKeyPathAndValues:keyPathValues ignoreKeys:ignoreKeys complete:complete];
  1663. }
  1664. dispatch_semaphore_signal(self.semaphore);
  1665. }
  1666. /**
  1667. 根据类删除此类所有表数据.
  1668. */
  1669. -(void)clearWithObject:(id _Nonnull)object complete:(bg_complete_B)complete{
  1670. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1671. NSString* tableName = [BGTool getTableNameWithObject:object];
  1672. __weak typeof(self) BGSelf = self;
  1673. [self isExistWithTableName:tableName complete:^(BOOL isExist) {
  1674. __strong typeof(BGSelf) strongSelf = BGSelf;
  1675. if (!isExist){//如果不存在就相当于清空,返回YES
  1676. bg_completeBlock(YES);
  1677. }else{
  1678. [strongSelf clearTable:tableName complete:complete];
  1679. }
  1680. }];
  1681. dispatch_semaphore_signal(self.semaphore);
  1682. }
  1683. /**
  1684. 根据类,删除这个类的表.
  1685. */
  1686. -(void)dropWithTableName:(NSString* _Nonnull)tablename complete:(bg_complete_B)complete{
  1687. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1688. __weak typeof(self) BGSelf = self;
  1689. [self isExistWithTableName:tablename complete:^(BOOL isExist){
  1690. __strong typeof(BGSelf) strongSelf = BGSelf;
  1691. if (!isExist){//如果不存在就返回NO
  1692. bg_completeBlock(NO);
  1693. }else{
  1694. [strongSelf dropTable:tablename complete:complete];
  1695. }
  1696. }];
  1697. dispatch_semaphore_signal(self.semaphore);
  1698. }
  1699. -(void)copyQueueTable:(NSString* _Nonnull)srcTable to:(NSString* _Nonnull)destTable keyDict:(NSDictionary* const _Nonnull)keydict append:(BOOL)append complete:(bg_complete_I)complete{
  1700. NSAssert(![srcTable isEqualToString:destTable],@"不能将本表数据拷贝给自己!");
  1701. NSArray* destKeys = keydict.allValues;
  1702. NSArray* srcKeys = keydict.allKeys;
  1703. [self isExistWithTableName:srcTable complete:^(BOOL isExist) {
  1704. NSAssert(isExist,@"原表中还没有数据,复制失败!");
  1705. }];
  1706. __weak typeof(self) BGSelf = self;
  1707. [self isExistWithTableName:destTable complete:^(BOOL isExist) {
  1708. if(!isExist){
  1709. NSAssert(NO,@"目标表不存在,复制失败!");
  1710. }else{
  1711. if (!append){//覆盖模式,即将原数据删掉,拷贝新的数据过来
  1712. [BGSelf clearTable:destTable complete:nil];
  1713. }
  1714. }
  1715. }];
  1716. __block bg_dealState copystate = bg_error;
  1717. __block BOOL recordError = NO;
  1718. __block BOOL recordSuccess = NO;
  1719. NSInteger srcCount = [self countQueueForTable:srcTable where:nil];
  1720. for(NSInteger i=0;i<srcCount;i+=MaxQueryPageNum){
  1721. @autoreleasepool{//由于查询出来的数据量可能巨大,所以加入自动释放池.
  1722. NSString* param = [NSString stringWithFormat:@"limit %@,%@",@(i),@(MaxQueryPageNum)];
  1723. [self queryWithTableName:srcTable where:param complete:^(NSArray * _Nullable array) {
  1724. for(NSDictionary* srcDict in array){
  1725. NSMutableDictionary* destDict = [NSMutableDictionary dictionary];
  1726. for(int i=0;i<srcKeys.count;i++){
  1727. //字段名前加上 @"BG_"
  1728. NSString* destSqlKey = [NSString stringWithFormat:@"%@%@",BG,destKeys[i]];
  1729. NSString* srcSqlKey = [NSString stringWithFormat:@"%@%@",BG,srcKeys[i]];
  1730. destDict[destSqlKey] = srcDict[srcSqlKey];
  1731. }
  1732. [BGSelf insertIntoTableName:destTable Dict:destDict complete:^(BOOL isSuccess) {
  1733. if (isSuccess){
  1734. if (!recordSuccess) {
  1735. recordSuccess = YES;
  1736. }
  1737. }else{
  1738. if (!recordError) {
  1739. recordError = YES;
  1740. }
  1741. }
  1742. }];
  1743. }
  1744. }];
  1745. }
  1746. }
  1747. if (complete){
  1748. if (recordError && recordSuccess) {
  1749. copystate = bg_incomplete;
  1750. }else if(recordError && !recordSuccess){
  1751. copystate = bg_error;
  1752. }else if (recordSuccess && !recordError){
  1753. copystate = bg_complete;
  1754. }else;
  1755. complete(copystate);
  1756. }
  1757. }
  1758. /**
  1759. 将某表的数据拷贝给另一个表
  1760. */
  1761. -(void)copyTable:(NSString* _Nonnull)srcTable to:(NSString* _Nonnull)destTable keyDict:(NSDictionary* const _Nonnull)keydict append:(BOOL)append complete:(bg_complete_I)complete{
  1762. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1763. @autoreleasepool {
  1764. [self copyQueueTable:srcTable to:destTable keyDict:keydict append:append complete:complete];
  1765. }
  1766. dispatch_semaphore_signal(self.semaphore);
  1767. }
  1768. /**
  1769. 直接执行sql语句.
  1770. @tablename 要操作的表名.
  1771. @cla 要操作的类.
  1772. */
  1773. -(id _Nullable)bg_executeSql:(NSString* const _Nonnull)sql tablename:(NSString* _Nonnull)tablename class:(__unsafe_unretained _Nonnull Class)cla{
  1774. NSAssert(sql,@"sql语句不能为空!");
  1775. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1776. __block id result;
  1777. [self executeDB:^(FMDatabase * _Nonnull db){
  1778. if([[sql lowercaseString] hasPrefix:@"select"]){
  1779. // 1.查询数据
  1780. FMResultSet *rs = [db executeQuery:sql];
  1781. if (rs == nil) {
  1782. bg_debug(@"查询错误,数据不存在,请存储后再读取!");
  1783. result = nil;
  1784. }else{
  1785. result = [NSMutableArray array];
  1786. }
  1787. result = [NSMutableArray array];
  1788. // 2.遍历结果集
  1789. while (rs.next) {
  1790. NSMutableDictionary* dictM = [[NSMutableDictionary alloc] init];
  1791. for (int i=0;i<[[[rs columnNameToIndexMap] allKeys] count];i++) {
  1792. dictM[[rs columnNameForIndex:i]] = [rs objectForColumnIndex:i];
  1793. }
  1794. [result addObject:dictM];
  1795. }
  1796. //查询完后要关闭rs,不然会报@"Warning: there is at least one open result set around after performing
  1797. [rs close];
  1798. //转换结果
  1799. result = [BGTool tansformDataFromSqlDataWithTableName:tablename class:cla array:result];
  1800. }else{
  1801. result = @([db executeUpdate:sql]);
  1802. }
  1803. bg_debug(sql);
  1804. }];
  1805. dispatch_semaphore_signal(self.semaphore);
  1806. return result;
  1807. }
  1808. #pragma mark 存储数组.
  1809. /**
  1810. 直接存储数组.
  1811. */
  1812. -(void)saveArray:(NSArray* _Nonnull)array name:(NSString*)name complete:(bg_complete_B)complete{
  1813. NSAssert(array&&array.count,@"数组不能为空!");
  1814. NSAssert(name,@"唯一标识名不能为空!");
  1815. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1816. @autoreleasepool {
  1817. __weak typeof(self) BGSelf = self;
  1818. [self isExistWithTableName:name complete:^(BOOL isSuccess) {
  1819. if (!isSuccess) {
  1820. [BGSelf createTableWithTableName:name keys:@[[NSString stringWithFormat:@"%@*i",bg_primaryKey],@"param*@\"NSString\"",@"index*i"] unionPrimaryKeys:nil uniqueKeys:nil complete:nil];
  1821. }
  1822. }];
  1823. __block NSInteger sqlCount = [self countQueueForTable:name where:nil];
  1824. __block NSInteger num = 0;
  1825. [self executeTransation:^BOOL{
  1826. for(id value in array){
  1827. NSString* type = [NSString stringWithFormat:@"@\"%@\"",NSStringFromClass([value class])];
  1828. id sqlValue = [BGTool getSqlValue:value type:type encode:YES];
  1829. sqlValue = [NSString stringWithFormat:@"%@$$$%@",sqlValue,type];
  1830. NSDictionary* dict = @{@"BG_param":sqlValue,@"BG_index":@(sqlCount++)};
  1831. [self insertIntoTableName:name Dict:dict complete:^(BOOL isSuccess) {
  1832. if(isSuccess) {
  1833. num++;
  1834. }
  1835. }];
  1836. }
  1837. return YES;
  1838. }];
  1839. bg_completeBlock(array.count==num);
  1840. }
  1841. dispatch_semaphore_signal(self.semaphore);
  1842. }
  1843. /**
  1844. 读取数组.
  1845. */
  1846. -(void)queryArrayWithName:(NSString*)name complete:(bg_complete_A)complete{
  1847. NSAssert(name,@"唯一标识名不能为空!");
  1848. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1849. @autoreleasepool {
  1850. NSString* condition = [NSString stringWithFormat:@"order by %@ asc",bg_sqlKey(bg_primaryKey)];
  1851. [self queryQueueWithTableName:name conditions:condition complete:^(NSArray * _Nullable array) {
  1852. NSMutableArray* resultM = nil;
  1853. if(array&&array.count){
  1854. resultM = [NSMutableArray array];
  1855. for(NSDictionary* dict in array){
  1856. NSArray* keyAndTypes = [dict[@"BG_param"] componentsSeparatedByString:@"$$$"];
  1857. id value = [keyAndTypes firstObject];
  1858. NSString* type = [keyAndTypes lastObject];
  1859. value = [BGTool getSqlValue:value type:type encode:NO];
  1860. [resultM addObject:value];
  1861. }
  1862. }
  1863. bg_completeBlock(resultM);
  1864. }];
  1865. }
  1866. dispatch_semaphore_signal(self.semaphore);
  1867. }
  1868. /**
  1869. 读取数组某个元素.
  1870. */
  1871. -(id _Nullable)queryArrayWithName:(NSString* _Nonnull)name index:(NSInteger)index{
  1872. NSAssert(name,@"唯一标识名不能为空!");
  1873. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1874. __block id resultValue = nil;
  1875. @autoreleasepool {
  1876. [self queryQueueWithTableName:name conditions:[NSString stringWithFormat:@"where BG_index=%@",@(index)] complete:^(NSArray * _Nullable array){
  1877. if(array&&array.count){
  1878. NSDictionary* dict = [array firstObject];
  1879. NSArray* keyAndTypes = [dict[@"BG_param"] componentsSeparatedByString:@"$$$"];
  1880. id value = [keyAndTypes firstObject];
  1881. NSString* type = [keyAndTypes lastObject];
  1882. resultValue = [BGTool getSqlValue:value type:type encode:NO];
  1883. }
  1884. }];
  1885. }
  1886. dispatch_semaphore_signal(self.semaphore);
  1887. return resultValue;
  1888. }
  1889. /**
  1890. 更新数组某个元素.
  1891. */
  1892. -(BOOL)updateObjectWithName:(NSString* _Nonnull)name object:(id _Nonnull)object index:(NSInteger)index{
  1893. NSAssert(name,@"唯一标识名不能为空!");
  1894. NSAssert(object,@"元素不能为空!");
  1895. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1896. __block BOOL result;
  1897. @autoreleasepool{
  1898. NSString* type = [NSString stringWithFormat:@"@\"%@\"",NSStringFromClass([object class])];
  1899. id sqlValue = [BGTool getSqlValue:object type:type encode:YES];
  1900. sqlValue = [NSString stringWithFormat:@"%@$$$%@",sqlValue,type];
  1901. NSDictionary* dict = @{@"BG_param":sqlValue};
  1902. [self updateWithTableName:name valueDict:dict where:@[@"index",@"=",@(index)] complete:^(BOOL isSuccess) {
  1903. result = isSuccess;
  1904. }];
  1905. }
  1906. dispatch_semaphore_signal(self.semaphore);
  1907. return result;
  1908. }
  1909. /**
  1910. 删除数组某个元素.
  1911. */
  1912. -(BOOL)deleteObjectWithName:(NSString* _Nonnull)name index:(NSInteger)index{
  1913. NSAssert(name,@"唯一标识名不能为空!");
  1914. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1915. __block NSInteger flag = 0;
  1916. @autoreleasepool {
  1917. [self executeTransation:^BOOL{
  1918. [self deleteQueueWithTableName:name conditions:[NSString stringWithFormat:@"where BG_index=%@",@(index)] complete:^(BOOL isSuccess) {
  1919. if(isSuccess) {
  1920. flag++;
  1921. }
  1922. }];
  1923. if(flag){
  1924. [self updateQueueWithTableName:name valueDict:nil conditions:[NSString stringWithFormat:@"set BG_index=BG_index-1 where BG_index>%@",@(index)] complete:^(BOOL isSuccess) {
  1925. if(isSuccess) {
  1926. flag++;
  1927. }
  1928. }];
  1929. }
  1930. return flag==2;
  1931. }];
  1932. }
  1933. dispatch_semaphore_signal(self.semaphore);
  1934. return flag==2;
  1935. }
  1936. #pragma mark 存储字典.
  1937. /**
  1938. 直接存储字典.
  1939. */
  1940. -(void)saveDictionary:(NSDictionary* _Nonnull)dictionary complete:(bg_complete_B)complete{
  1941. NSAssert(dictionary||dictionary.allKeys.count,@"字典不能为空!");
  1942. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1943. @autoreleasepool {
  1944. __weak typeof(self) BGSelf = self;
  1945. NSString* const tableName = @"BG_Dictionary";
  1946. [self isExistWithTableName:tableName complete:^(BOOL isSuccess) {
  1947. if (!isSuccess) {
  1948. [BGSelf createTableWithTableName:tableName keys:@[[NSString stringWithFormat:@"%@*i",bg_primaryKey],@"key*@\"NSString\"",@"value*@\"NSString\""] unionPrimaryKeys:nil uniqueKeys:@[@"key"] complete:nil];
  1949. }
  1950. }];
  1951. __block NSInteger num = 0;
  1952. [self executeTransation:^BOOL{
  1953. [dictionary enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull value, BOOL * _Nonnull stop){
  1954. NSString* type = [NSString stringWithFormat:@"@\"%@\"",NSStringFromClass([value class])];
  1955. id sqlValue = [BGTool getSqlValue:value type:type encode:YES];
  1956. sqlValue = [NSString stringWithFormat:@"%@$$$%@",sqlValue,type];
  1957. NSDictionary* dict = @{@"BG_key":key,@"BG_value":sqlValue};
  1958. [self insertIntoTableName:tableName Dict:dict complete:^(BOOL isSuccess) {
  1959. if(isSuccess) {
  1960. num++;
  1961. }
  1962. }];
  1963. }];
  1964. return YES;
  1965. }];
  1966. bg_completeBlock(dictionary.allKeys.count==num);
  1967. }
  1968. dispatch_semaphore_signal(self.semaphore);
  1969. }
  1970. /**
  1971. 添加字典元素.
  1972. */
  1973. -(BOOL)bg_setValue:(id _Nonnull)value forKey:(NSString* const _Nonnull)key{
  1974. NSAssert(key,@"key不能为空!");
  1975. NSAssert(value,@"value不能为空!");
  1976. NSDictionary* dict = @{key:value};
  1977. __block BOOL result;
  1978. [self saveDictionary:dict complete:^(BOOL isSuccess) {
  1979. result = isSuccess;
  1980. }];
  1981. return result;
  1982. }
  1983. /**
  1984. 更新字典元素.
  1985. */
  1986. -(BOOL)bg_updateValue:(id _Nonnull)value forKey:(NSString* const _Nonnull)key{
  1987. NSAssert(key,@"key不能为空!");
  1988. NSAssert(value,@"value不能为空!");
  1989. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  1990. __block BOOL result;
  1991. @autoreleasepool{
  1992. NSString* type = [NSString stringWithFormat:@"@\"%@\"",NSStringFromClass([value class])];
  1993. id sqlvalue = [BGTool getSqlValue:value type:type encode:YES];
  1994. sqlvalue = [NSString stringWithFormat:@"%@$$$%@",sqlvalue,type];
  1995. NSDictionary* dict = @{@"BG_value":sqlvalue};
  1996. NSString* const tableName = @"BG_Dictionary";
  1997. [self updateWithTableName:tableName valueDict:dict where:@[@"key",@"=",key] complete:^(BOOL isSuccess) {
  1998. result = isSuccess;
  1999. }];
  2000. }
  2001. dispatch_semaphore_signal(self.semaphore);
  2002. return result;
  2003. }
  2004. /**
  2005. 遍历字典元素.
  2006. */
  2007. -(void)bg_enumerateKeysAndObjectsUsingBlock:(void (^ _Nonnull)(NSString* _Nonnull key, id _Nonnull value,BOOL *stop))block{
  2008. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  2009. @autoreleasepool{
  2010. NSString* const tableName = @"BG_Dictionary";
  2011. NSString* condition = [NSString stringWithFormat:@"order by %@ asc",bg_sqlKey(bg_primaryKey)];
  2012. [self queryQueueWithTableName:tableName conditions:condition complete:^(NSArray * _Nullable array) {
  2013. BOOL stopFlag = NO;
  2014. for(NSDictionary* dict in array){
  2015. NSArray* keyAndTypes = [dict[@"BG_value"] componentsSeparatedByString:@"$$$"];
  2016. NSString* key = dict[@"BG_key"];
  2017. id value = [keyAndTypes firstObject];
  2018. NSString* type = [keyAndTypes lastObject];
  2019. value = [BGTool getSqlValue:value type:type encode:NO];
  2020. !block?:block(key,value,&stopFlag);
  2021. if(stopFlag){
  2022. break;
  2023. }
  2024. }
  2025. }];
  2026. }
  2027. dispatch_semaphore_signal(self.semaphore);
  2028. }
  2029. /**
  2030. 获取字典元素.
  2031. */
  2032. -(id _Nullable)bg_valueForKey:(NSString* const _Nonnull)key{
  2033. NSAssert(key,@"key不能为空!");
  2034. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  2035. __block id resultValue = nil;
  2036. @autoreleasepool {
  2037. NSString* const tableName = @"BG_Dictionary";
  2038. [self queryQueueWithTableName:tableName conditions:[NSString stringWithFormat:@"where BG_key='%@'",key] complete:^(NSArray * _Nullable array){
  2039. if(array&&array.count){
  2040. NSDictionary* dict = [array firstObject];
  2041. NSArray* keyAndTypes = [dict[@"BG_value"] componentsSeparatedByString:@"$$$"];
  2042. id value = [keyAndTypes firstObject];
  2043. NSString* type = [keyAndTypes lastObject];
  2044. resultValue = [BGTool getSqlValue:value type:type encode:NO];
  2045. }
  2046. }];
  2047. }
  2048. dispatch_semaphore_signal(self.semaphore);
  2049. return resultValue;
  2050. }
  2051. /**
  2052. 删除字典元素.
  2053. */
  2054. -(BOOL)bg_deleteValueForKey:(NSString* const _Nonnull)key{
  2055. NSAssert(key,@"key不能为空!");
  2056. dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
  2057. __block BOOL result;
  2058. @autoreleasepool {
  2059. NSString* const tableName = @"BG_Dictionary";
  2060. [self deleteQueueWithTableName:tableName conditions:[NSString stringWithFormat:@"where BG_key='%@'",key] complete:^(BOOL isSuccess) {
  2061. result = isSuccess;
  2062. }];
  2063. }
  2064. dispatch_semaphore_signal(self.semaphore);
  2065. return result;
  2066. }
  2067. @end