LKDBHelper.m 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. //
  2. // LKDBHelper.m
  3. // upin
  4. //
  5. // Created by Fanhuan on 12-12-6.
  6. // Copyright (c) 2012年 linggan. All rights reserved.
  7. //
  8. #import "LKDBHelper.h"
  9. #define checkClassIsInvalid(modelClass)if([LKDBUtils checkStringIsEmpty:[modelClass getTableName]]){\
  10. LKLog(@"model class name %@ table name is invalid!",NSStringFromClass(modelClass));\
  11. return NO;}
  12. #define checkModelIsInvalid(model)if(model == nil){LKLog(@"model is nil");return NO;}checkClassIsInvalid(model.class)
  13. @interface LKDBHelper()
  14. @property(unsafe_unretained,nonatomic)FMDatabase* usingdb;
  15. @property(strong,nonatomic)FMDatabaseQueue* bindingQueue;
  16. @property(copy,nonatomic)NSString* dbname;
  17. @property(strong,nonatomic)NSRecursiveLock* threadLock;
  18. @property(strong,nonatomic)LKTableManager* tableManager;
  19. @end
  20. @implementation LKDBHelper
  21. #pragma mark- deprecated
  22. +(LKDBHelper *)sharedDBHelper
  23. {return [LKDBHelper getUsingLKDBHelper];}
  24. #pragma mark-
  25. -(id)initWithDBName:(NSString *)dbname
  26. {
  27. self = [super init];
  28. if (self) {
  29. self.threadLock = [[NSRecursiveLock alloc]init];
  30. [self setDBName:dbname];
  31. }
  32. return self;
  33. }
  34. - (id)init
  35. {
  36. return [self initWithDBName:@"FreeMusic"];
  37. }
  38. -(void)setDBName:(NSString *)fileName
  39. {
  40. if([self.dbname isEqualToString:fileName] == NO)
  41. {
  42. if([fileName hasSuffix:@".db"] == NO)
  43. {
  44. self.dbname = [NSString stringWithFormat:@"%@.db",fileName];
  45. }
  46. else
  47. {
  48. self.dbname = fileName;
  49. }
  50. [self.bindingQueue close];
  51. self.bindingQueue = [[FMDatabaseQueue alloc]initWithPath:[LKDBUtils getPathForDocuments:self.dbname inDir:nil]];
  52. #ifdef DEBUG
  53. //debug 模式下 打印错误日志
  54. [_bindingQueue inDatabase:^(FMDatabase *db) {
  55. db.logsErrors = YES;
  56. }];
  57. #endif
  58. self.tableManager = [[LKTableManager alloc]initWithLKDBHelper:self];
  59. }
  60. }
  61. #pragma mark- core
  62. -(void)executeDB:(void (^)(FMDatabase *db))block
  63. {
  64. [_threadLock lock];
  65. if(self.usingdb != nil)
  66. {
  67. block(self.usingdb);
  68. }
  69. else
  70. {
  71. [_bindingQueue inDatabase:^(FMDatabase *db) {
  72. self.usingdb = db;
  73. block(db);
  74. self.usingdb = nil;
  75. }];
  76. }
  77. [_threadLock unlock];
  78. }
  79. -(BOOL)executeSQL:(NSString *)sql arguments:(NSArray *)args
  80. {
  81. __block BOOL execute = NO;
  82. [self executeDB:^(FMDatabase *db) {
  83. if(args.count>0)
  84. execute = [db executeUpdate:sql withArgumentsInArray:args];
  85. else
  86. execute = [db executeUpdate:sql];
  87. }];
  88. return execute;
  89. }
  90. -(NSString *)executeScalarWithSQL:(NSString *)sql arguments:(NSArray *)args
  91. {
  92. __block NSString* scalar = nil;
  93. [self executeDB:^(FMDatabase *db) {
  94. FMResultSet* set = nil;
  95. if(args.count>0)
  96. set = [db executeQuery:sql withArgumentsInArray:args];
  97. else
  98. set = [db executeQuery:sql];
  99. if([set columnCount]>0 && [set next])
  100. {
  101. scalar = [set stringForColumnIndex:0];
  102. }
  103. [set close];
  104. }];
  105. return scalar;
  106. }
  107. //splice 'where' 拼接where语句
  108. - (NSMutableArray *)extractQuery:(NSMutableString *)query where:(id)where
  109. {
  110. NSMutableArray* values = nil;
  111. if([where isKindOfClass:[NSString class]] && [LKDBUtils checkStringIsEmpty:where]==NO)
  112. {
  113. [query appendFormat:@" where %@",where];
  114. }
  115. else if ([where isKindOfClass:[NSDictionary class]] && [(NSArray* )where count] > 0)
  116. {
  117. values = [NSMutableArray arrayWithCapacity:[(NSArray* )where count]];
  118. NSString* wherekey = [self dictionaryToSqlWhere:where andValues:values];
  119. [query appendFormat:@" where %@",wherekey];
  120. }
  121. return values;
  122. }
  123. //dic where parse
  124. -(NSString*)dictionaryToSqlWhere:(NSDictionary*)dic andValues:(NSMutableArray*)values
  125. {
  126. NSMutableString* wherekey = [NSMutableString stringWithCapacity:0];
  127. if(dic != nil && dic.count >0 )
  128. {
  129. NSArray* keys = dic.allKeys;
  130. for (int i=0; i< keys.count;i++) {
  131. NSString* key = [keys objectAtIndex:i];
  132. id va = [dic objectForKey:key];
  133. if([va isKindOfClass:[NSArray class]])
  134. {
  135. NSArray* vlist = va;
  136. if(vlist.count==0)
  137. continue;
  138. if(wherekey.length > 0)
  139. [wherekey appendString:@" and"];
  140. [wherekey appendFormat:@" %@ in(",key];
  141. for (int j=0; j<vlist.count; j++) {
  142. [wherekey appendString:@"?"];
  143. if(j== vlist.count-1)
  144. [wherekey appendString:@")"];
  145. else
  146. [wherekey appendString:@","];
  147. [values addObject:[vlist objectAtIndex:j]];
  148. }
  149. }
  150. else
  151. {
  152. if(wherekey.length > 0)
  153. [wherekey appendFormat:@" and %@=?",key];
  154. else
  155. [wherekey appendFormat:@" %@=?",key];
  156. [values addObject:va];
  157. }
  158. }
  159. }
  160. return wherekey;
  161. }
  162. //where sql statements about model primary keys
  163. -(NSMutableString*)primaryKeyWhereSQLWithModel:(NSObject*)model addPValues:(NSMutableArray*)addPValues
  164. {
  165. LKModelInfos* infos = [model.class getModelInfos];
  166. NSArray* primaryKeys = infos.primaryKeys;
  167. NSMutableString* pwhere = [NSMutableString string];
  168. if(primaryKeys.count>0)
  169. {
  170. for (int i=0; i<primaryKeys.count; i++) {
  171. NSString* pk = [primaryKeys objectAtIndex:i];
  172. if([LKDBUtils checkStringIsEmpty:pk] == NO)
  173. {
  174. LKDBProperty* property = [infos objectWithSqlColumeName:pk];
  175. id pvalue = nil;
  176. if(property && [property.type isEqualToString:LKSQLUserCalculate])
  177. {
  178. pvalue = [model userGetValueForModel:property];
  179. }
  180. else if(pk && property)
  181. {
  182. pvalue = [model modelGetValue:property];
  183. }
  184. if(pvalue)
  185. {
  186. if(pwhere.length>0)
  187. [pwhere appendString:@"and"];
  188. if(addPValues)
  189. {
  190. [pwhere appendFormat:@" %@=? ",pk];
  191. [addPValues addObject:pvalue];
  192. }
  193. else
  194. {
  195. [pwhere appendFormat:@" %@='%@' ",pk,pvalue];
  196. }
  197. }
  198. }
  199. }
  200. }
  201. return pwhere;
  202. }
  203. #pragma mark- dealloc
  204. -(void)dealloc
  205. {
  206. [self.bindingQueue close];
  207. self.usingdb = nil;
  208. self.bindingQueue = nil;
  209. self.dbname = nil;
  210. self.tableManager = nil;
  211. self.threadLock = nil;
  212. }
  213. @end
  214. @implementation LKDBHelper(DatabaseManager)
  215. -(void)dropAllTable
  216. {
  217. [self executeDB:^(FMDatabase *db) {
  218. FMResultSet* set = [db executeQuery:@"select name from sqlite_master where type='table'"];
  219. NSMutableArray* dropTables = [NSMutableArray arrayWithCapacity:0];
  220. while ([set next]) {
  221. [dropTables addObject:[set stringForColumnIndex:0]];
  222. }
  223. [set close];
  224. for (NSString* tableName in dropTables) {
  225. NSString* dropTable = [NSString stringWithFormat:@"drop table %@",tableName];
  226. [db executeUpdate:dropTable];
  227. }
  228. }];
  229. [self.tableManager clearTableInfos];
  230. }
  231. -(BOOL)dropTableWithClass:(Class)modelClass
  232. {
  233. checkClassIsInvalid(modelClass);
  234. NSString* tableName = [modelClass getTableName];
  235. NSString* dropTable = [NSString stringWithFormat:@"drop table %@",tableName];
  236. BOOL isDrop = [self executeSQL:dropTable arguments:nil];
  237. if(isDrop)
  238. [_tableManager setTableName:tableName version:0];
  239. return isDrop;
  240. }
  241. -(BOOL)createTableWithModelClass:(Class)modelClass
  242. {
  243. checkClassIsInvalid(modelClass);
  244. NSString* tableName = [modelClass getTableName];
  245. int oldVersion = [_tableManager versionWithName:tableName];
  246. int newVersion = [modelClass getTableVersion];
  247. if(oldVersion>0 && oldVersion != newVersion)
  248. {
  249. LKTableUpdateType userOperation = [modelClass tableUpdateForOldVersion:oldVersion newVersion:newVersion];
  250. switch (userOperation) {
  251. case LKTableUpdateTypeDeleteOld:
  252. {
  253. [self dropTableWithClass:modelClass];
  254. }
  255. break;
  256. case LKTableUpdateTypeDefault:
  257. return NO;
  258. case LKTableUpdateTypeCustom:
  259. [_tableManager setTableName:tableName version:newVersion];
  260. return YES;
  261. }
  262. }
  263. else if(oldVersion == newVersion)
  264. {
  265. __block BOOL isTableCreated = NO;
  266. [self executeDB:^(FMDatabase *db) {
  267. FMResultSet* set = [db executeQuery:@"select count(name) from sqlite_master where type='table' and name=?",tableName];
  268. [set next];
  269. if([set intForColumnIndex:0]>0)
  270. {
  271. isTableCreated = YES;
  272. }
  273. [set close];
  274. }];
  275. if(isTableCreated)
  276. {
  277. //已创建表 就跳过
  278. return YES;
  279. }
  280. }
  281. LKModelInfos* infos = [modelClass getModelInfos];
  282. NSArray* primaryKeys = infos.primaryKeys;
  283. NSMutableString* table_pars = [NSMutableString string];
  284. for (int i=0; i<infos.count; i++) {
  285. if(i > 0)
  286. [table_pars appendString:@","];
  287. LKDBProperty* property = [infos objectWithIndex:i];
  288. [modelClass columeAttributeWithProperty:property];
  289. [table_pars appendFormat:@"%@ %@",property.sqlColumeName,property.sqlColumeType];
  290. if([property.sqlColumeType isEqualToString:LKSQLText])
  291. {
  292. if(property.length>0)
  293. {
  294. [table_pars appendFormat:@"(%d)",property.length];
  295. }
  296. }
  297. if(property.isNotNull)
  298. {
  299. [table_pars appendFormat:@" %@",LKSQLNotNull];
  300. }
  301. if(property.isUnique)
  302. {
  303. [table_pars appendFormat:@" %@",LKSQLUnique];
  304. }
  305. if(property.checkValue)
  306. {
  307. [table_pars appendFormat:@" %@(%@)",LKSQLCheck,property.checkValue];
  308. }
  309. if(property.defaultValue)
  310. {
  311. [table_pars appendFormat:@" %@ %@",LKSQLDefault,property.defaultValue];
  312. }
  313. }
  314. NSMutableString* pksb = [NSMutableString string];
  315. if(primaryKeys.count>0)
  316. {
  317. pksb = [NSMutableString stringWithString:@",primary key("];
  318. for (int i=0; i<primaryKeys.count; i++) {
  319. NSString* pk = [primaryKeys objectAtIndex:i];
  320. if(i>0)
  321. [pksb appendString:@","];
  322. [pksb appendString:pk];
  323. }
  324. [pksb appendString:@")"];
  325. }
  326. NSString* createTableSQL = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@(%@%@)",tableName,table_pars,pksb];
  327. BOOL isCreated = [self executeSQL:createTableSQL arguments:nil];
  328. if(isCreated)
  329. [_tableManager setTableName:tableName version:newVersion];
  330. return isCreated;
  331. }
  332. @end
  333. @implementation LKDBHelper(DatabaseExecute)
  334. -(id)modelValueWithProperty:(LKDBProperty *)property model:(NSObject *)model {
  335. id value = nil;
  336. if(property.isUserCalculate)
  337. {
  338. value = [model userGetValueForModel:property];
  339. }
  340. else
  341. {
  342. value = [model modelGetValue:property];
  343. }
  344. if(value == nil)
  345. {
  346. value = @"";
  347. }
  348. return value;
  349. }
  350. -(void)asyncBlock:(void(^)(void))block
  351. {
  352. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),block);
  353. }
  354. #pragma mark - row count operation
  355. -(int)rowCount:(Class)modelClass where:(id)where
  356. {
  357. return [self rowCountBase:modelClass where:where];
  358. }
  359. -(void)rowCount:(Class)modelClass where:(id)where callback:(void (^)(int))callback
  360. {
  361. [self asyncBlock:^{
  362. int result = [self rowCountBase:modelClass where:where];
  363. if(callback != nil)
  364. {
  365. callback(result);
  366. }
  367. }];
  368. }
  369. -(int)rowCountBase:(Class)modelClass where:(id)where
  370. {
  371. NSMutableString* rowCountSql = [NSMutableString stringWithFormat:@"select count(rowid) from %@",[modelClass getTableName]];
  372. NSMutableArray* valuesarray = [self extractQuery:rowCountSql where:where];
  373. int result = [[self executeScalarWithSQL:rowCountSql arguments:valuesarray] intValue];
  374. return result;
  375. }
  376. #pragma mark- search operation
  377. -(NSMutableArray *)search:(Class)modelClass where:(id)where orderBy:(NSString *)orderBy offset:(int)offset count:(int)count
  378. {
  379. return [self searchBase:modelClass where:where orderBy:orderBy offset:offset count:count];
  380. }
  381. -(id)searchSingle:(Class)modelClass where:(id)where orderBy:(NSString *)orderBy
  382. {
  383. NSMutableArray* array = [self searchBase:modelClass where:where orderBy:orderBy offset:0 count:1];
  384. if(array.count>0)
  385. return [array objectAtIndex:0];
  386. return nil;
  387. }
  388. -(void)search:(Class)modelClass where:(id)where orderBy:(NSString *)orderBy offset:(int)offset count:(int)count callback:(void (^)(NSMutableArray *))block
  389. {
  390. [self asyncBlock:^{
  391. NSMutableArray* array = [self searchBase:modelClass where:where orderBy:orderBy offset:offset count:count];
  392. if(block != nil)
  393. block(array);
  394. }];
  395. }
  396. -(NSMutableArray *)searchBase:(Class)modelClass where:(id)where orderBy:(NSString *)orderBy offset:(int)offset count:(int)count
  397. {
  398. NSMutableString* query = [NSMutableString stringWithFormat:@"select rowid,* from %@",[modelClass getTableName]];
  399. NSMutableArray * values = [self extractQuery:query where:where];
  400. [self sqlString:query AddOder:orderBy offset:offset count:count];
  401. __block NSMutableArray* results = nil;
  402. [self executeDB:^(FMDatabase *db) {
  403. FMResultSet* set = nil;
  404. if(values == nil)
  405. set = [db executeQuery:query];
  406. else
  407. set = [db executeQuery:query withArgumentsInArray:values];
  408. results = [self executeResult:set Class:modelClass];
  409. [set close];
  410. }];
  411. return results;
  412. }
  413. -(void)sqlString:(NSMutableString*)sql AddOder:(NSString*)orderby offset:(int)offset count:(int)count
  414. {
  415. if([LKDBUtils checkStringIsEmpty:orderby] == NO)
  416. {
  417. [sql appendFormat:@" order by %@",orderby];
  418. }
  419. if(count>0)
  420. {
  421. [sql appendFormat:@" limit %d offset %d",count,offset];
  422. }
  423. }
  424. - (NSMutableArray *)executeResult:(FMResultSet *)set Class:(Class)modelClass
  425. {
  426. NSMutableArray* array = [NSMutableArray arrayWithCapacity:0];
  427. LKModelInfos* infos = [modelClass getModelInfos];
  428. int columeCount = [set columnCount];
  429. while ([set next]) {
  430. NSObject* bindingModel = [[modelClass alloc]init];
  431. bindingModel.rowid = [set intForColumnIndex:0];
  432. for (int i=1; i<columeCount; i++) {
  433. NSString* sqlName = [set columnNameForIndex:i];
  434. NSString* sqlValue = [set stringForColumnIndex:i];
  435. LKDBProperty* property = [infos objectWithSqlColumeName:sqlName];
  436. if(property.propertyName && [property.type isEqualToString:LKSQLUserCalculate] ==NO)
  437. {
  438. [bindingModel modelSetValue:property value:sqlValue];
  439. }
  440. else
  441. {
  442. [bindingModel userSetValueForModel:property value:sqlValue];
  443. }
  444. }
  445. [array addObject:bindingModel];
  446. }
  447. return array;
  448. }
  449. #pragma mark- insert operation
  450. -(BOOL)insertToDB:(NSObject *)model
  451. {
  452. return [self insertBase:model];
  453. }
  454. -(void)insertToDB:(NSObject *)model callback:(void (^)(BOOL))block
  455. {
  456. [self asyncBlock:^{
  457. BOOL result = [self insertBase:model];
  458. if(block != nil)
  459. {
  460. block(result);
  461. }
  462. }];
  463. }
  464. -(BOOL)insertWhenNotExists:(NSObject *)model
  465. {
  466. if([self isExistsModel:model]==NO)
  467. {
  468. return [self insertToDB:model];
  469. }
  470. return NO;
  471. }
  472. -(void)insertWhenNotExists:(NSObject *)model callback:(void (^)(BOOL))block
  473. {
  474. [self asyncBlock:^{
  475. if(block != nil)
  476. {
  477. block([self insertWhenNotExists:model]);
  478. }
  479. else
  480. {
  481. [self insertWhenNotExists:model];
  482. }
  483. }];
  484. }
  485. -(BOOL)insertBase:(NSObject*)model{
  486. checkModelIsInvalid(model);
  487. Class modelClass = model.class;
  488. //callback
  489. [modelClass dbWillInsert:model];
  490. //--
  491. LKModelInfos* infos = [modelClass getModelInfos];
  492. NSMutableString* insertKey = [NSMutableString stringWithCapacity:0];
  493. NSMutableString* insertValuesString = [NSMutableString stringWithCapacity:0];
  494. NSMutableArray* insertValues = [NSMutableArray arrayWithCapacity:infos.count];
  495. for (int i=0; i<infos.count; i++) {
  496. LKDBProperty* property = [infos objectWithIndex:i];
  497. if([LKDBUtils checkStringIsEmpty:property.sqlColumeName])
  498. continue;
  499. if(i>0)
  500. {
  501. [insertKey appendString:@","];
  502. [insertValuesString appendString:@","];
  503. }
  504. [insertKey appendString:property.sqlColumeName];
  505. [insertValuesString appendString:@"?"];
  506. id value = [self modelValueWithProperty:property model:model];
  507. [insertValues addObject:value];
  508. }
  509. //拼接insertSQL 语句 采用 replace 插入
  510. NSString* insertSQL = [NSString stringWithFormat:@"replace into %@(%@) values(%@)",[modelClass getTableName],insertKey,insertValuesString];
  511. __block BOOL execute = NO;
  512. __block int lastInsertRowId = 0;
  513. [self executeDB:^(FMDatabase *db) {
  514. execute = [db executeUpdate:insertSQL withArgumentsInArray:insertValues];
  515. lastInsertRowId= (int)db.lastInsertRowId;
  516. }];
  517. model.rowid = lastInsertRowId;
  518. if(execute == NO)
  519. LKLog(@"database insert fail %@, sql:%@",NSStringFromClass(modelClass),insertSQL);
  520. //callback
  521. [modelClass dbDidInserted:model result:execute];
  522. return execute;
  523. }
  524. #pragma mark- update operation
  525. -(BOOL)updateToDB:(NSObject *)model where:(id)where
  526. {
  527. return [self updateToDBBase:model where:where];
  528. }
  529. -(void)updateToDB:(NSObject *)model where:(id)where callback:(void (^)(BOOL))block
  530. {
  531. [self asyncBlock:^{
  532. BOOL result = [self updateToDBBase:model where:where];
  533. if(block != nil)
  534. block(result);
  535. }];
  536. }
  537. -(BOOL)updateToDBBase:(NSObject *)model where:(id)where
  538. {
  539. checkModelIsInvalid(model);
  540. Class modelClass = model.class;
  541. //callback
  542. [modelClass dbWillUpdate:model];
  543. LKModelInfos* infos = [modelClass getModelInfos];
  544. NSMutableString* updateKey = [NSMutableString string];
  545. NSMutableArray* updateValues = [NSMutableArray arrayWithCapacity:infos.count];
  546. for (int i=0; i<infos.count; i++) {
  547. LKDBProperty* property = [infos objectWithIndex:i];
  548. if(i>0)
  549. [updateKey appendString:@","];
  550. [updateKey appendFormat:@"%@=?",property.sqlColumeName];
  551. id value = [self modelValueWithProperty:property model:model];
  552. [updateValues addObject:value];
  553. }
  554. NSMutableString* updateSQL = [NSMutableString stringWithFormat:@"update %@ set %@ where ",[modelClass getTableName],updateKey];
  555. //添加where 语句
  556. if([where isKindOfClass:[NSString class]] && [LKDBUtils checkStringIsEmpty:where]== NO)
  557. {
  558. [updateSQL appendString:where];
  559. }
  560. else if([where isKindOfClass:[NSDictionary class]] && [(NSArray* )where count]>0)
  561. {
  562. NSMutableArray* valuearray = [NSMutableArray array];
  563. NSString* sqlwhere = [self dictionaryToSqlWhere:where andValues:valuearray];
  564. [updateSQL appendString:sqlwhere];
  565. [updateValues addObjectsFromArray:valuearray];
  566. }
  567. else if(model.rowid > 0)
  568. {
  569. [updateSQL appendFormat:@" rowid=%d",model.rowid];
  570. }
  571. else
  572. {
  573. //如果不通过 rowid 来 更新数据 那 primarykey 一定要有值
  574. NSString* pwhere = [self primaryKeyWhereSQLWithModel:model addPValues:updateValues];
  575. if(pwhere.length ==0)
  576. {
  577. LKLog(@"database update fail : %@ no find primary key!",NSStringFromClass(modelClass));
  578. return NO;
  579. }
  580. [updateSQL appendString:pwhere];
  581. }
  582. BOOL execute = [self executeSQL:updateSQL arguments:updateValues];
  583. if(execute == NO)
  584. {
  585. LKLog(@"database update fail : %@ -----> update sql: %@",NSStringFromClass(modelClass),updateSQL);
  586. }
  587. //callback
  588. [modelClass dbDidUpdated:model result:execute];
  589. return execute;
  590. }
  591. -(BOOL)updateToDB:(Class)modelClass set:(NSString *)sets where:(id)where
  592. {
  593. checkClassIsInvalid(modelClass);
  594. NSMutableString* updateSQL = [NSMutableString stringWithFormat:@"update %@ set %@ ",[modelClass getTableName],sets];
  595. NSMutableArray* updateValues = [self extractQuery:updateSQL where:where];
  596. BOOL execute = [self executeSQL:updateSQL arguments:updateValues];
  597. if(execute == NO)
  598. LKLog(@"database update fail %@ ----->sql:%@",NSStringFromClass(modelClass),updateSQL);
  599. return execute;
  600. }
  601. #pragma mark - delete operation
  602. -(BOOL)deleteToDB:(NSObject *)model
  603. {
  604. return [self deleteToDBBase:model];
  605. }
  606. -(void)deleteToDB:(NSObject *)model callback:(void (^)(BOOL))block
  607. {
  608. [self asyncBlock:^{
  609. BOOL isDeleted = [self deleteToDBBase:model];
  610. if(block != nil)
  611. block(isDeleted);
  612. }];
  613. }
  614. -(BOOL)deleteToDBBase:(NSObject *)model
  615. {
  616. checkModelIsInvalid(model);
  617. Class modelClass = model.class;
  618. //callback
  619. [modelClass dbWillDelete:model];
  620. NSMutableString* deleteSQL =[NSMutableString stringWithFormat:@"delete from %@ where ",[modelClass getTableName]];
  621. NSMutableArray* parsArray = [NSMutableArray array];
  622. if(model.rowid > 0)
  623. {
  624. [deleteSQL appendFormat:@"rowid = %d",model.rowid];
  625. }
  626. else
  627. {
  628. NSString* pwhere = [self primaryKeyWhereSQLWithModel:model addPValues:parsArray];
  629. if(pwhere.length==0)
  630. {
  631. LKLog(@"delete fail : %@ primary value is nil",NSStringFromClass(modelClass));
  632. return NO;
  633. }
  634. [deleteSQL appendString:pwhere];
  635. }
  636. if(parsArray.count==0)
  637. parsArray = nil;
  638. BOOL execute = [self executeSQL:deleteSQL arguments:parsArray];
  639. //callback
  640. [modelClass dbDidIDeleted:model result:execute];
  641. return execute;
  642. }
  643. -(BOOL)deleteWithClass:(Class)modelClass where:(id)where
  644. {
  645. return [self deleteWithClassBase:modelClass where:where];
  646. }
  647. -(void)deleteWithClass:(Class)modelClass where:(id)where callback:(void (^)(BOOL))block
  648. {
  649. [self asyncBlock:^{
  650. BOOL isDeleted = [self deleteWithClassBase:modelClass where:where];
  651. if (block != nil) {
  652. block(isDeleted);
  653. }
  654. }];
  655. }
  656. -(BOOL)deleteWithClassBase:(Class)modelClass where:(id)where
  657. {
  658. checkClassIsInvalid(modelClass);
  659. NSMutableString* deleteSQL = [NSMutableString stringWithFormat:@"delete from %@",[modelClass getTableName]];
  660. NSMutableArray* values = [self extractQuery:deleteSQL where:where];
  661. BOOL result = [self executeSQL:deleteSQL arguments:values];
  662. return result;
  663. }
  664. #pragma mark - other operation
  665. -(BOOL)isExistsModel:(NSObject *)model
  666. {
  667. checkModelIsInvalid(model);
  668. if(model.rowid>0)
  669. return YES;
  670. else
  671. {
  672. NSMutableString* pwhere = [self primaryKeyWhereSQLWithModel:model addPValues:nil];
  673. if(pwhere.length == 0)
  674. {
  675. LKLog(@"exists model fail: primary key is nil or invalid");
  676. return NO;
  677. }
  678. return [self isExistsClass:model.class where:pwhere];
  679. }
  680. }
  681. -(BOOL)isExistsClass:(Class)modelClass where:(id)where
  682. {
  683. return [self isExistsClassBase:modelClass where:where];
  684. }
  685. -(BOOL)isExistsClassBase:(Class)modelClass where:(id)where
  686. {
  687. return [self rowCount:modelClass where:where] > 0;
  688. }
  689. #pragma mark- clear operation
  690. +(void)clearTableData:(Class)modelClass
  691. {
  692. [[modelClass getUsingLKDBHelper] executeDB:^(FMDatabase *db) {
  693. NSString* delete = [NSString stringWithFormat:@"DELETE FROM %@",[modelClass getTableName]];
  694. [db executeUpdate:delete];
  695. }];
  696. }
  697. +(void)clearNoneImage:(Class)modelClass columes:(NSArray *)columes
  698. {
  699. [self clearFileWithTable:modelClass columes:columes type:1];
  700. }
  701. +(void)clearNoneData:(Class)modelClass columes:(NSArray *)columes
  702. {
  703. [self clearFileWithTable:modelClass columes:columes type:2];
  704. }
  705. #define LKTestDirFilename @"LKTestDirFilename111"
  706. +(void)clearFileWithTable:(Class)modelClass columes:(NSArray*)columes type:(int)type
  707. {
  708. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
  709. NSString* testpath = nil;
  710. switch (type) {
  711. case 1:
  712. testpath = [modelClass getDBImagePathWithName:LKTestDirFilename];
  713. break;
  714. case 2:
  715. testpath = [modelClass getDBDataPathWithName:LKTestDirFilename];
  716. break;
  717. }
  718. if([LKDBUtils checkStringIsEmpty:testpath])
  719. return ;
  720. NSString* dir = [testpath stringByReplacingOccurrencesOfString:LKTestDirFilename withString:@""];
  721. NSInteger count = columes.count;
  722. //获取该目录下所有文件名
  723. NSArray* files = [LKDBUtils getFilenamesWithDir:dir];
  724. NSString* seleteColume = [columes componentsJoinedByString:@","];
  725. NSMutableString* whereStr =[NSMutableString string];
  726. for (int i=0; i<count ; i++) {
  727. [whereStr appendFormat:@" %@ != '' ",[columes objectAtIndex:i]];
  728. if(i< count -1)
  729. {
  730. [whereStr appendString:@" or "];
  731. }
  732. }
  733. NSString* querySql = [NSString stringWithFormat:@"select %@ from %@ where %@",seleteColume,[modelClass getTableName],whereStr];
  734. __block NSArray* dbfiles;
  735. [[modelClass getUsingLKDBHelper] executeDB:^(FMDatabase *db) {
  736. NSMutableArray* tempfiles = [NSMutableArray arrayWithCapacity:6];
  737. FMResultSet* set = [db executeQuery:querySql];
  738. while ([set next]) {
  739. for (int j=0; j<count; j++) {
  740. NSString* str = [set stringForColumnIndex:j];
  741. if([LKDBUtils checkStringIsEmpty:str] ==NO)
  742. {
  743. [tempfiles addObject:str];
  744. }
  745. }
  746. }
  747. [set close];
  748. dbfiles = tempfiles;
  749. }];
  750. //遍历 当不再数据库记录中 就删除
  751. for (NSString* deletefile in files) {
  752. if([dbfiles indexOfObject:deletefile] == NSNotFound)
  753. {
  754. [LKDBUtils deleteWithFilepath:[dir stringByAppendingPathComponent:deletefile]];
  755. }
  756. }
  757. });
  758. }
  759. @end