BGDB.m 87 KB

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