├── Podfile
├── FMDBHelper.xcodeproj
├── xcuserdata
│ └── tcyx.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── FMDBHelper.xcscheme
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── tcyx.xcuserdatad
│ │ │ ├── UserInterfaceState.xcuserstate
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── FMDBHelper.xccheckout
└── project.pbxproj
├── FMDBHelper
├── CKTest.m
├── CKTestSubModel.m
├── CKTest.h
├── CKTestSubModel.h
├── FMDBHelper
│ ├── CKDictionary.h
│ ├── NSDictionary+CKExternal.h
│ ├── NSString+CKDB.h
│ ├── NSDictionary+CKExternal.m
│ ├── CKManager.h
│ ├── NSObject+CKProperty.h
│ ├── NSString+CKDB.m
│ ├── CKFMDBHelper.h
│ ├── CKConditionMaker.h
│ ├── NSObject+CKProperty.m
│ ├── CKModel.h
│ ├── CKDictionary.m
│ ├── CKManager.m
│ ├── CKConditionMaker.m
│ └── CKModel.m
├── AppDelegate.h
├── main.m
├── CKTestModel.h
├── CKTestModel.m
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Info.plist
├── Storyboard.storyboard
├── AppDelegate.m
└── Base.lproj
│ └── LaunchScreen.xib
├── FMDBHelperTests
├── Info.plist
└── FMDBHelperTests.m
├── README.md
└── .gitignore
/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | platform :ios, "7.0"
3 |
4 | target "FMDBHelper" do
5 |
6 | pod 'FMDB'
7 |
8 | end
9 |
10 |
--------------------------------------------------------------------------------
/FMDBHelper.xcodeproj/xcuserdata/tcyx.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/FMDBHelper.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/FMDBHelper.xcodeproj/project.xcworkspace/xcuserdata/tcyx.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaydenK/CKFMDBHelper/HEAD/FMDBHelper.xcodeproj/project.xcworkspace/xcuserdata/tcyx.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/FMDBHelper/CKTest.m:
--------------------------------------------------------------------------------
1 | //
2 | // CKTest.m
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/7/15.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import "CKTest.h"
10 |
11 | @implementation CKTest
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/FMDBHelper/CKTestSubModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // CKTestSubModel.m
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/7/15.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import "CKTestSubModel.h"
10 |
11 | @implementation CKTestSubModel
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/FMDBHelper/CKTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // CKTest.h
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/7/15.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import "CKModel.h"
10 |
11 | @interface CKTest : CKModel
12 |
13 | @property (nonatomic, copy) NSString *index;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/FMDBHelper/CKTestSubModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // CKTestSubModel.h
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/7/15.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import "CKTestModel.h"
10 |
11 | @interface CKTestSubModel : CKTestModel
12 |
13 | @property (nonatomic, copy) NSString *subIndex;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/FMDBHelper/FMDBHelper/CKDictionary.h:
--------------------------------------------------------------------------------
1 | //
2 | // CKDictionary.h
3 | // GameCenter
4 | //
5 | // Created by caydenk on 15/7/28.
6 | // Copyright (c) 2015年 CaydenK. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CKDictionary : NSMutableDictionary
12 |
13 | + (CKDictionary *)shareInstance;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/FMDBHelper/FMDBHelper/NSDictionary+CKExternal.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSDictionary+CKExternal.h
3 | // GameCenter
4 | //
5 | // Created by caydenk on 15/6/19.
6 | // Copyright (c) 2015年 CaydenK. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSDictionary (CKExternal)
12 |
13 | - (id)ckObjectForKey:(id)aKey;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/FMDBHelper/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/5/19.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/FMDBHelper/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/5/19.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/FMDBHelper/FMDBHelper/NSString+CKDB.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+CKDB.h
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/5/22.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSString (CKDB)
12 |
13 | /**
14 | * 处理插入/更新数据库字段中存在引号插入失败
15 | *
16 | * @param string 待处理字符串
17 | *
18 | * @return 处理后的字符串
19 | */
20 | - (NSString *)chuliyinhao;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/FMDBHelper.xcodeproj/project.xcworkspace/xcuserdata/tcyx.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges
6 |
7 | SnapshotAutomaticallyBeforeSignificantChanges
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/FMDBHelper/CKTestModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // CKTestModel.h
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/5/22.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import "CKModel.h"
10 | #import "CKTest.h"
11 |
12 | @interface CKTestModel : CKModel
13 |
14 | @property (nonatomic, copy) NSNumber *index;
15 | @property (nonatomic, copy) NSString *name;
16 | @property (nonatomic, copy) NSString *lastName;
17 | @property (nonatomic, copy) CKTest *test;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/FMDBHelper/FMDBHelper/NSDictionary+CKExternal.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSDictionary+CKExternal.m
3 | // GameCenter
4 | //
5 | // Created by caydenk on 15/6/19.
6 | // Copyright (c) 2015年 CaydenK. All rights reserved.
7 | //
8 |
9 | #import "NSDictionary+CKExternal.h"
10 |
11 | @implementation NSDictionary (CKExternal)
12 |
13 | - (id)ckObjectForKey:(id)aKey{
14 | id item = [self objectForKey:aKey];
15 | if (item == nil || [[NSNull null] isEqual:item]) {
16 | return @"";
17 | }
18 | return item;
19 | }
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/FMDBHelper/CKTestModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // CKTestModel.m
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/5/22.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import "CKTestModel.h"
10 |
11 | @implementation CKTestModel
12 |
13 | + (NSDictionary *)jsonKeyPathMapping{
14 | return @{
15 | @"index":@"ind",
16 | @"name":@"ac",
17 | @"lastName":@"bbb",
18 | @"test.index":@"ccc",
19 | };
20 | }
21 |
22 | - (instancetype)init
23 | {
24 | self = [super init];
25 | if (self) {
26 | _test = [CKTest new];
27 | }
28 | return self;
29 | }
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/FMDBHelper.xcodeproj/xcuserdata/tcyx.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | FMDBHelper.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | B8D2C7021B0B2E65006A032F
16 |
17 | primary
18 |
19 |
20 | B8D2C71B1B0B2E65006A032F
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/FMDBHelper/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/FMDBHelperTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.caydenk.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/FMDBHelper/FMDBHelper/CKManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // CKManager.h
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/5/19.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class FMDatabase;
12 | @class FMDatabaseQueue;
13 | /**
14 | * 数据库助手类
15 | */
16 | @interface CKManager : NSObject
17 |
18 | @property (nonatomic, copy) NSString *dbPath;
19 |
20 | /**
21 | * 获取当前单例
22 | *
23 | * @return 当前单例
24 | */
25 | + (CKManager *)shareManager;
26 |
27 | /**
28 | * 根据库名获取FMDatabase
29 | *
30 | * @param dbName 数据库名称
31 | *
32 | * @return FMDatabase
33 | */
34 | - (FMDatabase *)databaseWithName:(NSString *)dbName;
35 | /**
36 | * 根据库名获取FMDatabaseQueue
37 | *
38 | * @param dbName 数据库名称
39 | *
40 | * @return FMDatabaseQueue
41 | */
42 | - (FMDatabaseQueue *)databaseQueueWithName:(NSString *)dbName;
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/FMDBHelper/FMDBHelper/NSObject+CKProperty.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+CKProperty.h
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/5/19.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSObject (CKProperty)
12 |
13 | /**
14 | * 获取属性列表
15 | *
16 | * @return 属性列表
17 | */
18 | + (NSArray *)propertyArray;
19 |
20 | /**
21 | * 获取属性集合
22 | *
23 | * @return 属性集合
24 | */
25 | + (NSSet *)propertySet;
26 | /**
27 | * 属性字典,key为属性名称,value是数组,属性的编译属性列表
28 | *
29 | * @return 属性字典
30 | */
31 | + (NSDictionary *)propertyDict;
32 |
33 | /**
34 | * 获取属性列表
35 | *
36 | * @return 属性列表
37 | */
38 | - (NSArray *)propertyArray;
39 |
40 | /**
41 | * 获取属性集合
42 | *
43 | * @return 属性集合
44 | */
45 | - (NSSet *)propertySet;
46 | /**
47 | * 属性字典,key为属性名称,value是数组,属性的编译属性列表
48 | *
49 | * @return 属性字典
50 | */
51 | - (NSDictionary *)propertyDict;
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/FMDBHelper/FMDBHelper/NSString+CKDB.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+CKDB.m
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/5/22.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import "NSString+CKDB.h"
10 |
11 | @implementation NSString (CKDB)
12 |
13 | /**
14 | * 处理插入/更新数据库字段中存在引号插入失败
15 | *
16 | * @param string 待处理字符串
17 | *
18 | * @return 处理后的字符串
19 | */
20 | - (NSString *)chuliyinhao{
21 | NSRange range=[self rangeOfString:@"'"];
22 | if (range.length>0){
23 | NSMutableString *mValue = self.mutableCopy;
24 | for (NSInteger i = mValue.length-1; i>=0; i--) {
25 | NSString *charValue = [mValue substringWithRange:NSMakeRange(i, 1)];
26 | if ([charValue isEqualToString:@"'"]) {
27 | [mValue replaceCharactersInRange:NSMakeRange(i, 1) withString:@"''"];
28 | }
29 | }
30 | return [NSString stringWithFormat:@"'%@'",mValue];
31 | }
32 | else{
33 | return [NSString stringWithFormat:@"'%@'",self];
34 | }
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/FMDBHelperTests/FMDBHelperTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // FMDBHelperTests.m
3 | // FMDBHelperTests
4 | //
5 | // Created by caydenk on 15/5/19.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface FMDBHelperTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation FMDBHelperTests
17 |
18 | - (void)setUp {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown {
24 | // Put teardown code here. This method is called after the invocation of each test method in the class.
25 | [super tearDown];
26 | }
27 |
28 | - (void)testExample {
29 | // This is an example of a functional test case.
30 | XCTAssert(YES, @"Pass");
31 | }
32 |
33 | - (void)testPerformanceExample {
34 | // This is an example of a performance test case.
35 | [self measureBlock:^{
36 | // Put the code you want to measure the time of here.
37 | }];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/FMDBHelper/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.caydenk.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Storyboard
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/FMDBHelper.xcodeproj/project.xcworkspace/xcshareddata/FMDBHelper.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 43E7B814-355B-4B0A-B0E9-4D5E225D6165
9 | IDESourceControlProjectName
10 | FMDBHelper
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | 530D80540C7964249B9D029C4210D9C3667051E7
14 | https://github.com/CaydenK/CKFMDBHelper.git
15 |
16 | IDESourceControlProjectPath
17 | FMDBHelper.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | 530D80540C7964249B9D029C4210D9C3667051E7
21 | ../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/CaydenK/CKFMDBHelper.git
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | 530D80540C7964249B9D029C4210D9C3667051E7
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | 530D80540C7964249B9D029C4210D9C3667051E7
36 | IDESourceControlWCCName
37 | CKFMDBHelper
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/FMDBHelper/Storyboard.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/FMDBHelper/FMDBHelper/CKFMDBHelper.h:
--------------------------------------------------------------------------------
1 |
2 | //////////////////////////////////////////////////////
3 | // //
4 | // _oo0oo_ //
5 | // o8888888o //
6 | // 88" . "88 //
7 | // (| -_- |) //
8 | // 0\ = /0 //
9 | // ___/`---'\___ //
10 | // .' \\| |// '. //
11 | // / \\||| : |||// \ //
12 | // / _||||| -:- |||||- \ //
13 | // | | \\\ - /// | | //
14 | // | \_| ''\---/'' |_/ | //
15 | // \ .-\__ '-' ___/-. / //
16 | // ___'. .' /--.--\ `. .'___ //
17 | // ."" '< `.___\_<|>_/___.' >' "". //
18 | // | | : `- \`.;`\ _ /`;.`/ - ` : | | //
19 | // \ \ `_. \_ __\ /__ _/ .-` / / //
20 | // =====`-.____`.___ \_____/___.-`___.-'===== //
21 | // `=---=' //
22 | // //
23 | // //
24 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
25 | // //
26 | // 佛祖保佑 永无BUG //
27 | // //
28 | // //
29 | //////////////////////////////////////////////////////
30 |
31 | #ifndef FMDBHelper_FMDBHelper_h
32 | #define FMDBHelper_FMDBHelper_h
33 |
34 | #import "NSObject+CKProperty.h"
35 | #import "CKModel.h"
36 | #import "CKConditionMaker.h"
37 | #import "NSDictionary+CKExternal.h"
38 | #import "CKDictionary.h"
39 |
40 |
41 | #define CKDBNAME @"CityGamesInfo"
42 |
43 | #define CKDICTIONARY @"CKDictionary"
44 |
45 | #endif
46 |
--------------------------------------------------------------------------------
/FMDBHelper/FMDBHelper/CKConditionMaker.h:
--------------------------------------------------------------------------------
1 | //
2 | // CKFuckMaker.h
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/5/22.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /**
12 | * 条件排序
13 | */
14 | typedef NS_ENUM(NSUInteger, CKConditionMakerOrderByType){
15 | /**
16 | * 正序
17 | */
18 | CKOrderByAsc = 1,
19 | /**
20 | * 倒序
21 | */
22 | CKOrderByDesc = 0,
23 | };
24 |
25 | /**
26 | * 条件基类
27 | */
28 | @interface CKBaseMaker : NSObject
29 |
30 | /**
31 | * 创建对象
32 | *
33 | * @param cls model类型
34 | *
35 | * @return 条件Maker
36 | */
37 | + (instancetype)newWithModelClass:(Class)cls;
38 | /**
39 | * 初始化对象
40 | *
41 | * @param cls model类型
42 | *
43 | * @return 条件maker
44 | */
45 | - (instancetype)initWithModelClass:(Class)cls;
46 |
47 | @end
48 |
49 |
50 | /**
51 | * 查询条件
52 | */
53 | @interface CKConditionMaker : CKBaseMaker
54 |
55 | /**
56 | * 组合的条件语句
57 | */
58 | @property (nonatomic, copy) NSString *sqlCondition;
59 |
60 | /**
61 | * where子句
62 | */
63 | - (CKConditionMaker * (^)(NSString *))where;
64 | /**
65 | * 与运算
66 | */
67 | - (CKConditionMaker * (^)(NSString *))and;
68 | /**
69 | * 或运算
70 | */
71 | - (CKConditionMaker * (^)(NSString *))or;
72 | /**
73 | * 包含于运算
74 | */
75 | - (CKConditionMaker * (^)(NSArray *))in;
76 | /**
77 | * 模糊查询
78 | */
79 | - (CKConditionMaker * (^)(NSString *))like;
80 | /**
81 | * 排序
82 | */
83 | - (CKConditionMaker * (^)(NSString *orderKey, CKConditionMakerOrderByType orderType))orderBy;
84 | /**
85 | * 界限
86 | */
87 | - (CKConditionMaker * (^)(NSInteger location, NSInteger count))limit;
88 |
89 | @end
90 |
91 | @interface CKQueryMaker : CKBaseMaker
92 |
93 | @property (nonatomic, strong) NSMutableDictionary *sqlQueryDict;
94 |
95 | /**
96 | * 个数
97 | */
98 | - (CKQueryMaker * (^)(NSString *))count;
99 | /**
100 | * 最大值
101 | */
102 | - (CKQueryMaker * (^)(NSString *,NSString *))max;
103 | /**
104 | * 最小值
105 | */
106 | - (CKQueryMaker *(^)(NSString *,NSString *))min;
107 | /**
108 | * 平均值
109 | */
110 | - (CKQueryMaker *(^)(NSString *,NSString *))avg;
111 | /**
112 | * 求和
113 | */
114 | - (CKQueryMaker *(^)(NSString *,NSString *))sum;
115 | /**
116 | * 字母转大写
117 | */
118 | - (CKQueryMaker *(^)(NSString *,NSString *))upper;
119 | /**
120 | * 字母转小写
121 | */
122 | - (CKQueryMaker *(^)(NSString *,NSString *))lower;
123 | /**
124 | * 字段长度
125 | */
126 | - (CKQueryMaker *(^)(NSString *,NSString *))length;
127 | /**
128 | * 自定义列查询
129 | */
130 | - (CKQueryMaker *(^)(NSString *,...))columns;
131 |
132 | @end
133 |
--------------------------------------------------------------------------------
/FMDBHelper/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/5/19.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "CKFMDBHelper.h"
11 | #import "CKTestModel.h"
12 | #import "CKManager.h"
13 | #import "CKTestSubModel.h"
14 |
15 | @class AAModel;
16 | @interface AppDelegate ()
17 |
18 | @end
19 |
20 | @implementation AppDelegate
21 |
22 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
23 |
24 | if ([[NSFileManager defaultManager] fileExistsAtPath:[CKManager shareManager].dbPath] == NO) {
25 | [CKTestModel createTable];
26 | [CKTestModel createIndex:@"testIndex" unique:YES columns:@"index",@"name",nil];
27 | [CKTestModel dropIndex:@"testIndex"];
28 | [CKTestModel createIndex:@"testIndex" unique:YES columnDict:@{@"index":kCKModelIndexAsc,@"name":kCKModelIndexDesc}];
29 | // [CKTestModel createIndex:@"testIndex" unique:YES columns:@"index",@"lastName",nil];
30 | [CKTestModel updateColumn];
31 | }
32 |
33 | NSArray *array = [CKTestModel queryWithConditions:^id(CKConditionMaker *maker) {
34 | return maker.where(@"index = 1").and(@"index = 1").orderBy(@"[index]",CKOrderByAsc).limit(0,1);
35 | }];
36 | NSLog(@"%@",array);
37 |
38 | CKTestModel *model1 = [CKTestModel new];
39 | model1.index = (id)@1;
40 | model1.name = @"222";
41 | model1.lastName = @"333";
42 | [model1 insert];
43 |
44 | [model1 setValuesFromDictionary:@{@"ind":@1234,@"ac":@"nameValue",@"bbb":@"lastNameValue",@"ccc":@"indexValue"}];
45 | NSLog(@"%@",[CKTestSubModel propertyDict]);
46 |
47 | [CKTestModel insertWithArray:@[model1]];
48 | NSArray *array2 = [CKTestModel queryWithConditions:NULL];
49 | NSLog(@"%@",array2);
50 |
51 | model1.name = @"修改后的name";
52 | [CKTestModel updateWithArray:@[model1] conditions:^id(CKConditionMaker *maker) {
53 | return maker.where(@"[index] = 1").and(@"lastName = 333");
54 | }];
55 | NSArray *array3 = [CKTestModel queryWithConditions:NULL];
56 | NSLog(@"%@",array3);
57 |
58 |
59 | model1.name = @"再次修改后的值";
60 | [CKTestModel replaceWithArray:@[model1]];
61 | NSArray *array4 = [CKTestModel queryWithConditions:NULL];
62 | NSLog(@"%@",array4);
63 |
64 | NSArray *_array = [CKTestModel query:^id(CKQueryMaker *maker) {
65 | return maker.count(nil).max(@"index",nil).min(@"lastName",nil);
66 | } withConditions:^id(CKConditionMaker *maker) {
67 | return maker.where(@"index = 1").and(@"index = 1").orderBy(@"[index]",CKOrderByAsc).limit(0,1);
68 | }];
69 | NSLog(@"%@",_array);
70 |
71 | [model1 delete];
72 | NSArray *array6 = [CKTestModel queryWithConditions:NULL];
73 | NSLog(@"%@",array6);
74 |
75 | NSArray *array7 = [CKTestModel queryDictArrayWithSql:@"select * from CKTestModel"];
76 | NSLog(@"%@",array7);
77 |
78 |
79 | return YES;
80 | }
81 |
82 | //- (void)aaa:(NSString *)a,... bbb:(NSString *)b,...{
83 | //
84 | //}
85 |
86 | @end
87 |
--------------------------------------------------------------------------------
/FMDBHelper/FMDBHelper/NSObject+CKProperty.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+CKProperty.m
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/5/19.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import "NSObject+CKProperty.h"
10 | #import
11 |
12 | @implementation NSObject (CKProperty)
13 |
14 | /**
15 | * 获取属性列表
16 | *
17 | * @return 属性列表
18 | */
19 | + (NSArray *)propertyArray{
20 | NSMutableArray *array=[NSMutableArray array];
21 | Class itemClass = objc_getClass(object_getClassName(self));
22 | unsigned int outCount, i;
23 | objc_property_t *properties = class_copyPropertyList(itemClass, &outCount);
24 | for (i = 0; i < outCount; i++) {
25 | objc_property_t property = properties[i];
26 | NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)];
27 | if ([@[@"hash",@"superclass",@"description",@"debugDescription"] containsObject:propertyName]) {
28 | continue;
29 | }
30 | [array addObject:propertyName];
31 | }
32 | Class cls = class_getSuperclass(self);
33 | if (!(cls == NSClassFromString(@"CKModel") || cls == [NSObject class])) {
34 | [array addObjectsFromArray:[cls propertyArray]];
35 | }
36 | return array;
37 | }
38 |
39 | /**
40 | * 获取属性集合
41 | *
42 | * @return 属性集合
43 | */
44 | + (NSSet *)propertySet{
45 | return [NSSet setWithArray:[self propertyArray]];
46 | }
47 |
48 | /**
49 | * 属性字典,key为属性名称,value是数组,属性的编译属性列表
50 | *
51 | * @return 属性字典
52 | */
53 | + (NSDictionary *)propertyDict{
54 | NSMutableDictionary *dict=@{}.mutableCopy;
55 | Class itemClass = objc_getClass(object_getClassName(self));
56 | unsigned int outCount, i;
57 | objc_property_t *properties = class_copyPropertyList(itemClass, &outCount);
58 | for (i = 0; i < outCount; i++) {
59 | objc_property_t property = properties[i];
60 | NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)];
61 | NSString *propertyAttributes = [NSString stringWithUTF8String:property_getAttributes(property)];
62 | if ([@[@"hash",@"superclass",@"description",@"debugDescription"] containsObject:propertyName]) {
63 | continue;
64 | }
65 | [dict setObject:[propertyAttributes componentsSeparatedByString:@","] forKey:propertyName];
66 | }
67 | Class cls = class_getSuperclass(self);
68 | if (!(cls == NSClassFromString(@"CKModel") || cls == [NSObject class])) {
69 | [dict addEntriesFromDictionary:[cls propertyDict]];
70 | }
71 |
72 | return dict;
73 |
74 | }
75 |
76 | /**
77 | * 获取属性列表
78 | *
79 | * @return 属性列表
80 | */
81 | - (NSArray *)propertyArray{
82 | return [[self class] propertyArray];
83 | }
84 |
85 | /**
86 | * 获取属性集合
87 | *
88 | * @return 属性集合
89 | */
90 | - (NSSet *)propertySet{
91 | return [NSSet setWithArray:[[self class] propertyArray]];
92 | }
93 |
94 | /**
95 | * 属性字典,key为属性名称,value是数组,属性的编译属性列表
96 | *
97 | * @return 属性字典
98 | */
99 | - (NSDictionary *)propertyDict{
100 | return [[self class] propertyDict];
101 | }
102 |
103 |
104 |
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CKFMDBHelper
2 | ---
3 |
4 | ##这是什么
5 |
6 | 对FMDB的封装,以面向对象的方式操作数据库,并且对服务器model的支持,模型、字典、json相互转换,并提供字段映射
7 |
8 | ##如何使用
9 |
10 | ###Model创建
11 | ```
12 | #import "CKModel.h"
13 |
14 | @interface CKTestModel : CKModel
15 |
16 | @property (nonatomic, copy) NSNumber *index;
17 | @property (nonatomic, copy) NSString *name;
18 | @property (nonatomic, copy) NSString *lastName;
19 |
20 | @end
21 | ```
22 |
23 | ###表操作
24 | ```
25 | //创建表
26 | [CKTestModel createTable];
27 | //创建索引
28 | [CKTestModel createIndex:@"testIndex" unique:YES columns:@"index",@"name",nil];
29 | //删除索引
30 | [CKTestModel dropIndex:@"testIndex"];
31 | //创建索引
32 | [CKTestModel createIndex:@"testIndex" unique:YES columnDict:@{@"index":kCKModelIndexAsc,@"lastName":kCKModelIndexDesc}];
33 | //表结构更新,更新到最新结构
34 | [CKTestModel updateColumn];
35 |
36 | ```
37 | ###数据库操作
38 | ##### 查询语句
39 | ```
40 | NSArray *array = [CKTestModel queryWithConditions:^id(CKConditionMaker *maker) {
41 | return maker.where(@"index = 1").and(@"index = 1").orderBy(@"[index]",CKOrderByAsc).limit(0,1);
42 | }];
43 | NSLog(@"%@",array);
44 |
45 | NSArray *_array = [CKTestModel query:^id(CKQueryMaker *maker) {
46 | return maker.count(nil).max(@"index",nil).min(@"lastName",nil);
47 | } withConditions:^id(CKConditionMaker *maker) {
48 | return maker.where(@"index = 1").and(@"index = 1").orderBy(@"[index]",CKOrderByAsc).limit(0,1);
49 | }];
50 | NSLog(@"%@",_arra);
51 | ```
52 | ##### 插入语句
53 | ```
54 | CKTestModel *model1 = [CKTestModel new];
55 | model1.index = (id)@1;
56 | model1.name = @"222";
57 | model1.lastName = @"333";
58 | [model1 insert];
59 | [CKTestModel insertWithArray:@[model1]];
60 | NSArray *array2 = [CKTestModel queryWithConditions:NULL];
61 | NSLog(@"%@",array2);
62 | ```
63 | 或者
64 |
65 | ```
66 | CKTestModel *model1 = [CKTestModel new];
67 | model1.index = 1;
68 | model1.name = @"222";
69 | model1.lastName = @"333";
70 | [model1 insert];
71 | NSArray *array2 = [CKTestModel queryWithConditions:NULL];
72 | NSLog(@"%@",array2);
73 |
74 | ```
75 | 同理,还有删、改、replace等,操作基本相同
76 |
77 | ##### mapping
78 | ```
79 | #import "CKModel.h"
80 | #import "CKTest.h"
81 |
82 | @interface CKTestModel : CKModel
83 |
84 | @property (nonatomic, copy) NSNumber *index;
85 | @property (nonatomic, copy) NSString *name;
86 | @property (nonatomic, copy) NSString *lastName;
87 | @property (nonatomic, copy) CKTest *test;
88 |
89 | @end
90 |
91 |
92 | #import "CKTestModel.h"
93 |
94 | @implementation CKTestModel
95 |
96 | + (NSDictionary *)jsonKeyPathMapping{
97 | return @{
98 | @"index":@"ind",
99 | @"name":@"ac",
100 | @"lastName":@"bbb",
101 | @"test.index":@"ccc",
102 | };
103 | }
104 |
105 | - (instancetype)init
106 | {
107 | self = [super init];
108 | if (self) {
109 | _test = [CKTest new];
110 | }
111 | return self;
112 | }
113 |
114 | @end
115 |
116 | CKTestModel *model1 = [CKTestModel new];
117 | [model1 setValuesFromDictionary:@{@"ind":@1234,@"ac":@"nameValue",@"bbb":@"lastNameValue",@"ccc":@"indexValue"}];
118 |
119 |
120 | ```
121 |
122 | ####字典表的支持
123 | 表是否已经创建不用在意,直接赋值,就会自动创建,然后尽管取值就行了,而且不用担心速度慢,都会直接异步操作好数据库
124 |
125 | ```
126 | CKDictionary *dict = [CKDictionary shareInstance];
127 | if (!dict[@"key"]) {
128 | [dict setObject:@"value" forKey:@"key"];
129 | }
130 | NSLog(@"%@",dict[@"key"]);
131 |
132 | ```
133 |
--------------------------------------------------------------------------------
/FMDBHelper/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/FMDBHelper.xcodeproj/xcuserdata/tcyx.xcuserdatad/xcschemes/FMDBHelper.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
77 |
83 |
84 |
85 |
86 |
87 |
88 |
94 |
96 |
102 |
103 |
104 |
105 |
107 |
108 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/FMDBHelper/FMDBHelper/CKModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // CKModel.h
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/5/19.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class CKConditionMaker;
12 | @class CKQueryMaker;
13 |
14 | @protocol CKPrimaryKey
15 | @end
16 |
17 | /**
18 | * 正序
19 | */
20 | extern NSString * const kCKModelIndexAsc;
21 | /**
22 | * 倒序
23 | */
24 | extern NSString * const kCKModelIndexDesc;
25 |
26 | @protocol CKFmdbOperate
27 |
28 | @required
29 | #pragma mark
30 | #pragma mark - Table Operate
31 |
32 | #pragma mark - Create
33 | /**
34 | * 创建表
35 | *
36 | * @return 成功/失败
37 | */
38 | + (void)createTable;
39 | /**
40 | * 创建索引
41 | *
42 | * @param indexName 索引名称
43 | * @param isUnique 是否唯一
44 | * @param column 字段列表
45 | *
46 | * @return 是否成功
47 | */
48 | + (void)createIndex:(NSString *)indexName unique:(BOOL)isUnique columns:(NSString *)column,...;
49 | /**
50 | * 创建索引
51 | *
52 | * @param indexName 索引名称
53 | * @param isUnique 是否唯一
54 | * @param aColumnDict 字段列表、是否排序格式如下:
55 | * @{"column1":@"asc",@"column2":@"desc"}
56 | *
57 | * @return 是否成功
58 | */
59 | + (void)createIndex:(NSString *)indexName unique:(BOOL)isUnique columnDict:(NSDictionary *)aColumnDict;
60 |
61 | #pragma mark - Drop
62 | /**
63 | * 删除表
64 | *
65 | * @return 是否成功
66 | */
67 | + (void)dropTable;
68 | /**
69 | * 删除索引
70 | *
71 | * @param indexName 索引名称
72 | *
73 | * @return 是否成功
74 | */
75 | + (void)dropIndex:(NSString *)indexName;
76 |
77 | #pragma mark - Alert
78 | /**
79 | * 修改表名
80 | *
81 | * @param oldName 旧表名
82 | *
83 | * @return 是否修改成功
84 | */
85 | + (void)renameTableWithOldName:(NSString *)oldName;
86 | /**
87 | * 表结构更新到最新
88 | *
89 | * @return 是否成功
90 | */
91 | + (void)updateColumn;
92 | /**
93 | * 获取表结构
94 | *
95 | * @param tableName 表名
96 | *
97 | * @return 表字段数组
98 | */
99 | + (NSArray *)columnArrayWithTable:(NSString *)tableName;
100 |
101 | #pragma mark
102 | #pragma mark - Content Operate
103 |
104 | #pragma mark
105 | #pragma mark - Select
106 | /**
107 | * 条件查询单表
108 | *
109 | * @param block 查询条件
110 | *
111 | * @return Model列表
112 | */
113 | + (NSArray *)queryWithConditions:(id (^)(CKConditionMaker * maker))block;
114 | /**
115 | * 函数查询(count()、max()等)
116 | *
117 | * @param aQuery 函数语句
118 | * @param block 条件语句
119 | *
120 | * @return 查询结果
121 | */
122 | + (NSArray *)query:(id (^)(CKQueryMaker* maker))aQuery withConditions:(id (^)(CKConditionMaker * maker))block;
123 |
124 | /**
125 | * 查询任意自定义语句
126 | *
127 | * @param sql 查询语句
128 | *
129 | * @return 查询到的字典数组
130 | */
131 | + (NSArray *)queryDictArrayWithSql:(NSString *)sql;
132 | #pragma mark
133 | #pragma mark - insert
134 | /**
135 | * 多条数据插入
136 | *
137 | * @param array 数据数组
138 | */
139 | + (void)insertWithArray:(NSArray *)array;
140 | /**
141 | * 单条数据插入
142 | */
143 | - (void)insert;
144 |
145 | #pragma mark
146 | #pragma mark - update
147 | /**
148 | * 多数据条件更新(可设置唯一索引做唯一标识)
149 | *
150 | * @param array 数据数组
151 | * @param block 条件语句
152 | */
153 | + (void)updateWithArray:(NSArray *)array conditions:(id (^)(CKConditionMaker * maker))block;
154 | /**
155 | * 单条数据更新
156 | *
157 | * @param block 条件语句
158 | */
159 | - (void)updateWithConditions:(id (^)(CKConditionMaker * maker))block;
160 |
161 | #pragma mark
162 | #pragma mark - replace
163 | /**
164 | * 有则更新/无则插入语句 (多条数据)
165 | *
166 | * @param array 数据数组
167 | */
168 | + (void)replaceWithArray:(NSArray *)array;
169 | /**
170 | * 有则更新/无则插入语句 (单条数据)
171 | */
172 | - (void)replace;
173 |
174 | #pragma mark
175 | #pragma mark - delete
176 | /**
177 | * 删除多条数据(每个字段都唯一对应)
178 | *
179 | * @param array 数据数组
180 | */
181 | + (void)deleteWithArray:(NSArray *)array;
182 | /**
183 | * 条件删除数据
184 | *
185 | * @param block 条件语句
186 | */
187 | + (void)deleteWithConditions:(id (^)(CKConditionMaker * maker))block;
188 | /**
189 | * 单条数据删除
190 | */
191 | - (void)delete;
192 |
193 | @end
194 |
195 | @protocol CKFmdbJsonOperate
196 |
197 | /**
198 | * 字典转换model
199 | *
200 | * @param dict model字典
201 | *
202 | * @return model
203 | */
204 | + (id)modelWithDictionary:(NSDictionary *)dict;
205 | /**
206 | * 字典转换为数组模型
207 | *
208 | * @param dicts 字典数组
209 | *
210 | * @return 模型数组
211 | */
212 | + (NSArray *)modelsWithDictionarys:(NSArray *)dicts;
213 | /**
214 | * 模型数组转换为字典数组
215 | *
216 | * @param models 模型数组
217 | *
218 | * @return 字典数组
219 | */
220 | + (NSArray *)modelDictnarysWithModels:(NSArray *)models;
221 | /**
222 | * 模型数组转换为json
223 | *
224 | * @param models 模型数组
225 | *
226 | * @return json
227 | */
228 | + (NSString *)modelsJsonWithModels:(NSArray *)models;
229 | /**
230 | * 根据字典赋值
231 | *
232 | * @param dicts 模型字典
233 | */
234 | - (void)setValuesFromDictionary:(NSDictionary *)dicts;
235 | /**
236 | * 获取模型字典
237 | *
238 | * @return 模型字典
239 | */
240 | - (NSDictionary *)modelDictionary;
241 | /**
242 | * 获取模型json
243 | *
244 | * @return 模型json
245 | */
246 | - (NSString *)modelJson;
247 |
248 |
249 | @end
250 |
251 | @protocol CKFmdbJsonSerializing
252 | @required
253 | /**
254 | * json 解析Key mapping
255 | *
256 | * @return mapping
257 | */
258 | + (NSDictionary *)jsonKeyPathMapping;
259 |
260 | @end
261 |
262 | /**
263 | * FMDBHelperBaseModel
264 | */
265 | @interface CKModel : NSObject
266 |
267 | //根据字典初始化
268 | - (instancetype)initWithDictionary:(NSDictionary *)dict;
269 |
270 | @end
271 |
--------------------------------------------------------------------------------
/FMDBHelper/FMDBHelper/CKDictionary.m:
--------------------------------------------------------------------------------
1 | //
2 | // CKDictionary.m
3 | // GameCenter
4 | //
5 | // Created by caydenk on 15/7/28.
6 | // Copyright (c) 2015年 CaydenK. All rights reserved.
7 | //
8 |
9 | #import "CKFMDBHelper.h"
10 | #import "CKManager.h"
11 | #import
12 |
13 | //键 列名
14 | #define CK_DICT_KEY @"ckkey"
15 | //值 列名
16 | #define CK_DICT_VALUE @"ckvalue"
17 |
18 | @interface CKDictionary ()
19 | {
20 | CFMutableDictionaryRef _dictionary;
21 | }
22 |
23 | @property (nonatomic, strong) dispatch_queue_t dictQueue;
24 |
25 | @end
26 |
27 | @implementation CKDictionary
28 |
29 | + (CKDictionary *)shareInstance {
30 | static CKDictionary *instance;
31 | static dispatch_once_t onceToken;
32 | dispatch_once(&onceToken, ^{
33 | instance = [[self alloc] init];
34 | instance.dictQueue = dispatch_queue_create("ck_dict_serial_queue", DISPATCH_QUEUE_SERIAL);
35 | });
36 | return instance;
37 | }
38 |
39 | /**
40 | * 创建表,并创建唯一索引
41 | */
42 | + (void)createTable{
43 | NSString *createTableSql = [NSString stringWithFormat:@"create table if not exists '%@' (%@ text default '' NOT NULL,%@ text default '' NOT NULL)",CKDICTIONARY,CK_DICT_KEY,CK_DICT_VALUE];
44 | NSMutableString *createIndexSql = [NSMutableString stringWithFormat:@"create unique index '%@_index' on '%@' (%@)",CKDICTIONARY,CKDICTIONARY,CK_DICT_KEY];
45 | FMDatabase *db = [[CKManager shareManager] databaseWithName:CKDBNAME];
46 | [db open];
47 | [db executeUpdate:createTableSql];
48 | [db executeUpdate:createIndexSql];
49 | [db close];
50 | }
51 |
52 | + (id)valueFromDBForKey:(id)aKey {
53 | NSString *querySql = [NSString stringWithFormat:@"select %@ from %@ where %@ = '%@'",CK_DICT_VALUE,CKDICTIONARY,CK_DICT_KEY,aKey];
54 | id value = nil;
55 | FMDatabase *db = [[CKManager shareManager] databaseWithName:CKDBNAME];
56 | [db open];
57 | FMResultSet *rs = [db executeQuery:querySql];
58 | while ([rs next]) {
59 | value = [rs objectForColumnName:CK_DICT_VALUE];
60 | }
61 | [db close];
62 | return value;
63 | }
64 |
65 | #pragma mark
66 | #pragma mark - NSMutableDictionary
67 | - (id)init {
68 | self = [super init];
69 | if (self)
70 | {
71 | _dictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
72 | &kCFTypeDictionaryKeyCallBacks,
73 | &kCFTypeDictionaryValueCallBacks);
74 |
75 | NSString *querySql = [NSString stringWithFormat:@"select %@ from %@",CK_DICT_VALUE,CKDICTIONARY];
76 | FMDatabase *db = [[CKManager shareManager] databaseWithName:CKDBNAME];
77 | [db open];
78 | FMResultSet *rs = [db executeQuery:querySql];
79 | while ([rs next]) {
80 | id key = [rs objectForColumnName:CK_DICT_KEY];
81 | id value = [rs objectForColumnName:CK_DICT_VALUE];
82 | CFDictionarySetValue(_dictionary, (__bridge const void *)key, (__bridge const void *)value);
83 | }
84 | [db close];
85 |
86 | }
87 | return self;
88 | }
89 | - (NSUInteger)count {
90 | NSUInteger count = CFDictionaryGetCount(_dictionary);
91 | return count;
92 | }
93 | - (id)objectForKey:(id)aKey {
94 | NSAssert(aKey, @"key cannot be nil");
95 | id result = CFDictionaryGetValue(_dictionary, (__bridge const void *)(aKey));
96 | if (!result) {
97 | result = [[self class] valueFromDBForKey:aKey];
98 | CFDictionarySetValue(_dictionary, (__bridge const void *)aKey, (__bridge const void *)result);
99 | }
100 | return result;
101 | }
102 | - (NSEnumerator *)keyEnumerator {
103 | id result = [(__bridge id)_dictionary keyEnumerator];
104 | return result;
105 | }
106 | - (void)setObject:(id)anObject forKey:(id)aKey {
107 | NSAssert(anObject, @"object cannot be nil");
108 | NSAssert(aKey, @"key cannot be nil");
109 | CFDictionarySetValue(_dictionary, (__bridge const void *)aKey, (__bridge const void *)anObject);
110 | [[[CKManager shareManager] databaseQueueWithName:CKDBNAME] inTransaction:^(FMDatabase *db, BOOL *rollback) {
111 | BOOL success = [db executeUpdate:[NSString stringWithFormat:@"replace into %@ ([%@],[%@]) values ('%@','%@')",CKDICTIONARY,CK_DICT_KEY,CK_DICT_VALUE,aKey,anObject]];
112 | if (!success) {
113 | NSArray *columnArray = [CKModel columnArrayWithTable:CKDICTIONARY];
114 | if (columnArray.count == 0) {
115 | [[self class] createTable];
116 | }
117 | [db executeUpdate:[NSString stringWithFormat:@"replace into %@ ([%@],[%@]) values ('%@','%@')",CKDICTIONARY,CK_DICT_KEY,CK_DICT_VALUE,aKey,anObject]];
118 | }
119 |
120 | }];
121 | }
122 | - (void)removeObjectForKey:(id)aKey {
123 | NSAssert(aKey, @"key cannot be nil");
124 | CFDictionaryRemoveValue(_dictionary, (__bridge const void *)aKey);
125 | [[[CKManager shareManager] databaseQueueWithName:CKDBNAME] inTransaction:^(FMDatabase *db, BOOL *rollback) {
126 | [db executeUpdate:[NSString stringWithFormat:@"delete from %@ where [%@] = '%@'",CKDICTIONARY,CK_DICT_KEY,aKey]];
127 | }];
128 | }
129 | - (void)removeAllObjects {
130 | CFDictionaryRemoveAllValues(_dictionary);
131 | [[[CKManager shareManager] databaseQueueWithName:CKDBNAME] inTransaction:^(FMDatabase *db, BOOL *rollback) {
132 | [db executeUpdate:[NSString stringWithFormat:@"delete from %@",CKDICTIONARY]];
133 | }];
134 | }
135 | - (void)dealloc {
136 | if (_dictionary)
137 | {
138 | CFRelease(_dictionary);
139 | _dictionary = NULL;
140 | }
141 | }
142 |
143 | @end
144 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | Podfile.lock
2 | FMDBHelper.xcworkspace
3 | FMDBHelper.xcworkspace/contents.xcworkspacedata
4 | FMDBHelper.xcworkspace/xcshareddata/FMDBHelper.xccheckout
5 | FMDBHelper.xcworkspace/xcuserdata/tcyx.xcuserdatad/UserInterfaceState.xcuserstate
6 | Pods/FMDB/src/fmdb/FMDatabase.h
7 | Pods/FMDB/src/fmdb/FMDatabase.m
8 | Pods/FMDB/src/fmdb/FMDatabaseAdditions.h
9 | Pods/FMDB/src/fmdb/FMDatabaseAdditions.m
10 | Pods/FMDB/src/fmdb/FMDatabasePool.h
11 | Pods/FMDB/src/fmdb/FMDatabasePool.m
12 | Pods/FMDB/src/fmdb/FMDatabaseQueue.h
13 | Pods/FMDB/src/fmdb/FMDatabaseQueue.m
14 | Pods/FMDB/src/fmdb/FMDB.h
15 | Pods/FMDB/src/fmdb/FMResultSet.h
16 | Pods/FMDB/src/fmdb/FMResultSet.m
17 | Pods/Headers/Build/FMDB/FMDatabase.h
18 | Pods/Headers/Build/FMDB/FMDatabaseAdditions.h
19 | Pods/Headers/Build/FMDB/FMDatabasePool.h
20 | Pods/Headers/Build/FMDB/FMDatabaseQueue.h
21 | Pods/Headers/Build/FMDB/FMDB.h
22 | Pods/Headers/Build/FMDB/FMResultSet.h
23 | Pods/Headers/Build/Mantle/EXTKeyPathCoding.h
24 | Pods/Headers/Build/Mantle/EXTRuntimeExtensions.h
25 | Pods/Headers/Build/Mantle/EXTScope.h
26 | Pods/Headers/Build/Mantle/Mantle.h
27 | Pods/Headers/Build/Mantle/metamacros.h
28 | Pods/Headers/Build/Mantle/MTLJSONAdapter.h
29 | Pods/Headers/Build/Mantle/MTLManagedObjectAdapter.h
30 | Pods/Headers/Build/Mantle/MTLModel+NSCoding.h
31 | Pods/Headers/Build/Mantle/MTLModel.h
32 | Pods/Headers/Build/Mantle/MTLReflection.h
33 | Pods/Headers/Build/Mantle/MTLValueTransformer.h
34 | Pods/Headers/Build/Mantle/NSArray+MTLManipulationAdditions.h
35 | Pods/Headers/Build/Mantle/NSDictionary+MTLManipulationAdditions.h
36 | Pods/Headers/Build/Mantle/NSError+MTLModelException.h
37 | Pods/Headers/Build/Mantle/NSObject+MTLComparisonAdditions.h
38 | Pods/Headers/Build/Mantle/NSValueTransformer+MTLInversionAdditions.h
39 | Pods/Headers/Build/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h
40 | Pods/Headers/Public/FMDB/FMDatabase.h
41 | Pods/Headers/Public/FMDB/FMDatabaseAdditions.h
42 | Pods/Headers/Public/FMDB/FMDatabasePool.h
43 | Pods/Headers/Public/FMDB/FMDatabaseQueue.h
44 | Pods/Headers/Public/FMDB/FMDB.h
45 | Pods/Headers/Public/FMDB/FMResultSet.h
46 | Pods/Headers/Public/Mantle/EXTKeyPathCoding.h
47 | Pods/Headers/Public/Mantle/EXTRuntimeExtensions.h
48 | Pods/Headers/Public/Mantle/EXTScope.h
49 | Pods/Headers/Public/Mantle/Mantle.h
50 | Pods/Headers/Public/Mantle/metamacros.h
51 | Pods/Headers/Public/Mantle/MTLJSONAdapter.h
52 | Pods/Headers/Public/Mantle/MTLManagedObjectAdapter.h
53 | Pods/Headers/Public/Mantle/MTLModel+NSCoding.h
54 | Pods/Headers/Public/Mantle/MTLModel.h
55 | Pods/Headers/Public/Mantle/MTLReflection.h
56 | Pods/Headers/Public/Mantle/MTLValueTransformer.h
57 | Pods/Headers/Public/Mantle/NSArray+MTLManipulationAdditions.h
58 | Pods/Headers/Public/Mantle/NSDictionary+MTLManipulationAdditions.h
59 | Pods/Headers/Public/Mantle/NSError+MTLModelException.h
60 | Pods/Headers/Public/Mantle/NSObject+MTLComparisonAdditions.h
61 | Pods/Headers/Public/Mantle/NSValueTransformer+MTLInversionAdditions.h
62 | Pods/Headers/Public/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h
63 | Pods/Mantle/LICENSE.md
64 | Pods/Mantle/README.md
65 | Pods/Mantle/Mantle/Mantle.h
66 | Pods/Mantle/Mantle/MTLJSONAdapter.h
67 | Pods/Mantle/Mantle/MTLJSONAdapter.m
68 | Pods/Mantle/Mantle/MTLManagedObjectAdapter.h
69 | Pods/Mantle/Mantle/MTLManagedObjectAdapter.m
70 | Pods/Mantle/Mantle/MTLModel+NSCoding.h
71 | Pods/Mantle/Mantle/MTLModel+NSCoding.m
72 | Pods/Mantle/Mantle/MTLModel.h
73 | Pods/Mantle/Mantle/MTLModel.m
74 | Pods/Mantle/Mantle/MTLReflection.h
75 | Pods/Mantle/Mantle/MTLReflection.m
76 | Pods/Mantle/Mantle/MTLValueTransformer.h
77 | Pods/Mantle/Mantle/MTLValueTransformer.m
78 | Pods/Mantle/Mantle/NSArray+MTLManipulationAdditions.h
79 | Pods/Mantle/Mantle/NSArray+MTLManipulationAdditions.m
80 | Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.h
81 | Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.m
82 | Pods/Mantle/Mantle/NSError+MTLModelException.h
83 | Pods/Mantle/Mantle/NSError+MTLModelException.m
84 | Pods/Mantle/Mantle/NSObject+MTLComparisonAdditions.h
85 | Pods/Mantle/Mantle/NSObject+MTLComparisonAdditions.m
86 | Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.h
87 | Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.m
88 | Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h
89 | Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.m
90 | Pods/Mantle/Mantle/extobjc/EXTKeyPathCoding.h
91 | Pods/Mantle/Mantle/extobjc/EXTRuntimeExtensions.h
92 | Pods/Mantle/Mantle/extobjc/EXTRuntimeExtensions.m
93 | Pods/Mantle/Mantle/extobjc/EXTScope.h
94 | Pods/Mantle/Mantle/extobjc/EXTScope.m
95 | Pods/Mantle/Mantle/extobjc/metamacros.h
96 | Pods/Pods.xcodeproj/project.pbxproj
97 | Pods/Pods.xcodeproj/xcuserdata/CaydenK.xcuserdatad/xcschemes/Pods-FMDBHelper-FMDB.xcscheme
98 | Pods/Pods.xcodeproj/xcuserdata/CaydenK.xcuserdatad/xcschemes/Pods-FMDBHelper-Mantle.xcscheme
99 | Pods/Pods.xcodeproj/xcuserdata/CaydenK.xcuserdatad/xcschemes/Pods-FMDBHelper.xcscheme
100 | Pods/Pods.xcodeproj/xcuserdata/CaydenK.xcuserdatad/xcschemes/xcschememanagement.plist
101 | Pods/Target Support Files/Pods-FMDBHelper/Pods-FMDBHelper-acknowledgements.markdown
102 | Pods/Target Support Files/Pods-FMDBHelper/Pods-FMDBHelper-acknowledgements.plist
103 | Pods/Target Support Files/Pods-FMDBHelper/Pods-FMDBHelper-dummy.m
104 | Pods/Target Support Files/Pods-FMDBHelper/Pods-FMDBHelper-environment.h
105 | Pods/Target Support Files/Pods-FMDBHelper/Pods-FMDBHelper-resources.sh
106 | Pods/Target Support Files/Pods-FMDBHelper/Pods-FMDBHelper.debug.xcconfig
107 | Pods/Target Support Files/Pods-FMDBHelper/Pods-FMDBHelper.release.xcconfig
108 | Pods/Target Support Files/Pods-FMDBHelper-FMDB/Pods-FMDBHelper-FMDB-dummy.m
109 | Pods/Target Support Files/Pods-FMDBHelper-FMDB/Pods-FMDBHelper-FMDB-prefix.pch
110 | Pods/Target Support Files/Pods-FMDBHelper-FMDB/Pods-FMDBHelper-FMDB-Private.xcconfig
111 | Pods/Target Support Files/Pods-FMDBHelper-FMDB/Pods-FMDBHelper-FMDB.xcconfig
112 | Pods/Target Support Files/Pods-FMDBHelper-Mantle/Pods-FMDBHelper-Mantle-dummy.m
113 | Pods/Target Support Files/Pods-FMDBHelper-Mantle/Pods-FMDBHelper-Mantle-prefix.pch
114 | Pods/Target Support Files/Pods-FMDBHelper-Mantle/Pods-FMDBHelper-Mantle-Private.xcconfig
115 | Pods/Target Support Files/Pods-FMDBHelper-Mantle/Pods-FMDBHelper-Mantle.xcconfig
116 | FMDBHelper.xcodeproj/xcuserdata/CaydenK.xcuserdatad/xcschemes/FMDBHelper.xcscheme
117 | FMDBHelper.xcodeproj/xcuserdata/CaydenK.xcuserdatad/xcschemes/xcschememanagement.plist
118 | FMDBHelper.xcworkspace/xcuserdata/CaydenK.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
119 | Pods/Manifest.lock
120 | Pods/FMDB/LICENSE.txt
121 |
--------------------------------------------------------------------------------
/FMDBHelper/FMDBHelper/CKManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // CKManager.m
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/5/19.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import "CKManager.h"
10 | #import "FMDB.h"
11 | #import
12 |
13 | #import "NSObject+CKProperty.h"
14 | #import "CKFMDBHelper.h"
15 |
16 | #define PATH_OF_APP_HOME NSHomeDirectory()
17 | #define PATH_OF_TEMP NSTemporaryDirectory()
18 | #define PATH_OF_DOCUMENT [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
19 | #define PATH_OF_CACHES [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]
20 |
21 | static NSString const *sqliteType = @"sqlite";
22 | static NSString const *sqliteGroup = @"Archive";
23 |
24 | @interface CKManager (){
25 | NSMutableDictionary *_customerIvarDict;
26 | }
27 | @end
28 |
29 | @implementation CKManager
30 |
31 | - (NSString *)dbPath{
32 | return sqlitePathWithName(CKDBNAME);
33 | }
34 |
35 | /**
36 | * 获取当前单例
37 | *
38 | * @return 当前单例
39 | */
40 | + (CKManager *)shareManager{
41 | static CKManager *instance;
42 | static dispatch_once_t onceToken;
43 | dispatch_once(&onceToken, ^{
44 | instance = [[self class] new];
45 | instance->_customerIvarDict = @{}.mutableCopy;
46 | });
47 | return instance;
48 | }
49 |
50 |
51 | /**
52 | * 根据库名获取FMDatabase
53 | *
54 | * @param dbName 数据库名称
55 | *
56 | * @return FMDatabase
57 | */
58 | - (FMDatabase *)databaseWithName:(NSString *)dbName{
59 | if (dbName.length == 0) {return nil;}
60 | NSString *propertyName = [NSString stringWithFormat:@"db%@",dbName];
61 | //propertyName 的值中,不要出现下划线 "_",会导致set方法合成失败,crash
62 | [self addPropertyName:propertyName Class:[FMDatabase class]];
63 | FMDatabase *db = [self valueForKey:propertyName];
64 | if (db == nil) {
65 | db = [FMDatabase databaseWithPath:sqlitePathWithName(dbName)];
66 | [self->_customerIvarDict setObject:db forKey:propertyName];
67 | // [self setValue:db forKey:propertyName];
68 | }
69 | return db;
70 | }
71 | /**
72 | * 根据库名获取FMDatabaseQueue
73 | *
74 | * @param dbName 数据库名称
75 | *
76 | * @return FMDatabaseQueue
77 | */
78 | - (FMDatabaseQueue *)databaseQueueWithName:(NSString *)dbName{
79 | if (dbName.length == 0) {return nil;}
80 | //此处请无视 //propertyName 的值中,不要出现下划线 "_",会导致set方法合成失败,crash
81 | NSString *propertyName = [NSString stringWithFormat:@"queue%@",dbName];
82 | [self addPropertyName:propertyName Class:[FMDatabaseQueue class]];
83 | FMDatabaseQueue *queue = [self valueForKey:propertyName];
84 | if (queue == nil) {
85 | queue = [FMDatabaseQueue databaseQueueWithPath:sqlitePathWithName(dbName)];
86 | [self->_customerIvarDict setObject:queue forKey:propertyName];
87 | // [self setValue:queue forKey:propertyName];
88 | }
89 | return queue;
90 | }
91 |
92 | /**
93 | * 增加属性(get/set)
94 | *
95 | * @param propertyName 属性名称
96 | * @param cls 属性类型
97 | */
98 | - (void)addPropertyName:(NSString *)propertyName Class:(Class)cls{
99 | objc_property_attribute_t type = { "T", [[NSString stringWithFormat:@"@\"%@\"",cls] UTF8String] };
100 | objc_property_attribute_t ownership = { "&", "N" };
101 | objc_property_attribute_t backingivar = { "V", [[NSString stringWithFormat:@"_%@", propertyName] UTF8String] };
102 | objc_property_attribute_t attrs[] = { type, ownership, backingivar };
103 | if (class_addProperty([self class], [propertyName UTF8String], attrs, 3)) {
104 | //添加get和set方法
105 | class_addMethod([self class], NSSelectorFromString(propertyName), (IMP)getter, "@@:");
106 | // class_addMethod([self class], NSSelectorFromString([NSString stringWithFormat:@"set%@:",[propertyName capitalizedString]]), (IMP)setter, "v@:@");
107 | }
108 | }
109 |
110 |
111 | //处理get方法
112 | id getter(id self1, SEL _cmd1) {
113 | NSString *key = NSStringFromSelector(_cmd1);
114 | Ivar ivar = class_getInstanceVariable([self1 class], "_customerIvarDict");
115 | NSMutableDictionary *dictCustomerProperty = object_getIvar(self1, ivar);
116 | return [dictCustomerProperty objectForKey:key];
117 | }
118 |
119 | //处理set方法
120 | void setter(id self1, SEL _cmd1, id newValue) {
121 | //移除set
122 | NSString *key = [NSStringFromSelector(_cmd1) stringByReplacingCharactersInRange:NSMakeRange(0, 3) withString:@""];
123 | //首字母小写
124 | NSString *head = [key substringWithRange:NSMakeRange(0, 1)];
125 | head = [head lowercaseString];
126 | key = [key stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:head];
127 | //移除后缀 ":"
128 | key = [key stringByReplacingCharactersInRange:NSMakeRange(key.length - 1, 1) withString:@""];
129 | Ivar ivar = class_getInstanceVariable([self1 class], "_customerIvarDict");
130 | NSMutableDictionary *dictCustomerProperty = object_getIvar(self1, ivar);
131 | object_setIvar(self1, ivar, dictCustomerProperty);
132 | [dictCustomerProperty setObject:newValue forKey:key];
133 | }
134 |
135 | //创建路径
136 | NSString* sqlitePathWithName(NSString* name){
137 | NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
138 | NSString *group = [NSString stringWithFormat:@"%@/%@",document,sqliteGroup];
139 | NSFileManager *fm = [NSFileManager defaultManager];
140 | if (![fm fileExistsAtPath:group]) {
141 | // 文件夹不存在
142 | // 创建文件夹
143 | [fm createDirectoryAtPath:group withIntermediateDirectories:YES attributes:nil error:nil];
144 | }
145 | NSString *path = [NSString stringWithFormat:@"%@/%@.%@",group,name,sqliteType];
146 | return path;
147 | }
148 |
149 |
150 |
151 | //以下代码暂时废弃,多库支持时,再使用
152 |
153 | /*
154 | + (void)executeUpdateWithName:(NSString *)dbName
155 | Operate:(void(^)(FMDatabaseQueue *queue, FMDatabase *db))operate
156 | Completion:(void (^)(void))completion {
157 | CKManager *manager = [self shareManager];
158 | NSMutableDictionary *blocks = @{}.mutableCopy;
159 | if (operate) {
160 | [blocks setObject:operate forKeyedSubscript:@"operate"];
161 | }
162 | if (completion) {
163 | [blocks setObject:completion forKeyedSubscript:@"completion"];
164 | }
165 | NSThread *thread = [[NSThread alloc]initWithTarget:manager selector:@selector(executeUpdateInThreadOperate:) object:blocks];
166 | thread.name = dbName;
167 | [thread start];
168 | }
169 | //*/
170 |
171 | /**
172 | * 支线程中回调block执行任务
173 | *
174 | * @param blocks 任务回调block/任务完成回调block
175 | */
176 | /*
177 | - (void)executeUpdateInThreadOperate:(NSDictionary *)blocks{
178 | void(^operate)(FMDatabaseQueue *queue, FMDatabase *db) = blocks[@"operate"];
179 | void (^completion)(void) = blocks[@"completion"];
180 |
181 | CKManager *manager = [CKManager shareManager];
182 | NSThread *thread = [NSThread currentThread];
183 | NSString *dbName = thread.name;
184 | FMDatabase *db = [manager databaseWithName:dbName];
185 | FMDatabaseQueue *queue = [manager databaseQueueWithName:dbName];
186 | if (operate) {
187 | operate(queue,db);
188 | }
189 | dispatch_async(dispatch_get_main_queue(), ^{
190 | if (completion) {
191 | completion();
192 | }
193 | });
194 | }
195 | //*/
196 |
197 | @end
198 |
--------------------------------------------------------------------------------
/FMDBHelper/FMDBHelper/CKConditionMaker.m:
--------------------------------------------------------------------------------
1 | //
2 | // CKFuckMaker.m
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/5/22.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import "CKConditionMaker.h"
10 | #import "NSObject+CKProperty.h"
11 |
12 | @interface CKBaseMaker ()
13 |
14 | @property (nonatomic, unsafe_unretained) Class cls;
15 |
16 | @end
17 |
18 | @implementation CKBaseMaker
19 |
20 | + (instancetype)newWithModelClass:(Class)cls{
21 | CKConditionMaker *maker = [self new];
22 | maker.cls = cls;
23 | return maker;
24 | }
25 | - (instancetype)initWithModelClass:(Class)cls{
26 | self = [super init];
27 | if (self) {
28 | _cls = cls;
29 | }
30 | return self;
31 | }
32 |
33 | /**
34 | * sql关键字替换
35 | *
36 | * @param item 关键字字句
37 | * @param cls 类型
38 | *
39 | * @return 替换后的语句
40 | */
41 | NSString *sqlKeywordsReplace(NSString *item, Class cls){
42 | NSString *value = item.copy;
43 | NSArray *propertyArray = [cls propertyArray];
44 | for (NSString *property in propertyArray) {
45 | NSRange range = [value rangeOfString:property];
46 | NSRange range2 = [value rangeOfString:[NSString stringWithFormat:@"[%@]",property]];
47 | if (range.location != NSNotFound && range2.location == NSNotFound) {
48 | value = [value stringByReplacingCharactersInRange:range withString:[NSString stringWithFormat:@"[%@]",property]];
49 | }
50 | }
51 | return value;
52 | }
53 |
54 | /**
55 | * 排序枚举映射
56 | *
57 | * @param type 类型
58 | *
59 | * @return 正序/倒序
60 | */
61 | NSString *conditionMakerMap(CKConditionMakerOrderByType type){
62 | if (type == CKOrderByAsc) {
63 | return @"asc";
64 | }
65 | else{
66 | return @"desc";
67 | }
68 | }
69 |
70 | - (void)dealloc
71 | {
72 | _cls = nil;
73 | }
74 |
75 | @end
76 |
77 | @implementation CKConditionMaker
78 |
79 | - (CKConditionMaker * (^)(NSString *))where{
80 | /**
81 | * where 条件
82 | *
83 | * @param item 条件
84 | *
85 | * @return CKConditionMaker
86 | */
87 | return ^CKConditionMaker *(NSString *item) {
88 | self.sqlCondition = [self.sqlCondition stringByAppendingFormat:@" where %@",sqlKeywordsReplace(item, self.cls)];
89 | return self;
90 | };
91 | }
92 | - (CKConditionMaker * (^)(NSString *))and{
93 | /**
94 | * where 的 and字句
95 | *
96 | * @param item 条件
97 | *
98 | * @return CKConditionMaker
99 | */
100 | return ^CKConditionMaker *(NSString *item) {
101 | self.sqlCondition = [self.sqlCondition stringByAppendingFormat:@" and %@",sqlKeywordsReplace(item, self.cls)];
102 | return self;
103 | };
104 | }
105 | - (CKConditionMaker *(^)(NSString *))or{
106 | /**
107 | * where 的or字句
108 | *
109 | * @param item 条件
110 | *
111 | * @return CKConditionMaker
112 | */
113 | return ^CKConditionMaker *(NSString *item) {
114 | self.sqlCondition = [self.sqlCondition stringByAppendingFormat:@" or %@",sqlKeywordsReplace(item, self.cls)];
115 | return self;
116 | };
117 | }
118 | /**
119 | * 包含于运算
120 | */
121 | - (CKConditionMaker * (^)(NSArray *))in{
122 | /**
123 | * where 的in字句
124 | *
125 | * @param items 内容列表
126 | *
127 | * @return CKConditionMaker
128 | */
129 | return ^CKConditionMaker *(NSArray *items) {
130 | self.sqlCondition = [self.sqlCondition stringByAppendingFormat:@" in (%@)",sqlKeywordsReplace([items componentsJoinedByString:@","], self.cls)];
131 | return self;
132 | };
133 | }
134 |
135 | - (CKConditionMaker *(^)(NSString *))like{
136 | /**
137 | * 模糊查询
138 | *
139 | * @param item 模糊方式
140 | *
141 | * @return CKConditionMaker
142 | */
143 | return ^CKConditionMaker *(NSString *item) {
144 | self.sqlCondition = [self.sqlCondition stringByAppendingFormat:@" like %@",sqlKeywordsReplace(item, self.cls)];
145 | return self;
146 | };
147 | }
148 | - (CKConditionMaker * (^)(NSString *orderKey, CKConditionMakerOrderByType orderType))orderBy{
149 | /**
150 | * @param orderKey 排序字段
151 | * @param orderType 正序/倒序
152 | *
153 | * @return CKConditionMaker
154 | */
155 | return ^CKConditionMaker *(NSString *orderKey, CKConditionMakerOrderByType orderType) {
156 | self.sqlCondition = [self.sqlCondition stringByAppendingFormat:@" order by %@ %@",sqlKeywordsReplace(orderKey, self.cls),conditionMakerMap(orderType)];
157 | return self;
158 | };
159 | }
160 | - (CKConditionMaker * (^)(NSInteger location, NSInteger count))limit{
161 | /**
162 | * @param location 位置
163 | * @param count 个数
164 | *
165 | * @return CKConditionMaker
166 | */
167 | return ^CKConditionMaker *(NSInteger location, NSInteger count) {
168 | self.sqlCondition = [self.sqlCondition stringByAppendingFormat:@" limit %ld,%ld",(long)location,(long)count];
169 | return self;
170 | };
171 | }
172 |
173 | #pragma mark
174 | #pragma mark - Get
175 | - (NSString *)sqlCondition{
176 | if (_sqlCondition == nil) {
177 | _sqlCondition = @"";
178 | }
179 | return _sqlCondition;
180 | }
181 |
182 | @end
183 |
184 | @implementation CKQueryMaker
185 |
186 | - (CKQueryMaker * (^)(NSString *))count{
187 | /**
188 | * 获取个数
189 | *
190 | * @param alias 别名
191 | *
192 | * @return CKQueryMaker
193 | */
194 | return ^CKQueryMaker *(NSString *alias) {
195 | [self.sqlQueryDict setObject:alias?:NSStringFromSelector(_cmd) forKey:@"count(0)"];
196 | return self;
197 | };
198 | }
199 | - (CKQueryMaker *(^)(NSString *,NSString *))max{
200 | /**
201 | * 最大值函数
202 | *
203 | * @param column 字段名
204 | * @param alias 别名
205 | *
206 | * @return CKQueryMaker
207 | */
208 | return ^CKQueryMaker *(NSString *column,NSString *alias) {
209 | [self.sqlQueryDict setObject:alias?:NSStringFromSelector(_cmd) forKey:[NSString stringWithFormat:@"max(%@)",sqlKeywordsReplace(column, self.cls)]];
210 | return self;
211 | };
212 | }
213 | - (CKQueryMaker *(^)(NSString *,NSString *))min{
214 | /**
215 | * 最小值函数
216 | *
217 | * @param column 字段名
218 | * @param alias 别名
219 | *
220 | * @return CKQueryMaker
221 | */
222 | return ^CKQueryMaker *(NSString *column,NSString *alias) {
223 | [self.sqlQueryDict setObject:alias?:NSStringFromSelector(_cmd) forKey:[NSString stringWithFormat:@"min(%@)",sqlKeywordsReplace(column, self.cls)]];
224 | return self;
225 | };
226 | }
227 | - (CKQueryMaker *(^)(NSString *,NSString *))avg{
228 | /**
229 | * 平均值函数
230 | *
231 | * @param column 字段名
232 | * @param alias 别名
233 | *
234 | * @return CKQueryMaker
235 | */
236 | return ^CKQueryMaker *(NSString *column,NSString *alias) {
237 | [self.sqlQueryDict setObject:alias?:NSStringFromSelector(_cmd) forKey:[NSString stringWithFormat:@"avg(%@)",sqlKeywordsReplace(column, self.cls)]];
238 | return self;
239 | };
240 | }
241 | - (CKQueryMaker *(^)(NSString *,NSString *))sum{
242 | /**
243 | * 求和函数
244 | *
245 | * @param column 字段名
246 | * @param alias 别名
247 | *
248 | * @return CKQueryMaker
249 | */
250 | return ^CKQueryMaker *(NSString *column,NSString *alias) {
251 | [self.sqlQueryDict setObject:alias?:NSStringFromSelector(_cmd) forKey:[NSString stringWithFormat:@"sum(%@)",sqlKeywordsReplace(column, self.cls)]];
252 | return self;
253 | };
254 | }
255 | - (CKQueryMaker *(^)(NSString *,NSString *))upper{
256 | /**
257 | * 转大写字母
258 | *
259 | * @param column 字段名
260 | * @param alias 别名
261 | *
262 | * @return CKQueryMaker
263 | */
264 | return ^CKQueryMaker *(NSString *column,NSString *alias) {
265 | [self.sqlQueryDict setObject:alias?:NSStringFromSelector(_cmd) forKey:[NSString stringWithFormat:@"upper(%@)",sqlKeywordsReplace(column, self.cls)]];
266 | return self;
267 | };
268 | }
269 | - (CKQueryMaker *(^)(NSString *,NSString *))lower{
270 | /**
271 | * 转小写字母
272 | *
273 | * @param column 字段名
274 | * @param alias 别名
275 | *
276 | * @return CKQueryMaker
277 | */
278 | return ^CKQueryMaker *(NSString *column,NSString *alias) {
279 | [self.sqlQueryDict setObject:alias?:NSStringFromSelector(_cmd) forKey:[NSString stringWithFormat:@"min(%@)",sqlKeywordsReplace(column, self.cls)]];
280 | return self;
281 | };
282 | }
283 | - (CKQueryMaker *(^)(NSString *,NSString *))length{
284 | /**
285 | * 长度
286 | *
287 | * @param column 字段名
288 | * @param alias 别名
289 | *
290 | * @return CKQueryMaker
291 | */
292 | return ^CKQueryMaker *(NSString *column,NSString *alias) {
293 | [self.sqlQueryDict setObject:alias?:NSStringFromSelector(_cmd) forKey:[NSString stringWithFormat:@"length(%@)",sqlKeywordsReplace(column, self.cls)]];
294 | return self;
295 | };
296 | }
297 | /**
298 | * 自定义列查询
299 | */
300 | - (CKQueryMaker *(^)(NSString *,...))columns {
301 | return ^CKQueryMaker *(NSString *column,...) {
302 | NSMutableArray *columnArray = @[[NSString stringWithFormat:@"[%@]",column]].mutableCopy;
303 | va_list list;
304 | va_start(list, column);
305 | while (1)
306 | {
307 | NSString *item = va_arg(list, NSString *);
308 | if (item == nil) {break;}
309 | [columnArray addObject:[NSString stringWithFormat:@"[%@]",item]];
310 | }
311 | va_end(list);
312 | NSString *columnComp = [columnArray componentsJoinedByString:@","];
313 | [self.sqlQueryDict setObject:columnComp forKey:@""];
314 | return self;
315 | };
316 | }
317 |
318 | #pragma mark
319 | #pragma mark - Get
320 | - (NSMutableDictionary *)sqlQueryDict{
321 | if (_sqlQueryDict == nil) {
322 | _sqlQueryDict = @{}.mutableCopy;
323 | }
324 | return _sqlQueryDict;
325 | }
326 |
327 | @end
328 |
329 |
330 |
--------------------------------------------------------------------------------
/FMDBHelper.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 5095938C1B9E460A7BE2F47D /* libPods-FMDBHelper.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5909B46354EAC37B3BC4F01A /* libPods-FMDBHelper.a */; };
11 | B8052F391B0F067E00D54F37 /* CKConditionMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = B8052F381B0F067E00D54F37 /* CKConditionMaker.m */; };
12 | B821CEF11B0ED2820077129C /* NSString+CKDB.m in Sources */ = {isa = PBXBuildFile; fileRef = B821CEF01B0ED2820077129C /* NSString+CKDB.m */; };
13 | B82A90FD1B55F9460060D939 /* CKTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B82A90FC1B55F9460060D939 /* CKTest.m */; };
14 | B82A91001B560AB80060D939 /* CKTestSubModel.m in Sources */ = {isa = PBXBuildFile; fileRef = B82A90FF1B560AB80060D939 /* CKTestSubModel.m */; };
15 | B8993F9D1B67758400E8797B /* CKDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = B8993F9C1B67758400E8797B /* CKDictionary.m */; };
16 | B89F07C01B0EECB30024B59A /* CKTestModel.m in Sources */ = {isa = PBXBuildFile; fileRef = B89F07BF1B0EECB30024B59A /* CKTestModel.m */; };
17 | B8C3AE6F1B33F96000D7F719 /* NSDictionary+CKExternal.m in Sources */ = {isa = PBXBuildFile; fileRef = B8C3AE6E1B33F96000D7F719 /* NSDictionary+CKExternal.m */; };
18 | B8D2C7091B0B2E65006A032F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D2C7081B0B2E65006A032F /* main.m */; };
19 | B8D2C70C1B0B2E65006A032F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D2C70B1B0B2E65006A032F /* AppDelegate.m */; };
20 | B8D2C7141B0B2E65006A032F /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B8D2C7131B0B2E65006A032F /* Images.xcassets */; };
21 | B8D2C7171B0B2E65006A032F /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = B8D2C7151B0B2E65006A032F /* LaunchScreen.xib */; };
22 | B8D2C7231B0B2E65006A032F /* FMDBHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D2C7221B0B2E65006A032F /* FMDBHelperTests.m */; };
23 | B8D2C73E1B0B2F20006A032F /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B8D2C73D1B0B2F20006A032F /* libsqlite3.0.dylib */; };
24 | B8D2C7441B0B325F006A032F /* NSObject+CKProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D2C7431B0B325F006A032F /* NSObject+CKProperty.m */; };
25 | B8D2C7471B0B35FE006A032F /* CKModel.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D2C7461B0B35FE006A032F /* CKModel.m */; };
26 | B8D2C7811B0B4EED006A032F /* CKManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D2C7801B0B4EED006A032F /* CKManager.m */; };
27 | B8D2C7831B0B60C8006A032F /* Storyboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B8D2C7821B0B60C8006A032F /* Storyboard.storyboard */; };
28 | /* End PBXBuildFile section */
29 |
30 | /* Begin PBXContainerItemProxy section */
31 | B8D2C71D1B0B2E65006A032F /* PBXContainerItemProxy */ = {
32 | isa = PBXContainerItemProxy;
33 | containerPortal = B8D2C6FB1B0B2E65006A032F /* Project object */;
34 | proxyType = 1;
35 | remoteGlobalIDString = B8D2C7021B0B2E65006A032F;
36 | remoteInfo = FMDBHelper;
37 | };
38 | /* End PBXContainerItemProxy section */
39 |
40 | /* Begin PBXFileReference section */
41 | 413E69E0969F63F09073F350 /* Pods-FMDBHelper.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FMDBHelper.release.xcconfig"; path = "Pods/Target Support Files/Pods-FMDBHelper/Pods-FMDBHelper.release.xcconfig"; sourceTree = ""; };
42 | 5909B46354EAC37B3BC4F01A /* libPods-FMDBHelper.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FMDBHelper.a"; sourceTree = BUILT_PRODUCTS_DIR; };
43 | 76E73E9D8098579D98821C55 /* Pods-FMDBHelper.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FMDBHelper.debug.xcconfig"; path = "Pods/Target Support Files/Pods-FMDBHelper/Pods-FMDBHelper.debug.xcconfig"; sourceTree = ""; };
44 | B8052F371B0F067E00D54F37 /* CKConditionMaker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKConditionMaker.h; sourceTree = ""; };
45 | B8052F381B0F067E00D54F37 /* CKConditionMaker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKConditionMaker.m; sourceTree = ""; };
46 | B821CEEF1B0ED2820077129C /* NSString+CKDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+CKDB.h"; sourceTree = ""; };
47 | B821CEF01B0ED2820077129C /* NSString+CKDB.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+CKDB.m"; sourceTree = ""; };
48 | B82A90FB1B55F9460060D939 /* CKTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKTest.h; sourceTree = ""; };
49 | B82A90FC1B55F9460060D939 /* CKTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKTest.m; sourceTree = ""; };
50 | B82A90FE1B560AB80060D939 /* CKTestSubModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKTestSubModel.h; sourceTree = ""; };
51 | B82A90FF1B560AB80060D939 /* CKTestSubModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKTestSubModel.m; sourceTree = ""; };
52 | B8993F9B1B67758400E8797B /* CKDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKDictionary.h; sourceTree = ""; };
53 | B8993F9C1B67758400E8797B /* CKDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKDictionary.m; sourceTree = ""; };
54 | B89F07BE1B0EECB30024B59A /* CKTestModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKTestModel.h; sourceTree = ""; };
55 | B89F07BF1B0EECB30024B59A /* CKTestModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKTestModel.m; sourceTree = ""; };
56 | B8C3AE6D1B33F96000D7F719 /* NSDictionary+CKExternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+CKExternal.h"; sourceTree = ""; };
57 | B8C3AE6E1B33F96000D7F719 /* NSDictionary+CKExternal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+CKExternal.m"; sourceTree = ""; };
58 | B8D2C7031B0B2E65006A032F /* FMDBHelper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FMDBHelper.app; sourceTree = BUILT_PRODUCTS_DIR; };
59 | B8D2C7071B0B2E65006A032F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
60 | B8D2C7081B0B2E65006A032F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
61 | B8D2C70A1B0B2E65006A032F /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
62 | B8D2C70B1B0B2E65006A032F /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
63 | B8D2C7131B0B2E65006A032F /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
64 | B8D2C7161B0B2E65006A032F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
65 | B8D2C71C1B0B2E65006A032F /* FMDBHelperTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FMDBHelperTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
66 | B8D2C7211B0B2E65006A032F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
67 | B8D2C7221B0B2E65006A032F /* FMDBHelperTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FMDBHelperTests.m; sourceTree = ""; };
68 | B8D2C73D1B0B2F20006A032F /* libsqlite3.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.0.dylib; path = usr/lib/libsqlite3.0.dylib; sourceTree = SDKROOT; };
69 | B8D2C7411B0B3240006A032F /* CKFMDBHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKFMDBHelper.h; sourceTree = ""; };
70 | B8D2C7421B0B325F006A032F /* NSObject+CKProperty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+CKProperty.h"; sourceTree = ""; };
71 | B8D2C7431B0B325F006A032F /* NSObject+CKProperty.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+CKProperty.m"; sourceTree = ""; };
72 | B8D2C7451B0B35FE006A032F /* CKModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKModel.h; sourceTree = ""; };
73 | B8D2C7461B0B35FE006A032F /* CKModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKModel.m; sourceTree = ""; };
74 | B8D2C77F1B0B4EED006A032F /* CKManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKManager.h; sourceTree = ""; };
75 | B8D2C7801B0B4EED006A032F /* CKManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKManager.m; sourceTree = ""; };
76 | B8D2C7821B0B60C8006A032F /* Storyboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Storyboard.storyboard; sourceTree = ""; };
77 | /* End PBXFileReference section */
78 |
79 | /* Begin PBXFrameworksBuildPhase section */
80 | B8D2C7001B0B2E65006A032F /* Frameworks */ = {
81 | isa = PBXFrameworksBuildPhase;
82 | buildActionMask = 2147483647;
83 | files = (
84 | B8D2C73E1B0B2F20006A032F /* libsqlite3.0.dylib in Frameworks */,
85 | 5095938C1B9E460A7BE2F47D /* libPods-FMDBHelper.a in Frameworks */,
86 | );
87 | runOnlyForDeploymentPostprocessing = 0;
88 | };
89 | B8D2C7191B0B2E65006A032F /* Frameworks */ = {
90 | isa = PBXFrameworksBuildPhase;
91 | buildActionMask = 2147483647;
92 | files = (
93 | );
94 | runOnlyForDeploymentPostprocessing = 0;
95 | };
96 | /* End PBXFrameworksBuildPhase section */
97 |
98 | /* Begin PBXGroup section */
99 | A21BF518C534A84047822657 /* Frameworks */ = {
100 | isa = PBXGroup;
101 | children = (
102 | 5909B46354EAC37B3BC4F01A /* libPods-FMDBHelper.a */,
103 | );
104 | name = Frameworks;
105 | sourceTree = "";
106 | };
107 | A32615083F7C4F28BF61DA99 /* Pods */ = {
108 | isa = PBXGroup;
109 | children = (
110 | 76E73E9D8098579D98821C55 /* Pods-FMDBHelper.debug.xcconfig */,
111 | 413E69E0969F63F09073F350 /* Pods-FMDBHelper.release.xcconfig */,
112 | );
113 | name = Pods;
114 | sourceTree = "";
115 | };
116 | B8D2C6FA1B0B2E65006A032F = {
117 | isa = PBXGroup;
118 | children = (
119 | B8D2C73D1B0B2F20006A032F /* libsqlite3.0.dylib */,
120 | B8D2C7051B0B2E65006A032F /* FMDBHelper */,
121 | B8D2C71F1B0B2E65006A032F /* FMDBHelperTests */,
122 | B8D2C7041B0B2E65006A032F /* Products */,
123 | A32615083F7C4F28BF61DA99 /* Pods */,
124 | A21BF518C534A84047822657 /* Frameworks */,
125 | );
126 | sourceTree = "";
127 | };
128 | B8D2C7041B0B2E65006A032F /* Products */ = {
129 | isa = PBXGroup;
130 | children = (
131 | B8D2C7031B0B2E65006A032F /* FMDBHelper.app */,
132 | B8D2C71C1B0B2E65006A032F /* FMDBHelperTests.xctest */,
133 | );
134 | name = Products;
135 | sourceTree = "";
136 | };
137 | B8D2C7051B0B2E65006A032F /* FMDBHelper */ = {
138 | isa = PBXGroup;
139 | children = (
140 | B8D2C70A1B0B2E65006A032F /* AppDelegate.h */,
141 | B8D2C70B1B0B2E65006A032F /* AppDelegate.m */,
142 | B82A90FE1B560AB80060D939 /* CKTestSubModel.h */,
143 | B82A90FF1B560AB80060D939 /* CKTestSubModel.m */,
144 | B89F07BE1B0EECB30024B59A /* CKTestModel.h */,
145 | B89F07BF1B0EECB30024B59A /* CKTestModel.m */,
146 | B82A90FB1B55F9460060D939 /* CKTest.h */,
147 | B82A90FC1B55F9460060D939 /* CKTest.m */,
148 | B8D2C7131B0B2E65006A032F /* Images.xcassets */,
149 | B8D2C7151B0B2E65006A032F /* LaunchScreen.xib */,
150 | B8D2C7821B0B60C8006A032F /* Storyboard.storyboard */,
151 | B8D2C73F1B0B3214006A032F /* FMDBHelper */,
152 | B8D2C7061B0B2E65006A032F /* Supporting Files */,
153 | );
154 | path = FMDBHelper;
155 | sourceTree = "";
156 | };
157 | B8D2C7061B0B2E65006A032F /* Supporting Files */ = {
158 | isa = PBXGroup;
159 | children = (
160 | B8D2C7071B0B2E65006A032F /* Info.plist */,
161 | B8D2C7081B0B2E65006A032F /* main.m */,
162 | );
163 | name = "Supporting Files";
164 | sourceTree = "";
165 | };
166 | B8D2C71F1B0B2E65006A032F /* FMDBHelperTests */ = {
167 | isa = PBXGroup;
168 | children = (
169 | B8D2C7221B0B2E65006A032F /* FMDBHelperTests.m */,
170 | B8D2C7201B0B2E65006A032F /* Supporting Files */,
171 | );
172 | path = FMDBHelperTests;
173 | sourceTree = "";
174 | };
175 | B8D2C7201B0B2E65006A032F /* Supporting Files */ = {
176 | isa = PBXGroup;
177 | children = (
178 | B8D2C7211B0B2E65006A032F /* Info.plist */,
179 | );
180 | name = "Supporting Files";
181 | sourceTree = "";
182 | };
183 | B8D2C73F1B0B3214006A032F /* FMDBHelper */ = {
184 | isa = PBXGroup;
185 | children = (
186 | B8D2C7411B0B3240006A032F /* CKFMDBHelper.h */,
187 | B8D2C7421B0B325F006A032F /* NSObject+CKProperty.h */,
188 | B8D2C7431B0B325F006A032F /* NSObject+CKProperty.m */,
189 | B821CEEF1B0ED2820077129C /* NSString+CKDB.h */,
190 | B821CEF01B0ED2820077129C /* NSString+CKDB.m */,
191 | B8D2C7451B0B35FE006A032F /* CKModel.h */,
192 | B8D2C7461B0B35FE006A032F /* CKModel.m */,
193 | B8993F9B1B67758400E8797B /* CKDictionary.h */,
194 | B8993F9C1B67758400E8797B /* CKDictionary.m */,
195 | B8052F371B0F067E00D54F37 /* CKConditionMaker.h */,
196 | B8052F381B0F067E00D54F37 /* CKConditionMaker.m */,
197 | B8D2C77F1B0B4EED006A032F /* CKManager.h */,
198 | B8D2C7801B0B4EED006A032F /* CKManager.m */,
199 | B8C3AE6D1B33F96000D7F719 /* NSDictionary+CKExternal.h */,
200 | B8C3AE6E1B33F96000D7F719 /* NSDictionary+CKExternal.m */,
201 | );
202 | path = FMDBHelper;
203 | sourceTree = "";
204 | };
205 | /* End PBXGroup section */
206 |
207 | /* Begin PBXNativeTarget section */
208 | B8D2C7021B0B2E65006A032F /* FMDBHelper */ = {
209 | isa = PBXNativeTarget;
210 | buildConfigurationList = B8D2C7261B0B2E65006A032F /* Build configuration list for PBXNativeTarget "FMDBHelper" */;
211 | buildPhases = (
212 | BFD31172190BFDC6877A1180 /* Check Pods Manifest.lock */,
213 | B8D2C6FF1B0B2E65006A032F /* Sources */,
214 | B8D2C7001B0B2E65006A032F /* Frameworks */,
215 | B8D2C7011B0B2E65006A032F /* Resources */,
216 | B968C770B4B57270499BD17A /* Copy Pods Resources */,
217 | );
218 | buildRules = (
219 | );
220 | dependencies = (
221 | );
222 | name = FMDBHelper;
223 | productName = FMDBHelper;
224 | productReference = B8D2C7031B0B2E65006A032F /* FMDBHelper.app */;
225 | productType = "com.apple.product-type.application";
226 | };
227 | B8D2C71B1B0B2E65006A032F /* FMDBHelperTests */ = {
228 | isa = PBXNativeTarget;
229 | buildConfigurationList = B8D2C7291B0B2E65006A032F /* Build configuration list for PBXNativeTarget "FMDBHelperTests" */;
230 | buildPhases = (
231 | B8D2C7181B0B2E65006A032F /* Sources */,
232 | B8D2C7191B0B2E65006A032F /* Frameworks */,
233 | B8D2C71A1B0B2E65006A032F /* Resources */,
234 | );
235 | buildRules = (
236 | );
237 | dependencies = (
238 | B8D2C71E1B0B2E65006A032F /* PBXTargetDependency */,
239 | );
240 | name = FMDBHelperTests;
241 | productName = FMDBHelperTests;
242 | productReference = B8D2C71C1B0B2E65006A032F /* FMDBHelperTests.xctest */;
243 | productType = "com.apple.product-type.bundle.unit-test";
244 | };
245 | /* End PBXNativeTarget section */
246 |
247 | /* Begin PBXProject section */
248 | B8D2C6FB1B0B2E65006A032F /* Project object */ = {
249 | isa = PBXProject;
250 | attributes = {
251 | CLASSPREFIX = CK;
252 | LastUpgradeCheck = 0630;
253 | ORGANIZATIONNAME = tcyx;
254 | TargetAttributes = {
255 | B8D2C7021B0B2E65006A032F = {
256 | CreatedOnToolsVersion = 6.3.1;
257 | };
258 | B8D2C71B1B0B2E65006A032F = {
259 | CreatedOnToolsVersion = 6.3.1;
260 | TestTargetID = B8D2C7021B0B2E65006A032F;
261 | };
262 | };
263 | };
264 | buildConfigurationList = B8D2C6FE1B0B2E65006A032F /* Build configuration list for PBXProject "FMDBHelper" */;
265 | compatibilityVersion = "Xcode 3.2";
266 | developmentRegion = English;
267 | hasScannedForEncodings = 0;
268 | knownRegions = (
269 | en,
270 | Base,
271 | );
272 | mainGroup = B8D2C6FA1B0B2E65006A032F;
273 | productRefGroup = B8D2C7041B0B2E65006A032F /* Products */;
274 | projectDirPath = "";
275 | projectRoot = "";
276 | targets = (
277 | B8D2C7021B0B2E65006A032F /* FMDBHelper */,
278 | B8D2C71B1B0B2E65006A032F /* FMDBHelperTests */,
279 | );
280 | };
281 | /* End PBXProject section */
282 |
283 | /* Begin PBXResourcesBuildPhase section */
284 | B8D2C7011B0B2E65006A032F /* Resources */ = {
285 | isa = PBXResourcesBuildPhase;
286 | buildActionMask = 2147483647;
287 | files = (
288 | B8D2C7171B0B2E65006A032F /* LaunchScreen.xib in Resources */,
289 | B8D2C7831B0B60C8006A032F /* Storyboard.storyboard in Resources */,
290 | B8D2C7141B0B2E65006A032F /* Images.xcassets in Resources */,
291 | );
292 | runOnlyForDeploymentPostprocessing = 0;
293 | };
294 | B8D2C71A1B0B2E65006A032F /* Resources */ = {
295 | isa = PBXResourcesBuildPhase;
296 | buildActionMask = 2147483647;
297 | files = (
298 | );
299 | runOnlyForDeploymentPostprocessing = 0;
300 | };
301 | /* End PBXResourcesBuildPhase section */
302 |
303 | /* Begin PBXShellScriptBuildPhase section */
304 | B968C770B4B57270499BD17A /* Copy Pods Resources */ = {
305 | isa = PBXShellScriptBuildPhase;
306 | buildActionMask = 2147483647;
307 | files = (
308 | );
309 | inputPaths = (
310 | );
311 | name = "Copy Pods Resources";
312 | outputPaths = (
313 | );
314 | runOnlyForDeploymentPostprocessing = 0;
315 | shellPath = /bin/sh;
316 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-FMDBHelper/Pods-FMDBHelper-resources.sh\"\n";
317 | showEnvVarsInLog = 0;
318 | };
319 | BFD31172190BFDC6877A1180 /* Check Pods Manifest.lock */ = {
320 | isa = PBXShellScriptBuildPhase;
321 | buildActionMask = 2147483647;
322 | files = (
323 | );
324 | inputPaths = (
325 | );
326 | name = "Check Pods Manifest.lock";
327 | outputPaths = (
328 | );
329 | runOnlyForDeploymentPostprocessing = 0;
330 | shellPath = /bin/sh;
331 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
332 | showEnvVarsInLog = 0;
333 | };
334 | /* End PBXShellScriptBuildPhase section */
335 |
336 | /* Begin PBXSourcesBuildPhase section */
337 | B8D2C6FF1B0B2E65006A032F /* Sources */ = {
338 | isa = PBXSourcesBuildPhase;
339 | buildActionMask = 2147483647;
340 | files = (
341 | B821CEF11B0ED2820077129C /* NSString+CKDB.m in Sources */,
342 | B8993F9D1B67758400E8797B /* CKDictionary.m in Sources */,
343 | B8D2C70C1B0B2E65006A032F /* AppDelegate.m in Sources */,
344 | B89F07C01B0EECB30024B59A /* CKTestModel.m in Sources */,
345 | B8052F391B0F067E00D54F37 /* CKConditionMaker.m in Sources */,
346 | B8D2C7091B0B2E65006A032F /* main.m in Sources */,
347 | B8C3AE6F1B33F96000D7F719 /* NSDictionary+CKExternal.m in Sources */,
348 | B82A91001B560AB80060D939 /* CKTestSubModel.m in Sources */,
349 | B8D2C7811B0B4EED006A032F /* CKManager.m in Sources */,
350 | B8D2C7471B0B35FE006A032F /* CKModel.m in Sources */,
351 | B8D2C7441B0B325F006A032F /* NSObject+CKProperty.m in Sources */,
352 | B82A90FD1B55F9460060D939 /* CKTest.m in Sources */,
353 | );
354 | runOnlyForDeploymentPostprocessing = 0;
355 | };
356 | B8D2C7181B0B2E65006A032F /* Sources */ = {
357 | isa = PBXSourcesBuildPhase;
358 | buildActionMask = 2147483647;
359 | files = (
360 | B8D2C7231B0B2E65006A032F /* FMDBHelperTests.m in Sources */,
361 | );
362 | runOnlyForDeploymentPostprocessing = 0;
363 | };
364 | /* End PBXSourcesBuildPhase section */
365 |
366 | /* Begin PBXTargetDependency section */
367 | B8D2C71E1B0B2E65006A032F /* PBXTargetDependency */ = {
368 | isa = PBXTargetDependency;
369 | target = B8D2C7021B0B2E65006A032F /* FMDBHelper */;
370 | targetProxy = B8D2C71D1B0B2E65006A032F /* PBXContainerItemProxy */;
371 | };
372 | /* End PBXTargetDependency section */
373 |
374 | /* Begin PBXVariantGroup section */
375 | B8D2C7151B0B2E65006A032F /* LaunchScreen.xib */ = {
376 | isa = PBXVariantGroup;
377 | children = (
378 | B8D2C7161B0B2E65006A032F /* Base */,
379 | );
380 | name = LaunchScreen.xib;
381 | sourceTree = "";
382 | };
383 | /* End PBXVariantGroup section */
384 |
385 | /* Begin XCBuildConfiguration section */
386 | B8D2C7241B0B2E65006A032F /* Debug */ = {
387 | isa = XCBuildConfiguration;
388 | buildSettings = {
389 | ALWAYS_SEARCH_USER_PATHS = NO;
390 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
391 | CLANG_CXX_LIBRARY = "libc++";
392 | CLANG_ENABLE_MODULES = YES;
393 | CLANG_ENABLE_OBJC_ARC = YES;
394 | CLANG_WARN_BOOL_CONVERSION = YES;
395 | CLANG_WARN_CONSTANT_CONVERSION = YES;
396 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
397 | CLANG_WARN_EMPTY_BODY = YES;
398 | CLANG_WARN_ENUM_CONVERSION = YES;
399 | CLANG_WARN_INT_CONVERSION = YES;
400 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
401 | CLANG_WARN_UNREACHABLE_CODE = YES;
402 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
403 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
404 | COPY_PHASE_STRIP = NO;
405 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
406 | ENABLE_STRICT_OBJC_MSGSEND = YES;
407 | GCC_C_LANGUAGE_STANDARD = gnu99;
408 | GCC_DYNAMIC_NO_PIC = NO;
409 | GCC_NO_COMMON_BLOCKS = YES;
410 | GCC_OPTIMIZATION_LEVEL = 0;
411 | GCC_PREPROCESSOR_DEFINITIONS = (
412 | "DEBUG=1",
413 | "$(inherited)",
414 | );
415 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
416 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
417 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
418 | GCC_WARN_UNDECLARED_SELECTOR = YES;
419 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
420 | GCC_WARN_UNUSED_FUNCTION = YES;
421 | GCC_WARN_UNUSED_VARIABLE = YES;
422 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
423 | MTL_ENABLE_DEBUG_INFO = YES;
424 | ONLY_ACTIVE_ARCH = YES;
425 | SDKROOT = iphoneos;
426 | };
427 | name = Debug;
428 | };
429 | B8D2C7251B0B2E65006A032F /* Release */ = {
430 | isa = XCBuildConfiguration;
431 | buildSettings = {
432 | ALWAYS_SEARCH_USER_PATHS = NO;
433 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
434 | CLANG_CXX_LIBRARY = "libc++";
435 | CLANG_ENABLE_MODULES = YES;
436 | CLANG_ENABLE_OBJC_ARC = YES;
437 | CLANG_WARN_BOOL_CONVERSION = YES;
438 | CLANG_WARN_CONSTANT_CONVERSION = YES;
439 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
440 | CLANG_WARN_EMPTY_BODY = YES;
441 | CLANG_WARN_ENUM_CONVERSION = YES;
442 | CLANG_WARN_INT_CONVERSION = YES;
443 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
444 | CLANG_WARN_UNREACHABLE_CODE = YES;
445 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
446 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
447 | COPY_PHASE_STRIP = NO;
448 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
449 | ENABLE_NS_ASSERTIONS = NO;
450 | ENABLE_STRICT_OBJC_MSGSEND = YES;
451 | GCC_C_LANGUAGE_STANDARD = gnu99;
452 | GCC_NO_COMMON_BLOCKS = YES;
453 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
454 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
455 | GCC_WARN_UNDECLARED_SELECTOR = YES;
456 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
457 | GCC_WARN_UNUSED_FUNCTION = YES;
458 | GCC_WARN_UNUSED_VARIABLE = YES;
459 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
460 | MTL_ENABLE_DEBUG_INFO = NO;
461 | SDKROOT = iphoneos;
462 | VALIDATE_PRODUCT = YES;
463 | };
464 | name = Release;
465 | };
466 | B8D2C7271B0B2E65006A032F /* Debug */ = {
467 | isa = XCBuildConfiguration;
468 | baseConfigurationReference = 76E73E9D8098579D98821C55 /* Pods-FMDBHelper.debug.xcconfig */;
469 | buildSettings = {
470 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
471 | INFOPLIST_FILE = FMDBHelper/Info.plist;
472 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
473 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
474 | PRODUCT_NAME = "$(TARGET_NAME)";
475 | };
476 | name = Debug;
477 | };
478 | B8D2C7281B0B2E65006A032F /* Release */ = {
479 | isa = XCBuildConfiguration;
480 | baseConfigurationReference = 413E69E0969F63F09073F350 /* Pods-FMDBHelper.release.xcconfig */;
481 | buildSettings = {
482 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
483 | INFOPLIST_FILE = FMDBHelper/Info.plist;
484 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
485 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
486 | PRODUCT_NAME = "$(TARGET_NAME)";
487 | };
488 | name = Release;
489 | };
490 | B8D2C72A1B0B2E65006A032F /* Debug */ = {
491 | isa = XCBuildConfiguration;
492 | buildSettings = {
493 | BUNDLE_LOADER = "$(TEST_HOST)";
494 | FRAMEWORK_SEARCH_PATHS = (
495 | "$(SDKROOT)/Developer/Library/Frameworks",
496 | "$(inherited)",
497 | );
498 | GCC_PREPROCESSOR_DEFINITIONS = (
499 | "DEBUG=1",
500 | "$(inherited)",
501 | );
502 | INFOPLIST_FILE = FMDBHelperTests/Info.plist;
503 | IPHONEOS_DEPLOYMENT_TARGET = 8.2;
504 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
505 | PRODUCT_NAME = "$(TARGET_NAME)";
506 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/FMDBHelper.app/FMDBHelper";
507 | };
508 | name = Debug;
509 | };
510 | B8D2C72B1B0B2E65006A032F /* Release */ = {
511 | isa = XCBuildConfiguration;
512 | buildSettings = {
513 | BUNDLE_LOADER = "$(TEST_HOST)";
514 | FRAMEWORK_SEARCH_PATHS = (
515 | "$(SDKROOT)/Developer/Library/Frameworks",
516 | "$(inherited)",
517 | );
518 | INFOPLIST_FILE = FMDBHelperTests/Info.plist;
519 | IPHONEOS_DEPLOYMENT_TARGET = 8.2;
520 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
521 | PRODUCT_NAME = "$(TARGET_NAME)";
522 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/FMDBHelper.app/FMDBHelper";
523 | };
524 | name = Release;
525 | };
526 | /* End XCBuildConfiguration section */
527 |
528 | /* Begin XCConfigurationList section */
529 | B8D2C6FE1B0B2E65006A032F /* Build configuration list for PBXProject "FMDBHelper" */ = {
530 | isa = XCConfigurationList;
531 | buildConfigurations = (
532 | B8D2C7241B0B2E65006A032F /* Debug */,
533 | B8D2C7251B0B2E65006A032F /* Release */,
534 | );
535 | defaultConfigurationIsVisible = 0;
536 | defaultConfigurationName = Release;
537 | };
538 | B8D2C7261B0B2E65006A032F /* Build configuration list for PBXNativeTarget "FMDBHelper" */ = {
539 | isa = XCConfigurationList;
540 | buildConfigurations = (
541 | B8D2C7271B0B2E65006A032F /* Debug */,
542 | B8D2C7281B0B2E65006A032F /* Release */,
543 | );
544 | defaultConfigurationIsVisible = 0;
545 | defaultConfigurationName = Release;
546 | };
547 | B8D2C7291B0B2E65006A032F /* Build configuration list for PBXNativeTarget "FMDBHelperTests" */ = {
548 | isa = XCConfigurationList;
549 | buildConfigurations = (
550 | B8D2C72A1B0B2E65006A032F /* Debug */,
551 | B8D2C72B1B0B2E65006A032F /* Release */,
552 | );
553 | defaultConfigurationIsVisible = 0;
554 | defaultConfigurationName = Release;
555 | };
556 | /* End XCConfigurationList section */
557 | };
558 | rootObject = B8D2C6FB1B0B2E65006A032F /* Project object */;
559 | }
560 |
--------------------------------------------------------------------------------
/FMDBHelper/FMDBHelper/CKModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // CKModel.m
3 | // FMDBHelper
4 | //
5 | // Created by caydenk on 15/5/19.
6 | // Copyright (c) 2015年 caydenk. All rights reserved.
7 | //
8 |
9 | #import "CKModel.h"
10 | #import "CKFMDBHelper.h"
11 | #import "FMDB.h"
12 | #import "NSObject+CKProperty.h"
13 | #import "CKManager.h"
14 | #import "NSString+CKDB.h"
15 | #import "NSDictionary+CKExternal.h"
16 | #import
17 |
18 | /**
19 | * 正序
20 | */
21 | NSString * const kCKModelIndexAsc = @"asc";
22 | /**
23 | * 倒序
24 | */
25 | NSString * const kCKModelIndexDesc = @"desc";
26 |
27 | @interface CKModel ()
28 |
29 | @end
30 |
31 | @implementation CKModel
32 |
33 | #pragma mark
34 | #pragma mark - CKFmdbOperate
35 | #pragma mark
36 | #pragma mark - Query Update
37 | /*
38 | *拼装好SQL 语句,就能完成查询
39 | */
40 | + (NSMutableArray *)queryArrayWithSQL:(NSString *)sql{
41 | FMDatabase *db = [[CKManager shareManager] databaseWithName:CKDBNAME];
42 | if (![db open]) {return nil;}
43 | FMResultSet *rs=[db executeQuery:sql];
44 | NSArray *propertys=[self propertyArray];
45 | NSMutableArray *result=[NSMutableArray array];
46 | while ([rs next]) {
47 | id item=[[[self class] alloc]init];
48 | for ( NSString *key in propertys) {
49 | [item setValue:[rs stringForColumn:key] forKey:key];
50 | }
51 | [result addObject:item];
52 | }
53 | [db close];
54 | return result;
55 | }
56 | /**
57 | * 拼装好SQL 语句,并传入Model类型就能完成查询
58 | *
59 | * @param aQueryDict 查询字典
60 | * @param sql sql语句
61 | *
62 | * @return 查询到的字典
63 | */
64 | + (NSArray *)queryDict:(NSDictionary *)aQueryDict withSQL:(NSString *)sql{
65 | FMDatabase *db = [[CKManager shareManager] databaseWithName:CKDBNAME];
66 | if (![db open]) {return nil;}
67 | FMResultSet *rs=[db executeQuery:sql];
68 | NSArray *keys=aQueryDict.allKeys;
69 | NSMutableArray *result = @[].mutableCopy;
70 | while ([rs next]) {
71 | NSMutableDictionary *resultDict=@{}.mutableCopy;
72 | for ( NSString *key in keys) {
73 | NSString *alias = [aQueryDict objectForKey:key];
74 | NSString *finalKey = alias.length>0?alias:key;
75 | [resultDict setObject:[rs stringForColumn:finalKey]?:@"" forKey:finalKey];
76 | }
77 | [result addObject:resultDict];
78 | }
79 | [db close];
80 | return result;
81 | }
82 |
83 | /*
84 | *拼装好SQL 语句,并传入Model类型就能完成查询
85 | */
86 | + (id)queryWithSQL:(NSString *)sql{
87 | FMDatabase *db = [[CKManager shareManager] databaseWithName:CKDBNAME];
88 | if (![db open]) {return nil;}
89 | FMResultSet *rs=[db executeQuery:sql];
90 | NSArray *propertys=[self propertyArray];
91 | id item;
92 | while ([rs next]) {
93 | item=[[self alloc]init];
94 | for ( NSString *key in propertys) {
95 | [item setValue:[rs stringForColumn:key] forKey:key];
96 | }
97 | }
98 | [db close];
99 | return item;
100 | }
101 |
102 | /**
103 | * 单sql语句更新
104 | *
105 | * @param sql sql语句
106 | */
107 | + (void)executeUpdateWithSql:(NSString *)sql{
108 | FMDatabaseQueue *queue = [[CKManager shareManager] databaseQueueWithName:CKDBNAME];
109 | [queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
110 | BOOL success = [db executeUpdate:sql];
111 | *rollback = !success;
112 | }];
113 | }
114 | /**
115 | * 多sql语句更新
116 | *
117 | * @param sqls sql语句数组
118 | */
119 | + (void)executeUpdateWithMuchSql:(NSArray *)sqls{
120 | FMDatabaseQueue *queue = [[CKManager shareManager] databaseQueueWithName:CKDBNAME];
121 | // 如果要支持事务
122 | if (!queue) {return ;}
123 | [queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
124 | for (NSString *sql in sqls) {
125 | BOOL success = [db executeUpdate:sql];
126 | if (!success) {
127 | *rollback = YES;
128 | }
129 | }
130 | }];
131 | }
132 |
133 | #pragma mark
134 | #pragma mark - get Sql
135 | /**
136 | * replace语句拼装
137 | *
138 | * @param table 表名称
139 | *
140 | * @return replace语句
141 | */
142 | + (NSString *)replaceSqlFromItem:(id)item{
143 | NSString *tableName = NSStringFromClass([self class]);
144 | NSArray *propertys=[item propertyArray];
145 | NSMutableArray *pArray = @[].mutableCopy;
146 | for (NSString *property in propertys) {
147 | [pArray addObject:[NSString stringWithFormat:@"[%@]",property]];
148 | }
149 | NSString *columsStr=[pArray componentsJoinedByString:@","];
150 | NSMutableArray *columnValueArray=[NSMutableArray array];
151 | for (NSString *property in propertys) {
152 | NSString *value=[NSString stringWithFormat:@"%@",[item valueForKey:property]?:@""];
153 | [columnValueArray addObject:[value chuliyinhao]];
154 | }
155 | NSString *columnValueStr=[columnValueArray componentsJoinedByString:@","];
156 | NSString *replaceSql=[NSString stringWithFormat:@"replace into %@ (%@ ) VALUES (%@)",tableName,columsStr,columnValueStr];
157 | return replaceSql;
158 | }
159 | /**
160 | * insert语句拼装
161 | *
162 | * @param item Model
163 | *
164 | * @return insert语句
165 | */
166 | + (NSString *)insertSqlFromItem:(id)item{
167 | NSString *tableName = NSStringFromClass([self class]);
168 | NSArray *propertys=[item propertyArray];
169 | NSMutableArray *pArray = @[].mutableCopy;
170 | for (NSString *property in propertys) {
171 | [pArray addObject:[NSString stringWithFormat:@"[%@]",property]];
172 | }
173 | NSString *columsStr=[pArray componentsJoinedByString:@","];
174 | NSMutableArray *columnValueArray=[NSMutableArray array];
175 | for (NSString *property in propertys) {
176 | NSString *value=[NSString stringWithFormat:@"%@",[item valueForKey:property]?:@""];
177 | [columnValueArray addObject:[value chuliyinhao]];
178 | }
179 | NSString *columnValueStr=[columnValueArray componentsJoinedByString:@","];
180 | NSString *replaceSql=[NSString stringWithFormat:@"insert into %@ (%@ ) VALUES (%@)",tableName,columsStr,columnValueStr];
181 | return replaceSql;
182 | }
183 | /**
184 | * update语句拼装
185 | *
186 | * @param table 表名称
187 | *
188 | * @return update语句
189 | */
190 | + (NSString *)updateSqlFromItem:(id)item{
191 | NSString *tableName = NSStringFromClass([self class]);
192 | NSArray *propertys=[item propertyArray];
193 | NSMutableArray *columnArray=[NSMutableArray array];
194 | for (NSString *property in propertys) {
195 | NSString *value=[NSString stringWithFormat:@"%@",[item valueForKey:property]?:@""];
196 | [columnArray addObject:[NSString stringWithFormat:@"[%@] = %@",property,[value chuliyinhao]]];
197 | }
198 | NSString *columnStr=[columnArray componentsJoinedByString:@","];
199 | NSString *replaceSql=[NSString stringWithFormat:@"update %@ set %@",tableName,columnStr];
200 | return replaceSql;
201 | }
202 | /**
203 | * delete语句拼装
204 | *
205 | * @param table 表名称
206 | *
207 | * @return delete语句
208 | */
209 | + (NSString *)deleteSqlFromItem:(id)item{
210 | NSString *tableName = NSStringFromClass([self class]);
211 | NSArray *propertys=[item propertyArray];
212 | NSMutableArray *columnArray=[NSMutableArray array];
213 | for (NSString *property in propertys) {
214 | NSString *value=[NSString stringWithFormat:@"%@",[item valueForKey:property]?:@""];
215 | [columnArray addObject:[NSString stringWithFormat:@"[%@] = %@",property,[value chuliyinhao]]];
216 | }
217 | NSString *columnStr=[columnArray componentsJoinedByString:@" and "];
218 | NSString *replaceSql=[NSString stringWithFormat:@"delete from %@ where %@",tableName,columnStr];
219 | return replaceSql;
220 | }
221 |
222 | #pragma mark
223 | #pragma mark - Create
224 | /**
225 | * 创建表
226 | *
227 | * @return 成功/失败
228 | */
229 | + (void)createTable{
230 | NSString *tableName = NSStringFromClass([self class]);
231 | NSDictionary *propertyDict = [[self class] propertyDict];
232 | NSArray *propertyArray = [propertyDict allKeys];
233 | NSMutableString *sql = [NSMutableString stringWithFormat:@"create table if not exists '%@' ( ",tableName];
234 | for (NSString *property in propertyArray) {
235 | NSArray *attributes = [propertyDict objectForKey:property];
236 | [sql appendFormat:@"'%@' %@ not null,",property,[self isPrimaryKey:attributes]?@"integer primary key default 0":@"text default ''"];
237 | }
238 | if (propertyArray.count > 0) {
239 | [sql deleteCharactersInRange:NSMakeRange(sql.length-1, 1)];
240 | }
241 | [sql appendFormat:@");"];
242 | [self executeUpdateWithSql:sql];
243 | }
244 | + (BOOL)isPrimaryKey:(NSArray *)attributes{
245 | for (NSString *str in attributes) {
246 | if ([str rangeOfString:@""].length>0) {
247 | return YES;
248 | }
249 | }
250 | return NO;
251 | }
252 |
253 | /**
254 | * 创建索引
255 | *
256 | * @param indexName 索引名称
257 | * @param isUnique 是否唯一
258 | * @param column 字段列表
259 | *
260 | * @return 是否成功
261 | */
262 | + (void)createIndex:(NSString *)indexName unique:(BOOL)isUnique columns:(NSString *)column,...{
263 | if (column == nil) {return;}
264 | NSString *tableName = NSStringFromClass([self class]);
265 | NSMutableString *sql = [NSMutableString stringWithFormat:@"create %@ index '%@' on '%@' (",isUnique?@"unique":@"",indexName,tableName];
266 |
267 | NSMutableArray *columnArray = @[[NSString stringWithFormat:@"[%@]",column]].mutableCopy;
268 | va_list list;
269 | va_start(list, column);
270 | while (1)
271 | {
272 | NSString *item = va_arg(list, NSString *);
273 | if (item == nil) {break;}
274 | [columnArray addObject:[NSString stringWithFormat:@"[%@]",item]];
275 | }
276 | va_end(list);
277 | NSString *columnComp = [columnArray componentsJoinedByString:@","];
278 | [sql appendFormat:@"%@);",columnComp];
279 | [self executeUpdateWithSql:sql];
280 | }
281 | /**
282 | * 创建索引
283 | *
284 | * @param indexName 索引名称
285 | * @param isUnique 是否唯一
286 | * @param aColumnDict 字段列表、是否排序格式如下:
287 | * @{"column1":@"asc",@"column2":@"desc"}
288 | *
289 | * @return 是否成功
290 | */
291 | + (void)createIndex:(NSString *)indexName unique:(BOOL)isUnique columnDict:(NSDictionary *)aColumnDict{
292 | if (aColumnDict.count == 0) {return;}
293 | NSString *tableName = NSStringFromClass([self class]);
294 | NSMutableString *sql = [NSMutableString stringWithFormat:@"create %@ index '%@' on '%@' (",isUnique?@"unique":@"",indexName,tableName];
295 | NSMutableArray *columnArray = @[].mutableCopy;
296 |
297 | NSArray *keyArray = aColumnDict.allKeys;
298 | for (NSString *key in keyArray) {
299 | NSString *item = [NSString stringWithFormat:@"'%@' %@",key,[aColumnDict objectForKey:key]];
300 | if (item == nil) {break;}
301 | [columnArray addObject:item];
302 | }
303 | NSString *columnComp = [columnArray componentsJoinedByString:@","];
304 | [sql appendFormat:@"%@);",columnComp];
305 | [self executeUpdateWithSql:sql];
306 | }
307 |
308 | #pragma mark
309 | #pragma mark - Drop
310 | /**
311 | * 删除表
312 | *
313 | * @return 是否成功
314 | */
315 | + (void)dropTable{
316 | NSString *tableName = NSStringFromClass([self class]);
317 | NSMutableString *sql = [NSMutableString stringWithFormat:@"drop table if exists '%@';",tableName];
318 | [self executeUpdateWithSql:sql];
319 | }
320 |
321 | /**
322 | * 删除索引
323 | *
324 | * @param indexName 索引名称
325 | *
326 | * @return 是否成功
327 | */
328 | + (void)dropIndex:(NSString *)indexName{
329 | NSMutableString *sql = [NSMutableString stringWithFormat:@"drop index if exists '%@';",indexName];
330 | [self executeUpdateWithSql:sql];
331 | }
332 |
333 | #pragma mark
334 | #pragma mark - Alert
335 | /**
336 | * 修改表名
337 | *
338 | * @param oldName 旧表名
339 | *
340 | * @return 是否修改成功
341 | */
342 | + (void)renameTableWithOldName:(NSString *)oldName{
343 | NSString *tableName = NSStringFromClass([self class]);
344 | NSMutableString *sql = [NSMutableString stringWithFormat:@"alter table %@ rename to '%@';",oldName,tableName];
345 | [self executeUpdateWithSql:sql];
346 | }
347 | /**
348 | * 表结构更新到最新
349 | *
350 | * @return 是否成功
351 | */
352 | + (void)updateColumn{
353 | // 一下两种方式可以获取当前表结构,当前只需知道字段列表,所以采用第二种
354 | // select * from sqlite_master
355 | // PRAGMA table_info(tableName)
356 | NSString *tableName = NSStringFromClass([self class]);
357 | NSMutableArray *propertyArray = [self propertyArray].mutableCopy;
358 | NSArray *oldColumnArray = [self columnArrayWithTable:tableName];
359 | [propertyArray removeObjectsInArray:oldColumnArray];
360 | NSMutableArray *sqls = @[].mutableCopy;
361 | for (NSString *columnNew in propertyArray) {
362 | NSString *sql = [NSString stringWithFormat:@"alter table %@ add column '%@' text;",tableName,columnNew];
363 | [sqls addObject:sql];
364 | }
365 | [self executeUpdateWithMuchSql:sqls];
366 | }
367 |
368 | + (NSArray *)columnArrayWithTable:(NSString *)tableName {
369 | NSMutableString *query = [NSMutableString stringWithFormat:@"PRAGMA table_info(%@)",tableName];
370 | FMDatabase *db = [[CKManager shareManager] databaseWithName:CKDBNAME];
371 | if (![db open]) {return nil;}
372 | FMResultSet *rs=[db executeQuery:query];
373 | NSMutableArray *oldColumnArray=[NSMutableArray array];
374 | while ([rs next]) {
375 | [oldColumnArray addObject:[rs stringForColumn:@"name"]];
376 | }
377 | [db close];
378 | return oldColumnArray;
379 | }
380 |
381 | #pragma mark
382 | #pragma mark - Select
383 | /**
384 | * 条件查询单表
385 | *
386 | * @param block 查询条件
387 | *
388 | * @return Model列表
389 | */
390 | + (NSArray *)queryWithConditions:(id (^)(CKConditionMaker * maker))block{
391 | NSString *sqlCondition;
392 | if (block) {
393 | CKConditionMaker *make = block([CKConditionMaker newWithModelClass:[self class]]);
394 | sqlCondition = make.sqlCondition;
395 | }
396 | NSString *tableName = NSStringFromClass([self class]);
397 | NSString *sql = [NSString stringWithFormat:@"select * from '%@' %@",tableName,sqlCondition?:@""];
398 | return [self queryArrayWithSQL:sql];
399 | }
400 | /**
401 | * 函数查询(count()、max()等)
402 | *
403 | * @param aQuery 函数语句
404 | * @param block 条件语句
405 | *
406 | * @return 查询结果
407 | */
408 | + (NSArray *)query:(id (^)(CKQueryMaker* maker))aQuery withConditions:(id (^)(CKConditionMaker * maker))block{
409 | NSString *sqlQuery,*sqlCondition;
410 | NSDictionary *sqlQueryDict;
411 | if (aQuery) {
412 | CKQueryMaker *make = aQuery([CKQueryMaker newWithModelClass:[self class]]);
413 | sqlQueryDict = make.sqlQueryDict;
414 | NSMutableArray *tmpQueryArray = @[].mutableCopy;
415 | NSArray *keys = sqlQueryDict.allKeys;
416 | for (NSString *key in keys) {
417 | NSString *value = sqlQueryDict[key];
418 | NSString *query = [NSString stringWithFormat:@"%@ %@",key,value];
419 | [tmpQueryArray addObject:query];
420 | }
421 | sqlQuery = [tmpQueryArray componentsJoinedByString:@","];
422 | }
423 | if (block) {
424 | CKConditionMaker *make = block([CKConditionMaker newWithModelClass:[self class]]);
425 | sqlCondition = make.sqlCondition;
426 | }
427 | NSString *tableName = NSStringFromClass([self class]);
428 | NSString *sql = [NSString stringWithFormat:@"select %@ from '%@' %@",sqlQuery?:@"*",tableName,sqlCondition?:@""];
429 | return [self queryDict:sqlQueryDict withSQL:sql];
430 | }
431 |
432 | /**
433 | * 查询任意自定义语句
434 | *
435 | * @param sql 查询语句
436 | *
437 | * @return 查询到的字典数组
438 | */
439 | + (NSArray *)queryDictArrayWithSql:(NSString *)sql{
440 | FMDatabase *db = [[CKManager shareManager] databaseWithName:CKDBNAME];
441 | if (![db open]) {return nil;}
442 | FMResultSet *rs=[db executeQuery:sql];
443 | NSArray *keys=rs.columnNameToIndexMap.allKeys;
444 | NSMutableArray *result = @[].mutableCopy;
445 | while ([rs next]) {
446 | NSMutableDictionary *resultDict=@{}.mutableCopy;
447 | for ( NSString *key in keys) {
448 | [resultDict setObject:[rs stringForColumn:key]?:@"" forKey:key];
449 | }
450 | [result addObject:resultDict];
451 | }
452 | [db close];
453 | return result;
454 | }
455 |
456 | #pragma mark
457 | #pragma mark - insert
458 | /**
459 | * 多条数据插入
460 | *
461 | * @param array 数据数组
462 | */
463 | + (void)insertWithArray:(NSArray *)array{
464 | NSMutableArray *sqls = @[].mutableCopy;
465 | for (id item in array) {
466 | NSString *sql = [self insertSqlFromItem:item];
467 | [sqls addObject:sql];
468 | }
469 | [self executeUpdateWithMuchSql:sqls];
470 | }
471 | /**
472 | * 单条数据插入
473 | */
474 | - (void)insert{
475 | NSString *sql = [[self class] insertSqlFromItem:self];
476 | [[self class] executeUpdateWithSql:sql];
477 | }
478 | #pragma mark
479 | #pragma mark - update
480 | /**
481 | * 多数据条件更新(可设置唯一索引做唯一标识)
482 | *
483 | * @param array 数据数组
484 | * @param block 条件语句
485 | */
486 | + (void)updateWithArray:(NSArray *)array conditions:(id (^)(CKConditionMaker * maker))block{
487 | NSString *sqlCondition;
488 | if (block) {
489 | CKConditionMaker *make = block([CKConditionMaker newWithModelClass:[self class]]);
490 | sqlCondition = make.sqlCondition;
491 | }
492 | NSMutableArray *sqls = @[].mutableCopy;
493 | for (id item in array) {
494 | NSString *sql = [[[self class] updateSqlFromItem:item] stringByAppendingString:sqlCondition?:@""];
495 | [sqls addObject:sql];
496 | }
497 | [self executeUpdateWithMuchSql:sqls];
498 |
499 | }
500 | /**
501 | * 单条数据更新
502 | *
503 | * @param block 条件语句
504 | */
505 | - (void)updateWithConditions:(id (^)(CKConditionMaker * maker))block{
506 | NSString *sqlCondition;
507 | if (block) {
508 | CKConditionMaker *make = block([CKConditionMaker newWithModelClass:[self class]]);
509 | sqlCondition = make.sqlCondition;
510 | }
511 | NSString *sql = [[[self class] updateSqlFromItem:self] stringByAppendingString:sqlCondition?:@""];
512 | return [[self class]executeUpdateWithSql:sql];
513 | }
514 |
515 | #pragma mark
516 | #pragma mark - replace
517 | /**
518 | * 有则更新/无则插入语句 (多条数据)
519 | *
520 | * @param array 数据数组
521 | */
522 | + (void)replaceWithArray:(NSArray *)array{
523 | NSMutableArray *sqls = @[].mutableCopy;
524 | for (id item in array) {
525 | NSString *sql = [self replaceSqlFromItem:item];
526 | [sqls addObject:sql];
527 | }
528 | [self executeUpdateWithMuchSql:sqls];
529 | }
530 | /**
531 | * 有则更新/无则插入语句 (单条数据)
532 | */
533 | - (void)replace{
534 | NSString *sql = [[self class] replaceSqlFromItem:self];
535 | [[self class] executeUpdateWithSql:sql];
536 | }
537 | #pragma mark
538 | #pragma mark - delete
539 | /**
540 | * 删除多条数据(每个字段都唯一对应)
541 | *
542 | * @param array 数据数组
543 | */
544 | + (void)deleteWithArray:(NSArray *)array{
545 | NSMutableArray *sqls = @[].mutableCopy;
546 | for (id item in array) {
547 | NSString *sql = [self deleteSqlFromItem:item];
548 | [sqls addObject:sql];
549 | }
550 | [self executeUpdateWithMuchSql:sqls];
551 | }
552 | /**
553 | * 条件删除数据
554 | *
555 | * @param block 条件语句
556 | */
557 | + (void)deleteWithConditions:(id (^)(CKConditionMaker * maker))block{
558 | NSString *sqlCondition;
559 | if (block) {
560 | CKConditionMaker *make = block([CKConditionMaker newWithModelClass:[self class]]);
561 | sqlCondition = make.sqlCondition;
562 | }
563 | NSString *tableName = NSStringFromClass([self class]);
564 | NSString *sql = [[NSString stringWithFormat:@"delete from %@",tableName] stringByAppendingString:sqlCondition?:@""];
565 | return [[self class]executeUpdateWithSql:sql];
566 |
567 | }
568 | /**
569 | * 单条数据删除
570 | */
571 | - (void)delete{
572 | NSString *sql = [[self class] deleteSqlFromItem:self];
573 | [[self class] executeUpdateWithSql:sql];
574 | }
575 |
576 | #pragma mark
577 | #pragma mark - CKFmdbJsonOperate
578 | /**
579 | * 字典转换model
580 | *
581 | * @param dict model字典
582 | *
583 | * @return model
584 | */
585 | + (id)modelWithDictionary:(NSDictionary *)dict{
586 | id item = [[self alloc]init];
587 | [item setValuesFromDictionary:dict];
588 | return item;
589 | }
590 | /**
591 | * 字典转换为数组模型
592 | *
593 | * @param dicts 字典数组
594 | *
595 | * @return 模型数组
596 | */
597 | + (NSArray *)modelsWithDictionarys:(NSArray *)dicts{
598 | NSMutableArray *array = @[].mutableCopy;
599 | for (NSDictionary *dict in dicts) {
600 | id item = [self modelWithDictionary:dict];
601 | [array addObject:item];
602 | }
603 | return array.copy;
604 | }
605 | /**
606 | * 模型数组转换为字典数组
607 | *
608 | * @param models 模型数组
609 | *
610 | * @return 字典数组
611 | */
612 | + (NSArray *)modelDictnarysWithModels:(NSArray *)models{
613 | NSMutableArray *array = @[].mutableCopy;
614 | for (id item in models) {
615 | [array addObject:[item modelDictionary]];
616 | }
617 | return array.copy;
618 | }
619 | /**
620 | * 模型数组转换为json
621 | *
622 | * @param models 模型数组
623 | *
624 | * @return json
625 | */
626 | + (NSString *)modelsJsonWithModels:(NSArray *)models{
627 | NSArray *array = [self modelDictnarysWithModels:models];
628 | NSString *jsonString = nil;
629 | NSError *error;
630 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:array
631 | options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
632 | error:&error];
633 | if (! jsonData) {
634 | NSLog(@"Got an error: %@", error);
635 | } else {
636 | jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
637 | }
638 | return jsonString;
639 | }
640 | /**
641 | * 根据字典赋值
642 | *
643 | * @param dicts 模型字典
644 | */
645 | - (void)setValuesFromDictionary:(NSDictionary *)dicts{
646 | if ([self conformsToProtocol:@protocol(CKFmdbJsonSerializing)]&&[self.class respondsToSelector:@selector(jsonKeyPathMapping)]) {
647 | NSDictionary *jsonKeyPathMapping = [self.class jsonKeyPathMapping];
648 | NSSet *propertyKeys = [self propertySet];
649 | for (NSString *mappedPropertyKey in jsonKeyPathMapping.allKeys) {
650 | id value = jsonKeyPathMapping[mappedPropertyKey];
651 |
652 | if ([mappedPropertyKey rangeOfString:@"."].location != NSNotFound) {
653 | NSArray *array = [mappedPropertyKey componentsSeparatedByString:@"."];
654 | if (![propertyKeys containsObject:array.firstObject]) {
655 | NSAssert(NO, @"%@ is not a property of %@.", array.firstObject, self.class);
656 | }
657 | }else if (![propertyKeys containsObject:mappedPropertyKey]) {
658 | NSAssert(NO, @"%@ is not a property of %@.", mappedPropertyKey, self.class);
659 | }
660 |
661 | if ([value isKindOfClass:NSArray.class]) {
662 | for (NSString *keyPath in value) {
663 | if ([keyPath isKindOfClass:NSString.class]) continue;
664 | NSAssert(NO, @"%@ must either map to a JSON key path or a JSON array of key paths, got: %@.", mappedPropertyKey, value);
665 | }
666 | } else if (![value isKindOfClass:NSString.class]) {
667 | NSAssert(NO, @"%@ must either map to a JSON key path or a JSON array of key paths, got: %@.",mappedPropertyKey, value);
668 | }
669 | [self setValue:dicts[value] forKeyPath:mappedPropertyKey];
670 | }
671 | }
672 | else{
673 | NSSet *propertySet = [self propertySet];
674 | for (NSString *property in propertySet) {
675 | if ([dicts.allKeys containsObject:property]) {
676 | [self setValue:[dicts objectForKey:property] forKey:property];
677 | }
678 | }
679 | }
680 | }
681 | /**
682 | * 获取模型字典
683 | *
684 | * @return 模型字典
685 | */
686 | - (NSDictionary *)modelDictionary{
687 | NSSet *propertySet = [self propertySet];
688 | NSMutableDictionary *dict = @{}.mutableCopy;
689 | for (NSString *property in propertySet) {
690 | [dict setObject:[self valueForKey:property]?:@"" forKey:property];
691 | }
692 | return dict;
693 | }
694 | /**
695 | * 获取模型json
696 | *
697 | * @return 模型json
698 | */
699 | - (NSString *)modelJson{
700 | NSString *jsonString = nil;
701 | NSError *error;
702 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[self modelDictionary]
703 | options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
704 | error:&error];
705 | if (! jsonData) {
706 | NSLog(@"Got an error: %@", error);
707 | } else {
708 | jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
709 | }
710 | return jsonString;
711 | }
712 |
713 | #pragma mark
714 | #pragma mark - NSCopying
715 | - (id)copyWithZone:(NSZone *)zone{
716 | return [[[self class] allocWithZone:zone] initWithDictionary:self.modelDictionary];
717 | }
718 |
719 |
720 | #pragma mark
721 | #pragma mark - Method
722 |
723 | - (instancetype)initWithDictionary:(NSDictionary *)dict{
724 | self = [super init];
725 | if (self) {
726 | [self setValuesFromDictionary:dict];
727 | }
728 | return self;
729 | }
730 |
731 | - (BOOL)isEqual:(id)object{
732 | if (self == object) return YES;
733 | if (![object isMemberOfClass:self.class]) return NO;
734 |
735 | for (NSString *key in self.class.propertyArray) {
736 | id selfValue = [self valueForKey:key];
737 | id modelValue = [object valueForKey:key];
738 | BOOL valuesEqual = ((selfValue == nil && modelValue == nil) || [selfValue isEqual:modelValue]);
739 | if (!valuesEqual) return NO;
740 | }
741 | return YES;
742 | }
743 |
744 | - (NSString *)description{
745 | return [self modelJson];
746 | }
747 | - (NSString *)debugDescription{
748 | return [NSString stringWithFormat:@"<%@:%p,%@>",[self class],self,[self modelJson]];
749 | }
750 | - (NSUInteger)hash {
751 | NSUInteger value = 0;
752 | for (NSString *key in self.class.propertyArray) {
753 | value ^= [[self valueForKey:key] hash];
754 | }
755 | return value;
756 | }
757 |
758 | - (void)setValue:(id)value forKey:(NSString *)key {
759 | if ((value == nil || [[NSNull null] isEqual:value])) {
760 | objc_property_t property = class_getProperty([self class], [key UTF8String]);
761 | NSString *propertyAttribute = [NSString stringWithUTF8String:property_getAttributes(property)];
762 | NSArray *array = [propertyAttribute componentsSeparatedByString:@","];
763 | NSString *firstItem = array.firstObject;
764 | if ([@[@"tq",@"td",@"tf",@"ti",@"tb",@"ts",@"tl"] containsObject:[firstItem lowercaseString]]) {
765 | [super setValue:@0 forKey:key];
766 | }
767 | else if ([@"tc" isEqualToString:[firstItem lowercaseString]]) {
768 | [super setValue:[NSNumber numberWithChar:' '] forKey:key];
769 | }
770 | else {
771 | Class cls = NSClassFromString([firstItem substringWithRange:NSMakeRange(3, firstItem.length - 4)]);
772 | id aValue = [[cls alloc]init];
773 | [super setValue:aValue forKey:key];
774 | }
775 | }
776 | else if ([value isKindOfClass:[NSString class]]) {
777 | objc_property_t property = class_getProperty([self class], [key UTF8String]);
778 | NSString *propertyAttribute = [NSString stringWithUTF8String:property_getAttributes(property)];
779 | if ([propertyAttribute hasPrefix:@"T@"] || [propertyAttribute hasPrefix:@"T{"]) {
780 | [super setValue:value forKey:key];
781 | return;
782 | }
783 | else {
784 | propertyAttribute = [propertyAttribute lowercaseString];
785 | NSNumber *num;
786 | if ([propertyAttribute hasPrefix:@"ti"] || [propertyAttribute hasPrefix:@"tb"] || [propertyAttribute hasPrefix:@"tl"] || [propertyAttribute hasPrefix:@"tq"]){
787 | num = [NSNumber numberWithInteger:[value integerValue]];
788 | } else if ([propertyAttribute hasPrefix:@"tf"]){
789 | num = [NSNumber numberWithFloat:[value floatValue]];
790 | } else if([propertyAttribute hasPrefix:@"td"]) {
791 | num = [NSNumber numberWithDouble:[value doubleValue]];
792 | // } else if([propertyAttribute hasPrefix:@"tl"] || [propertyAttribute hasPrefix:@"tq"]){
793 | // num = [NSNumber numberWithLong:[value integerValue]];
794 | } else if ([propertyAttribute hasPrefix:@"tc"]) {
795 | num = [NSNumber numberWithChar:[value charValue]];
796 | } else if([propertyAttribute hasPrefix:@"ts"]){
797 | num = [NSNumber numberWithShort:[value shortValue]];
798 | } else {
799 | [super setValue:value forKey:key];
800 | return;
801 | }
802 | [super setValue:num forKey:key];
803 | return;
804 | }
805 | }
806 | else {
807 | [super setValue:value forKey:key];
808 | }
809 |
810 | }
811 |
812 | @end
813 |
814 |
--------------------------------------------------------------------------------