RQQuestionDBManager.m 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. //
  2. // RQQuestionDBManager.m
  3. // SDJK
  4. //
  5. // Created by 张嵘 on 2021/8/20.
  6. //
  7. #import "RQQuestionDBManager.h"
  8. static NSString *dbNameStr = @"question";
  9. static NSString *dbTypeStr = @"db";
  10. static NSString *questionTableNameStr = @"question_info";
  11. @interface RQQuestionDBManager ()
  12. @property (nonatomic, readwrite, strong) FMDatabaseQueue *databaseQueue;
  13. @end
  14. @implementation RQQuestionDBManager
  15. static id rq_questionDBManager = nil;
  16. #pragma mark - init
  17. + (instancetype)sharedInstance {
  18. static dispatch_once_t onceToken;
  19. dispatch_once(&onceToken, ^{
  20. rq_questionDBManager = [[self alloc] init];
  21. });
  22. return rq_questionDBManager;
  23. }
  24. - (instancetype)init {
  25. if (self = [super init]) {
  26. NSString *resourcePath = [[NSBundle mainBundle] pathForResource:@"question" ofType:@"db"];
  27. [self initDatabaseQueueWithResourcePath:resourcePath];
  28. }
  29. return self;
  30. }
  31. - (void)initDatabaseQueueWithResourcePath:(NSString *)resourcePath {
  32. NSError *error;
  33. NSString *dbPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:[NSString stringWithFormat:@"question.db"]];
  34. if ([RQFileManager isPathExist:dbPath]) {
  35. self.databaseQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
  36. NSLog(@"数据库path-----%@",dbPath);
  37. if ([self getQuestionVersion] >= [self getQuestionVersionWithResourcePath:resourcePath]) {
  38. } else {
  39. [[RQFileManager fileManager] removeItemAtPath:dbPath error:&error];
  40. [[RQFileManager fileManager] copyItemAtPath:resourcePath toPath:[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:[NSString stringWithFormat:@"question.db"]] error:&error];
  41. self.databaseQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
  42. }
  43. } else {
  44. [[RQFileManager fileManager] copyItemAtPath:resourcePath toPath:[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:[NSString stringWithFormat:@"question.db"]] error:&error];
  45. self.databaseQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
  46. NSLog(@"数据库path-----%@",dbPath);
  47. }
  48. }
  49. #pragma mark - Public Method
  50. - (NSArray *)getColumnWithCarType:(RQHomePageCarType)carType subject:(RQHomePageSubjectType)subject pageType:(RQHomeSubPageType)pageType {
  51. /// 默认为轿车 cart,bus,truck
  52. NSString *queryCarTypeStr = @"model LIKE '%cart%'";
  53. switch (carType) {
  54. case RQHomePageCarType_Car:
  55. queryCarTypeStr = @"model LIKE '%cart%'";
  56. break;
  57. case RQHomePageCarType_Bus:
  58. queryCarTypeStr = @"model LIKE '%bus%'";
  59. break;
  60. case RQHomePageCarType_Truck:
  61. queryCarTypeStr = @"model LIKE '%truck%'";
  62. break;
  63. case RQHomePageCarType_Motorcycle:
  64. queryCarTypeStr = @"model LIKE '%mtc%'";
  65. break;
  66. default:
  67. break;
  68. }
  69. /// 默认科目一
  70. NSString *querySubjectTypeStr = @"k1";
  71. switch (subject) {
  72. case RQHomePageSubjectType_SubjectOne:
  73. querySubjectTypeStr = @"k1";
  74. break;
  75. case RQHomePageSubjectType_SubjectTwo:
  76. querySubjectTypeStr = @"k2";
  77. break;
  78. case RQHomePageSubjectType_SubjectThree:
  79. querySubjectTypeStr = @"k3";
  80. break;
  81. case RQHomePageSubjectType_SubjectFour:
  82. querySubjectTypeStr = @"k4";
  83. break;
  84. default:
  85. break;
  86. }
  87. /// 默认顺序练习
  88. NSString *pageTypeStr = @"title";
  89. NSString *pageTypeByOrderStr = @"sort";
  90. switch (pageType) {
  91. case RQHomeSubPageType_SequentialPractice:/// 顺序练习
  92. pageTypeStr = @"title,column_id";
  93. pageTypeByOrderStr = @"sort";
  94. querySubjectTypeStr = [NSString stringWithFormat:@"subject = '%@'",querySubjectTypeStr];
  95. break;
  96. case RQHomeSubPageType_LocalTopics: /// 地方专题
  97. pageTypeStr = @"title,column_id";
  98. pageTypeByOrderStr = @"sort";
  99. querySubjectTypeStr = [NSString stringWithFormat:@"%@_4",querySubjectTypeStr];
  100. querySubjectTypeStr = [NSString stringWithFormat:@"subject = '%@'",querySubjectTypeStr];
  101. break;
  102. case RQHomeSubPageType_ClassificationExercise:/// 分类练习
  103. pageTypeStr = @"title,column_id";
  104. pageTypeByOrderStr = @"sort";
  105. querySubjectTypeStr = [NSString stringWithFormat:@"%@_3",querySubjectTypeStr];
  106. querySubjectTypeStr = [NSString stringWithFormat:@"subject = '%@'",querySubjectTypeStr];
  107. break;
  108. case RQHomeSubPageType_SelectedTestQuestions: //精选考题
  109. pageTypeStr = @"title,column_id";
  110. pageTypeByOrderStr = @"sort";
  111. querySubjectTypeStr = [NSString stringWithFormat:@"%@_2",querySubjectTypeStr];
  112. querySubjectTypeStr = [NSString stringWithFormat:@"subject = '%@'",querySubjectTypeStr];
  113. break;
  114. default:
  115. break;
  116. }
  117. //v1.1.2 旧逻辑
  118. // NSString *queryStr = [NSString stringWithFormat:@"select distinct %@ from question_info where %@ and %@ %@ order by %@ + 0 ASC", pageTypeStr, queryCarTypeStr, querySubjectTypeStr, (pageType == RQHomeSubPageType_LocalTopics)? @"and place_issue IS NOT NULL" : @"", pageTypeByOrderStr];
  119. //v1.1.3
  120. NSString *queryStr = [NSString stringWithFormat:@"select distinct %@ from question_column where %@ and %@ order by %@ + 0 ASC", pageTypeStr, queryCarTypeStr, querySubjectTypeStr, pageTypeByOrderStr];
  121. // select distinct * from WHERE subject = 'k1_2' AND model LIKE '%cart%' order by sort ASC
  122. NSMutableArray *arr = @[].mutableCopy;
  123. @weakify(arr)
  124. [_databaseQueue inTransaction:^(FMDatabase * _Nonnull db, BOOL * _Nonnull rollback) {
  125. @try {
  126. @strongify(arr)
  127. FMResultSet *resultSet = [db executeQuery:queryStr];
  128. while ([resultSet next]) {
  129. if([pageTypeStr containsString:@","]){
  130. NSString *str = [resultSet stringForColumn:@"title"];
  131. NSString *strCol = [resultSet stringForColumn:@"column_id"];
  132. NSString *str_title = [NSString stringWithFormat:@"%@,%@",str,strCol];
  133. // 对应字段来取数据
  134. [arr addObject:str_title? : @"地方题"];
  135. }else{
  136. NSString *str = [resultSet stringForColumn:pageTypeStr];
  137. // 对应字段来取数据
  138. [arr addObject:str? : @"地方题"];
  139. }
  140. }
  141. if ([arr containsObject:@"地方题"] && [arr indexOfObject:@"地方题"] == 0) {
  142. NSString *saveStr = arr.firstObject;
  143. [arr removeFirstObject];
  144. [arr addObject:saveStr];
  145. }
  146. } @catch (NSException *exception) {
  147. *rollback = YES;
  148. } @finally {
  149. *rollback = NO;
  150. }
  151. }];
  152. return arr.copy;
  153. }
  154. - (NSArray *)getQuestionWithCarType:(RQHomePageCarType)carType subject:(RQHomePageSubjectType)subject pageType:(RQHomeSubPageType)pageType name:(NSString *)name exerciseType:(RQExerciseType)exerciseType {
  155. NSMutableArray *arr = @[].mutableCopy;
  156. /// 默认为轿车 cart,bus,truck
  157. NSString *queryCarTypeStr = @"model LIKE '%cart%'";
  158. NSString *carTypeStr = @"cart";
  159. switch (carType) {
  160. case RQHomePageCarType_Car:
  161. queryCarTypeStr = @"model LIKE '%cart%'";
  162. carTypeStr = @"cart";
  163. break;
  164. case RQHomePageCarType_Bus:
  165. queryCarTypeStr = @"model LIKE '%bus%'";
  166. carTypeStr = @"bus";
  167. break;
  168. case RQHomePageCarType_Truck:
  169. queryCarTypeStr = @"model LIKE '%truck%'";
  170. carTypeStr = @"truck";
  171. break;
  172. case RQHomePageCarType_Motorcycle:
  173. queryCarTypeStr = @"model LIKE '%mtc%'";
  174. break;
  175. default:
  176. break;
  177. }
  178. /// 默认科目一
  179. NSString *querySubjectTypeStr = @"subject = 1";
  180. NSString *subjectTypeStr = @"1";
  181. switch (subject) {
  182. case RQHomePageSubjectType_SubjectOne:
  183. querySubjectTypeStr = @"subject = 1";
  184. subjectTypeStr = @"1";
  185. break;
  186. case RQHomePageSubjectType_SubjectTwo:
  187. querySubjectTypeStr = @"subject = 2";
  188. subjectTypeStr = @"2";
  189. break;
  190. case RQHomePageSubjectType_SubjectThree:
  191. querySubjectTypeStr = @"subject = 3";
  192. subjectTypeStr = @"3";
  193. break;
  194. case RQHomePageSubjectType_SubjectFour:
  195. querySubjectTypeStr = @"subject = 4";
  196. subjectTypeStr = @"4";
  197. break;
  198. default:
  199. break;
  200. }
  201. /// 默认顺序练习
  202. // NSString *pageTypeStr = @"seque_issue_name";
  203. // NSString *pageTypeByOrderStr = @"seque_issue";
  204. NSString *nameStr = @"";
  205. NSString *orderStr = @"";
  206. NSString *colidStr = @"";
  207. if([name containsString:@","]){
  208. colidStr = [[name componentsSeparatedByString:@","] lastObject];
  209. }
  210. switch (pageType) {
  211. //// pageTypeStr = @"place_issue_name";
  212. //// pageTypeByOrderStr = @"place_issue";
  213. // nameStr = [NSString stringWithFormat:@"and place_issue_name = '%@'",name];
  214. // orderStr = @"number";
  215. // break;
  216. case RQHomeSubPageType_LocalTopics:
  217. case RQHomeSubPageType_ClassificationExercise:
  218. case RQHomeSubPageType_SequentialPractice:
  219. case RQHomeSubPageType_SelectedTestQuestions:
  220. // pageTypeStr = @"excell_issue_name";
  221. // pageTypeByOrderStr = @"excell_issue";
  222. nameStr = [NSString stringWithFormat:@"(INSTR ( column_all, ',' || '%@' || ',' ) > 0 OR INSTR ( column_all, '%@' || ',' ) = 1 OR INSTR ( column_all, ',' || '%@' ) = ( length( column_all ) - length( ',' || '%@' ) ) + 1 OR column_all = '%@')",colidStr,colidStr,colidStr,colidStr,colidStr];
  223. orderStr = @"number";
  224. break;
  225. default:
  226. break;
  227. }
  228. if (RQStringIsEmpty(name)) {
  229. nameStr = @"";
  230. }
  231. /// excell_sort
  232. /// 默认按_id排序
  233. NSString *exerciseTypeStr = [NSString stringWithFormat:@"%@ + 0 ASC", orderStr];
  234. switch (exerciseType) {
  235. case RQExerciseType_Sequential:
  236. // exerciseTypeStr = [NSString stringWithFormat:@"%@ + 0 ASC", orderStr];
  237. break;
  238. case RQExerciseType_Random:
  239. // exerciseTypeStr = @"random()";
  240. break;
  241. case RQExerciseType_Recitation:
  242. // exerciseTypeStr = [NSString stringWithFormat:@"%@ + 0 ASC", orderStr];
  243. break;
  244. case RQExerciseType_Test:
  245. // exerciseTypeStr = @"random() limit 50";
  246. break;
  247. case RQExerciseType_Exam:
  248. // exerciseTypeStr = @"random() limit 5";
  249. break;
  250. default:
  251. break;
  252. }
  253. // resultSet = [_db executeQuery:@"select * from question_info where answer like '%-%'"];
  254. NSString *queryStr = [NSString stringWithFormat:@"select * from question_info where %@ and %@ order by %@", queryCarTypeStr, nameStr, exerciseTypeStr];
  255. @weakify(queryStr)
  256. if (pageType == RQHomeSubPageType_MockExamination && exerciseType == RQExerciseType_Test) {
  257. NSString *excellIssueNameStr = (carType == RQHomePageCarType_Motorcycle)? @"" : @"AND excell_issue_name LIKE '%%必%%'";
  258. NSString *newExcellIssueNameStr = (carType == RQHomePageCarType_Motorcycle)? @"" : @"AND excell_issue_name LIKE '%%新%%'";
  259. RACSignal *signal1 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
  260. @strongify(queryStr)
  261. queryStr = [NSString stringWithFormat:@"select * from question_info where %@ and %@ %@ and question_type = 1 and place_issue IS NULL %@ order by %@", queryCarTypeStr, querySubjectTypeStr, nameStr, excellIssueNameStr, [self getQuestionNumQueryStrWithCarType:carType subject:subject questionType:RQQuestionType_Judgment isNew:NO]];
  262. [subscriber sendNext:[self queryQuestionWithQueryStr:queryStr exerciseType:exerciseType]];
  263. [subscriber sendCompleted];
  264. return [RACDisposable disposableWithBlock:^{
  265. }];
  266. }];
  267. RACSignal *signal2 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
  268. @strongify(queryStr)
  269. queryStr = [NSString stringWithFormat:@"select * from question_info where %@ and %@ %@ and question_type = 1 and place_issue IS NULL %@ order by %@", queryCarTypeStr, querySubjectTypeStr, nameStr, newExcellIssueNameStr, [self getQuestionNumQueryStrWithCarType:carType subject:subject questionType:RQQuestionType_Judgment isNew:YES]];
  270. [subscriber sendNext:[self queryQuestionWithQueryStr:queryStr exerciseType:exerciseType]];
  271. [subscriber sendCompleted];
  272. return [RACDisposable disposableWithBlock:^{
  273. }];
  274. }];
  275. RACSignal *signal3 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
  276. @strongify(queryStr)
  277. queryStr = [NSString stringWithFormat:@"select * from question_info where %@ and %@ %@ and question_type = 2 and place_issue IS NULL %@ order by %@", queryCarTypeStr, querySubjectTypeStr, nameStr, excellIssueNameStr, [self getQuestionNumQueryStrWithCarType:carType subject:subject questionType:RQQuestionType_SingleChoice isNew:NO]];
  278. [subscriber sendNext:[self queryQuestionWithQueryStr:queryStr exerciseType:exerciseType]];
  279. [subscriber sendCompleted];
  280. return [RACDisposable disposableWithBlock:^{
  281. }];
  282. }];
  283. RACSignal *signal4 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
  284. @strongify(queryStr)
  285. queryStr = [NSString stringWithFormat:@"select * from question_info where %@ and %@ %@ and question_type = 2 and place_issue IS NULL %@ order by %@", queryCarTypeStr, querySubjectTypeStr, nameStr, newExcellIssueNameStr, [self getQuestionNumQueryStrWithCarType:carType subject:subject questionType:RQQuestionType_SingleChoice isNew:YES]];
  286. [subscriber sendNext:[self queryQuestionWithQueryStr:queryStr exerciseType:exerciseType]];
  287. [subscriber sendCompleted];
  288. return [RACDisposable disposableWithBlock:^{
  289. }];
  290. }];
  291. RACSignal *signal5 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
  292. @strongify(queryStr)
  293. queryStr = [NSString stringWithFormat:@"select * from question_info where %@ and %@ %@ and question_type = 3 and place_issue IS NULL %@ order by %@", queryCarTypeStr, querySubjectTypeStr, nameStr, excellIssueNameStr, [self getQuestionNumQueryStrWithCarType:carType subject:subject questionType:RQQuestionType_MultipleChoice isNew:NO]];
  294. [subscriber sendNext:[self queryQuestionWithQueryStr:queryStr exerciseType:exerciseType]];
  295. [subscriber sendCompleted];
  296. return [RACDisposable disposableWithBlock:^{
  297. }];
  298. }];
  299. RACSignal *signal6 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
  300. @strongify(queryStr)
  301. queryStr = [NSString stringWithFormat:@"select * from question_info where %@ and %@ %@ and question_type = 3 and place_issue IS NULL %@ order by %@", queryCarTypeStr, querySubjectTypeStr, nameStr, newExcellIssueNameStr, [self getQuestionNumQueryStrWithCarType:carType subject:subject questionType:RQQuestionType_MultipleChoice isNew:YES]];
  302. [subscriber sendNext:[self queryQuestionWithQueryStr:queryStr exerciseType:exerciseType]];
  303. [subscriber sendCompleted];
  304. return [RACDisposable disposableWithBlock:^{
  305. }];
  306. }];
  307. RACSignal *signal = [RACSignal combineLatest:@[signal1, signal2, signal3, signal4, signal5, signal6] reduce:^id (NSArray *arr1, NSArray *arr2, NSArray *arr3, NSArray *arr4, NSArray *arr5, NSArray *arr6) {
  308. NSMutableArray *judgmentArr = @[].mutableCopy;
  309. [judgmentArr addObjectsFromArray:arr1];
  310. [judgmentArr addObjectsFromArray:arr2];
  311. judgmentArr = [judgmentArr rq_randomArray].mutableCopy;
  312. NSMutableArray *singleChoiceArr = @[].mutableCopy;
  313. [singleChoiceArr addObjectsFromArray:arr3];
  314. [singleChoiceArr addObjectsFromArray:arr4];
  315. singleChoiceArr = [singleChoiceArr rq_randomArray].mutableCopy;
  316. NSMutableArray *multipleChoiceArr = @[].mutableCopy;
  317. [multipleChoiceArr addObjectsFromArray:arr5];
  318. [multipleChoiceArr addObjectsFromArray:arr6];
  319. multipleChoiceArr = [multipleChoiceArr rq_randomArray].mutableCopy;
  320. [arr addObjectsFromArray:judgmentArr];
  321. [arr addObjectsFromArray:singleChoiceArr];
  322. [arr addObjectsFromArray:multipleChoiceArr];
  323. return arr.copy;
  324. }];
  325. [signal subscribeNext:^(NSArray *allArr) {
  326. }];
  327. return arr.copy;
  328. } else if (pageType == RQHomeSubPageType_MockExamination && exerciseType == RQExerciseType_Exam) {
  329. @weakify(self)
  330. RACSignal *signal0 = [RQ_HTTP_Service getSelectTestK14QuestionInfoList:carTypeStr subject:subjectTypeStr];
  331. [[signal0 takeUntil:self.rac_willDeallocSignal] subscribeNext:^(NSArray *array) {
  332. NSLog(@"%@",array);
  333. } error:^(NSError * _Nullable error) {
  334. }];
  335. RACSignal *signal = [RACSignal combineLatest:@[signal0] reduce:^id (NSArray *arr1) {
  336. NSLog(@"signal0=========%@",arr1);
  337. [arr addObjectsFromArray:arr1];
  338. return arr.copy;
  339. }];
  340. [signal subscribeNext:^(NSArray *allArr) {
  341. }];
  342. return arr.copy;
  343. // RACSignal *signal0 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
  344. // @strongify(self)
  345. // NSMutableArray *difficultArr = @[].mutableCopy;
  346. //
  347. //// [[[self getExamRuleWithCarType:carType subject:subject].rac_sequence.signal map:^id _Nullable(RQExamRuleModel *examRuleModel) {
  348. //// NSString *chapterIdStr = [NSString stringWithFormat:@"chapter_id = %ld",(long)examRuleModel.chapter_id];
  349. //// NSString *typeStr = [NSString stringWithFormat:@"question_type IN %@",(subject == RQHomePageSubjectType_SubjectOne)? @"(1, 2)" : @"(1, 2, 3)"];
  350. //// NSString *randomStr = [NSString stringWithFormat:@"RANDOM() LIMIT %@",[NSString qmui_stringWithNSInteger:examRuleModel.difficult_count]];
  351. //// NSString *difficultQueryStr = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@ AND %@ AND diff_degree IN (4, 5) AND place_issue IS NULL AND %@ AND %@ ORDER BY %@",questionTableNameStr , queryCarTypeStr, querySubjectTypeStr, chapterIdStr, typeStr, randomStr];
  352. //// return difficultQueryStr;
  353. //// }].toArray.rac_sequence.signal subscribeNext:^(NSString *difficultQueryStr) {
  354. //// @strongify(self)
  355. //// [difficultArr addObjectsFromArray:[self queryQuestionWithQueryStr:difficultQueryStr]];
  356. //// } completed:^{
  357. //// [subscriber sendNext:difficultArr.copy];
  358. //// [subscriber sendCompleted];
  359. //// }];
  360. // return [RACDisposable disposableWithBlock:^{}];
  361. // }];
  362. // RACSignal *signal1 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
  363. // NSMutableArray *judgeArr = @[].mutableCopy;
  364. // [[[self getExamRuleWithCarType:carType subject:subject].rac_sequence.signal map:^id _Nullable(RQExamRuleModel *examRuleModel) {
  365. // NSString *chapterIdStr = [NSString stringWithFormat:@"AND chapter_id = %ld",(long)examRuleModel.chapter_id];
  366. // NSString *judgeCountStr = [NSString stringWithFormat:@"RANDOM() LIMIT %ld",(long)examRuleModel.judge_count];
  367. // NSString *judgeQueryStr = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@ AND %@ AND question_type = 1 AND diff_degree IN (0,1,2,3) AND place_issue IS NULL %@ ORDER BY %@",questionTableNameStr , queryCarTypeStr, querySubjectTypeStr, chapterIdStr, judgeCountStr];
  368. // NSMutableArray *judgeChapterArr = [self queryQuestionWithQueryStr:judgeQueryStr].mutableCopy;
  369. // if (judgeChapterArr.count < examRuleModel.judge_count) {
  370. // NSString *judgeQueryAddStr = [NSString stringWithFormat:@"SELECT DISTINCT * FROM %@ WHERE %@ AND %@ AND question_type = 1 AND diff_degree IN (4,5) AND place_issue IS NULL %@ ORDER BY RANDOM() LIMIT %@",questionTableNameStr , queryCarTypeStr, querySubjectTypeStr, chapterIdStr, [NSString stringWithFormat:@"%ld",(long)(examRuleModel.judge_count - judgeChapterArr.count)]];
  371. // NSArray *judgeChapterAddArr = [self queryQuestionWithQueryStr:judgeQueryAddStr];
  372. // [judgeChapterArr addObjectsFromArray:judgeChapterAddArr];
  373. // return judgeChapterArr.copy;
  374. // } else {
  375. // return judgeChapterArr.copy;
  376. // }
  377. // }].toArray.rac_sequence.signal subscribeNext:^(NSArray *judgeChapterArr) {
  378. // [judgeArr addObjectsFromArray:judgeChapterArr];
  379. // } completed:^{
  380. // [subscriber sendNext:judgeArr.copy];
  381. // [subscriber sendCompleted];
  382. // }];
  383. // return [RACDisposable disposableWithBlock:^{}];
  384. // }];
  385. //
  386. // RACSignal *signal2 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
  387. // NSMutableArray *choiceArr = @[].mutableCopy;
  388. // [[[self getExamRuleWithCarType:carType subject:subject].rac_sequence.signal map:^id _Nullable(RQExamRuleModel *examRuleModel) {
  389. // NSString *chapterIdStr = [NSString stringWithFormat:@"AND chapter_id = %ld",(long)examRuleModel.chapter_id];
  390. // NSString *choiceCountStr = [NSString stringWithFormat:@"RANDOM() LIMIT %ld",(long)examRuleModel.choice_count];
  391. // NSString *choiceQueryStr = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@ AND %@ AND question_type = 2 AND diff_degree IN (0,1,2,3) AND place_issue IS NULL %@ ORDER BY %@",questionTableNameStr , queryCarTypeStr, querySubjectTypeStr, chapterIdStr, choiceCountStr];
  392. // NSMutableArray *choiceChapterArr = [self queryQuestionWithQueryStr:choiceQueryStr].mutableCopy;
  393. // if (choiceChapterArr.count < examRuleModel.choice_count) {
  394. // NSString *choiceQueryAddStr = [NSString stringWithFormat:@"SELECT DISTINCT * FROM %@ WHERE %@ AND %@ AND question_type = 2 AND diff_degree IN (4,5) AND place_issue IS NULL %@ ORDER BY RANDOM() LIMIT %@",questionTableNameStr , queryCarTypeStr, querySubjectTypeStr, chapterIdStr, [NSString stringWithFormat:@"%ld",(long)(examRuleModel.choice_count - choiceChapterArr.count)]];
  395. // NSArray *choiceChapterAddArr = [self queryQuestionWithQueryStr:choiceQueryAddStr];
  396. // [choiceChapterArr addObjectsFromArray:choiceChapterAddArr];
  397. // return choiceChapterArr.copy;
  398. // } else {
  399. // return choiceChapterArr.copy;
  400. // }
  401. // }].toArray.rac_sequence.signal subscribeNext:^(NSArray *choiceChapterArr) {
  402. // [choiceArr addObjectsFromArray:choiceChapterArr];
  403. // } completed:^{
  404. // [subscriber sendNext:choiceArr.copy];
  405. // [subscriber sendCompleted];
  406. // }];
  407. // return [RACDisposable disposableWithBlock:^{}];
  408. // }];
  409. // RACSignal *signal3 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
  410. // NSMutableArray *multipleChoiceArr = @[].mutableCopy;
  411. // [[[self getExamRuleWithCarType:carType subject:subject].rac_sequence.signal map:^id _Nullable(RQExamRuleModel *examRuleModel) {
  412. // NSString *chapterIdStr = [NSString stringWithFormat:@"AND chapter_id = %ld",(long)examRuleModel.chapter_id];
  413. // NSString *multipleChoiceCountStr = [NSString stringWithFormat:@"RANDOM() LIMIT %ld",(long)examRuleModel.multiple_choice_count];
  414. // NSString *multipleChoiceQueryStr = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@ AND %@ AND question_type = 3 AND diff_degree IN (0,1,2,3) AND place_issue IS NULL %@ ORDER BY %@",questionTableNameStr , queryCarTypeStr, querySubjectTypeStr, chapterIdStr, multipleChoiceCountStr];
  415. // NSMutableArray *multipleChoiceChapterArr = [self queryQuestionWithQueryStr:multipleChoiceQueryStr].mutableCopy;
  416. // if (multipleChoiceChapterArr.count < examRuleModel.multiple_choice_count) {
  417. // NSString *multipleChoiceQueryAddStr = [NSString stringWithFormat:@"SELECT DISTINCT * FROM %@ WHERE %@ AND %@ AND question_type = 3 AND diff_degree IN (4,5) AND place_issue IS NULL %@ ORDER BY RANDOM() LIMIT %@",questionTableNameStr , queryCarTypeStr, querySubjectTypeStr, chapterIdStr, [NSString stringWithFormat:@"%ld",(long)(examRuleModel.multiple_choice_count - multipleChoiceChapterArr.count)]];
  418. // NSArray *multipleChoiceChapterAddArr = [self queryQuestionWithQueryStr:multipleChoiceQueryAddStr];
  419. // [multipleChoiceChapterArr addObjectsFromArray:multipleChoiceChapterAddArr];
  420. // return multipleChoiceChapterArr.copy;
  421. // } else {
  422. // return multipleChoiceChapterArr.copy;
  423. // }
  424. // }].toArray.rac_sequence.signal subscribeNext:^(NSArray *multipleChoiceChapterArr) {
  425. // [multipleChoiceArr addObjectsFromArray:multipleChoiceChapterArr];
  426. // } completed:^{
  427. // [subscriber sendNext:multipleChoiceArr.copy];
  428. // [subscriber sendCompleted];
  429. // }];
  430. // return [RACDisposable disposableWithBlock:^{}];
  431. // }];
  432. // return [[[RACSignal combineLatest:@[signal0] reduce:^id (NSArray *arr0){
  433. // NSMutableArray *judgeArr = [NSMutableArray array];
  434. // dispatch_semaphore_t sema = dispatch_semaphore_create(0);
  435. // [[arr0.rac_sequence.signal filter:^BOOL(RQExerciseModel *difficultQuestionModel) {
  436. // return ![judgeArr containsObject:difficultQuestionModel];
  437. // }].toArray.rac_sequence.signal subscribeNext:^(RQExerciseModel *difficultQuestionModel) {
  438. // if (difficultQuestionModel.question_type == 1) {
  439. // NSMutableArray *sortChapterArr = [judgeArr.rac_sequence.signal filter:^BOOL(RQExerciseModel *judgeQuestionModel) {
  440. // return (judgeQuestionModel.chapter_id == difficultQuestionModel.chapter_id) && ![arr0 containsObject:judgeQuestionModel];
  441. // }].toArray.mutableCopy;
  442. // if (sortChapterArr.count > 0) {
  443. // [judgeArr replaceObjectAtIndex:[judgeArr indexOfObject:sortChapterArr.lastObject] withObject:difficultQuestionModel];
  444. // }
  445. // }
  446. //// else if (difficultQuestionModel.question_type == 2) {
  447. //// NSMutableArray *sortChapterArr = [choiceArr.rac_sequence.signal filter:^BOOL(RQExerciseModel *choiceQuestionModel) {
  448. //// return (choiceQuestionModel.chapter_id == difficultQuestionModel.chapter_id) && ![arr0 containsObject:choiceQuestionModel];
  449. //// }].toArray.mutableCopy;
  450. //// if (sortChapterArr.count > 0) {
  451. //// [choiceArr replaceObjectAtIndex:[choiceArr indexOfObject:sortChapterArr.lastObject] withObject:difficultQuestionModel];
  452. //// }
  453. //// } else {
  454. //// NSMutableArray *sortChapterArr = [multipleChoiceArr.rac_sequence.signal filter:^BOOL(RQExerciseModel *multiChoiceQuestionModel) {
  455. //// return (multiChoiceQuestionModel.chapter_id == difficultQuestionModel.chapter_id) && ![arr0 containsObject:multiChoiceQuestionModel];
  456. //// }].toArray.mutableCopy;
  457. //// if (sortChapterArr.count > 0) {
  458. //// [multipleChoiceArr replaceObjectAtIndex:[multipleChoiceArr indexOfObject:sortChapterArr.lastObject] withObject:difficultQuestionModel];
  459. //// }
  460. //// }
  461. // } completed:^{
  462. // /// Key: 按照排序的key; ascending: YES为升序, NO为降序。
  463. // NSSortDescriptor *strTppeSorter = [[NSSortDescriptor alloc] initWithKey:@"chapter_id" ascending:YES];
  464. //// NSSortDescriptor *diff_degreeSorter = [NSSortDescriptor sortDescriptorWithKey:@"diff_degree" ascending:YES];
  465. // NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:strTppeSorter, nil];
  466. //
  467. // [arr addObjectsFromArray:[judgeArr sortedArrayUsingDescriptors:sortDescriptors]];
  468. //// [arr addObjectsFromArray:[choiceArr sortedArrayUsingDescriptors:sortDescriptors]];
  469. //// [arr addObjectsFromArray:[multipleChoiceArr sortedArrayUsingDescriptors:sortDescriptors]];
  470. // dispatch_semaphore_signal(sema);
  471. // }];
  472. // dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
  473. //
  474. // return arr.copy;
  475. // }] map:^id _Nullable(NSArray *examArr) {
  476. // return examArr;
  477. // }].toArray firstObject];
  478. // return arr.copy;
  479. } else if (pageType == RQHomeSubPageType_FreeTry) {
  480. queryStr = [NSString stringWithFormat:@"SELECT * FROM question_info INNER JOIN question_free ON question_info.id = question_free.id AND question_free.subject = '%@' ORDER BY %@", [RQ_COMMON_MANAGER getSubjectTypeNumStrWithSubjectType:subject],(exerciseType == RQExerciseType_Random)? @"random()" : @"question_free.free_sort + 0 ASC"];
  481. return [self queryQuestionWithQueryStr:queryStr exerciseType:exerciseType];
  482. } else if (pageType == RQHomeSubPageType_MockExamination && exerciseType == RQExerciseType_MiExam) {
  483. queryStr = [NSString stringWithFormat:@"SELECT * FROM (SELECT * FROM question_info AS a JOIN (SELECT id_ydt, MAX(id) AS id FROM question_info GROUP BY id_ydt) AS t ON a.id = t.id) AS q JOIN t_app_question_category AS c ON q.id_ydt = c.question_id AND c.kemu = %@ AND c.gs = '%@' AND c.category = %@ ORDER BY c.sort_order + 0 ASC", [RQ_COMMON_MANAGER getSubjectTypeNumStrWithSubjectType:subject],[RQ_COMMON_MANAGER getCarTypeSimpleCNStrWithCarType:carType],[RQ_COMMON_MANAGER getMiExamTypeNumStrWithMiExamType:RQ_COMMON_MANAGER.miExamType]];
  484. return [self queryQuestionWithQueryStr:queryStr];
  485. } else {
  486. return [self queryQuestionWithQueryStr:queryStr exerciseType:exerciseType];
  487. }
  488. }
  489. - (RQExerciseModel *)getQuestionWithQuestionId:(NSInteger )questionId {
  490. __block RQExerciseModel *exerciseModel;
  491. if (_databaseQueue) {
  492. [_databaseQueue inDatabase:^(FMDatabase * _Nonnull db) {
  493. exerciseModel = [self getQuestionWithDataBase:db questionId:questionId];
  494. }];
  495. }
  496. return exerciseModel;
  497. }
  498. - (void)getQuestionsWithQuestionIdArr:(NSArray *)questionIdArr complete:(VoidBlock_id)complete {
  499. NSMutableArray *arr = @[].mutableCopy;
  500. if (_databaseQueue) {
  501. [_databaseQueue inTransaction:^(FMDatabase * _Nonnull db, BOOL * _Nonnull rollback) {
  502. @try {
  503. [questionIdArr.rac_sequence.signal subscribeNext:^(NSString *questionIdStr) {
  504. RQExerciseModel *exerciseModel = [self getQuestionWithDataBase:db questionId:questionIdStr.integerValue];
  505. [arr addObject:exerciseModel];
  506. } completed:^{
  507. if (complete) {
  508. complete(arr.copy);
  509. }
  510. }];
  511. } @catch (NSException *exception) {
  512. *rollback = YES;
  513. } @finally {
  514. *rollback = NO;
  515. }
  516. }];
  517. }
  518. }
  519. #pragma mark - Private Method
  520. - (NSArray *)queryQuestionWithQueryStr:(NSString *)queryStr exerciseType:(RQExerciseType)exerciseType {
  521. NSMutableArray *arr = @[].mutableCopy;
  522. if (_databaseQueue) {
  523. [_databaseQueue inDatabase:^(FMDatabase * _Nonnull db) {
  524. FMResultSet *resultSet;
  525. resultSet = [db executeQuery:queryStr];
  526. while ([resultSet next]) {
  527. RQExerciseModel *exerciseModel = [RQExerciseModel exerciseModelWithFMResultSet:resultSet];
  528. if (exerciseType == RQExerciseType_Recitation) {
  529. exerciseModel.userAnswer = exerciseModel.answer;
  530. }
  531. [arr addObject:exerciseModel];
  532. }
  533. }];
  534. }
  535. return arr.copy;
  536. }
  537. - (NSArray *)queryQuestionWithQueryStr:(NSString *)queryStr {
  538. NSMutableArray *arr = @[].mutableCopy;
  539. if (_databaseQueue) {
  540. [_databaseQueue inDatabase:^(FMDatabase * _Nonnull db) {
  541. FMResultSet *resultSet;
  542. resultSet = [db executeQuery:queryStr];
  543. while ([resultSet next]) {
  544. RQExerciseModel *exerciseModel = [RQExerciseModel exerciseModelWithFMResultSet:resultSet];
  545. [arr addObject:exerciseModel];
  546. }
  547. }];
  548. }
  549. return arr.copy;
  550. }
  551. - (NSString *)getQuestionNumQueryStrWithCarType:(RQHomePageCarType)carType subject:(RQHomePageSubjectType)subject questionType:(RQQuestionType)questionType isNew:(BOOL)isNew {
  552. switch (subject) {
  553. case RQHomePageSubjectType_SubjectOne: {
  554. switch (questionType) {
  555. case RQQuestionType_Judgment: {
  556. switch (carType) {
  557. case RQHomePageCarType_Car:
  558. return isNew? @"random() limit 20" : @"random() limit 20";
  559. case RQHomePageCarType_Bus:
  560. return isNew? @"random() limit 20" : @"random() limit 20";
  561. case RQHomePageCarType_Truck:
  562. return isNew? @"random() limit 20" : @"random() limit 20";
  563. case RQHomePageCarType_Motorcycle:
  564. return isNew? @"random() limit 10" : @"random() limit 10";
  565. default:
  566. return isNew? @"random() limit 20" : @"random() limit 20";
  567. }
  568. }
  569. case RQQuestionType_SingleChoice: {
  570. switch (carType) {
  571. case RQHomePageCarType_Car:
  572. return isNew? @"random() limit 10" : @"random() limit 50";
  573. case RQHomePageCarType_Bus:
  574. return isNew? @"random() limit 10" : @"random() limit 50";
  575. case RQHomePageCarType_Truck:
  576. return isNew? @"random() limit 10" : @"random() limit 50";
  577. case RQHomePageCarType_Motorcycle:
  578. return isNew? @"random() limit 5" : @"random() limit 25";
  579. default:
  580. return isNew? @"random() limit 10" : @"random() limit 50";
  581. }
  582. }
  583. case RQQuestionType_MultipleChoice: {
  584. switch (carType) {
  585. case RQHomePageCarType_Car:
  586. return @"random() limit 0";
  587. case RQHomePageCarType_Bus:
  588. return @"random() limit 0";
  589. case RQHomePageCarType_Truck:
  590. return @"random() limit 0";
  591. case RQHomePageCarType_Motorcycle:
  592. return @"random() limit 0";
  593. default:
  594. return @"random() limit 0";
  595. }
  596. }
  597. }
  598. }
  599. case RQHomePageSubjectType_SubjectFour: {
  600. switch (questionType) {
  601. case RQQuestionType_Judgment: {
  602. switch (carType) {
  603. case RQHomePageCarType_Car:
  604. return @"random() limit 10";
  605. case RQHomePageCarType_Bus:
  606. return @"random() limit 10";
  607. case RQHomePageCarType_Truck:
  608. return @"random() limit 10";
  609. case RQHomePageCarType_Motorcycle:
  610. return @"random() limit 10";
  611. default:
  612. return @"random() limit 10";
  613. }
  614. }
  615. case RQQuestionType_SingleChoice: {
  616. switch (carType) {
  617. case RQHomePageCarType_Car:
  618. return @"random() limit 10";
  619. case RQHomePageCarType_Bus:
  620. return @"random() limit 10";
  621. case RQHomePageCarType_Truck:
  622. return @"random() limit 10";
  623. case RQHomePageCarType_Motorcycle:
  624. return @"random() limit 10";
  625. default:
  626. return @"random() limit 10";
  627. }
  628. }
  629. case RQQuestionType_MultipleChoice: {
  630. switch (carType) {
  631. case RQHomePageCarType_Car:
  632. return @"random() limit 5";
  633. case RQHomePageCarType_Bus:
  634. return @"random() limit 5";
  635. case RQHomePageCarType_Truck:
  636. return @"random() limit 5";
  637. case RQHomePageCarType_Motorcycle:
  638. return @"random() limit 5";
  639. default:
  640. return @"random() limit 5";
  641. }
  642. }
  643. }
  644. }
  645. default:
  646. return @"random() limit 5";
  647. }
  648. }
  649. - (RQExerciseModel *)getQuestionWithDataBase:(FMDatabase *)dataBase questionId:(NSInteger )questionId {
  650. RQExerciseModel *exerciseModel;
  651. FMResultSet *resultSet;
  652. resultSet = [dataBase executeQuery:[NSString stringWithFormat:@"select * from question_info where id = %ld or id_ydt = %ld", questionId, questionId]];
  653. while ([resultSet next]) {
  654. exerciseModel = [RQExerciseModel exerciseModelWithFMResultSet:resultSet];
  655. }
  656. return exerciseModel;
  657. }
  658. - (NSInteger)getQuestionVersion {
  659. __block NSInteger version = 0;
  660. if (_databaseQueue) {
  661. [_databaseQueue inDatabase:^(FMDatabase * _Nonnull db) {
  662. FMResultSet *resultSet;
  663. resultSet = [db executeQuery:@"select version_num from question_version"];
  664. while ([resultSet next]) {
  665. version = [resultSet longLongIntForColumn:@"version_num"];
  666. }
  667. }];
  668. }
  669. return version;
  670. }
  671. - (NSInteger)getQuestionVersionWithResourcePath:(NSString *)resourcePath {
  672. __block NSInteger version = 0;
  673. [[FMDatabaseQueue databaseQueueWithPath:resourcePath] inDatabase:^(FMDatabase * _Nonnull db) {
  674. FMResultSet *resultSet;
  675. resultSet = [db executeQuery:@"SELECT version_num FROM question_version"];
  676. while ([resultSet next]) {
  677. version = [resultSet longLongIntForColumn:@"version_num"];
  678. }
  679. }];
  680. return version;
  681. }
  682. - (NSArray *)getExamRuleWithCarType:(RQHomePageCarType)carType subject:(RQHomePageSubjectType)subject {
  683. NSString *queryCarTypeStr = [NSString stringWithFormat:@"gs LIKE '%%%@%%'",[RQ_COMMON_MANAGER getCarTypeSimpleCNStrWithCarType:carType]];
  684. NSString *querySubjectTypeStr = [NSString stringWithFormat:@"kemu = '%@'",[RQ_COMMON_MANAGER getSubjectTypeNumStrWithSubjectType:subject]];
  685. NSString *examRuleTableName = @"t_app_exam_rule";
  686. NSString *queryStr = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@ AND %@ AND areacode = 0 ", examRuleTableName, queryCarTypeStr, querySubjectTypeStr];
  687. return [self queryExamRuleWithQueryStr:queryStr];
  688. }
  689. - (NSArray *)queryExamRuleWithQueryStr:(NSString *)queryStr {
  690. NSMutableArray *arr = @[].mutableCopy;
  691. if (_databaseQueue) {
  692. [_databaseQueue inDatabase:^(FMDatabase * _Nonnull db) {
  693. FMResultSet *resultSet;
  694. resultSet = [db executeQuery:queryStr];
  695. while ([resultSet next]) {
  696. RQExamRuleModel *examRuleModel = [RQExamRuleModel sdjkExamRuleModelWithFMResultSet:resultSet];
  697. [arr addObject:examRuleModel];
  698. }
  699. }];
  700. }
  701. return arr.copy;
  702. }
  703. - (RQExplainModel *)getExplainWithExerciseModel:(RQExerciseModel *)exerciseModel {
  704. __block RQExplainModel *explainModel;
  705. if (_databaseQueue) {
  706. [_databaseQueue inDatabase:^(FMDatabase * _Nonnull db) {
  707. FMResultSet *resultSet;
  708. NSString *queryStr = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE questionIds = %ld", @"question_sd_js", (long)exerciseModel.id_ydt];
  709. resultSet = [db executeQuery:queryStr];
  710. while ([resultSet next]) {
  711. explainModel = [RQExplainModel questionExplainWithFMResultSet:resultSet];
  712. }
  713. }];
  714. }
  715. return explainModel;
  716. }
  717. @end