NSObject+LKModel.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. //
  2. // NSObject+LKModel.m
  3. // LKDBHelper
  4. //
  5. // Created by upin on 13-4-15.
  6. // Copyright (c) 2013年 ljh. All rights reserved.
  7. //
  8. #import "NSObject+LKModel.h"
  9. #import "LKDBHelper.h"
  10. static char LKModelBase_Key_RowID;
  11. @implementation NSObject (LKModel)
  12. +(LKDBHelper *)getUsingLKDBHelper
  13. {
  14. static LKDBHelper* helper;
  15. static dispatch_once_t onceToken;
  16. dispatch_once(&onceToken, ^{
  17. helper = [[LKDBHelper alloc]init];
  18. });
  19. return helper;
  20. }
  21. #pragma mark Tabel Structure Function 表结构
  22. +(NSString *)getTableName
  23. {
  24. return nil;
  25. }
  26. +(NSString *)getPrimaryKey
  27. {
  28. return nil;
  29. }
  30. +(NSArray *)getPrimaryKeyUnionArray
  31. {
  32. return nil;
  33. }
  34. +(void)columeAttributeWithProperty:(LKDBProperty *)property
  35. {
  36. //overwrite
  37. }
  38. -(void)setRowid:(int)rowid
  39. {
  40. objc_setAssociatedObject(self, &LKModelBase_Key_RowID,[NSNumber numberWithInt:rowid], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  41. }
  42. -(int)rowid
  43. {
  44. return [objc_getAssociatedObject(self, &LKModelBase_Key_RowID) intValue];
  45. }
  46. +(NSString *)getDBImagePathWithName:(NSString *)filename
  47. {
  48. NSString* dir = [NSString stringWithFormat:@"dbimg/%@",NSStringFromClass(self)];
  49. return [LKDBUtils getPathForDocuments:filename inDir:dir];
  50. }
  51. +(NSString*)getDBDataPathWithName:(NSString *)filename
  52. {
  53. NSString* dir = [NSString stringWithFormat:@"dbdata/%@",NSStringFromClass(self)];
  54. return [LKDBUtils getPathForDocuments:filename inDir:dir];
  55. }
  56. +(NSDictionary *)getTableMapping
  57. {
  58. return nil;
  59. }
  60. #pragma mark- Table Data Function 表数据
  61. -(id)modelGetValue:(LKDBProperty *)property
  62. {
  63. id value = [self valueForKey:property.propertyName];
  64. id returnValue = value;
  65. if(value == nil)
  66. {
  67. return nil;
  68. }
  69. else if([value isKindOfClass:[NSString class]])
  70. {
  71. returnValue = value;
  72. }
  73. else if([value isKindOfClass:[NSNumber class]])
  74. {
  75. returnValue = [value stringValue];
  76. }
  77. else if([value isKindOfClass:[NSDate class]])
  78. {
  79. returnValue = [LKDBUtils stringWithDate:value];
  80. }
  81. else if([value isKindOfClass:[UIColor class]])
  82. {
  83. UIColor* color = value;
  84. float r,g,b,a;
  85. [color getRed:&r green:&g blue:&b alpha:&a];
  86. returnValue = [NSString stringWithFormat:@"%.3f,%.3f,%.3f,%.3f",r,g,b,a];
  87. }
  88. else if([value isKindOfClass:[NSValue class]])
  89. {
  90. NSString* columeType = property.propertyType;
  91. if([columeType isEqualToString:@"CGRect"])
  92. {
  93. returnValue = NSStringFromCGRect([value CGRectValue]);
  94. }
  95. else if([columeType isEqualToString:@"CGPoint"])
  96. {
  97. returnValue = NSStringFromCGPoint([value CGPointValue]);
  98. }
  99. else if([columeType isEqualToString:@"CGSize"])
  100. {
  101. returnValue = NSStringFromCGSize([value CGSizeValue]);
  102. }
  103. }
  104. else if([value isKindOfClass:[UIImage class]])
  105. {
  106. long random = arc4random();
  107. long date = [[NSDate date] timeIntervalSince1970];
  108. NSString* filename = [NSString stringWithFormat:@"img%ld%ld",date&0xFFFFF,random&0xFFF];
  109. NSData* datas = UIImageJPEGRepresentation(value, 1);
  110. [datas writeToFile:[self.class getDBImagePathWithName:filename] atomically:YES];
  111. returnValue = filename;
  112. }
  113. else if([value isKindOfClass:[NSData class]])
  114. {
  115. long random = arc4random();
  116. long date = [[NSDate date] timeIntervalSince1970];
  117. NSString* filename = [NSString stringWithFormat:@"data%ld%ld",date&0xFFFFF,random&0xFFF];
  118. [value writeToFile:[self.class getDBDataPathWithName:filename] atomically:YES];
  119. returnValue = filename;
  120. }
  121. return returnValue;
  122. }
  123. -(void)modelSetValue:(LKDBProperty *)property value:(id)value
  124. {
  125. id modelValue = value;
  126. NSString* columeType = property.propertyType;
  127. if([columeType isEqualToString:@"NSString"])
  128. {
  129. }
  130. else if([LKSQLFloatType rangeOfString:columeType].location != NSNotFound)
  131. {
  132. modelValue = [NSNumber numberWithFloat:[value floatValue]];
  133. }
  134. else if([LKSQLIntType rangeOfString:columeType].location != NSNotFound)
  135. {
  136. modelValue = [NSNumber numberWithFloat:[value intValue]];
  137. }
  138. else if([columeType isEqualToString:@"NSDate"])
  139. {
  140. NSString* datestr = value;
  141. modelValue = [LKDBUtils dateWithString:datestr];
  142. }
  143. else if([columeType isEqualToString:@"UIColor"])
  144. {
  145. NSString* color = value;
  146. NSArray* array = [color componentsSeparatedByString:@","];
  147. float r,g,b,a;
  148. r = [[array objectAtIndex:0] floatValue];
  149. g = [[array objectAtIndex:1] floatValue];
  150. b = [[array objectAtIndex:2] floatValue];
  151. a = [[array objectAtIndex:3] floatValue];
  152. modelValue = [UIColor colorWithRed:r green:g blue:b alpha:a];
  153. }
  154. else if([columeType isEqualToString:@"CGRect"])
  155. {
  156. modelValue = [NSValue valueWithCGRect:CGRectFromString(value)];
  157. }
  158. else if([columeType isEqualToString:@"CGPoint"])
  159. {
  160. modelValue = [NSValue valueWithCGPoint:CGPointFromString(value)];
  161. }
  162. else if([columeType isEqualToString:@"CGSize"])
  163. {
  164. modelValue = [NSValue valueWithCGSize:CGSizeFromString(value)];
  165. }
  166. else if([columeType isEqualToString:@"UIImage"])
  167. {
  168. NSString* filename = value;
  169. NSString* filepath = [self.class getDBImagePathWithName:filename];
  170. if([LKDBUtils isFileExists:filepath])
  171. {
  172. UIImage* img = [UIImage imageWithContentsOfFile:filepath];
  173. modelValue = img;
  174. }
  175. else
  176. {
  177. modelValue = nil;
  178. }
  179. }
  180. else if([columeType isEqualToString:@"NSData"])
  181. {
  182. NSString* filename = value;
  183. NSString* filepath = [self.class getDBDataPathWithName:filename];
  184. if([LKDBUtils isFileExists:filepath])
  185. {
  186. NSData* data = [NSData dataWithContentsOfFile:filepath];
  187. modelValue = data;
  188. }
  189. else
  190. {
  191. modelValue = nil;
  192. }
  193. }
  194. [self setValue:modelValue forKey:property.propertyName];
  195. }
  196. -(void)userSetValueForModel:(LKDBProperty *)property value:(id)value{}
  197. -(id)userGetValueForModel:(LKDBProperty *)property
  198. {
  199. return nil;
  200. }
  201. -(id)getPrimaryValue
  202. {
  203. NSString* primarykey = [self.class getPrimaryKey];
  204. LKModelInfos* infos = [self.class getModelInfos];
  205. LKDBProperty* property = [infos objectWithSqlColumeName:primarykey];
  206. if(property && [property.type isEqualToString:LKSQLUserCalculate])
  207. {
  208. return [self userGetValueForModel:property];
  209. }
  210. else if(primarykey && property)
  211. {
  212. return [self modelGetValue:property];
  213. }
  214. return nil;
  215. }
  216. #pragma mark- get model property info
  217. +(LKModelInfos *)getModelInfos
  218. {
  219. static __strong NSMutableDictionary* oncePropertyDic;
  220. static dispatch_once_t onceToken;
  221. dispatch_once(&onceToken, ^{
  222. oncePropertyDic = [[NSMutableDictionary alloc]initWithCapacity:8];
  223. });
  224. LKModelInfos* infos;
  225. @synchronized(self)
  226. {
  227. infos = [oncePropertyDic objectForKey:NSStringFromClass(self)];
  228. if(infos == nil)
  229. {
  230. NSMutableArray* pronames = [NSMutableArray array];
  231. NSMutableArray* protypes = [NSMutableArray array];
  232. NSDictionary* keymapping = [self getTableMapping];
  233. [self getSelfPropertys:pronames protypes:protypes];
  234. NSArray* pkArray = [self getPrimaryKeyUnionArray];
  235. if(pkArray.count == 0)
  236. {
  237. pkArray = nil;
  238. NSString* pk = [self getPrimaryKey];
  239. if([LKDBUtils checkStringIsEmpty:pk] == NO)
  240. {
  241. pkArray = [NSArray arrayWithObject:pk];
  242. }
  243. }
  244. infos = [[LKModelInfos alloc]initWithKeyMapping:keymapping propertyNames:pronames propertyType:protypes primaryKeys:pkArray];
  245. [oncePropertyDic setObject:infos forKey:NSStringFromClass(self)];
  246. }
  247. }
  248. return infos;
  249. }
  250. +(BOOL)isContainParent
  251. {
  252. return NO;
  253. }
  254. /**
  255. * @brief 获取自身的属性
  256. *
  257. * @param pronames 保存属性名称
  258. * @param protypes 保存属性类型
  259. */
  260. + (void)getSelfPropertys:(NSMutableArray *)pronames protypes:(NSMutableArray *)protypes
  261. {
  262. unsigned int outCount, i;
  263. objc_property_t *properties = class_copyPropertyList(self, &outCount);
  264. for (i = 0; i < outCount; i++) {
  265. objc_property_t property = properties[i];
  266. NSString *propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
  267. //取消rowid 的插入 //子类 已重载的属性 取消插入
  268. if([propertyName isEqualToString:@"rowid"] ||
  269. [pronames indexOfObject:propertyName] != NSNotFound)
  270. {
  271. continue;
  272. }
  273. [pronames addObject:propertyName];
  274. NSString *propertyType = [NSString stringWithCString: property_getAttributes(property) encoding:NSUTF8StringEncoding];
  275. /*
  276. c char
  277. i int
  278. l long
  279. s short
  280. d double
  281. f float
  282. @ id //指针 对象
  283. ... BOOL 获取到的表示 方式是 char
  284. .... ^i 表示 int* 一般都不会用到
  285. */
  286. if ([propertyType hasPrefix:@"T@"]) {
  287. [protypes addObject:[propertyType substringWithRange:NSMakeRange(3, [propertyType rangeOfString:@","].location-4)]];
  288. }
  289. else if([propertyType hasPrefix:@"T{"])
  290. {
  291. [protypes addObject:[propertyType substringWithRange:NSMakeRange(2, [propertyType rangeOfString:@"="].location-2)]];
  292. }
  293. else
  294. {
  295. propertyType = [propertyType lowercaseString];
  296. if ([propertyType hasPrefix:@"ti"])
  297. {
  298. [protypes addObject:@"int"];
  299. }
  300. else if ([propertyType hasPrefix:@"tf"])
  301. {
  302. [protypes addObject:@"float"];
  303. }
  304. else if([propertyType hasPrefix:@"td"]) {
  305. [protypes addObject:@"double"];
  306. }
  307. else if([propertyType hasPrefix:@"tl"])
  308. {
  309. [protypes addObject:@"long"];
  310. }
  311. else if ([propertyType hasPrefix:@"tc"]) {
  312. [protypes addObject:@"char"];
  313. }
  314. else if([propertyType hasPrefix:@"ts"])
  315. {
  316. [protypes addObject:@"short"];
  317. }
  318. else {
  319. [protypes addObject:@"NSString"];
  320. }
  321. }
  322. }
  323. free(properties);
  324. if([self isContainParent] && [self superclass] != [NSObject class])
  325. {
  326. [[self superclass] getSelfPropertys:pronames protypes:protypes];
  327. }
  328. }
  329. #pragma mark - log all property
  330. -(NSString*)printAllPropertys
  331. {
  332. #ifdef DEBUG
  333. NSMutableString* sb = [NSMutableString stringWithFormat:@"<%@> \n", [self class]];
  334. unsigned int outCount, i;
  335. objc_property_t *properties = class_copyPropertyList([self class], &outCount);
  336. [sb appendFormat:@" %@ : %@ \n",@"rowid",[self valueForKey:@"rowid"]];
  337. for (i = 0; i < outCount; i++) {
  338. objc_property_t property = properties[i];
  339. NSString *propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
  340. [sb appendFormat:@" %@ : %@ \n",propertyName,[self valueForKey:propertyName]];
  341. }
  342. free(properties);
  343. NSLog(@"%@",sb);
  344. return sb;
  345. #else
  346. return @"";
  347. #endif
  348. }
  349. @end