// // DBOperation.m // zhuxun // // Created by winsoft on 17/4/24. // // #import "DBOperation.h" #import #import "DBConfigureCenter.h" #import //static FMDatabaseQueue *dbqueue; @interface DBOperation() @property (nonatomic , strong) FMDatabaseQueue *dbqueue; @end @implementation DBOperation + (instancetype)dbOperationWithPath:(NSString *)path { DBOperation *dbOperation = [[DBOperation alloc]init]; if (!dbOperation.dbqueue) { dbOperation.dbqueue = [FMDatabaseQueue databaseQueueWithPath:path]; } return dbOperation; } - (void)creatDBbySQL:(NSString *)sql Path:(NSString *)path { [self.dbqueue inDatabase:^(FMDatabase *db) { [db executeUpdate:sql]; }]; //dbqueue = [FMDatabaseQueue databaseQueueWithPath:path]; // if (dbqueue == nil) { // dbqueue = [FMDatabaseQueue databaseQueueWithPath:path]; // } // // [dbqueue inDatabase:^(FMDatabase *db) { // [db executeUpdate:sql]; // // }]; } - (void)creatDBWithTableName:(NSString *)tableName dbModelClass:(Class)dbModelClass Path:(NSString *)path autoUpgrade:(BOOL)autoUpgrade uniqueCloumName:(NSString *)uniqueCloumName { NSString *sql = [DBConfigureCenter getDBTableWithTableName:tableName className:dbModelClass]; [self creatDBbySQL:sql Path:path]; //自动升级. if (autoUpgrade) { [self judgeCloumExistAndAutoUpdateWithTableName:tableName allCloumnName_TypeArray:[DBConfigureCenter sqlCloumnCheckWithClassName:dbModelClass]]; } if (uniqueCloumName.length) { NSString *indexSql = [NSString stringWithFormat:@"create unique index %@_index_%@ on %@(%@)",tableName,uniqueCloumName,tableName,uniqueCloumName]; [self addDataToDBWithSQL:indexSql]; } } //自动升级. - (void)judgeCloumExistAndAutoUpdateWithTableName:(NSString *)tableName allCloumnName_TypeArray:(NSArray *)allCloumnName_TypeArray { NSString *sql = [NSString stringWithFormat:@"pragma table_info (%@)",tableName]; __weak typeof(self)weakself = self; [self quaryDBbySQL:sql result:^(NSMutableArray *array) { NSArray *dbStructArray = [DBStructModel mj_objectArrayWithKeyValuesArray:array]; for (DBStructModel *dbModel in allCloumnName_TypeArray) { NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@",dbModel.name]; //如果name在数据库返回的字段内找不到,则插入. NSArray *targetKeyArray = [dbStructArray filteredArrayUsingPredicate:predicate]; if (!targetKeyArray.count) { NSString *alertStr = [NSString stringWithFormat:@"ALTER TABLE %@ ADD %@ %@",tableName,dbModel.name,dbModel.type]; [weakself addDataToDBWithSQL:alertStr]; } } }]; } //查询目标群组 - (void)quaryDBbySQL:(NSString *)sql result:(void(^)(NSMutableArray *array))result { __block FMResultSet *rs = nil; NSMutableArray *tempArray = [NSMutableArray array]; [self.dbqueue inDatabase:^(FMDatabase *db) { rs = [db executeQuery:sql]; while (rs.next) { //获取nsdata // NSData *data = rs.resultDictionary ;//[rs dataForColumn:nil]; // //将nsdata转成weibostatusmodel // GroupObject *groupObject = [NSKeyedUnarchiver unarchiveObjectWithData:data]; // [tempArray addObject:groupObject]; NSDictionary *dict = rs.resultDictionary; [tempArray addObject:dict]; } }]; if (tempArray.count) { result(tempArray); }else result (nil); } //插入模型 - (void)addDataDBWithTableName:(NSString *)tableName model:(id)model { NSString *sql = [self getInsertModelSqlWithTableName:tableName model:model]; [self addDataToDBWithSQL:sql]; } - (void)addDatasDBWithTableName:(NSString *)tableName models:(NSArray *)models { NSMutableArray *tempSqlsArray = [NSMutableArray array]; for (id model in models) { [tempSqlsArray addObject:[self getInsertModelSqlWithTableName:tableName model:model]]; } [self addDatasToDBWithSQLs:tempSqlsArray]; } - (void)addDataToDBWithSQL:(NSString *)sql { [self.dbqueue inDatabase:^(FMDatabase *db) { [db executeUpdate:sql]; }]; } - (void)addDatasToDBWithSQLs:(NSArray *)sqls { [self.dbqueue inDatabase:^(FMDatabase *db) { #ifdef DEBUG db.logsErrors = YES; #else db.logsErrors = NO; #endif NSLog(@"start1111111111"); [db beginTransaction]; @try { for (NSString *sql in sqls) { [db executeUpdate:sql]; } } @catch (NSException *exception) { [db rollback]; } @finally { [db commit]; } NSLog(@"end1111111111"); }]; } - (NSString *)getInsertModelSqlWithTableName:(NSString *)tableName model:(id)model { Class cls = [model class]; unsigned int ivarsCnt = 0; // 获取类成员变量列表,ivarsCnt为类成员数量 Ivar *ivars = class_copyIvarList(cls, &ivarsCnt); // 遍历成员变量列表,其中每个变量都是Ivar类型的结构体 int i = 0; NSMutableArray *keys = [NSMutableArray array]; NSMutableArray *values = [NSMutableArray array]; // NSMutableArray *valueSqlSymbol = [NSMutableArray array]; for (const Ivar *p = ivars; p < ivars + ivarsCnt; ++p) { Ivar const ivar = *p; // 获取变量名 NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)]; // 若此变量未在类结构体中声明而只声明为Property,则变量名加前缀 '_'下划线 // 比如 @property(retain) NSString *abc;则 key == _abc; // 获取变量值 id value = [model valueForKey:key]; // id value = [self valueForKey:key]; // 取得变量类型 // 通过 type[0]可以判断其具体的内置类型 // const char *type = ivar_getTypeEncoding(ivar); if(value) { BOOL strValue = NO; if ([value isKindOfClass:[NSString class]]) { strValue = YES; NSString *strValue = value; if (!strValue.length) { continue; } } [keys addObject:[key substringFromIndex:1]]; //字符串需要新增一个'',如果是字典对象呢? if (strValue) { [values addObject:[NSString stringWithFormat:@"'%@'",value]]; }else [values addObject:value]; // [valueSqlSymbol addObject:@"?"]; } i++; } free(ivars); NSString *fileKeyListStr = [keys componentsJoinedByString:@","]; NSString *fileValueListStr = [values componentsJoinedByString:@","]; NSString *SQL = [NSString stringWithFormat:@"insert into %@ (%@) values(%@)",tableName,fileKeyListStr,fileValueListStr]; return SQL; } @end