├── CoreModel.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── Charlin.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── Charlin.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ ├── CoreModel.xcscheme
│ └── xcschememanagement.plist
├── CoreModel
├── APP
│ ├── Common
│ │ ├── CommonVC.h
│ │ ├── CommonVC.m
│ │ └── CoreSVP
│ │ │ ├── CoreSVP.h
│ │ │ ├── CoreSVP.m
│ │ │ └── Lib
│ │ │ ├── SVP.bundle
│ │ │ ├── green@2x.png
│ │ │ ├── green@3x.png
│ │ │ ├── red@2x.png
│ │ │ ├── red@3x.png
│ │ │ ├── yellow@2x.png
│ │ │ └── yellow@3x.png
│ │ │ └── SVProgressHUD
│ │ │ ├── SVIndefiniteAnimatedView.h
│ │ │ ├── SVIndefiniteAnimatedView.m
│ │ │ ├── SVProgressHUD-Prefix.pch
│ │ │ ├── SVProgressHUD.bundle
│ │ │ ├── angle-mask.png
│ │ │ ├── angle-mask@2x.png
│ │ │ ├── angle-mask@3x.png
│ │ │ ├── error.png
│ │ │ ├── error@2x.png
│ │ │ ├── error@3x.png
│ │ │ ├── info.png
│ │ │ ├── info@2x.png
│ │ │ ├── info@3x.png
│ │ │ ├── success.png
│ │ │ ├── success@2x.png
│ │ │ └── success@3x.png
│ │ │ ├── SVProgressHUD.h
│ │ │ └── SVProgressHUD.m
│ ├── List
│ │ ├── ListTVC.h
│ │ └── ListTVC.m
│ ├── Model
│ │ ├── City.h
│ │ ├── City.m
│ │ ├── Pen.h
│ │ ├── Pen.m
│ │ ├── Person.h
│ │ └── Person.m
│ └── Modules
│ │ ├── Test10VC.h
│ │ ├── Test10VC.m
│ │ ├── Test11VC.h
│ │ ├── Test11VC.m
│ │ ├── Test12VC.h
│ │ ├── Test12VC.m
│ │ ├── Test12VC.xib
│ │ ├── Test13VC.h
│ │ ├── Test13VC.m
│ │ ├── Test14VC.h
│ │ ├── Test14VC.m
│ │ ├── Test15VC.h
│ │ ├── Test15VC.m
│ │ ├── Test15VC.xib
│ │ ├── Test16VC.h
│ │ ├── Test16VC.m
│ │ ├── Test17VC.h
│ │ ├── Test17VC.m
│ │ ├── Test2VC.h
│ │ ├── Test2VC.m
│ │ ├── Test3VC.h
│ │ ├── Test3VC.m
│ │ ├── Test4VC.h
│ │ ├── Test4VC.m
│ │ ├── Test5VC.h
│ │ ├── Test5VC.m
│ │ ├── Test6VC.h
│ │ ├── Test6VC.m
│ │ ├── Test7VC.h
│ │ ├── Test7VC.m
│ │ ├── Test8VC.h
│ │ ├── Test8VC.m
│ │ ├── Test9VC.h
│ │ └── Test9VC.m
├── AppDelegate.h
├── AppDelegate.m
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ ├── p1.imageset
│ │ ├── Contents.json
│ │ └── p1.png
│ ├── p2.imageset
│ │ ├── Contents.json
│ │ └── p2.png
│ └── p3.imageset
│ │ ├── Contents.json
│ │ └── p3.png
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── CoreModel
│ ├── CoreModel.h
│ ├── CoreModel.m
│ └── Lib
│ │ ├── Category
│ │ ├── NSArray
│ │ │ ├── NSArray+CoreModel.h
│ │ │ └── NSArray+CoreModel.m
│ │ ├── NSDictionary
│ │ │ ├── NSDictionary+Sqlite.h
│ │ │ └── NSDictionary+Sqlite.m
│ │ ├── NSObject
│ │ │ ├── CoreModel+Cache.h
│ │ │ ├── CoreModel+Cache.m
│ │ │ ├── NSObject+CoreModelCommon.h
│ │ │ ├── NSObject+CoreModelCommon.m
│ │ │ ├── NSObject+Create.h
│ │ │ ├── NSObject+Create.m
│ │ │ ├── NSObject+Delete.h
│ │ │ ├── NSObject+Delete.m
│ │ │ ├── NSObject+Insert.h
│ │ │ ├── NSObject+Insert.m
│ │ │ ├── NSObject+Save.h
│ │ │ ├── NSObject+Save.m
│ │ │ ├── NSObject+Select.h
│ │ │ ├── NSObject+Select.m
│ │ │ ├── NSObject+Update.h
│ │ │ └── NSObject+Update.m
│ │ ├── NSOperationQueue
│ │ │ ├── NSOperationQueue+Queue.h
│ │ │ └── NSOperationQueue+Queue.m
│ │ └── NSString
│ │ │ ├── NSString+Stackoverflow.h
│ │ │ └── NSString+Stackoverflow.m
│ │ ├── CoreMoelConst
│ │ ├── CoreModelConst.h
│ │ └── CoreModelConst.m
│ │ ├── Protocol
│ │ ├── CoreModelProtocol.h
│ │ └── CorePageModelProtocol.h
│ │ ├── Reflect
│ │ ├── CoreProperty.h
│ │ ├── CoreProperty.m
│ │ ├── NSObject+Runtime.h
│ │ └── NSObject+Runtime.m
│ │ └── Type
│ │ └── CoreModelType.h
├── FrameWorks
│ └── CoreFMDB
│ │ ├── CoreFMDB.h
│ │ ├── CoreFMDB.m
│ │ └── Lib
│ │ ├── Category
│ │ ├── NSString+CoreFMDB.h
│ │ └── NSString+CoreFMDB.m
│ │ ├── Singleton
│ │ └── CoreFMDBSingleton.h
│ │ └── fmdb
│ │ ├── FMDB.h
│ │ ├── FMDatabase.h
│ │ ├── FMDatabase.m
│ │ ├── FMDatabaseAdditions.h
│ │ ├── FMDatabaseAdditions.m
│ │ ├── FMDatabasePool.h
│ │ ├── FMDatabasePool.m
│ │ ├── FMDatabaseQueue.h
│ │ ├── FMDatabaseQueue.m
│ │ ├── FMResultSet.h
│ │ └── FMResultSet.m
├── Info.plist
├── ViewController.h
├── ViewController.m
└── main.m
└── README.md
/CoreModel.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CoreModel.xcodeproj/project.xcworkspace/xcuserdata/Charlin.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel.xcodeproj/project.xcworkspace/xcuserdata/Charlin.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/CoreModel.xcodeproj/xcuserdata/Charlin.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/CoreModel.xcodeproj/xcuserdata/Charlin.xcuserdatad/xcschemes/CoreModel.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/CoreModel.xcodeproj/xcuserdata/Charlin.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | CoreModel.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 89CFA0A11CAFCB1700A280D2
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CommonVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // CommonVC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CoreSVP.h"
11 |
12 | #import "Person.h"
13 |
14 |
15 |
16 | @interface CommonVC : UIViewController
17 |
18 | -(void)show:(BOOL)res;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CommonVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // CommonVC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CommonVC.h"
10 |
11 | @interface CommonVC ()
12 |
13 | @end
14 |
15 | @implementation CommonVC
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 |
20 |
21 | self.view.backgroundColor = [UIColor whiteColor];
22 |
23 |
24 |
25 | }
26 |
27 |
28 |
29 | -(void)show:(BOOL)res{
30 |
31 | if(res){
32 |
33 | CoreSVPSuccess(@"操作成功")
34 |
35 | }else{
36 |
37 | CoreSVPError(@"操作失败")
38 | }
39 |
40 | }
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/CoreSVP.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreSVP.h
3 | //
4 | // Created by muxi on 14/10/22.
5 | // Copyright (c) 2014年 muxi. All rights reserved.
6 | // 提示工具类
7 |
8 |
9 |
10 | #import
11 | #import
12 | #import "SVProgressHUD.h"
13 |
14 | #define CoreSVPSuccess(msg) [CoreSVP showSVPWithType:CoreSVPTypeSuccess Msg:msg duration:1.5 allowEdit:NO beginBlock:nil completeBlock:nil];
15 | #define CoreSVPError(msg) [CoreSVP showSVPWithType:CoreSVPTypeError Msg:msg duration:2.0 allowEdit:NO beginBlock:nil completeBlock:nil];
16 | #define CoreSVPLoading(msg,allow) [CoreSVP showSVPWithType:CoreSVPTypeLoadingInterface Msg:msg duration:0 allowEdit:allow beginBlock:nil completeBlock:nil];
17 |
18 |
19 |
20 |
21 |
22 | typedef enum {
23 |
24 | CoreSVPTypeNone = 0, //默认无状态
25 |
26 | CoreSVPTypeCenterMsg, //无图片普通提示,显示在屏幕正中间
27 |
28 | CoreSVPTypeBottomMsg, //无图片普通提示,显示在屏幕下方,tabbar之上
29 |
30 | CoreSVPTypeInfo, //Info
31 |
32 | CoreSVPTypeLoadingInterface, //Progress,可以互
33 |
34 | CoreSVPTypeError, //error
35 |
36 | CoreSVPTypeSuccess //success
37 |
38 | }CoreSVPType;
39 |
40 |
41 |
42 |
43 |
44 | @interface CoreSVP : NSObject
45 |
46 |
47 |
48 |
49 | /**
50 | * 展示提示框
51 | *
52 | * @param type 类型
53 | * @param msg 文字
54 | * @param duration 时间(当type=CoreSVPTypeLoadingInterface时无效)
55 | * @param allowEdit 否允许编辑
56 | * @param beginBlock 提示开始时的回调
57 | * @param completeBlock 提示结束时的回调
58 | */
59 | +(void)showSVPWithType:(CoreSVPType)type Msg:(NSString *)msg duration:(CGFloat)duration allowEdit:(BOOL)allowEdit beginBlock:(void(^)())beginBlock completeBlock:(void(^)())completeBlock;
60 |
61 |
62 | /*
63 | * 进度
64 | */
65 | +(void)showProgess:(CGFloat)progress Msg:(NSString *)msg maskType:(SVProgressHUDMaskType)maskType;
66 |
67 |
68 |
69 |
70 | /**
71 | * 隐藏提示框
72 | */
73 | +(void)dismiss;
74 |
75 |
76 | @end
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/CoreSVP.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreSVP.m
3 | // 新浪微博2014MJ版
4 | //
5 | // Created by muxi on 14/10/22.
6 | // Copyright (c) 2014年 muxi. All rights reserved.
7 | //
8 |
9 | #import "CoreSVP.h"
10 |
11 | static CoreSVPType SVPtype = CoreSVPTypeNone;
12 |
13 | #define rgba(r,g,b,a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a]
14 |
15 | @interface CoreSVP ()
16 |
17 |
18 |
19 | @end
20 |
21 |
22 |
23 | @implementation CoreSVP
24 |
25 |
26 | /**
27 | * 展示提示框
28 | *
29 | * @param type 类型
30 | * @param msg 文字
31 | * @param duration 时间(当type=CoreSVPTypeLoadingInterface时无效)
32 | * @param allowEdit 否允许编辑
33 | * @param beginBlock 提示开始时的回调
34 | * @param completeBlock 提示结束时的回调
35 | */
36 | +(void)showSVPWithType:(CoreSVPType)type Msg:(NSString *)msg duration:(CGFloat)duration allowEdit:(BOOL)allowEdit beginBlock:(void(^)())beginBlock completeBlock:(void(^)())completeBlock{
37 |
38 | if(CoreSVPTypeLoadingInterface != type && CoreSVPTypeLoadingInterface == SVPtype){
39 |
40 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.8f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
41 |
42 | SVPtype = type;
43 |
44 | [self showSVPWithType:type Msg:msg duration:duration allowEdit:allowEdit beginBlock:beginBlock completeBlock:completeBlock];
45 | });
46 |
47 | return;
48 | }
49 |
50 | //记录状态
51 | SVPtype = type;
52 |
53 |
54 | //无状态直接返回
55 | if (CoreSVPTypeNone == type) return;
56 |
57 |
58 |
59 | dispatch_async(dispatch_get_main_queue(), ^{
60 |
61 | //基本配置
62 | [self hudSetting];
63 |
64 | if(CoreSVPTypeBottomMsg == type) [SVProgressHUD setOffsetFromCenter:UIOffsetMake(0, [UIScreen mainScreen].applicationFrame.size.height * .5f-49.0f)];
65 |
66 |
67 | //设置时间
68 | [SVProgressHUD setDuration:duration];
69 |
70 | //错误图片
71 | [SVProgressHUD setErrorImage:[UIImage imageNamed:@"SVP.bundle/red"]];
72 |
73 | //成功图片
74 | [SVProgressHUD setSuccessImage:[UIImage imageNamed:@"SVP.bundle/green"]];
75 |
76 | //警告图片
77 | [SVProgressHUD setInfoImage:[UIImage imageNamed:@"SVP.bundle/yellow"]];
78 |
79 | SVProgressHUDMaskType maskType=allowEdit?SVProgressHUDMaskTypeNone:SVProgressHUDMaskTypeClear;
80 | [SVProgressHUD setDefaultMaskType:maskType];
81 |
82 | //开始回调
83 | if(beginBlock != nil) beginBlock();
84 |
85 | if(CoreSVPTypeLoadingInterface != type) [SVProgressHUD setCompleteBlock:completeBlock];
86 |
87 | switch (type) {
88 |
89 | case CoreSVPTypeCenterMsg:
90 | case CoreSVPTypeBottomMsg:
91 | [SVProgressHUD showImage:nil status:msg];
92 | break;
93 |
94 | case CoreSVPTypeInfo:
95 | [SVProgressHUD showInfoWithStatus:msg];
96 | break;
97 |
98 | case CoreSVPTypeLoadingInterface:
99 | [SVProgressHUD showWithStatus:msg];
100 | break;
101 |
102 | case CoreSVPTypeError:
103 | [SVProgressHUD showErrorWithStatus:msg];
104 | break;
105 |
106 | case CoreSVPTypeSuccess:
107 | [SVProgressHUD showSuccessWithStatus:msg];
108 | break;
109 |
110 | default:
111 | break;
112 | }
113 |
114 | });
115 | }
116 |
117 |
118 | /*
119 | * 进度
120 | */
121 | +(void)showProgess:(CGFloat)progress Msg:(NSString *)msg maskType:(SVProgressHUDMaskType)maskType{
122 |
123 | if (progress<=0) progress = 0;
124 |
125 | dispatch_async(dispatch_get_main_queue(), ^{
126 |
127 | //基本配置
128 | [self hudSetting];
129 |
130 | [SVProgressHUD showProgress:progress status:msg maskType:maskType];
131 |
132 | if(progress>=1) {
133 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
134 | [self dismiss];
135 | });
136 | }
137 | });
138 | }
139 |
140 |
141 | /*
142 | * 基本配置
143 | */
144 | +(void)hudSetting{
145 |
146 | //设置背景色
147 | [SVProgressHUD setBackgroundColor:rgba(92,93,94,1)];
148 |
149 | //文字颜色
150 | [SVProgressHUD setForegroundColor:rgba(241, 241, 241, 1)];
151 |
152 | //字体大小
153 | [SVProgressHUD setFont:[UIFont systemFontOfSize:16.0f]];
154 |
155 | //设置线宽
156 | [SVProgressHUD setRingThickness:2.f];
157 |
158 | //边角
159 | [SVProgressHUD setCornerRadius:2.0f];
160 | }
161 |
162 |
163 | /**
164 | * 隐藏提示框
165 | */
166 | +(void)dismiss{
167 |
168 | dispatch_async(dispatch_get_main_queue(), ^{
169 | [SVProgressHUD dismiss];
170 | });
171 | }
172 |
173 | @end
174 |
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVP.bundle/green@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVP.bundle/green@2x.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVP.bundle/green@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVP.bundle/green@3x.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVP.bundle/red@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVP.bundle/red@2x.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVP.bundle/red@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVP.bundle/red@3x.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVP.bundle/yellow@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVP.bundle/yellow@2x.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVP.bundle/yellow@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVP.bundle/yellow@3x.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVIndefiniteAnimatedView.h:
--------------------------------------------------------------------------------
1 | //
2 | // SVIndefiniteAnimatedView.h
3 | // SVProgressHUD
4 | //
5 | // Created by Guillaume Campagna on 2014-12-05.
6 | //
7 | //
8 |
9 | #import
10 |
11 | @interface SVIndefiniteAnimatedView : UIView
12 |
13 | @property (nonatomic, assign) CGFloat strokeThickness;
14 | @property (nonatomic, assign) CGFloat radius;
15 | @property (nonatomic, strong) UIColor *strokeColor;
16 |
17 | @end
18 |
19 |
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVIndefiniteAnimatedView.m:
--------------------------------------------------------------------------------
1 | //
2 | // SVIndefiniteAnimatedView.m
3 | // SVProgressHUD
4 | //
5 | // Created by Guillaume Campagna on 2014-12-05.
6 | //
7 | //
8 |
9 | #import "SVIndefiniteAnimatedView.h"
10 |
11 | #pragma mark SVIndefiniteAnimatedView
12 |
13 | @interface SVIndefiniteAnimatedView ()
14 |
15 | @property (nonatomic, strong) CAShapeLayer *indefiniteAnimatedLayer;
16 |
17 | @end
18 |
19 | @implementation SVIndefiniteAnimatedView
20 |
21 | - (void)willMoveToSuperview:(UIView *)newSuperview {
22 | if (newSuperview) {
23 | [self layoutAnimatedLayer];
24 | } else {
25 | [_indefiniteAnimatedLayer removeFromSuperlayer];
26 | _indefiniteAnimatedLayer = nil;
27 | }
28 | }
29 |
30 | - (void)layoutAnimatedLayer {
31 | CALayer *layer = self.indefiniteAnimatedLayer;
32 | [self.layer addSublayer:layer];
33 | layer.position = CGPointMake(CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds) / 2, CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds) / 2);
34 | }
35 |
36 | - (CAShapeLayer*)indefiniteAnimatedLayer {
37 | if(!_indefiniteAnimatedLayer) {
38 | CGPoint arcCenter = CGPointMake(self.radius+self.strokeThickness/2+5, self.radius+self.strokeThickness/2+5);
39 | CGRect rect = CGRectMake(0.0f, 0.0f, arcCenter.x*2, arcCenter.y*2);
40 |
41 | UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:arcCenter
42 | radius:self.radius
43 | startAngle:M_PI*3/2
44 | endAngle:M_PI/2+M_PI*5
45 | clockwise:YES];
46 |
47 | _indefiniteAnimatedLayer = [CAShapeLayer layer];
48 | _indefiniteAnimatedLayer.contentsScale = [[UIScreen mainScreen] scale];
49 | _indefiniteAnimatedLayer.frame = rect;
50 | _indefiniteAnimatedLayer.fillColor = [UIColor clearColor].CGColor;
51 | _indefiniteAnimatedLayer.strokeColor = self.strokeColor.CGColor;
52 | _indefiniteAnimatedLayer.lineWidth = self.strokeThickness;
53 | _indefiniteAnimatedLayer.lineCap = kCALineCapRound;
54 | _indefiniteAnimatedLayer.lineJoin = kCALineJoinBevel;
55 | _indefiniteAnimatedLayer.path = smoothedPath.CGPath;
56 |
57 | CALayer *maskLayer = [CALayer layer];
58 |
59 | NSBundle *bundle = [NSBundle bundleForClass:self.class];
60 | NSURL *url = [bundle URLForResource:@"SVProgressHUD" withExtension:@"bundle"];
61 | NSBundle *imageBundle = [NSBundle bundleWithURL:url];
62 | NSString *path = [imageBundle pathForResource:@"angle-mask" ofType:@"png"];
63 |
64 | maskLayer.contents = (id)[[UIImage imageWithContentsOfFile:path] CGImage];;
65 | maskLayer.frame = _indefiniteAnimatedLayer.bounds;
66 | _indefiniteAnimatedLayer.mask = maskLayer;
67 |
68 | NSTimeInterval animationDuration = 1;
69 | CAMediaTimingFunction *linearCurve = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
70 |
71 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
72 | animation.fromValue = 0;
73 | animation.toValue = @(M_PI*2);
74 | animation.duration = animationDuration;
75 | animation.timingFunction = linearCurve;
76 | animation.removedOnCompletion = NO;
77 | animation.repeatCount = INFINITY;
78 | animation.fillMode = kCAFillModeForwards;
79 | animation.autoreverses = NO;
80 | [_indefiniteAnimatedLayer.mask addAnimation:animation forKey:@"rotate"];
81 |
82 | CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
83 | animationGroup.duration = animationDuration;
84 | animationGroup.repeatCount = INFINITY;
85 | animationGroup.removedOnCompletion = NO;
86 | animationGroup.timingFunction = linearCurve;
87 |
88 | CABasicAnimation *strokeStartAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
89 | strokeStartAnimation.fromValue = @0.015;
90 | strokeStartAnimation.toValue = @0.515;
91 |
92 | CABasicAnimation *strokeEndAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
93 | strokeEndAnimation.fromValue = @0.485;
94 | strokeEndAnimation.toValue = @0.985;
95 |
96 | animationGroup.animations = @[strokeStartAnimation, strokeEndAnimation];
97 | [_indefiniteAnimatedLayer addAnimation:animationGroup forKey:@"progress"];
98 |
99 | }
100 | return _indefiniteAnimatedLayer;
101 | }
102 |
103 | - (void)setFrame:(CGRect)frame {
104 | if(!CGRectEqualToRect(frame, super.frame)){
105 | [super setFrame:frame];
106 |
107 | if (self.superview) {
108 | [self layoutAnimatedLayer];
109 | }
110 | }
111 |
112 | }
113 |
114 | - (void)setRadius:(CGFloat)radius {
115 | if(radius != _radius){
116 | _radius = radius;
117 |
118 | [_indefiniteAnimatedLayer removeFromSuperlayer];
119 | _indefiniteAnimatedLayer = nil;
120 |
121 | if (self.superview) {
122 | [self layoutAnimatedLayer];
123 | }
124 | }
125 | }
126 |
127 | - (void)setStrokeColor:(UIColor *)strokeColor {
128 | _strokeColor = strokeColor;
129 | _indefiniteAnimatedLayer.strokeColor = strokeColor.CGColor;
130 | }
131 |
132 | - (void)setStrokeThickness:(CGFloat)strokeThickness {
133 | _strokeThickness = strokeThickness;
134 | _indefiniteAnimatedLayer.lineWidth = _strokeThickness;
135 | }
136 |
137 | - (CGSize)sizeThatFits:(CGSize)size {
138 | return CGSizeMake((self.radius+self.strokeThickness/2+5)*2, (self.radius+self.strokeThickness/2+5)*2);
139 | }
140 |
141 | @end
142 |
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'SVProgressHUD' target in the 'SVProgressHUD' project
3 | //
4 |
5 | #ifdef __OBJC__
6 | #import
7 | #endif
8 |
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/angle-mask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/angle-mask.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/angle-mask@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/angle-mask@2x.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/angle-mask@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/angle-mask@3x.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/error.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/error@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/error@2x.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/error@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/error@3x.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/info.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/info@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/info@2x.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/info@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/info@3x.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/success.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/success@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/success@2x.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/success@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.bundle/success@3x.png
--------------------------------------------------------------------------------
/CoreModel/APP/Common/CoreSVP/Lib/SVProgressHUD/SVProgressHUD.h:
--------------------------------------------------------------------------------
1 | //
2 | // SVProgressHUD.h
3 | //
4 | // Copyright 2011-2014 Sam Vermette. All rights reserved.
5 | //
6 | // https://github.com/samvermette/SVProgressHUD
7 | //
8 |
9 | #import
10 | #import
11 |
12 | extern NSString * const SVProgressHUDDidReceiveTouchEventNotification;
13 | extern NSString * const SVProgressHUDDidTouchDownInsideNotification;
14 | extern NSString * const SVProgressHUDWillDisappearNotification;
15 | extern NSString * const SVProgressHUDDidDisappearNotification;
16 | extern NSString * const SVProgressHUDWillAppearNotification;
17 | extern NSString * const SVProgressHUDDidAppearNotification;
18 |
19 | extern NSString * const SVProgressHUDStatusUserInfoKey;
20 |
21 | typedef NS_ENUM(NSUInteger, SVProgressHUDMaskType) {
22 | SVProgressHUDMaskTypeNone = 1, // allow user interactions while HUD is displayed
23 | SVProgressHUDMaskTypeClear, // don't allow user interactions
24 | SVProgressHUDMaskTypeBlack, // don't allow user interactions and dim the UI in the back of the HUD
25 | SVProgressHUDMaskTypeGradient // don't allow user interactions and dim the UI with a a-la-alert-view background gradient
26 | };
27 |
28 | @interface SVProgressHUD : UIView
29 |
30 | #pragma mark - Customization
31 |
32 | + (void)setBackgroundColor:(UIColor*)color; // default is [UIColor whiteColor]
33 | + (void)setForegroundColor:(UIColor*)color; // default is [UIColor blackColor]
34 | + (void)setCornerRadius:(CGFloat)cornerRadius; // default is 14 pt
35 | + (void)setRingThickness:(CGFloat)width; // default is 4 pt
36 | + (void)setFont:(UIFont*)font; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]
37 | + (void)setInfoImage:(UIImage*)image; // default is the bundled info image provided by Freepik
38 | + (void)setSuccessImage:(UIImage*)image; // default is the bundled success image provided by Freepik
39 | + (void)setErrorImage:(UIImage*)image; // default is the bundled error image provided by Freepik
40 | + (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType; // default is SVProgressHUDMaskTypeNone
41 | + (void)setViewForExtension:(UIView*)view; // default is nil, only used if #define SV_APP_EXTENSIONS is set
42 |
43 | #pragma mark - Show Methods
44 |
45 | + (void)show;
46 | + (void)showWithMaskType:(SVProgressHUDMaskType)maskType;
47 | + (void)showWithStatus:(NSString*)status;
48 | + (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType;
49 |
50 | + (void)showProgress:(float)progress;
51 | + (void)showProgress:(float)progress maskType:(SVProgressHUDMaskType)maskType;
52 | + (void)showProgress:(float)progress status:(NSString*)status;
53 | + (void)showProgress:(float)progress status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType;
54 |
55 | + (void)setStatus:(NSString*)string; // change the HUD loading status while it's showing
56 |
57 | // stops the activity indicator, shows a glyph + status, and dismisses HUD a little bit later
58 | + (void)showInfoWithStatus:(NSString *)string;
59 | + (void)showInfoWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType;
60 |
61 | + (void)showSuccessWithStatus:(NSString*)string;
62 | + (void)showSuccessWithStatus:(NSString*)string maskType:(SVProgressHUDMaskType)maskType;
63 |
64 | + (void)showErrorWithStatus:(NSString *)string;
65 | + (void)showErrorWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType;
66 |
67 | // use 28x28 white pngs
68 | + (void)showImage:(UIImage*)image status:(NSString*)status;
69 | + (void)showImage:(UIImage*)image status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType;
70 |
71 | + (void)setOffsetFromCenter:(UIOffset)offset;
72 | + (void)resetOffsetFromCenter;
73 |
74 | + (void)popActivity; // decrease activity count, if activity count == 0 the HUD is dismissed
75 | + (void)dismiss;
76 |
77 | + (BOOL)isVisible;
78 |
79 |
80 |
81 |
82 |
83 | /** 对HUB进行扩展 */
84 | +(void)setDuration:(NSTimeInterval)duration;
85 |
86 | /** 完成时回调 */
87 | +(void)setCompleteBlock:(void(^)())completeBlock;
88 |
89 | @end
90 |
91 |
--------------------------------------------------------------------------------
/CoreModel/APP/List/ListTVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // ListTableView.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ListTVC : UITableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/List/ListTVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // ListTableView.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "ListTVC.h"
10 | #import "Test2VC.h"
11 | #import "Test3VC.h"
12 | #import "Test4VC.h"
13 | #import "Test5VC.h"
14 | #import "Test6VC.h"
15 | #import "Test7VC.h"
16 | #import "Test8VC.h"
17 | #import "Test9VC.h"
18 | #import "Test10VC.h"
19 | #import "Test11VC.h"
20 | #import "Test12VC.h"
21 | #import "Test13VC.h"
22 | #import "Test14VC.h"
23 | #import "Test15VC.h"
24 | #import "Test16VC.h"
25 | #import "Test17VC.h"
26 |
27 |
28 |
29 |
30 |
31 | @interface ListTVC ()
32 |
33 | @property (nonatomic,strong) NSArray *dataList;
34 |
35 |
36 | @end
37 |
38 | @implementation ListTVC
39 |
40 | - (void)viewDidLoad {
41 | [super viewDidLoad];
42 |
43 | self.title = @"成都时点软件原创出品";
44 |
45 | self.dataList = @[
46 |
47 | @[[Test2VC class],@"子线程全自动创表"],
48 | @[[Test3VC class],@"无hostID自动处理"],
49 | @[[Test4VC class],@"基本模型 + 单条数据插入"],
50 | @[[Test5VC class],@"基本模型 + 批量数据插入"],
51 | @[[Test6VC class],@"基本模型 + 单条数据修改"],
52 | @[[Test7VC class],@"基本模型 + 批量数据修改"],
53 | @[[Test8VC class],@"基本模型 + 单条/批量/模糊保存"],
54 | @[[Test9VC class],@"基本模型 + 条件删除"],
55 | @[[Test10VC class],@"基本模型 + 条件查询"],
56 | @[[Test11VC class],@"基本模型 + 清空所有表记录"],
57 | @[[Test12VC class],@"NSData的支持"],
58 | @[[Test13VC class],@"属性为单模型级联:数据插入"],
59 | @[[Test14VC class],@"数组支持:基本类型数组"],
60 | @[[Test15VC class],@"数组支持:NSData类型数组"],
61 | @[[Test16VC class],@"数组支持:自定义模型数组"],
62 | @[[Test17VC class],@"大数量调整并发"],
63 | ];
64 |
65 | }
66 |
67 |
68 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
69 | return self.dataList.count;
70 |
71 |
72 | }
73 |
74 |
75 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
76 |
77 | static NSString *ListTVCRid = @"ListTVC";
78 |
79 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ListTVCRid];
80 |
81 | if(cell == nil) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ListTVCRid];
82 |
83 | cell.textLabel.text = [NSString stringWithFormat:@"%@. %@",@(indexPath.row+1),((NSArray *)self.dataList[indexPath.row])[1]];
84 |
85 | return cell;
86 | }
87 |
88 |
89 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
90 |
91 | Class Cls = ((NSArray *)self.dataList[indexPath.row])[0];
92 |
93 | UIViewController *vc = [[Cls alloc] init];
94 | vc.title = ((NSArray *)self.dataList[indexPath.row])[1];
95 |
96 | [self.navigationController pushViewController:vc animated:YES];
97 | }
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | @end
108 |
--------------------------------------------------------------------------------
/CoreModel/APP/Model/City.h:
--------------------------------------------------------------------------------
1 | //
2 | // City.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CoreModel.h"
10 |
11 | @interface City : CoreModel
12 |
13 | @property (nonatomic,copy) NSString *cityName;
14 |
15 | @property (nonatomic,copy) NSString *spell;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/CoreModel/APP/Model/City.m:
--------------------------------------------------------------------------------
1 | //
2 | // City.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "City.h"
10 |
11 | @implementation City
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Model/Pen.h:
--------------------------------------------------------------------------------
1 | //
2 | // Pen.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/10.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CoreModel.h"
10 | #import
11 |
12 | @interface Pen : CoreModel
13 |
14 | @property (nonatomic,copy) NSString *color;
15 |
16 | @property (nonatomic,assign) CGFloat price;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/CoreModel/APP/Model/Pen.m:
--------------------------------------------------------------------------------
1 | //
2 | // Pen.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/10.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Pen.h"
10 |
11 | @implementation Pen
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Model/Person.h:
--------------------------------------------------------------------------------
1 | //
2 | // Person.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CoreModel.h"
10 | #import "City.h"
11 | #import "Pen.h"
12 | #import
13 |
14 | @interface Person : CoreModel
15 |
16 | @property (nonatomic,copy) NSString *name;
17 |
18 | @property (nonatomic,assign) NSInteger age;
19 |
20 | @property (nonatomic,assign) CGFloat height;
21 |
22 | @property (nonatomic,strong) NSData *photoData;
23 |
24 | @property (nonatomic,strong) City *city;
25 |
26 | @property (nonatomic,strong) Person *teacher;
27 |
28 | @property (nonatomic,strong) NSArray *tags;
29 |
30 | @property (nonatomic,strong) NSArray *dreams;
31 |
32 | @property (nonatomic,strong) NSArray *pens;
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/CoreModel/APP/Model/Person.m:
--------------------------------------------------------------------------------
1 | //
2 | // Person.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Person.h"
10 |
11 |
12 | @implementation Person
13 |
14 | +(NSDictionary *)statementForNSArrayProperties{
15 | return @{@"tags":NSStringFromClass([NSString class]),@"dreams":NSStringFromClass([NSData class]),@"pens":NSStringFromClass([Pen class])};
16 | }
17 |
18 | +(NSDictionary *)objectClassInArray{
19 | return @{@"tags":NSStringFromClass([NSString class]),@"pens":NSStringFromClass([Pen class])};
20 | }
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test10VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test10VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CommonVC.h"
10 |
11 | @interface Test10VC : CommonVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test10VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test10VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test10VC.h"
10 |
11 | @interface Test10VC ()
12 |
13 | @end
14 |
15 | @implementation Test10VC
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 |
20 | [Person selectWhere:nil groupBy:nil orderBy:nil limit:nil selectResultsBlock:^(NSArray *selectResults) {
21 |
22 | NSString *msg = [NSString stringWithFormat:@"查到%@条记录",@(selectResults.count)];
23 |
24 | CoreSVPSuccess(msg)
25 |
26 | NSLog(@"%@",selectResults);
27 | }];
28 |
29 |
30 |
31 | }
32 |
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test11VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test11VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CommonVC.h"
10 |
11 | @interface Test11VC : CommonVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test11VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test11VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test11VC.h"
10 |
11 | @interface Test11VC ()
12 |
13 | @end
14 |
15 | @implementation Test11VC
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 |
20 |
21 | [Person truncateTable:^(BOOL res) {
22 | [self show:res];
23 | }];
24 |
25 |
26 | }
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test12VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test12VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CommonVC.h"
10 |
11 | @interface Test12VC : CommonVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test12VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test12VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test12VC.h"
10 |
11 | @interface Test12VC ()
12 |
13 | @property (weak, nonatomic) IBOutlet UIImageView *imageV;
14 |
15 | @property (weak, nonatomic) IBOutlet UILabel *label;
16 |
17 | @end
18 |
19 | @implementation Test12VC
20 |
21 | - (void)viewDidLoad {
22 | [super viewDidLoad];
23 |
24 | }
25 |
26 | - (IBAction)saveModelAction:(id)sender {
27 |
28 | Person *charlin = [[Person alloc] init];
29 | charlin.hostID = 1;
30 | charlin.name = @"冯成林";
31 | charlin.age = 28;
32 | charlin.photoData = UIImagePNGRepresentation([UIImage imageNamed:@"1"]);
33 |
34 | [Person save:charlin resBlock:^(BOOL res) {
35 | [self show:res];
36 | }];
37 | }
38 |
39 | - (IBAction)readModelAction:(id)sender {
40 |
41 | __weak typeof(self) weakSelf=self;
42 |
43 | [Person find:1 selectResultBlock:^(Person *selectResult) {
44 |
45 | [weakSelf show:selectResult != nil];
46 |
47 | dispatch_async(dispatch_get_main_queue(), ^{
48 |
49 | weakSelf.imageV.image = [[UIImage alloc] initWithData:selectResult.photoData];
50 |
51 | weakSelf.label.text = [NSString stringWithFormat:@"%@%@",selectResult.name,@(selectResult.age)];
52 | });
53 |
54 | }];
55 | }
56 |
57 |
58 |
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test12VC.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
30 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test13VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test13VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CommonVC.h"
10 |
11 | @interface Test13VC : CommonVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test13VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test13VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test13VC.h"
10 |
11 | @interface Test13VC ()
12 |
13 | @end
14 |
15 | @implementation Test13VC
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 |
20 | City *city = [[City alloc] init];
21 | city.hostID = 1;
22 | city.cityName = @"成都";
23 | city.spell = @"ChengDu";
24 |
25 | Person *p5 = [[Person alloc] init];
26 | p5.hostID=5;
27 | p5.name = @"张三";
28 | p5.city=city;
29 | [Person save:p5 resBlock:^(BOOL res) {
30 |
31 | [self show:res];
32 | }];
33 |
34 | }
35 |
36 |
37 |
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test14VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test14VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CommonVC.h"
10 |
11 | @interface Test14VC : CommonVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test14VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test14VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test14VC.h"
10 |
11 | @interface Test14VC ()
12 |
13 | @end
14 |
15 | @implementation Test14VC
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 |
20 | Person *p = [[Person alloc] init];
21 | p.hostID=6;
22 | p.name = @"冯成林";
23 | p.tags = @[@"工作狂",@"电影迷",@"成都范",@"梦想青年"];
24 |
25 | [Person insert:p resBlock:^(BOOL res) {
26 | [self show:res];
27 | }];
28 |
29 | }
30 |
31 |
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test15VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test15VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CommonVC.h"
10 |
11 | @interface Test15VC : CommonVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test15VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test15VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test15VC.h"
10 |
11 | @interface Test15VC ()
12 |
13 | @property (strong, nonatomic) IBOutletCollection(UIImageView) NSArray *imgVs;
14 |
15 |
16 | @end
17 |
18 | @implementation Test15VC
19 |
20 | - (void)viewDidLoad {
21 | [super viewDidLoad];
22 |
23 |
24 | }
25 |
26 |
27 | - (IBAction)saveAction:(id)sender {
28 |
29 | Person *p = [[Person alloc] init];
30 | p.hostID=7;
31 | p.name = @"大雄";
32 | p.dreams = @[
33 | [self dataWithImageName:@"p1"],
34 | [self dataWithImageName:@"p2"],
35 | [self dataWithImageName:@"p3"],
36 | ];
37 |
38 | [Person save:p resBlock:^(BOOL res) {
39 | [self show:res];
40 | }];
41 |
42 | }
43 |
44 | - (IBAction)readAction:(id)sender {
45 |
46 | [Person find:7 selectResultBlock:^(Person *p) {
47 |
48 |
49 | CoreSVPSuccess(@"读取成功")
50 |
51 | [p.dreams enumerateObjectsUsingBlock:^(NSData *data, NSUInteger idx, BOOL *stop) {
52 |
53 | dispatch_async(dispatch_get_main_queue(), ^{
54 | ((UIImageView *)self.imgVs[idx]).image = [[UIImage alloc] initWithData:data];
55 | });
56 |
57 | }];
58 |
59 |
60 | }];
61 |
62 |
63 | }
64 |
65 |
66 | -(NSData *)dataWithImageName:(NSString *)name{
67 | return UIImagePNGRepresentation([UIImage imageNamed:name]);
68 | }
69 |
70 |
71 |
72 |
73 |
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test15VC.xib:
--------------------------------------------------------------------------------
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 |
29 |
30 |
31 |
45 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test16VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test16VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CommonVC.h"
10 |
11 | @interface Test16VC : CommonVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test16VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test16VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test16VC.h"
10 |
11 | @interface Test16VC ()
12 |
13 | @end
14 |
15 | @implementation Test16VC
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 |
20 | Pen *pen1=[[Pen alloc] init];
21 | pen1.hostID=1;
22 | pen1.color = @"red";
23 | pen1.price = 12.5;
24 | Pen *pen2=[[Pen alloc] init];
25 | pen2.hostID=2;
26 | pen2.color = @"blue";
27 | pen2.price = 9.8;
28 | Person *p = [[Person alloc] init];
29 | p.hostID = 8;
30 | p.name = @"静香";
31 | p.pens=@[pen1,pen2];
32 |
33 |
34 | [Person save:p resBlock:^(BOOL res) {
35 | [self show:res];
36 | }];
37 | }
38 |
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test17VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test17VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 16/4/3.
6 | // Copyright © 2016年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test2VC.h"
10 |
11 | @interface Test17VC : Test2VC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test17VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test17VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 16/4/3.
6 | // Copyright © 2016年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test17VC.h"
10 |
11 | @implementation Test17VC
12 |
13 |
14 |
15 | - (void)viewDidLoad {
16 | [super viewDidLoad];
17 |
18 | Person *person = [[Person alloc] init];
19 | person.name = @"冯成林";
20 | person.age = 28;
21 | person.height = 174.0;
22 | person.hostID = 100;
23 |
24 | __block NSInteger num = 0;
25 |
26 | for (NSUInteger i = 0; i< 100; i++) {
27 |
28 | [Person insert:person resBlock:^(BOOL res) {
29 |
30 | num++;
31 | }];
32 | }
33 |
34 | }
35 |
36 |
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test2VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test2VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CommonVC.h"
11 |
12 | @interface Test2VC : CommonVC
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test2VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test2VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test2VC.h"
10 |
11 |
12 | @interface Test2VC ()
13 |
14 | @end
15 |
16 | @implementation Test2VC
17 |
18 | - (void)viewDidLoad {
19 | [super viewDidLoad];
20 |
21 |
22 | /** 全自动创表 */
23 | Person *person = [[Person alloc] init];
24 |
25 | }
26 |
27 |
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test3VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test3VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CommonVC.h"
10 |
11 | @interface Test3VC : CommonVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test3VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test3VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test3VC.h"
10 |
11 | @interface Test3VC ()
12 |
13 | @end
14 |
15 | @implementation Test3VC
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 |
20 | Person *person = [[Person alloc] init];
21 | person.name = @"冯成林";
22 | person.age = 28;
23 | person.height = 174.0;
24 |
25 | [Person insert:person resBlock:^(BOOL res) {
26 |
27 | [self show:res];
28 | }];
29 |
30 | }
31 |
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test4VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test4VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CommonVC.h"
10 |
11 | @interface Test4VC : CommonVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test4VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test4VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test4VC.h"
10 |
11 | @interface Test4VC ()
12 |
13 | @end
14 |
15 | @implementation Test4VC
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 |
20 | Person *person = [[Person alloc] init];
21 | person.hostID = 12;
22 | person.name = @"冯成林";
23 | person.age = 28;
24 | person.height = 174.0;
25 |
26 | /** Insert */
27 | [Person insert:person resBlock:^(BOOL res) {
28 |
29 | [self show:res];
30 | }];
31 |
32 | }
33 |
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test5VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test5VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CommonVC.h"
10 |
11 | @interface Test5VC : CommonVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test5VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test5VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test5VC.h"
10 |
11 | @interface Test5VC ()
12 |
13 | @end
14 |
15 | @implementation Test5VC
16 |
17 |
18 |
19 | - (void)viewDidLoad {
20 | [super viewDidLoad];
21 |
22 | Person *p1 = [[Person alloc] init];
23 | p1.hostID = 2;
24 | p1.name = @"jack";
25 | p1.age = 25;
26 | p1.height = 180;
27 |
28 | Person *p2 = [[Person alloc] init];
29 | p2.hostID = 3;
30 | p2.name = @"jim";
31 | p2.age = 22;
32 | p2.height = 172;
33 |
34 |
35 | [Person inserts:@[p1,p2] resBlock:^(BOOL res) {
36 | [self show:res];
37 | }];
38 | }
39 |
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test6VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test6VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CommonVC.h"
10 |
11 | @interface Test6VC : CommonVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test6VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test6VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test6VC.h"
10 |
11 | @interface Test6VC ()
12 |
13 | @end
14 |
15 | @implementation Test6VC
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 |
20 |
21 | Person *person = [[Person alloc] init];
22 | person.hostID = 1;
23 | person.name = @"Charlin Feng";
24 | person.age = 28;
25 | person.height = 173.5;
26 |
27 |
28 | [Person update:person resBlock:^(BOOL res) {
29 | [self show:res];
30 | }];
31 |
32 |
33 |
34 | }
35 |
36 |
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test7VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test7VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CommonVC.h"
10 |
11 | @interface Test7VC : CommonVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test7VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test7VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test7VC.h"
10 |
11 | @interface Test7VC ()
12 |
13 | @end
14 |
15 | @implementation Test7VC
16 |
17 | - (void)viewDidLoad {
18 |
19 | [super viewDidLoad];
20 |
21 | Person *p1 = [[Person alloc] init];
22 | p1.hostID = 2;
23 | p1.name = @"杰克";
24 | p1.age = 25;
25 | p1.height = 180;
26 |
27 | Person *p2 = [[Person alloc] init];
28 | p2.hostID = 3;
29 | p2.name = @"吉姆";
30 | p2.age = 22;
31 | p2.height = 172;
32 |
33 |
34 | [Person updateModels:@[p1,p2] resBlock:^(BOOL res) {
35 | [self show:res];
36 | }];
37 |
38 |
39 | }
40 |
41 |
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test8VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test8VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CommonVC.h"
10 |
11 | @interface Test8VC : CommonVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test8VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test8VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test8VC.h"
10 |
11 | @interface Test8VC ()
12 |
13 | @end
14 |
15 | @implementation Test8VC
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 |
20 | Person *p1 = [[Person alloc] init];
21 | p1.hostID = 2;
22 | p1.name = @"杰克先生";
23 | p1.age = 40;
24 | p1.height = 180;
25 |
26 | Person *p2 = [[Person alloc] init];
27 | p2.hostID = 3;
28 | p2.name = @"吉姆先生";
29 | p2.age = 38;
30 | p2.height = 172;
31 |
32 |
33 | [Person saveModels:@[p1,p2] resBlock:^(BOOL res) {
34 | [self show:res];
35 | }];
36 |
37 |
38 |
39 |
40 | }
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test9VC.h:
--------------------------------------------------------------------------------
1 | //
2 | // Test9VC.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CommonVC.h"
10 |
11 | @interface Test9VC : CommonVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/CoreModel/APP/Modules/Test9VC.m:
--------------------------------------------------------------------------------
1 | //
2 | // Test9VC.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/9.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "Test9VC.h"
10 |
11 | @interface Test9VC ()
12 |
13 | @end
14 |
15 | @implementation Test9VC
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 |
20 | [Person deleteWhere:@"age >= 40" resBlock:^(BOOL res) {
21 | [self show:res];
22 | }];
23 |
24 | }
25 |
26 |
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/CoreModel/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 16/4/2.
6 | // Copyright © 2016年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/CoreModel/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 16/4/2.
6 | // Copyright © 2016年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/CoreModel/Assets.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 | }
--------------------------------------------------------------------------------
/CoreModel/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/CoreModel/Assets.xcassets/p1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "p1.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/CoreModel/Assets.xcassets/p1.imageset/p1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/Assets.xcassets/p1.imageset/p1.png
--------------------------------------------------------------------------------
/CoreModel/Assets.xcassets/p2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "p2.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/CoreModel/Assets.xcassets/p2.imageset/p2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/Assets.xcassets/p2.imageset/p2.png
--------------------------------------------------------------------------------
/CoreModel/Assets.xcassets/p3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "p3.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/CoreModel/Assets.xcassets/p3.imageset/p3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharlinFeng/CoreModel/587ec368f997bc24db654cdfe759fe956c358d9d/CoreModel/Assets.xcassets/p3.imageset/p3.png
--------------------------------------------------------------------------------
/CoreModel/Base.lproj/LaunchScreen.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 |
--------------------------------------------------------------------------------
/CoreModel/Base.lproj/Main.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 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/CoreModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreModel.h
3 | // 4s
4 | //
5 | // Created by muxi on 15/3/11.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CoreModelProtocol.h"
11 | #import "CorePageModelProtocol.h"
12 | #import "NSObject+Insert.h"
13 | #import "NSObject+Save.h"
14 | #import "NSObject+Delete.h"
15 | #import "NSObject+Update.h"
16 | #import "NSObject+Select.h"
17 | #import "NSObject+CoreModelCommon.h"
18 |
19 |
20 | @interface CoreModel : NSObject
21 |
22 |
23 | /** 服务器数据的ID:字符串化 */
24 | @property (nonatomic,assign) NSInteger hostID;
25 |
26 |
27 | /** 父级模型名称:此属性用于完成级联添加以及查询,框架将自动处理,请不要手动修改! */
28 | @property (nonatomic,copy,readonly) NSString *pModel;
29 |
30 |
31 | /** 父模型的hostID:此属性用于完成级联添加以及查询,框架将自动处理,请不要手动修改! */
32 | @property (nonatomic,assign,readonly) NSInteger pid;
33 |
34 |
35 |
36 |
37 |
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/CoreModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreModel.m
3 | // 4s
4 | //
5 | // Created by muxi on 15/3/11.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import "CoreModel.h"
10 | #import "NSObject+Create.h"
11 |
12 |
13 | @implementation CoreModel
14 |
15 |
16 | +(void)initialize{
17 |
18 | if([[self modelName] isEqualToString:@"CoreModel"]) return;
19 |
20 | if(![self CoreModel_NeedFMDB]) return;
21 |
22 | //自动创表
23 | [self tableCreate];
24 | }
25 |
26 |
27 | +(NSDictionary *)replacedKeyFromPropertyName{
28 | return @{@"hostID":@"id"};
29 | }
30 |
31 |
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSArray/NSArray+CoreModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSArray+CoreModel.h
3 | // CoreClass
4 | //
5 | // Created by 成林 on 15/9/1.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSArray (CoreModel)
12 |
13 | @property (nonatomic,copy,readonly) NSString *toString;
14 |
15 | @property (nonatomic,strong,readonly) NSArray *descSortedArray;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSArray/NSArray+CoreModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSArray+CoreModel.m
3 | // CoreClass
4 | //
5 | // Created by 成林 on 15/9/1.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import "NSArray+CoreModel.h"
10 | #import "CoreModelConst.h"
11 | #import "CoreModel.h"
12 |
13 | @implementation NSArray (CoreModel)
14 |
15 | -(NSString *)toString{
16 |
17 | __block NSMutableString *strM = [NSMutableString string];
18 |
19 | __block NSInteger length = 0;
20 |
21 | [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
22 |
23 | if([obj isKindOfClass:[NSString class]]){
24 |
25 | if(length == 0) length = 1;
26 |
27 | [strM appendFormat:@"%@,",obj];
28 |
29 | }else if ([obj isKindOfClass:[NSData class]]){
30 |
31 | if(length == 0) length = SymbolString.length;
32 |
33 | [strM appendFormat:@"%@%@",[(NSData *)obj base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength],SymbolString];
34 | }
35 |
36 |
37 |
38 | }];
39 |
40 | return [[strM substringToIndex:strM.length-length] copy];
41 | }
42 |
43 | -(NSArray *)descSortedArray{
44 |
45 | NSArray *sortedArray = [self sortedArrayUsingComparator:^NSComparisonResult(CoreModel *m1, CoreModel *m2) {
46 |
47 | if (m1.hostIDm2.hostID) return NSOrderedAscending;
49 | return NSOrderedSame;
50 | }];
51 |
52 | return sortedArray;
53 | }
54 |
55 |
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSDictionary/NSDictionary+Sqlite.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSDictionary+Sqlite.h
3 | // CoreClass
4 | //
5 | // Created by 冯成林 on 15/5/28.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSDictionary (Sqlite)
12 |
13 | @property (nonatomic,copy,readonly) NSString *sqlWhere;
14 |
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSDictionary/NSDictionary+Sqlite.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSDictionary+Sqlite.m
3 | // CoreClass
4 | //
5 | // Created by 冯成林 on 15/5/28.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import "NSDictionary+Sqlite.h"
10 |
11 | @implementation NSDictionary (Sqlite)
12 |
13 |
14 | /**
15 | * 字典转为sql条件中的where条件字符串
16 | */
17 | -(NSString *)sqlWhere{
18 |
19 | if(![self isKindOfClass:[NSDictionary class]] || self.count == 0) return nil;
20 |
21 | NSMutableString *strM=[NSMutableString string];
22 |
23 | [self enumerateKeysAndObjectsUsingBlock:^(NSString *key,NSString *obj, BOOL *stop) {
24 |
25 | if([key isEqualToString:@"id"]) key=@"mid";
26 |
27 | if([obj isKindOfClass:[NSString class]]){
28 | [strM appendFormat:@"%@='%@' and ",key,obj];
29 | }else{
30 | [strM appendFormat:@"%@=%@ and ",key,obj];
31 | }
32 | }];
33 |
34 | //删除最后的 and
35 | NSString *where= [strM substringToIndex:strM.length-5];
36 |
37 | return where;
38 | }
39 |
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/CoreModel+Cache.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Cache.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/10.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CoreModel.h"
11 | #import "CoreModelType.h"
12 |
13 | @interface CoreModel (Cache)
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/CoreModel+Cache.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Cache.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 15/9/10.
6 | // Copyright (c) 2015年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CoreModel+Cache.h"
10 |
11 | @implementation CoreModel (Cache)
12 |
13 | /** 模型对比时需要忽略的字段 */
14 | +(NSArray *)constrastIgnorFields{
15 | return @[@"pModel",@"pid"];
16 | }
17 |
18 | /** 是否需要本地缓存:此处为CoreModel本身 */
19 | +(BOOL)CoreModel_NeedFMDB{return YES;}
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/NSObject+CoreModelCommon.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+CoreModelCommon.h
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "NSString+Stackoverflow.h"
11 | #import "NSOperationQueue+Queue.h"
12 | #import "CoreProperty.h"
13 |
14 |
15 | @interface NSObject (CoreModelCommon)
16 |
17 |
18 | +(NSString *)fieldSql:(CoreProperty *)ivar;
19 |
20 | +(BOOL)skipField:(CoreProperty *)ivar;
21 |
22 | + (NSArray *)ignoredPropertyNamesForSqlTransform;
23 |
24 | +(NSString *)deleteLastChar:(NSString *)str;
25 |
26 | +(BOOL)checkTableExists;
27 |
28 | +(void)checkUsage:(id)model;
29 |
30 | +(NSString *)sqliteType:(NSString *)fieldType;
31 |
32 | +(NSString *)modelName;
33 |
34 | +(BOOL)isBasicTypeInNSArray:(CoreProperty *)property;
35 |
36 | /** 模型对比时需要忽略的字段 */
37 | +(NSArray *)constrastIgnorFields;
38 |
39 | /** 当模型中含有NSArray数组成员属性时,需要明确指明NSArray内部数据类型key:属性名,value: 数据类型NSString版 */
40 | +(NSDictionary *)statementForNSArrayProperties;
41 |
42 | /** 封装 */
43 | +(void)enumNSObjectProperties:(void(^)(CoreProperty *property, BOOL *stop))properties;
44 |
45 |
46 |
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/NSObject+CoreModelCommon.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+CoreModelCommon.m
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import "NSObject+CoreModelCommon.h"
10 | #import "CoreModelConst.h"
11 | #import "CoreFMDB.h"
12 | #import "NSObject+Runtime.h"
13 |
14 |
15 | @implementation NSObject (CoreModelCommon)
16 |
17 |
18 | +(NSString *)fieldSql:(CoreProperty *)ivar{
19 |
20 | NSString *fieldName = ivar.name;
21 |
22 | NSString *fieldType = ivar.code;
23 |
24 | NSString *sqliteTye=[self sqliteType:fieldType];
25 |
26 | if([ivar.typeString isEqualToString:CoreNSArray]){
27 |
28 | if([self isBasicTypeInNSArray:[self statementForNSArrayProperties][ivar.name]]){
29 | sqliteTye = TEXT_TYPE;
30 | }
31 | }
32 |
33 | if([sqliteTye isEqualToString:EmptyString]){
34 |
35 | return EmptyString;
36 | }
37 |
38 | NSString *fieldSql=[NSString stringWithFormat:@"%@ %@,",fieldName,sqliteTye];
39 |
40 | return fieldSql;
41 | }
42 |
43 |
44 | +(BOOL)skipField:(CoreProperty *)ivar{
45 |
46 | NSArray *ignoredPropertyNames = nil;
47 | if ([[self class] respondsToSelector:@selector(ignoredPropertyNamesForSqlTransform)]) {
48 | ignoredPropertyNames = [[self class] ignoredPropertyNamesForSqlTransform];
49 | }
50 | BOOL skip=ignoredPropertyNames!=nil && [ignoredPropertyNames containsObject:ivar.name];
51 |
52 | return skip;
53 | }
54 |
55 |
56 | + (NSArray *)ignoredPropertyNamesForSqlTransform{return @[@"hash",@"superclass",@"description",@"debugDescription"];}
57 |
58 |
59 | +(NSString *)sqliteType:(NSString *)fieldType{
60 |
61 | NSDictionary *map=@{
62 | INTEGER_TYPE:@[CoreNSInteger,CoreNSUInteger,CoreEnum_int,CoreBOOL],
63 | TEXT_TYPE:@[CoreNSString],
64 | REAL_TYPE:@[CoreCGFloat],
65 | BLOB_TYPE:@[CoreNSData]
66 | };
67 |
68 | __block NSString *sqliteType=EmptyString;
69 |
70 | [map enumerateKeysAndObjectsUsingBlock:^(NSString *blockSqliteType, NSArray *blockFieldTypes, BOOL *stop) {
71 |
72 | [blockFieldTypes enumerateObjectsUsingBlock:^(NSString *typeStringConst, NSUInteger idx, BOOL *stop) {
73 |
74 | NSRange range = [typeStringConst rangeOfString:fieldType];
75 |
76 | if(range.length>0){
77 | sqliteType = blockSqliteType;
78 | }
79 | }];
80 | }];
81 |
82 | return sqliteType;
83 | }
84 |
85 |
86 | +(BOOL)checkTableExists{
87 |
88 | NSString *alias=@"tableCount";
89 |
90 | NSString *sql=[NSString stringWithFormat:@"SELECT COUNT(*) %@ FROM sqlite_master WHERE type='table' AND name='%@';",alias,[self modelName]];
91 |
92 | __block BOOL res=NO;
93 |
94 | [CoreFMDB executeQuery:sql queryResBlock:^(FMResultSet *set) {
95 |
96 | while ([set next]) {
97 |
98 | NSUInteger count = [[set stringForColumn:alias] integerValue];
99 |
100 | res=count==1;
101 | }
102 | }];
103 |
104 | return res;
105 | }
106 |
107 |
108 | +(void)checkUsage:(id)model{
109 | NSAssert([NSStringFromClass(self) isEqualToString:NSStringFromClass([model class])], @"错误:请使用模型%@所属类(而不是%@类)的静态方法来执行您的操作",NSStringFromClass([model class]),NSStringFromClass(self));
110 | }
111 |
112 |
113 | +(NSString *)deleteLastChar:(NSString *)str{
114 | if(str.length == 0) return @"";
115 | return [str substringToIndex:str.length - 1];
116 | }
117 |
118 |
119 | +(BOOL)isBasicTypeInNSArray:(NSString *)statement{
120 |
121 | return [NSArrayNorlMalTypes containsObject:statement];
122 | }
123 |
124 |
125 |
126 | +(NSString *)modelName{
127 | return [NSStringFromClass(self) componentsSeparatedByString:@"."].lastObject;
128 | }
129 |
130 |
131 | +(NSDictionary *)statementForNSArrayProperties{return nil;}
132 |
133 |
134 | //-(NSString *)description{
135 | //
136 | // NSMutableString *strM = [NSMutableString stringWithString:[NSString stringWithFormat:@"[%@]<%p>: \r",NSStringFromClass([self class]), self]];
137 | //
138 | // [[self class] enumNSObjectProperties:^(CoreProperty *property, BOOL *stop) {
139 | // BOOL skip=[[self class] skipField:property];
140 | //
141 | // if(!skip){
142 | // [strM appendFormat:@" %@: %@, \r",property.name, [self valueForKeyPath:property.name]];
143 | // }
144 | // }];
145 | //
146 | // return [strM copy];
147 | //}
148 |
149 |
150 | /** 封装 */
151 |
152 | +(void)enumNSObjectProperties:(void(^)(CoreProperty *property, BOOL *stop))properties{
153 | [self enumeratePropertiesUsingBlock:^(CoreProperty *p) {
154 |
155 | properties(p,NO);
156 |
157 | }];
158 | }
159 |
160 | @end
161 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/NSObject+Create.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Create.h
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | // 创表
8 |
9 | #import
10 |
11 | @interface NSObject (Create)
12 |
13 |
14 | +(void)tableCreate;
15 |
16 |
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/NSObject+Create.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Create.m
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import "NSObject+Create.h"
10 | #import "NSObject+CoreModelCommon.h"
11 | #import "CoreModelConst.h"
12 | #import "CoreFMDB.h"
13 |
14 |
15 | @implementation NSObject (Create)
16 |
17 |
18 | +(void)tableCreate{
19 |
20 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
21 | [self tableCreate_thread];
22 | });
23 | }
24 |
25 |
26 |
27 | +(void)tableCreate_thread{
28 |
29 | NSString *modelName = [self modelName];
30 |
31 | if([modelName isEqualToString:@"CoreModel"]) return;
32 |
33 | NSMutableString *sql=[NSMutableString string];
34 |
35 | [sql appendFormat:@"CREATE TABLE IF NOT EXISTS %@ (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL DEFAULT 0,",modelName];
36 |
37 | NSMutableArray *ivarsM=[NSMutableArray array];
38 |
39 | [self enumNSObjectProperties:^(CoreProperty *property, BOOL *stop) {
40 |
41 | NSString *sql_field = [self fieldSql:property];
42 |
43 | if([property.typeString isEqualToString:CoreNSArray]){
44 |
45 | NSDictionary *dict = [self statementForNSArrayProperties];
46 |
47 | NSString *errorMsg = [NSString stringWithFormat:@"错误:请在%@类中为您的NSArray类型的%@属性增加说明信息,实现statementForNSArrayProperties静态方法!",[self modelName],property.name];
48 |
49 | NSAssert(dict[property.name] != nil, errorMsg);
50 | NSAssert(![dict[property.name] isEqualToString:@"NSInteger"], @"错误:OC数组内不可能存放NSInteger");
51 | NSAssert(![dict[property.name] isEqualToString:@"NSUInteger"], @"错误:OC数组内不可能存放NSUInteger");
52 | NSAssert(![dict[property.name] isEqualToString:@"BOOL"], @"错误:OC数组内不可能存放BOOL");
53 | NSAssert(![dict[property.name] isEqualToString:@"CGFloat"], @"错误:OC数组内不可能存放CGFloat");
54 | NSAssert(![dict[property.name] isEqualToString:@"double"], @"错误:OC数组内不可能存放double");
55 |
56 |
57 | if([self isBasicTypeInNSArray:[self statementForNSArrayProperties][property.name]]){
58 | sql_field = [NSString stringWithFormat:@"%@ %@ ,",property.name,TEXT_TYPE];
59 | }
60 | }
61 |
62 | BOOL skip=[self skipField:property];
63 |
64 | if(![sql_field isEqualToString:EmptyString] && !skip){
65 |
66 | [sql appendString:sql_field];
67 |
68 | [ivarsM addObject:property];
69 | }
70 | }];
71 |
72 | NSString *subSql = [self deleteLastChar:sql];
73 |
74 | NSString *sql_Create = [NSString stringWithFormat:@"%@);",subSql];
75 |
76 | BOOL createRes = [CoreFMDB executeUpdate:sql_Create];
77 |
78 | if(!createRes){
79 | if(CoreModelDeBug) NSLog(@"%@ 创表失败",modelName);
80 | return;
81 | }
82 | if(CoreModelDeBug) NSLog(@"表创建完毕%@",[NSThread currentThread]);
83 |
84 | [self fieldsCheck:modelName ivars:ivarsM];
85 |
86 | ThreadShow(创表)
87 | }
88 |
89 | +(void)fieldsCheck:(NSString *)table ivars:(NSArray *)ivars{
90 |
91 | ThreadShow(字段检查)
92 |
93 | NSArray *columns=[CoreFMDB executeQueryColumnsInTable:table];
94 |
95 | NSMutableArray *columnsM=[NSMutableArray arrayWithArray:columns];
96 | [columnsM removeObject:@"id"];
97 | if(CoreModelDeBug) NSLog(@"字段也检查完毕%@",[NSThread currentThread]);
98 |
99 | if(columnsM.count>=ivars.count) return;
100 |
101 | for (CoreProperty *ivar in ivars) {
102 |
103 | if([columnsM containsObject:ivar.name]) continue;
104 |
105 | NSMutableString *sql_addM=[NSMutableString stringWithFormat:@"ALTER TABLE '%@' ADD COLUMN %@",table,[self fieldSql:ivar]];
106 |
107 | NSString *sql_add=[self deleteLastChar:sql_addM];
108 |
109 | NSString *sql=[NSString stringWithFormat:@"%@;",sql_add];
110 |
111 | BOOL addRes = [CoreFMDB executeUpdate:sql];
112 |
113 | if(!addRes){
114 | if(CoreModelDeBug) NSLog(@"模型%@字段新增失败!",table);
115 | return;
116 | }
117 |
118 | if(CoreModelDeBug) NSLog(@"注意:模型 %@ 有新增加的字段 %@,已经实时添加到数据库中!",table,ivar.name);
119 | }
120 | }
121 |
122 |
123 | @end
124 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/NSObject+Delete.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Delete.h
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | // 删除数据
8 | // 请在主线程中执行
9 |
10 | #import
11 |
12 | @interface NSObject (Delete)
13 |
14 |
15 | +(void)deleteWhere:(NSString *)where resBlock:(void(^)(BOOL res))resBlock;
16 |
17 |
18 | +(void)delete:(NSUInteger)hostID resBlock:(void(^)(BOOL res))resBlock;
19 |
20 |
21 | +(void)truncateTable:(void(^)(BOOL res))resBlock;
22 |
23 |
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/NSObject+Delete.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Delete.m
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import "NSObject+Delete.h"
10 | #import "NSObject+CoreModelCommon.h"
11 | #import "CoreFMDB.h"
12 | #import "NSObject+Select.h"
13 | #import "CoreModel.h"
14 | #import "CoreModelConst.h"
15 |
16 | @implementation NSObject (Delete)
17 |
18 |
19 | +(void)deleteWhere:(NSString *)where resBlock:(void(^)(BOOL res))resBlock{
20 | [self deleteWhere:where resBlock:resBlock needThread:YES];
21 | }
22 |
23 |
24 | +(void)deleteWhere:(NSString *)where resBlock:(void(^)(BOOL res))resBlock needThread:(BOOL)needThread{
25 |
26 | if(needThread){
27 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
28 | [self deleteWhereAction:where resBlock:resBlock];
29 | });
30 | }else{
31 | [self deleteWhereAction:where resBlock:resBlock];
32 | }
33 | }
34 |
35 | +(void)deleteWhereAction:(NSString *)where resBlock:(void(^)(BOOL res))resBlock{
36 |
37 | if(![self checkTableExists]){
38 |
39 | if(CoreModelDeBug) NSLog(@"错误:你操作的模型%@在数据库中没有对应的数据表!%@",[self modelName],AutoMsg);
40 | if(resBlock != nil) resBlock(NO);
41 | return;
42 | }
43 |
44 | NSString *sql=[NSString stringWithFormat:@"DELETE FROM %@",[self modelName]];
45 |
46 | if(where != nil) sql = [NSString stringWithFormat:@"%@ WHERE %@",sql,where];
47 |
48 | sql = [NSString stringWithFormat:@"%@;",sql];
49 |
50 | [self selectWhere:where groupBy:nil orderBy:nil limit:nil selectResultsBlock:^(NSArray *deleteModels) {
51 | if(deleteModels==nil || deleteModels.count==0){
52 | if (resBlock != nil) resBlock(YES);return;
53 | }
54 |
55 | for (CoreModel *baseModle in deleteModels) {
56 |
57 | [baseModle.class enumNSObjectProperties:^(CoreProperty *property, BOOL *stop) {
58 |
59 | BOOL skip=[self skipField:property];
60 |
61 | if(!skip){
62 |
63 | NSString *sqliteTye=[self sqliteType:property.code];
64 |
65 | if([property.typeString isEqualToString:CoreNSArray]){
66 |
67 | if([self isBasicTypeInNSArray:[self statementForNSArrayProperties][property.name]]){
68 | sqliteTye = TEXT_TYPE;
69 | }
70 | }
71 |
72 |
73 | if([sqliteTye isEqualToString:EmptyString]){
74 |
75 | if([property.typeString isEqualToString:CoreNSArray]){
76 |
77 | NSArray *CoreModels = (NSArray *)[baseModle valueForKeyPath:property.name];
78 |
79 | [CoreModels enumerateObjectsUsingBlock:^(CoreModel *sub, NSUInteger idx, BOOL *stop) {
80 |
81 | NSString *where=[NSString stringWithFormat:@"pModel='%@' AND pid=%@",NSStringFromClass(sub.class),@(sub.hostID)];
82 |
83 | [[sub class] deleteWhere:where resBlock:resBlock];
84 | }];
85 |
86 | }else{
87 |
88 | Class ModelClass=NSClassFromString(property.code);
89 |
90 | NSString *where=[NSString stringWithFormat:@"pModel='%@' AND pid=%@",NSStringFromClass(baseModle.class),@(baseModle.hostID)];
91 |
92 | [ModelClass deleteWhere:where resBlock:resBlock];
93 | }
94 |
95 | }
96 | }
97 | }];
98 | }
99 |
100 | BOOL res = [CoreFMDB executeUpdate:sql];
101 |
102 | if(CoreModelDeBug) {if(!res) NSLog(@"错误:执行删除失败,sql语句为:%@",sql);};
103 |
104 | ThreadShow(删除数据)
105 |
106 | TriggerBlock(resBlock, res)
107 | }];
108 | }
109 |
110 |
111 |
112 | +(void)delete:(NSUInteger)hostID resBlock:(void(^)(BOOL res))resBlock{
113 |
114 | NSString *where=[NSString stringWithFormat:@"hostID=%@",@(hostID)];
115 |
116 | [self deleteWhere:where resBlock:resBlock needThread:YES];
117 | }
118 |
119 | +(void)truncateTable:(void(^)(BOOL res))resBlock{
120 |
121 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
122 | if(![self checkTableExists]){
123 |
124 | if(CoreModelDeBug) NSLog(@"错误:你操作的模型%@在数据库中没有对应的数据表!%@",[self modelName],AutoMsg);
125 | if(resBlock != nil) resBlock(NO);
126 | return;
127 | }
128 |
129 | BOOL res = [CoreFMDB truncateTable:[self modelName]];
130 |
131 | TriggerBlock(resBlock, res)
132 | });
133 |
134 | }
135 |
136 | @end
137 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/NSObject+Insert.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Insert.h
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 |
8 |
9 | #import
10 |
11 | @interface NSObject (Insert)
12 |
13 |
14 | +(void)insert:(id)model resBlock:(void(^)(BOOL res))resBlock;
15 |
16 |
17 | +(void)inserts:(NSArray *)models resBlock:(void(^)(BOOL res))resBlock;
18 |
19 |
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/NSObject+Insert.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Insert.m
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import "NSObject+Insert.h"
10 | #import "CoreModel.h"
11 | #import "NSObject+CoreModelCommon.h"
12 | #import "CoreModelConst.h"
13 | #import "CoreFMDB.h"
14 | #import "NSObject+Select.h"
15 | #import "NSArray+CoreModel.h"
16 | #import "CoreProperty.h"
17 |
18 | @implementation NSObject (Insert)
19 |
20 |
21 |
22 |
23 | +(void)insertAction:(id)model resBlock:(void(^)(BOOL res))resBlock {
24 |
25 | [self checkUsage:model];
26 |
27 | if(![self checkTableExists]){
28 |
29 | if(CoreModelDeBug) NSLog(@"注意:单条数据插入时,你操作的模型%@在数据库中没有对应的数据表!%@",[self modelName],AutoMsg);
30 |
31 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(AutoTry * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
32 | [self insertAction:model resBlock:resBlock];
33 | });
34 |
35 | return;
36 | }
37 |
38 | CoreModel *coreModel=(CoreModel *)model;
39 |
40 | if (coreModel.hostID == 0){
41 |
42 | NSLog(@"错误:数据插入失败,无hostID的数据插入都是耍流氓,你必须设置模型的模型hostID!框架自动生成合理的hostID,不过模型含有服务器的hostID将更可可靠,否则或能出现大量重复数据。");
43 |
44 | [self selectWhere:nil groupBy:nil orderBy:@"hostID desc" limit:@"0,1" selectResultsBlock:^(NSArray *selectResults) {
45 |
46 | if (selectResults.count == 0) {
47 |
48 | coreModel.hostID = 1;
49 |
50 | }else {
51 |
52 | CoreModel *lastCoreModel = (CoreModel *)selectResults.lastObject;
53 |
54 | coreModel.hostID = lastCoreModel.hostID + 1;
55 | }
56 |
57 | [self insertAction_Real:model resBlock:resBlock];
58 | }];
59 |
60 | }else{
61 |
62 | [self insertAction_Real:model resBlock:resBlock];
63 | }
64 | }
65 |
66 | +(void)insertAction_Real:(id)model resBlock:(void(^)(BOOL res))resBlock {
67 |
68 | CoreModel *coreModel=(CoreModel *)model;
69 |
70 | if(CoreModelDeBug) NSLog(@"数据插入开始%@",[NSThread currentThread]);
71 |
72 | [self find:coreModel.hostID selectResultBlock:^(id dbModel) {
73 |
74 | if(dbModel!=nil){
75 |
76 | if(CoreModelDeBug) NSLog(@"错误:%@表中hostID=%@的数据记录已经存在!",[self modelName],@(coreModel.hostID));
77 | [self deleteModel:model];
78 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
79 | [self insertAction_Real:model resBlock:resBlock];
80 | });
81 | if(resBlock != nil) resBlock(NO);return;
82 | }
83 |
84 | NSMutableString *fields=[NSMutableString string];
85 | NSMutableString *values=[NSMutableString string];
86 |
87 | [self enumNSObjectProperties:^(CoreProperty *property, BOOL *stop) {
88 |
89 | BOOL skip=[self skipField:property];
90 |
91 | if(!skip){
92 |
93 | NSString *sqliteTye=[self sqliteType:property.code];
94 |
95 | id value =[model valueForKeyPath:property.name];
96 |
97 | if([property.typeString isEqualToString:CoreNSArray]){
98 |
99 | if([self isBasicTypeInNSArray:[self statementForNSArrayProperties][property.name]]){
100 | sqliteTye = TEXT_TYPE;
101 | }
102 | }
103 |
104 | if(![sqliteTye isEqualToString:EmptyString]){
105 |
106 | [fields appendFormat:@"%@,",property.name];
107 |
108 | if([property.typeString isEqualToString:CoreNSString]){
109 |
110 | if(value == nil) value=@"";
111 |
112 | value=[NSString stringWithFormat:@"'%@'",value];
113 |
114 | }else if ([property.typeString isEqualToString:CoreNSData]){
115 |
116 | if(value != nil) {
117 |
118 | value =[NSString stringWithFormat:@"'%@'",[(NSData *)value base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]];
119 | }else{
120 | value = @"''";
121 | }
122 | }
123 |
124 | if([property.typeString isEqualToString:CoreNSArray]){
125 |
126 |
127 | if([self isBasicTypeInNSArray:[self statementForNSArrayProperties][property.name]]){
128 |
129 | NSString *valueStr = nil;
130 |
131 | if(value == nil){
132 | valueStr = @"";
133 | }else{
134 | valueStr = ((NSArray *)value).toString;
135 | }
136 |
137 | value = [NSString stringWithFormat:@"'%@'",valueStr];
138 | }
139 | }
140 |
141 | if(value != nil) {
142 | [values appendFormat:@"%@,",value];
143 | }
144 |
145 | }else{
146 |
147 | if(property.name!=nil && value!=nil){
148 |
149 |
150 | if(![property.typeString isEqualToString:CoreNSArray]){
151 |
152 | CoreModel *childModel=(CoreModel *)value;
153 |
154 | [childModel setValue:[self modelName] forKey:@"pModel"];
155 |
156 | [childModel setValue:@(coreModel.hostID) forKey:@"pid"];
157 |
158 | [NSClassFromString(property.code) insert:value resBlock:resBlock];
159 |
160 | }else{
161 |
162 | if(![self isBasicTypeInNSArray:[self statementForNSArrayProperties][property.name]]){
163 |
164 | NSArray *modelsArray = (NSArray *)value;
165 | [modelsArray enumerateObjectsUsingBlock:^(CoreModel *i, NSUInteger idx, BOOL *stop) {
166 | [i setValue:NSStringFromClass([self class]) forKeyPath:@"pModel"];
167 | [i setValue:@(coreModel.hostID) forKeyPath:@"pid"];
168 | }];
169 |
170 | Class Cls = NSClassFromString([self statementForNSArrayProperties][property.name]);
171 |
172 | [Cls inserts:modelsArray resBlock:resBlock];
173 |
174 | }
175 | }
176 |
177 | }
178 | }
179 | }
180 | }];
181 |
182 | NSString *fields_sub=[self deleteLastChar:fields];
183 | NSString *values_sub=[self deleteLastChar:values];
184 |
185 | NSString *sql=[NSString stringWithFormat:@"INSERT INTO %@ (%@) VALUES (%@);",[self modelName],fields_sub,values_sub];
186 |
187 | BOOL insertRes = [CoreFMDB executeUpdate:sql];
188 |
189 | if(CoreModelDeBug) {if(!insertRes) NSLog(@"错误:添加对象失败%@",coreModel);};
190 | if(CoreModelDeBug) NSLog(@"数据插入结束%@",[NSThread currentThread]);
191 | TriggerBlock(resBlock, insertRes)
192 | }];
193 | }
194 |
195 | +(void)deleteModel:(id)model{
196 |
197 | NSString *sql = [NSString stringWithFormat:@"DELETE FROM %@ WHERE hostID = %@",[self modelName],@([model hostID])];
198 |
199 | [CoreFMDB executeUpdate:sql];
200 | }
201 |
202 |
203 | +(void)insert:(id)model resBlock:(void(^)(BOOL res))resBlock newThread:(BOOL)newThread{
204 |
205 | if (newThread){
206 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
207 | [self insertAction:model resBlock:resBlock];
208 | });
209 | }else{
210 | [self insertAction:model resBlock:resBlock];
211 | }
212 | }
213 |
214 | +(void)insert:(id)model resBlock:(void(^)(BOOL res))resBlock{
215 | [self insert:model resBlock:resBlock newThread:YES];
216 | }
217 |
218 |
219 | +(void)inserts:(NSArray *)models resBlock:(void(^)(BOOL res))resBlock{
220 |
221 | if(![self checkTableExists]){
222 |
223 | if(CoreModelDeBug)NSLog(@"注意:批量数据插入时,你操作的模型%@在数据库中没有对应的数据表!%@",[self modelName],AutoMsg);
224 |
225 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(AutoTry * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
226 | [self inserts:models resBlock:resBlock];
227 | });
228 |
229 | return;
230 | }
231 |
232 | if(CoreModelDeBug)NSLog(@"表创建成功,开始批量数据插入!");
233 |
234 | [self insertsActon:models resBlock:resBlock];
235 |
236 | }
237 |
238 | +(void)insertsActon:(NSArray *)models resBlock:(void(^)(BOOL res))resBlock{
239 |
240 | if(models == nil || models.count == 0){resBlock(NO);return;}
241 |
242 | if(![self checkTableExists]){
243 |
244 | if(CoreModelDeBug) NSLog(@"注意:单条数据插入时,你操作的模型%@在数据库中没有对应的数据表!%@",[self modelName],AutoMsg);
245 |
246 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(AutoTry * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
247 | [self insertsActon:models resBlock:resBlock];
248 | });
249 |
250 | return;
251 | }
252 |
253 | NSOperationQueue *queue = [NSOperationQueue queue];
254 |
255 | if(CoreModelDeBug)NSLog(@"批量插入开始%@",[NSThread currentThread]);
256 |
257 | for (CoreModel *CoreModel in models) {
258 |
259 | NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
260 | [self insert:CoreModel resBlock:resBlock newThread:NO];ThreadShow(批量插入操作)
261 | }];
262 |
263 | [queue addOperation:operation];
264 | }
265 | }
266 |
267 | @end
268 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/NSObject+Save.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Save.h
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | // 保存数据,如果数据不存在,则执行添加操作;如果数据已经存在,则执行更新操作,总之数据一定会记录到数据库中并成为最新的数据记录。
8 |
9 |
10 | #import
11 |
12 | @interface NSObject (Save)
13 |
14 |
15 |
16 |
17 | +(void)save:(id)model resBlock:(void(^)(BOOL res))resBlock;
18 |
19 |
20 |
21 | +(void)saveModels:(NSArray *)models resBlock:(void(^)(BOOL res))resBlock;
22 |
23 |
24 | +(void)saveDirect:(id)obj resBlock:(void(^)(BOOL res))resBlock;
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/NSObject+Save.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Save.m
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import "NSObject+Save.h"
10 | #import "CoreModel.h"
11 | #import "NSObject+Select.h"
12 | #import "NSObject+CoreModelCommon.h"
13 | #import "NSObject+Insert.h"
14 | #import "NSObject+Update.h"
15 | #import "CoreModelConst.h"
16 |
17 | @implementation NSObject (Save)
18 |
19 | +(void)save:(id)model resBlock:(void(^)(BOOL res))resBlock{
20 | [self save:model resBlock:resBlock needThread:YES];
21 | }
22 |
23 | +(void)save:(id)model resBlock:(void(^)(BOOL res))resBlock needThread:(BOOL)needThread{
24 | if (needThread) {
25 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
26 | [self saveAction:model resBlock:resBlock];
27 | });
28 | }else{
29 | [self saveAction:model resBlock:resBlock];
30 | }
31 | }
32 |
33 | +(void)saveAction:(id)model resBlock:(void(^)(BOOL res))resBlock{
34 |
35 | [self checkUsage:model];
36 |
37 | if(![self checkTableExists]){
38 | if(CoreModelDeBug) NSLog(@"注意:你操作的模型%@在数据库中没有对应的数据表,%@",[self modelName],AutoMsg);
39 |
40 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(AutoTry * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
41 | [self saveAction:model resBlock:resBlock];
42 | });
43 |
44 | return;
45 | }
46 |
47 | if(![model isKindOfClass:[self class]]){
48 | if(CoreModelDeBug) NSLog(@"错误:插入数据请使用%@模型类对象,您使用的是%@类型",[self modelName],[model class]);
49 | resBlock(NO);return;
50 | }
51 |
52 | CoreModel *coreModel = (CoreModel *)model;
53 |
54 | [self find:coreModel.hostID selectResultBlock:^(id selectResult) {
55 |
56 | if(selectResult==nil){
57 | if(CoreModelDeBug)NSLog(@"现在是新增");
58 | [self insert:coreModel resBlock:resBlock];
59 |
60 | }else{
61 | if(CoreModelDeBug)NSLog(@"现在是更新");
62 | [self update:coreModel resBlock:resBlock];
63 | }
64 | }];
65 | }
66 |
67 |
68 |
69 | +(void)saveModels:(NSArray *)models resBlock:(void(^)(BOOL res))resBlock{
70 |
71 | if(![self checkTableExists]){
72 |
73 | if(CoreModelDeBug) NSLog(@"注意:单条数据保存时,你操作的模型%@在数据库中没有对应的数据表!%@",[self modelName],AutoMsg);
74 |
75 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(AutoTry * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
76 | [self saveModels:models resBlock:resBlock];
77 | });
78 |
79 | return;
80 | }
81 |
82 |
83 | if(models==nil || models.count==0) {if (resBlock !=nil) resBlock(NO);return;};
84 |
85 | NSOperationQueue *queue = [NSOperationQueue queue];
86 |
87 | [models enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
88 |
89 | NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
90 | [self save:obj resBlock:resBlock needThread:NO];
91 | ThreadShow("批量保存")
92 | }];
93 | [queue addOperation:op];
94 | }];
95 | }
96 |
97 |
98 |
99 | +(void)saveDirect:(id)obj resBlock:(void(^)(BOOL res))resBlock{
100 |
101 | return [obj isKindOfClass:[NSArray class]]?[self saveModels:obj resBlock:resBlock]:[self save:obj resBlock:resBlock];
102 | }
103 |
104 |
105 | @end
106 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/NSObject+Select.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Select.h
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | // 查询数据
8 |
9 | #import
10 |
11 | @interface NSObject (Select)
12 |
13 |
14 |
15 | +(void)selectWhere:(NSString *)where groupBy:(NSString *)groupBy orderBy:(NSString *)orderBy limit:(NSString *)limit selectResultsBlock:(void(^)(NSArray *selectResults))selectResultsBlock;
16 |
17 |
18 | +(void)find:(NSUInteger)hostID selectResultBlock:(void(^)(id selectResult))selectResultBlock;
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/NSObject+Select.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Select.m
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import "NSObject+Select.h"
10 | #import "CoreFMDB.h"
11 | #import "CoreModel.h"
12 | #import "NSObject+CoreModelCommon.h"
13 | #import "CoreModelConst.h"
14 | #import "NSString+Stackoverflow.h"
15 |
16 | @implementation NSObject (Select)
17 |
18 |
19 | +(void)selectWhere:(NSString *)where groupBy:(NSString *)groupBy orderBy:(NSString *)orderBy limit:(NSString *)limit selectResultsBlock:(void(^)(NSArray *selectResults))selectResultsBlock{
20 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
21 | [self selectWhereAction:where groupBy:groupBy orderBy:orderBy limit:limit selectResultsBlock:selectResultsBlock];
22 | });
23 | }
24 |
25 | +(void)selectWhereAction:(NSString *)where groupBy:(NSString *)groupBy orderBy:(NSString *)orderBy limit:(NSString *)limit selectResultsBlock:(void(^)(NSArray *selectResults))selectResultsBlock{
26 |
27 |
28 | if(![self checkTableExists]){
29 | if(CoreModelDeBug) NSLog(@"错误:你操作的模型%@在数据库中没有对应的数据表!",[self modelName]);
30 | if(selectResultsBlock != nil) selectResultsBlock(nil);return;
31 | }
32 |
33 | if(CoreModelDeBug) NSLog(@"查询开始:%@",[NSThread currentThread]);
34 |
35 | NSMutableString *sqlM=[NSMutableString stringWithFormat:@"SELECT * FROM %@",[self modelName]];
36 |
37 | if(where != nil) [sqlM appendFormat:@" WHERE %@",where];
38 |
39 | if(groupBy != nil){[sqlM appendFormat:@" GROUP BY hostID,%@",groupBy];}else{[sqlM appendString:@" GROUP BY hostID"];};
40 |
41 | if(orderBy != nil) [sqlM appendFormat:@" ORDER BY %@",orderBy];
42 |
43 | if(limit != nil) [sqlM appendFormat:@" LIMIT %@",limit];
44 |
45 | NSString *sql=[NSString stringWithFormat:@"%@;",sqlM];
46 |
47 | NSMutableArray *resultsM=[NSMutableArray array];
48 |
49 | NSMutableArray *fieldsArrayM=[NSMutableArray array];
50 |
51 | [CoreFMDB executeQuery:sql queryResBlock:^(FMResultSet *set) {
52 |
53 | while ([set next]) {
54 |
55 | CoreModel *model=[[self alloc] init];
56 |
57 | [self enumNSObjectProperties:^(CoreProperty *property, BOOL *stop) {
58 |
59 | BOOL skip=[self skipField:property];
60 |
61 | if(!skip){
62 |
63 | NSString *code = property.code;
64 |
65 | NSString *sqliteTye=[self sqliteType:code];
66 |
67 | if([property.typeString isEqualToString:CoreNSArray]){
68 |
69 | if([self isBasicTypeInNSArray:[self statementForNSArrayProperties][property.name]]){
70 | sqliteTye = TEXT_TYPE;
71 | }
72 | }
73 |
74 | if(![sqliteTye isEqualToString:EmptyString]){
75 |
76 | NSString *propertyName = property.name;
77 | NSString *value=[set stringForColumn:propertyName];
78 |
79 | if([CoreBOOL rangeOfString:code].length>0){
80 |
81 | NSNumber *boolValue = @(value.integerValue);
82 |
83 | [model setValue:boolValue forKey:propertyName];
84 |
85 | }else{
86 |
87 | if([code isEqualToString:CoreNSData]){
88 | value = [[NSData alloc] initWithBase64EncodedString:value options:NSDataBase64DecodingIgnoreUnknownCharacters];
89 | }
90 |
91 | [model setValue:value forKey:propertyName];
92 | }
93 |
94 |
95 | if([property.typeString isEqualToString:CoreNSArray]){
96 |
97 | if([self isBasicTypeInNSArray:[self statementForNSArrayProperties][property.name]]){
98 |
99 |
100 | NSArray *normalArr = [value toArray:[[self statementForNSArrayProperties][property.name] isEqualToString:CoreNSString]];
101 |
102 | [model setValue:normalArr forKey:propertyName];
103 | }
104 | }
105 |
106 | }else{
107 | if(![fieldsArrayM containsObject:property]) [fieldsArrayM addObject:property];
108 | }
109 | }
110 | }];
111 |
112 | [resultsM addObject:model];
113 | }
114 | }];
115 |
116 | __block BOOL hasChildrendArrayProperty = NO;
117 |
118 | if(fieldsArrayM.count!=0){
119 |
120 | [resultsM enumerateObjectsUsingBlock:^(CoreModel *model, NSUInteger idx, BOOL *stop) {
121 |
122 | [fieldsArrayM enumerateObjectsUsingBlock:^(CoreProperty *ivar, NSUInteger idx, BOOL *stop) {
123 |
124 | if(![ivar.typeString isEqualToString:CoreNSArray]){
125 |
126 | NSString *where_childModelField=[NSString stringWithFormat:@"pModel='%@' AND pid=%@",NSStringFromClass(model.class),@(model.hostID)];
127 |
128 | NSString *limit=@"1";
129 |
130 | [NSClassFromString(ivar.typeString) selectWhere:where_childModelField groupBy:nil orderBy:nil limit:limit selectResultsBlock:^(NSArray *selectResults) {
131 |
132 | if(selectResults.count>0){
133 | [model setValue:selectResults.firstObject forKey:ivar.name];
134 | }
135 |
136 | }];
137 |
138 | }else{
139 |
140 | hasChildrendArrayProperty = YES;
141 |
142 | NSString *where_childModelField=[NSString stringWithFormat:@"pModel='%@' AND pid=%@",NSStringFromClass(model.class),@(model.hostID)];
143 |
144 | Class Cls = NSClassFromString([self statementForNSArrayProperties][ivar.name]);
145 |
146 |
147 | [Cls selectWhere:where_childModelField groupBy:nil orderBy:nil limit:nil selectResultsBlock:^(NSArray *selectResults) {
148 |
149 | if(selectResults.count>0){
150 | [model setValue:selectResults forKey:ivar.name];
151 | }
152 |
153 | if(selectResultsBlock != nil) selectResultsBlock(resultsM);
154 |
155 | }];
156 |
157 | }
158 |
159 | }];
160 |
161 | }];
162 | }
163 |
164 | if(!hasChildrendArrayProperty){if(selectResultsBlock != nil) selectResultsBlock(resultsM);}
165 |
166 | ThreadShow(数据查询)
167 | }
168 |
169 |
170 |
171 |
172 | +(void)find:(NSUInteger)hostID selectResultBlock:(void(^)(id selectResult))selectResultBlock{
173 |
174 | if(![self checkTableExists]){
175 |
176 | if(CoreModelDeBug) NSLog(@"错误:你操作的模型%@在数据库中没有对应的数据表!",[self modelName]);
177 | if (selectResultBlock != nil) selectResultBlock(nil);return;
178 | }
179 |
180 | NSString *where=[NSString stringWithFormat:@"hostID=%@",@(hostID)];
181 |
182 | NSString *limit=@"1";
183 |
184 | [self selectWhere:where groupBy:nil orderBy:nil limit:limit selectResultsBlock:^(NSArray *selectResults) {
185 |
186 | if (selectResultBlock != nil) selectResultBlock(selectResults.firstObject);
187 | }];
188 |
189 | }
190 |
191 |
192 | @end
193 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/NSObject+Update.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Update.h
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | // 更新数据:如果数据不存在,则自动忽略,不会自动添加
8 | // 请在线程中执行
9 |
10 | #import
11 |
12 | @interface NSObject (Update)
13 |
14 |
15 |
16 | +(void)update:(id)model resBlock:(void(^)(BOOL res))resBlock;
17 |
18 | +(void)updateModels:(NSArray *)models resBlock:(void(^)(BOOL res))resBlock;
19 |
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSObject/NSObject+Update.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Update.m
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import "NSObject+Update.h"
10 | #import "NSObject+CoreModelCommon.h"
11 | #import "CoreModel.h"
12 | #import "CoreModelConst.h"
13 | #import "CoreFMDB.h"
14 | #import "NSArray+CoreModel.h"
15 |
16 |
17 | @implementation NSObject (Update)
18 |
19 |
20 | +(void)update:(id)model resBlock:(void(^)(BOOL res))resBlock{
21 | [self update:model resBlock:resBlock needThead:YES];
22 | }
23 |
24 | +(void)update:(id)model resBlock:(void(^)(BOOL res))resBlock needThead:(BOOL)needThead{
25 |
26 | if (needThead) {
27 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
28 | [self updateAction:model resBlock:resBlock];
29 | });
30 | }else{
31 | [self updateAction:model resBlock:resBlock];
32 | }
33 | }
34 |
35 |
36 | +(void)updateAction:(id)model resBlock:(void(^)(BOOL res))resBlock{
37 |
38 | [self checkUsage:model];
39 |
40 | if(![self checkTableExists]){
41 |
42 | if(CoreModelDeBug) NSLog(@"错误:你操作的模型%@在数据库中没有对应的数据表!",[self modelName]);
43 |
44 | if(resBlock != nil) resBlock(NO);
45 |
46 | return;
47 | }
48 |
49 | if(![model isKindOfClass:[self class]]){
50 | if(CoreModelDeBug) NSLog(@"错误:插入数据请使用%@模型类对象,您使用的是%@类型",[self modelName],[model class]);
51 | if (resBlock != nil) resBlock(NO);
52 | }
53 |
54 | CoreModel *coreModel=(CoreModel *)model;
55 |
56 | [self find:coreModel.hostID selectResultBlock:^(id selectResult) {
57 |
58 | if(selectResult==nil) {if (resBlock != nil) resBlock(NO);return;};
59 |
60 | NSMutableString *keyValueString=[NSMutableString string];
61 |
62 | [self enumNSObjectProperties:^(CoreProperty *property, BOOL *stop) {
63 |
64 | BOOL skip=[self skipField:property];
65 |
66 | if(!skip){
67 |
68 | NSString *sqliteTye=[self sqliteType:property.code];
69 |
70 | id value =[model valueForKeyPath:property.name];
71 |
72 | if([property.typeString isEqualToString:CoreNSArray]){
73 |
74 | if([self isBasicTypeInNSArray:[self statementForNSArrayProperties][property.name]]){
75 | sqliteTye = TEXT_TYPE;
76 | }
77 | }
78 |
79 | if(![sqliteTye isEqualToString:EmptyString]){
80 |
81 | if([property.typeString isEqualToString:CoreNSString]){
82 |
83 | if(value == nil) value=@"";
84 |
85 | value=[NSString stringWithFormat:@"'%@'",value];
86 | }else if ([property.typeString isEqualToString:CoreNSData]){
87 |
88 | if(value != nil) {
89 |
90 | value =[NSString stringWithFormat:@"'%@'",[(NSData *)value base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]];
91 | }else{
92 | value = @"''";
93 | }
94 | }
95 |
96 | if([property.typeString isEqualToString:CoreNSArray]){
97 |
98 | if([self isBasicTypeInNSArray:[self statementForNSArrayProperties][property.name]]){
99 |
100 | NSString *valueStr = nil;
101 |
102 | if(value == nil){
103 | valueStr = @"";
104 | }else{
105 | valueStr = ((NSArray *)value).toString;
106 | }
107 |
108 | value = [NSString stringWithFormat:@"'%@'",valueStr];
109 | }
110 | }
111 |
112 |
113 | [keyValueString appendFormat:@"%@=%@,",property.name,value];
114 |
115 | }else{
116 |
117 | if(property.name!=nil && value!=nil){
118 |
119 | if(![property.typeString isEqualToString:CoreNSArray]){
120 |
121 | CoreModel *childModel=(CoreModel *)value;
122 |
123 | [childModel setValue:[self modelName] forKey:@"pModel"];
124 |
125 | [childModel setValue:@(coreModel.hostID) forKey:@"pid"];
126 |
127 | [NSClassFromString(property.code) update:childModel resBlock:^(BOOL res) {
128 | if(CoreModelDeBug) {if(!res) NSLog(@"错误:级联保存数据失败!级联父类:%@,子属性为:%@",NSStringFromClass(CoreModel.class),value);};
129 | }];
130 |
131 | }else{
132 |
133 |
134 | NSArray *modelsArray = (NSArray *)value;
135 |
136 | [modelsArray enumerateObjectsUsingBlock:^(CoreModel *i, NSUInteger idx, BOOL *stop) {
137 | [i setValue:NSStringFromClass([self class]) forKeyPath:@"pModel"];
138 | [i setValue:@(coreModel.hostID) forKeyPath:@"pid"];
139 | }];
140 |
141 | Class Cls = NSClassFromString([self statementForNSArrayProperties][property.name]);
142 |
143 | [Cls saveModels:modelsArray resBlock:resBlock];
144 | }
145 |
146 | }
147 | }
148 | }
149 |
150 | }];
151 |
152 | NSString *keyValues_sub=[self deleteLastChar:keyValueString];
153 |
154 | NSString *sql=[NSString stringWithFormat:@"UPDATE %@ SET %@ WHERE hostID=%@;",[self modelName],keyValues_sub,@(coreModel.hostID)];
155 |
156 | BOOL updateRes = [CoreFMDB executeUpdate:sql];
157 |
158 | if(CoreModelDeBug) {if(!updateRes) NSLog(@"错误:数据更新出错,出错模型数据为:%@",model);};
159 |
160 | TriggerBlock(resBlock, updateRes)
161 |
162 | }];
163 | }
164 |
165 |
166 |
167 | +(void)updateModels:(NSArray *)models resBlock:(void(^)(BOOL res))resBlock{
168 |
169 | if(![self checkTableExists]){
170 |
171 | if(CoreModelDeBug) NSLog(@"注意:单条数据更新时,你操作的模型%@在数据库中没有对应的数据表!%@",[self modelName],AutoMsg);
172 |
173 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(AutoTry * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
174 | [self updateModels:models resBlock:resBlock];
175 | });
176 |
177 | return;
178 | }
179 |
180 | if(models==nil || models.count==0) {if (resBlock != nil) resBlock(NO);};
181 |
182 | NSOperationQueue *queue = [NSOperationQueue queue];
183 |
184 | for (id obj in models) {
185 | NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
186 | [self update:obj resBlock:resBlock needThead:NO];ThreadShow(更新数据)
187 | }];
188 | [queue addOperation:op];
189 | }
190 | }
191 |
192 |
193 |
194 | @end
195 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSOperationQueue/NSOperationQueue+Queue.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSOperationQueue+Queue.h
3 | // CoreClass
4 | //
5 | // Created by 成林 on 15/8/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSOperationQueue (Queue)
12 |
13 |
14 | +(instancetype)queue;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSOperationQueue/NSOperationQueue+Queue.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSOperationQueue+Queue.m
3 | // CoreClass
4 | //
5 | // Created by 成林 on 15/8/30.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import "NSOperationQueue+Queue.h"
10 |
11 | @implementation NSOperationQueue (Queue)
12 |
13 | +(instancetype)queue{
14 | NSOperationQueue *queue = [[NSOperationQueue alloc] init];
15 | queue.maxConcurrentOperationCount = 3;
16 | return queue;
17 | }
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSString/NSString+Stackoverflow.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+Stackoverflow.h
3 | // CoreModel
4 | //
5 | // Created by 成林 on 15/3/29.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSString (Stackoverflow)
12 |
13 |
14 |
15 | -(NSArray *)toArray:(BOOL)isString;
16 |
17 |
18 | -(unsigned long long)unsignedLongLongValue;
19 |
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Category/NSString/NSString+Stackoverflow.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+Stackoverflow.m
3 | // CoreModel
4 | //
5 | // Created by 成林 on 15/3/29.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import "NSString+Stackoverflow.h"
10 | #import "CoreModelConst.h"
11 |
12 | @implementation NSString (Stackoverflow)
13 |
14 |
15 | -(NSArray *)toArray:(BOOL)isString{
16 |
17 | NSString *seperator = @",";
18 |
19 | if(!isString) seperator = SymbolString;
20 |
21 | NSArray *arr = [self componentsSeparatedByString:seperator];
22 |
23 | if(isString) return arr;
24 |
25 | NSMutableArray *arrM = [NSMutableArray arrayWithCapacity:arr.count];
26 |
27 | if(arr == nil || arr.count == 0) return nil;
28 |
29 | [arr enumerateObjectsUsingBlock:^(NSString *str, NSUInteger idx, BOOL *stop) {
30 |
31 | NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
32 |
33 | [arrM addObject:data];
34 | }];
35 |
36 | return arrM;
37 | }
38 |
39 |
40 |
41 |
42 |
43 | -(unsigned long long)unsignedLongLongValue{
44 |
45 | return self.longLongValue;
46 | }
47 |
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/CoreMoelConst/CoreModelConst.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreModelConst.h
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/27.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #ifndef _BaseMoelConst_H_
10 | #define _BaseMoelConst_H_
11 |
12 | /** Debug */
13 | #define CoreModelDeBug 1
14 |
15 |
16 |
17 | #import
18 | #import
19 |
20 | #define NSArrayNorlMalTypes @[@"NSString",@"NSData"]
21 |
22 | #define ThreadShow(msg) if(CoreModelDeBug){NSLog(@"%@所在线程:%@",@#msg,[NSThread currentThread]);};
23 | #define TriggerBlock(block,res) if(block != nil ) block(res);
24 | #define AutoMsg @"框架正在全自动创表,并稍后自动重新执行您的操作,请放心!"
25 | #define AutoTry 0.1
26 |
27 |
28 | /**
29 | * NSString
30 | */
31 | UIKIT_EXTERN NSString *const CoreNSString;
32 |
33 |
34 |
35 | /**
36 | * NSInteger
37 | */
38 | UIKIT_EXTERN NSString *const CoreNSInteger;
39 |
40 |
41 |
42 | /**
43 | * NSUInteger
44 | */
45 | UIKIT_EXTERN NSString *const CoreNSUInteger;
46 |
47 |
48 |
49 | /**
50 | * CGFloat
51 | */
52 | UIKIT_EXTERN NSString *const CoreCGFloat;
53 |
54 |
55 |
56 | /**
57 | * Enum、int
58 | */
59 | UIKIT_EXTERN NSString *const CoreEnum_int;
60 |
61 |
62 |
63 | /**
64 | * BOOL:BOOL类型的变量对应sqlite中的integer方便扩展
65 | */
66 | UIKIT_EXTERN NSString *const CoreBOOL;
67 |
68 |
69 |
70 |
71 | /**
72 | * NSData
73 | */
74 | UIKIT_EXTERN NSString *const CoreNSData;
75 |
76 |
77 |
78 | /**
79 | * NSArray
80 | */
81 | UIKIT_EXTERN NSString *const CoreNSArray;
82 |
83 |
84 |
85 |
86 |
87 |
88 | /**
89 | * SQL语句Const
90 | */
91 |
92 | /**
93 | * INTEGER
94 | */
95 | UIKIT_EXTERN NSString *const INTEGER_TYPE;
96 |
97 |
98 | /**
99 | * TEXT
100 | */
101 | UIKIT_EXTERN NSString *const TEXT_TYPE;
102 |
103 |
104 | /**
105 | * REAL
106 | */
107 | UIKIT_EXTERN NSString *const REAL_TYPE;
108 |
109 |
110 | /**
111 | * BLOB
112 | */
113 | UIKIT_EXTERN NSString *const BLOB_TYPE;
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | /**
122 | * 其他定义
123 | */
124 |
125 | /**
126 | * 空字符串
127 | */
128 | UIKIT_EXTERN NSString *const EmptyString;
129 |
130 |
131 | /**
132 | * 标识字符串
133 | */
134 | UIKIT_EXTERN NSString *const SymbolString;
135 |
136 |
137 | #endif
138 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/CoreMoelConst/CoreModelConst.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreModelConst.m
3 | // CoreModel
4 | //
5 | // Created by muxi on 15/3/27.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #ifndef _BaseMoelConst_M_
10 | #define _BaseMoelConst_M_
11 |
12 |
13 | #import
14 | #import
15 |
16 |
17 |
18 |
19 | /**
20 | * 字符串
21 | */
22 | NSString *const CoreNSString = @"NSString";
23 |
24 |
25 |
26 |
27 | /**
28 | * NSInteger
29 | */
30 | NSString *const CoreNSInteger = @"q,i";
31 |
32 |
33 |
34 | /**
35 | * NSUInteger
36 | */
37 | NSString *const CoreNSUInteger = @"Q,I";
38 |
39 |
40 |
41 |
42 | /**
43 | * CGFloat
44 | */
45 | NSString *const CoreCGFloat = @"d,f";
46 |
47 |
48 |
49 | /**
50 | * float
51 | */
52 | NSString *const Corefloat = @"f";
53 |
54 |
55 |
56 | /**
57 | * double
58 | */
59 | NSString *const Coredouble = @"d";
60 |
61 |
62 |
63 | /**
64 | * Enum、int
65 | */
66 | NSString *const CoreEnum_int = @"i";
67 |
68 |
69 |
70 | /**
71 | * BOOL
72 | */
73 | NSString *const CoreBOOL = @"B,c";
74 |
75 |
76 |
77 | /**
78 | * NSData
79 | */
80 | NSString *const CoreNSData = @"NSData";
81 |
82 |
83 |
84 | /**
85 | * NSArray
86 | */
87 | NSString *const CoreNSArray = @"NSArray";
88 |
89 |
90 |
91 |
92 | /**
93 | * SQL语句Const
94 | */
95 |
96 | /**
97 | * INTEGER
98 | */
99 | NSString *const INTEGER_TYPE = @"INTEGER NOT NULL DEFAULT 0";
100 |
101 |
102 | /**
103 | * TEXT
104 | */
105 | NSString *const TEXT_TYPE = @"TEXT NOT NULL DEFAULT ''";
106 |
107 |
108 | /**
109 | * REAL
110 | */
111 | NSString *const REAL_TYPE = @"REAL NOT NULL DEFAULT 0.0";
112 |
113 |
114 |
115 | /**
116 | * BLOB
117 | */
118 | NSString *const BLOB_TYPE = @"BLOB";
119 |
120 |
121 |
122 |
123 | /**
124 | * 其他定义
125 | */
126 |
127 | /**
128 | * 空字符串
129 | */
130 | NSString *const EmptyString = @"";
131 |
132 |
133 | /**
134 | * 标识字符串
135 | */
136 | NSString *const SymbolString = @"SymbolString";
137 |
138 |
139 |
140 |
141 | #endif
142 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Protocol/CoreModelProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreModelProtocol.h
3 | // CoreClass
4 | //
5 | // Created by 冯成林 on 15/5/28.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CoreModelType.h"
11 |
12 |
13 |
14 |
15 |
16 |
17 | @protocol CoreModelProtocol
18 |
19 | @required
20 |
21 |
22 | /** 接口地址 */
23 | +(NSString *)CoreModel_UrlString;
24 |
25 | /** 请求方式 */
26 | +(CoreModelHttpType)CoreModel_HttpType;
27 |
28 | /** 是否需要本地缓存 */
29 | +(BOOL)CoreModel_NeedFMDB;
30 |
31 | /** 缓存周期:单位秒 */
32 | +(NSTimeInterval)CoreModel_Duration;
33 |
34 |
35 | /**
36 | * 错误数据解析:请求成功,但服务器返回的接口状态码抛出错误
37 | *
38 | * @param hostData 服务器数据
39 | *
40 | * @return 如果为nil,表示无错误;如果不为空表示有错误,并且为错误信息。
41 | */
42 | +(NSString *)CoreModel_parseErrorData:(id)hostData;
43 |
44 |
45 | /** 服务器真正有用数据体:此时只是找到对应的key,还没有字典转模型 */
46 | +(id)CoreModel_findUsefullData:(id)hostData;
47 |
48 |
49 | /** 返回数据格式 */
50 | +(CoreModelHostDataType)CoreModel_hostDataType;
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | @end
60 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Protocol/CorePageModelProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // BasePageModelProtocol.h
3 | // CoreClass
4 | //
5 | // Created by 冯成林 on 15/6/5.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CoreModelType.h"
11 |
12 |
13 |
14 |
15 |
16 |
17 | @protocol CorePageModelProtocol
18 |
19 | @required
20 |
21 |
22 | /**
23 | * 是否为分页数据
24 | *
25 | * @return 如果为分页模型请返回YES,否则返回NO
26 | */
27 | +(BOOL)CoreModel_isPageEnable;
28 |
29 |
30 | /** page字段 */
31 | +(NSString *)CoreModel_PageKey;
32 |
33 |
34 | /** pagesize字段 */
35 | +(NSString *)CoreModel_PageSizeKey;
36 |
37 |
38 | /** 页码起点 */
39 | +(NSUInteger)CoreModel_StartPage;
40 |
41 |
42 | /** 每页数据量 */
43 | +(NSUInteger)CoreModel_PageSize;
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | @end
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Reflect/CoreProperty.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreProperty.h
3 | // test
4 | //
5 | // Created by 冯成林 on 16/3/31.
6 | // Copyright © 2016年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef enum {
12 |
13 | /** Unknown */
14 | CorePropertyTypeUnknown = 0,
15 |
16 | /** Bool */
17 | CorePropertyTypeBool,
18 |
19 | /** Int */
20 | CorePropertyTypeNSInteger,
21 |
22 | /** CGFloat */
23 | CorePropertyTypeCGFloat,
24 |
25 | /** double */
26 | CorePropertyTypeDouble,
27 |
28 | /** NSString */
29 | CorePropertyTypeNSString,
30 |
31 | /** NSArray */
32 | CorePropertyTypeNSArray,
33 |
34 | /** NSDictionary */
35 | CorePropertyTypeNSDictionary,
36 |
37 | /** UIImage */
38 | CorePropertyTypeUIImage,
39 |
40 | /** NSData */
41 | CorePropertyTypeNSData,
42 |
43 | /** CustomObj */
44 | CorePropertyTypeCustomObj,
45 |
46 | } CorePropertyType;
47 |
48 |
49 |
50 |
51 |
52 |
53 | @interface CoreProperty : NSObject
54 |
55 | @property (nonatomic,copy) NSString *name;
56 |
57 | @property (nonatomic,copy) NSString *code;
58 |
59 | @property (nonatomic,assign) CorePropertyType type;
60 |
61 | @property (nonatomic,copy) NSString *typeString;
62 |
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Reflect/CoreProperty.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreProperty.m
3 | // test
4 | //
5 | // Created by 冯成林 on 16/3/31.
6 | // Copyright © 2016年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "CoreProperty.h"
10 |
11 |
12 | @interface CoreProperty ()
13 |
14 | @property (nonatomic,strong) NSArray *typeNames;
15 |
16 | @end
17 |
18 |
19 |
20 |
21 | @implementation CoreProperty
22 |
23 | -(void)setCode:(NSString *)code{
24 |
25 | //去除@
26 | code = [code stringByReplacingOccurrencesOfString:@"@" withString:@""];
27 | //去除"
28 | code = [code stringByReplacingOccurrencesOfString:@"\"" withString:@""];
29 |
30 | //记录code
31 | _code = code;
32 |
33 | /** Unknown */
34 | self.type = CorePropertyTypeUnknown;
35 |
36 | /** Bool */
37 | if ([code isEqualToString:@"c"] || [code isEqualToString:@"B"]) {
38 |
39 | self.type = CorePropertyTypeBool; return;
40 | }
41 |
42 | /** Int */
43 | if ([code isEqualToString:@"i"] || [code isEqualToString:@"q"] || [code isEqualToString:@"Q"] || [code isEqualToString:@"I"]) {
44 |
45 | self.type = CorePropertyTypeNSInteger; return;
46 | }
47 |
48 | /** CGFloat */
49 | if ([code isEqualToString:@"f"]) {
50 |
51 | self.type = CorePropertyTypeCGFloat; return;
52 | }
53 |
54 |
55 | /** double */
56 | if ([code isEqualToString:@"d"]) {
57 |
58 | self.type = CorePropertyTypeDouble; return;
59 | }
60 |
61 |
62 | /** NSString */
63 | if ([code isEqualToString:@"NSString"]) {
64 |
65 | self.type = CorePropertyTypeNSString; return;
66 | }
67 |
68 |
69 | /** NSArray */
70 | if ([code isEqualToString:@"NSArray"]) {
71 |
72 | self.type = CorePropertyTypeNSArray; return;
73 | }
74 |
75 |
76 | /** NSDictionary */
77 | if ([code isEqualToString:@"NSDictionary"]) {
78 |
79 | self.type = CorePropertyTypeNSDictionary; return;
80 | }
81 |
82 | /** UIImage */
83 | if ([code isEqualToString:@"UIImage"]) {
84 |
85 | self.type = CorePropertyTypeUIImage; return;
86 | }
87 |
88 | /** NSData */
89 | if ([code isEqualToString:@"NSData"]) {
90 |
91 | self.type = CorePropertyTypeNSData; return;
92 | }
93 |
94 | /** CustomObj */
95 | Class cls = NSClassFromString(code);
96 |
97 | if(cls == nil) {return;}
98 |
99 | if(![[cls new] isKindOfClass:[NSObject class]]) {return;}
100 |
101 | self.type = CorePropertyTypeCustomObj;
102 |
103 | }
104 |
105 |
106 | -(NSArray *)typeNames{
107 |
108 | if(_typeNames == nil){
109 |
110 |
111 | _typeNames = @[@"Unknown",@"Bool",@"Int",@"CGFloat",@"double",@"NSString",@"NSArray",@"NSDictionary",@"UIImage",@"NSData",@"CustomObj"];
112 | }
113 |
114 | return _typeNames;
115 | }
116 |
117 |
118 | -(NSString *)typeString{
119 |
120 | if(_typeString == nil){
121 |
122 | _typeString = self.typeNames[self.type];
123 | }
124 |
125 | return _typeString;
126 | }
127 |
128 | @end
129 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Reflect/NSObject+Runtime.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Runtime.h
3 | // test
4 | //
5 | // Created by 冯成林 on 16/3/31.
6 | // Copyright © 2016年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CoreProperty.h"
11 |
12 | @interface NSObject (Runtime)
13 |
14 |
15 | /** 成员变量遍历 */
16 | +(void)enumeratePropertiesUsingBlock:(void(^)(CoreProperty *p))propertyBlock;
17 |
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Reflect/NSObject+Runtime.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Runtime.m
3 | // test
4 | //
5 | // Created by 冯成林 on 16/3/31.
6 | // Copyright © 2016年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "NSObject+Runtime.h"
10 | #import
11 |
12 | @implementation NSObject (Runtime)
13 |
14 | /** 成员变量遍历 */
15 | +(void)enumeratePropertiesUsingBlock:(void(^)(CoreProperty *p))propertyBlock{
16 |
17 | Class cls = self;
18 |
19 | do {
20 |
21 | [self enumerateCls:cls propertyBlock:propertyBlock];
22 |
23 | cls = class_getSuperclass(cls);
24 |
25 | }while (cls != [NSObject class]);
26 |
27 | }
28 |
29 |
30 | +(void)enumerateCls:(Class)cls propertyBlock:(void(^)(CoreProperty *p))propertyBlock{
31 |
32 | unsigned int numIvars; //成员变量个数
33 |
34 | Ivar *vars = class_copyIvarList(cls, &numIvars);
35 |
36 | //Ivar *vars = class_copyIvarList([UIView class], &numIvars);
37 |
38 | NSString *key=nil;
39 | NSString *type = nil;
40 |
41 | for(int i = 0; i < numIvars; i++) {
42 |
43 | //创建CoreProperty
44 | CoreProperty *p =[CoreProperty new];
45 |
46 | Ivar thisIvar = vars[i];
47 | key = [NSString stringWithUTF8String:ivar_getName(thisIvar)]; //获取成员变量的名字
48 |
49 | //记录变量名
50 | p.name = [key stringByReplacingOccurrencesOfString:@"_" withString:@""];
51 |
52 | type = [NSString stringWithUTF8String:ivar_getTypeEncoding(thisIvar)]; //获取成员变量的数据类型
53 |
54 | //处理并记录变量类型
55 | p.code = type;
56 |
57 | propertyBlock(p);
58 | }
59 |
60 | free(vars);
61 | }
62 |
63 |
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/CoreModel/CoreModel/Lib/Type/CoreModelType.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreModelType.h
3 | // CoreClass
4 | //
5 | // Created by 冯成林 on 15/5/28.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #ifndef CoreClass_CoreModelType_h
10 | #define CoreClass_CoreModelType_h
11 |
12 |
13 | /** 请求方式 */
14 | typedef enum{
15 |
16 | //GET
17 | CoreModelHttpTypeGET=0,
18 |
19 | //POST
20 | CoreModelHttpTypePOST
21 |
22 | }CoreModelHttpType;
23 |
24 |
25 |
26 | /** 返回数据格式 */
27 | typedef enum{
28 |
29 | //模型:单个
30 | CoreModelHostDataTypeModelSingle=0,
31 |
32 | //数组:数组
33 | CoreModelHostDataTypeModelArray
34 |
35 | }CoreModelHostDataType;
36 |
37 |
38 |
39 | /** 模型数据来源 */
40 | typedef enum{
41 |
42 | //默认值:无来源
43 | CoreModelDataSourceTypeNone,
44 |
45 | //本地数据库
46 | CoreModelDataSourceTypeSqlite,
47 |
48 | //服务器数据,且本地数据库无数据
49 | CoreModelDataSourceHostType_Sqlite_Nil,
50 |
51 | //服务器数据,本地数据库有数据,但本地数据过期
52 | CoreModelDataSourceHostType_Sqlite_Deprecated,
53 |
54 | }CoreModelDataSourceType;
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | #endif
66 |
--------------------------------------------------------------------------------
/CoreModel/FrameWorks/CoreFMDB/CoreFMDB.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreFMDB.h
3 | // CoreFMDB
4 | //
5 | // Created by muxi on 15/3/27.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CoreFMDBSingleton.h"
11 | #import "FMResultSet.h"
12 |
13 | @interface CoreFMDB : NSObject
14 | HMSingletonH(CoreFMDB)
15 |
16 |
17 | /**
18 | * 执行一个更新语句
19 | *
20 | * @param sql 更新语句的sql
21 | *
22 | * @return 更新语句的执行结果
23 | */
24 | +(BOOL)executeUpdate:(NSString *)sql;
25 |
26 |
27 | /**
28 | * 执行一个查询语句
29 | *
30 | * @param sql 查询语句sql
31 | * @param queryResBlock 查询语句的执行结果
32 | */
33 | +(void)executeQuery:(NSString *)sql queryResBlock:(void(^)(FMResultSet *set))queryResBlock;
34 |
35 |
36 | /**
37 | * 查询出指定表的列
38 | *
39 | * @param table table
40 | *
41 | * @return 查询出指定表的列的执行结果
42 | */
43 | +(NSArray *)executeQueryColumnsInTable:(NSString *)table;
44 |
45 |
46 | /**
47 | * 表记录数计算
48 | *
49 | * @param table 表
50 | *
51 | * @return 记录数
52 | */
53 | +(NSUInteger)countTable:(NSString *)table;
54 |
55 |
56 | /**
57 | * 清空表(但不清除表结构)
58 | *
59 | * @param table 表名
60 | *
61 | * @return 操作结果
62 | */
63 | +(BOOL)truncateTable:(NSString *)table;
64 |
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/CoreModel/FrameWorks/CoreFMDB/CoreFMDB.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreFMDB.m
3 | // CoreFMDB
4 | //
5 | // Created by muxi on 15/3/27.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import "CoreFMDB.h"
10 | #import "FMDB.h"
11 | #import "NSString+CoreFMDB.h"
12 |
13 | @interface CoreFMDB ()
14 |
15 |
16 | /**
17 | * 具有线程安全的数据队列
18 | */
19 | @property (nonatomic,strong) FMDatabaseQueue *queue;
20 |
21 |
22 |
23 | @end
24 |
25 |
26 |
27 |
28 |
29 | @implementation CoreFMDB
30 | HMSingletonM(CoreFMDB)
31 |
32 |
33 | /**
34 | * 数据库队列的初始化:本操作一个
35 | */
36 | +(void)initialize{
37 |
38 | //取出实例
39 | CoreFMDB *coreFMDB=[CoreFMDB sharedCoreFMDB];
40 |
41 | //获取项目info文件
42 | NSDictionary *infoDict=[[NSBundle mainBundle] infoDictionary];
43 |
44 | //获取项目Bundle Name:英文(CFBundleName)
45 | NSString *key=(NSString *)kCFBundleNameKey;
46 | NSString *bundleName=infoDict[key];
47 | //拼接数据库名
48 | NSString *dbName=[NSString stringWithFormat:@"%@%@",bundleName,@".sql"];
49 |
50 | //在沙盒中存入数据库文件
51 | NSString *dbPath=[bundleName.documentsSubFolder stringByAppendingPathComponent:dbName];
52 |
53 | const BOOL needLogSqlFilePath=YES;
54 |
55 | if(needLogSqlFilePath) NSLog(@"dbPath:%@",dbPath);
56 |
57 | //创建队列
58 | FMDatabaseQueue *queue =[FMDatabaseQueue databaseQueueWithPath:dbPath];
59 |
60 | if(queue==nil)NSLog(@"code=1:创建数据库失败,请检查");
61 |
62 | coreFMDB.queue = queue;
63 | }
64 |
65 |
66 |
67 |
68 | /**
69 | * 执行一个更新语句
70 | *
71 | * @param sql 更新语句的sql
72 | *
73 | * @return 更新语句的执行结果
74 | */
75 | +(BOOL)executeUpdate:(NSString *)sql{
76 |
77 | __block BOOL updateRes = NO;
78 |
79 | CoreFMDB *coreFMDB=[CoreFMDB sharedCoreFMDB];
80 |
81 | [coreFMDB.queue inDatabase:^(FMDatabase *db) {
82 |
83 | updateRes = [db executeUpdate:sql];
84 | }];
85 |
86 | return updateRes;
87 | }
88 |
89 |
90 |
91 |
92 |
93 | /**
94 | * 执行一个查询语句
95 | *
96 | * @param sql 查询语句sql
97 | * @param queryResBlock 查询语句的执行结果
98 | */
99 | +(void)executeQuery:(NSString *)sql queryResBlock:(void(^)(FMResultSet *set))queryResBlock{
100 |
101 | CoreFMDB *coreFMDB=[CoreFMDB sharedCoreFMDB];
102 |
103 | [coreFMDB.queue inDatabase:^(FMDatabase *db) {
104 |
105 | FMResultSet *set = [db executeQuery:sql];
106 |
107 | if(queryResBlock != nil) queryResBlock(set);
108 |
109 | NSLog(@"%@",[NSThread currentThread]);
110 | }];
111 | }
112 |
113 |
114 |
115 |
116 | /**
117 | * 查询出指定表的列
118 | *
119 | * @param table table
120 | *
121 | * @return 查询出指定表的列的执行结果
122 | */
123 | +(NSArray *)executeQueryColumnsInTable:(NSString *)table{
124 |
125 | NSMutableArray *columnsM=[NSMutableArray array];
126 |
127 | NSString *sql=[NSString stringWithFormat:@"PRAGMA table_info (%@);",table];
128 |
129 | [self executeQuery:sql queryResBlock:^(FMResultSet *set) {
130 |
131 | //循环取出数据
132 | while ([set next]) {
133 | NSString *column = [set stringForColumn:@"name"];
134 | [columnsM addObject:column];
135 | }
136 |
137 | if(columnsM.count==0) NSLog(@"code=2:您指定的表:%@,没有字段信息,可能是表尚未创建!",table);
138 | }];
139 |
140 | return [columnsM copy];
141 | }
142 |
143 |
144 | /**
145 | * 表记录数计算
146 | *
147 | * @param table 表
148 | *
149 | * @return 记录数
150 | */
151 | +(NSUInteger)countTable:(NSString *)table{
152 |
153 | NSString *alias=@"count";
154 |
155 | NSString *sql=[NSString stringWithFormat:@"SELECT COUNT(*) AS %@ FROM %@;",alias,table];
156 |
157 | __block NSUInteger count=0;
158 |
159 | [self executeQuery:sql queryResBlock:^(FMResultSet *set) {
160 |
161 | while ([set next]) {
162 |
163 | count = [[set stringForColumn:alias] integerValue];
164 | }
165 | }];
166 |
167 | return count;
168 | }
169 |
170 |
171 | /**
172 | * 清空表(但不清除表结构)
173 | *
174 | * @param table 表名
175 | *
176 | * @return 操作结果
177 | */
178 | +(BOOL)truncateTable:(NSString *)table{
179 |
180 | BOOL res = [self executeUpdate:[NSString stringWithFormat:@"DELETE FROM '%@'", table]];
181 | [self executeUpdate:[NSString stringWithFormat:@"DELETE FROM sqlite_sequence WHERE name='%@';", table]];
182 | return res;
183 | }
184 |
185 |
186 |
187 | @end
188 |
--------------------------------------------------------------------------------
/CoreModel/FrameWorks/CoreFMDB/Lib/Category/NSString+CoreFMDB.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+CoreFMDB.h
3 | // CoreFMDB
4 | //
5 | // Created by muxi on 15/3/27.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSString (CoreFMDB)
12 |
13 |
14 |
15 | /**
16 | * 转为documents下的子文件夹
17 | */
18 | @property (nonatomic,copy,readonly) NSString *documentsSubFolder;
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/CoreModel/FrameWorks/CoreFMDB/Lib/Category/NSString+CoreFMDB.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+CoreFMDB.m
3 | // CoreFMDB
4 | //
5 | // Created by muxi on 15/3/27.
6 | // Copyright (c) 2015年 muxi. All rights reserved.
7 | //
8 |
9 | #import "NSString+CoreFMDB.h"
10 |
11 | @implementation NSString (CoreFMDB)
12 |
13 |
14 |
15 | /**
16 | * 转为documents下的子文件夹
17 | */
18 | -(NSString *)documentsSubFolder{
19 |
20 | NSString *documentFolder=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
21 |
22 | return [NSString makeSubFolderInSuperFolder:documentFolder subFloder:self];
23 |
24 | }
25 |
26 |
27 |
28 | /**
29 | * 文件夹处理
30 | */
31 | +(NSString *)makeSubFolderInSuperFolder:(NSString *)superFolder subFloder:(NSString *)subFloder{
32 |
33 | NSString *folder=[NSString stringWithFormat:@"%@/%@",superFolder,subFloder];
34 |
35 | BOOL isDir = NO;
36 |
37 | NSFileManager *fileManager = [NSFileManager defaultManager];
38 |
39 | BOOL existed = [fileManager fileExistsAtPath:folder isDirectory:&isDir];
40 |
41 | if ( !(isDir == YES && existed == YES) )
42 | {
43 | [fileManager createDirectoryAtPath:folder withIntermediateDirectories:YES attributes:nil error:nil];
44 | }
45 |
46 | return folder;
47 | }
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | @end
77 |
--------------------------------------------------------------------------------
/CoreModel/FrameWorks/CoreFMDB/Lib/Singleton/CoreFMDBSingleton.h:
--------------------------------------------------------------------------------
1 | // .h文件
2 | #define HMSingletonH(name) + (instancetype)shared##name;
3 |
4 | // .m文件
5 | #if __has_feature(objc_arc)
6 |
7 | #define HMSingletonM(name) \
8 | static id _instace; \
9 | \
10 | + (id)allocWithZone:(struct _NSZone *)zone \
11 | { \
12 | static dispatch_once_t onceToken; \
13 | dispatch_once(&onceToken, ^{ \
14 | _instace = [super allocWithZone:zone]; \
15 | }); \
16 | return _instace; \
17 | } \
18 | \
19 | + (instancetype)shared##name \
20 | { \
21 | static dispatch_once_t onceToken; \
22 | dispatch_once(&onceToken, ^{ \
23 | _instace = [[self alloc] init]; \
24 | }); \
25 | return _instace; \
26 | } \
27 | \
28 | - (id)copyWithZone:(NSZone *)zone \
29 | { \
30 | return _instace; \
31 | }
32 |
33 | #else
34 |
35 | #define HMSingletonM(name) \
36 | static id _instace; \
37 | \
38 | + (id)allocWithZone:(struct _NSZone *)zone \
39 | { \
40 | static dispatch_once_t onceToken; \
41 | dispatch_once(&onceToken, ^{ \
42 | _instace = [super allocWithZone:zone]; \
43 | }); \
44 | return _instace; \
45 | } \
46 | \
47 | + (instancetype)shared##name \
48 | { \
49 | static dispatch_once_t onceToken; \
50 | dispatch_once(&onceToken, ^{ \
51 | _instace = [[self alloc] init]; \
52 | }); \
53 | return _instace; \
54 | } \
55 | \
56 | - (id)copyWithZone:(NSZone *)zone \
57 | { \
58 | return _instace; \
59 | } \
60 | \
61 | - (oneway void)release { } \
62 | - (id)retain { return self; } \
63 | - (NSUInteger)retainCount { return 1;} \
64 | - (id)autorelease { return self;}
65 |
66 | #endif
--------------------------------------------------------------------------------
/CoreModel/FrameWorks/CoreFMDB/Lib/fmdb/FMDB.h:
--------------------------------------------------------------------------------
1 | #import "FMDatabase.h"
2 | #import "FMResultSet.h"
3 | #import "FMDatabaseAdditions.h"
4 | #import "FMDatabaseQueue.h"
5 | #import "FMDatabasePool.h"
6 |
--------------------------------------------------------------------------------
/CoreModel/FrameWorks/CoreFMDB/Lib/fmdb/FMDatabaseAdditions.h:
--------------------------------------------------------------------------------
1 | //
2 | // FMDatabaseAdditions.h
3 | // fmdb
4 | //
5 | // Created by August Mueller on 10/30/05.
6 | // Copyright 2005 Flying Meat Inc.. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "FMDatabase.h"
11 |
12 |
13 | /** Category of additions for `` class.
14 |
15 | ### See also
16 |
17 | - ``
18 | */
19 |
20 | @interface FMDatabase (FMDatabaseAdditions)
21 |
22 | ///----------------------------------------
23 | /// @name Return results of SQL to variable
24 | ///----------------------------------------
25 |
26 | /** Return `int` value for query
27 |
28 | @param query The SQL query to be performed.
29 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query.
30 |
31 | @return `int` value.
32 |
33 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project.
34 | */
35 |
36 | - (int)intForQuery:(NSString*)query, ...;
37 |
38 | /** Return `long` value for query
39 |
40 | @param query The SQL query to be performed.
41 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query.
42 |
43 | @return `long` value.
44 |
45 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project.
46 | */
47 |
48 | - (long)longForQuery:(NSString*)query, ...;
49 |
50 | /** Return `BOOL` value for query
51 |
52 | @param query The SQL query to be performed.
53 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query.
54 |
55 | @return `BOOL` value.
56 |
57 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project.
58 | */
59 |
60 | - (BOOL)boolForQuery:(NSString*)query, ...;
61 |
62 | /** Return `double` value for query
63 |
64 | @param query The SQL query to be performed.
65 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query.
66 |
67 | @return `double` value.
68 |
69 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project.
70 | */
71 |
72 | - (double)doubleForQuery:(NSString*)query, ...;
73 |
74 | /** Return `NSString` value for query
75 |
76 | @param query The SQL query to be performed.
77 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query.
78 |
79 | @return `NSString` value.
80 |
81 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project.
82 | */
83 |
84 | - (NSString*)stringForQuery:(NSString*)query, ...;
85 |
86 | /** Return `NSData` value for query
87 |
88 | @param query The SQL query to be performed.
89 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query.
90 |
91 | @return `NSData` value.
92 |
93 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project.
94 | */
95 |
96 | - (NSData*)dataForQuery:(NSString*)query, ...;
97 |
98 | /** Return `NSDate` value for query
99 |
100 | @param query The SQL query to be performed.
101 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query.
102 |
103 | @return `NSDate` value.
104 |
105 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project.
106 | */
107 |
108 | - (NSDate*)dateForQuery:(NSString*)query, ...;
109 |
110 |
111 | // Notice that there's no dataNoCopyForQuery:.
112 | // That would be a bad idea, because we close out the result set, and then what
113 | // happens to the data that we just didn't copy? Who knows, not I.
114 |
115 |
116 | ///--------------------------------
117 | /// @name Schema related operations
118 | ///--------------------------------
119 |
120 | /** Does table exist in database?
121 |
122 | @param tableName The name of the table being looked for.
123 |
124 | @return `YES` if table found; `NO` if not found.
125 | */
126 |
127 | - (BOOL)tableExists:(NSString*)tableName;
128 |
129 | /** The schema of the database.
130 |
131 | This will be the schema for the entire database. For each entity, each row of the result set will include the following fields:
132 |
133 | - `type` - The type of entity (e.g. table, index, view, or trigger)
134 | - `name` - The name of the object
135 | - `tbl_name` - The name of the table to which the object references
136 | - `rootpage` - The page number of the root b-tree page for tables and indices
137 | - `sql` - The SQL that created the entity
138 |
139 | @return `FMResultSet` of schema; `nil` on error.
140 |
141 | @see [SQLite File Format](http://www.sqlite.org/fileformat.html)
142 | */
143 |
144 | - (FMResultSet*)getSchema;
145 |
146 | /** The schema of the database.
147 |
148 | This will be the schema for a particular table as report by SQLite `PRAGMA`, for example:
149 |
150 | PRAGMA table_info('employees')
151 |
152 | This will report:
153 |
154 | - `cid` - The column ID number
155 | - `name` - The name of the column
156 | - `type` - The data type specified for the column
157 | - `notnull` - whether the field is defined as NOT NULL (i.e. values required)
158 | - `dflt_value` - The default value for the column
159 | - `pk` - Whether the field is part of the primary key of the table
160 |
161 | @param tableName The name of the table for whom the schema will be returned.
162 |
163 | @return `FMResultSet` of schema; `nil` on error.
164 |
165 | @see [table_info](http://www.sqlite.org/pragma.html#pragma_table_info)
166 | */
167 |
168 | - (FMResultSet*)getTableSchema:(NSString*)tableName;
169 |
170 | /** Test to see if particular column exists for particular table in database
171 |
172 | @param columnName The name of the column.
173 |
174 | @param tableName The name of the table.
175 |
176 | @return `YES` if column exists in table in question; `NO` otherwise.
177 | */
178 |
179 | - (BOOL)columnExists:(NSString*)columnName inTableWithName:(NSString*)tableName;
180 |
181 | /** Test to see if particular column exists for particular table in database
182 |
183 | @param columnName The name of the column.
184 |
185 | @param tableName The name of the table.
186 |
187 | @return `YES` if column exists in table in question; `NO` otherwise.
188 |
189 | @see columnExists:inTableWithName:
190 |
191 | @warning Deprecated - use `` instead.
192 | */
193 |
194 | - (BOOL)columnExists:(NSString*)tableName columnName:(NSString*)columnName __attribute__ ((deprecated));
195 |
196 |
197 | /** Validate SQL statement
198 |
199 | This validates SQL statement by performing `sqlite3_prepare_v2`, but not returning the results, but instead immediately calling `sqlite3_finalize`.
200 |
201 | @param sql The SQL statement being validated.
202 |
203 | @param error This is a pointer to a `NSError` object that will receive the autoreleased `NSError` object if there was any error. If this is `nil`, no `NSError` result will be returned.
204 |
205 | @return `YES` if validation succeeded without incident; `NO` otherwise.
206 |
207 | */
208 |
209 | - (BOOL)validateSQL:(NSString*)sql error:(NSError**)error;
210 |
211 |
212 | #if SQLITE_VERSION_NUMBER >= 3007017
213 |
214 | ///-----------------------------------
215 | /// @name Application identifier tasks
216 | ///-----------------------------------
217 |
218 | /** Retrieve application ID
219 |
220 | @return The `uint32_t` numeric value of the application ID.
221 |
222 | @see setApplicationID:
223 | */
224 |
225 | - (uint32_t)applicationID;
226 |
227 | /** Set the application ID
228 |
229 | @param appID The `uint32_t` numeric value of the application ID.
230 |
231 | @see applicationID
232 | */
233 |
234 | - (void)setApplicationID:(uint32_t)appID;
235 |
236 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE
237 | /** Retrieve application ID string
238 |
239 | @return The `NSString` value of the application ID.
240 |
241 | @see setApplicationIDString:
242 | */
243 |
244 |
245 | - (NSString*)applicationIDString;
246 |
247 | /** Set the application ID string
248 |
249 | @param string The `NSString` value of the application ID.
250 |
251 | @see applicationIDString
252 | */
253 |
254 | - (void)setApplicationIDString:(NSString*)string;
255 | #endif
256 |
257 | #endif
258 |
259 | ///-----------------------------------
260 | /// @name user version identifier tasks
261 | ///-----------------------------------
262 |
263 | /** Retrieve user version
264 |
265 | @return The `uint32_t` numeric value of the user version.
266 |
267 | @see setUserVersion:
268 | */
269 |
270 | - (uint32_t)userVersion;
271 |
272 | /** Set the user-version
273 |
274 | @param version The `uint32_t` numeric value of the user version.
275 |
276 | @see userVersion
277 | */
278 |
279 | - (void)setUserVersion:(uint32_t)version;
280 |
281 | @end
282 |
--------------------------------------------------------------------------------
/CoreModel/FrameWorks/CoreFMDB/Lib/fmdb/FMDatabaseAdditions.m:
--------------------------------------------------------------------------------
1 | //
2 | // FMDatabaseAdditions.m
3 | // fmdb
4 | //
5 | // Created by August Mueller on 10/30/05.
6 | // Copyright 2005 Flying Meat Inc.. All rights reserved.
7 | //
8 |
9 | #import "FMDatabase.h"
10 | #import "FMDatabaseAdditions.h"
11 | #import "TargetConditionals.h"
12 |
13 | @interface FMDatabase (PrivateStuff)
14 | - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arrayArgs orDictionary:(NSDictionary *)dictionaryArgs orVAList:(va_list)args;
15 | @end
16 |
17 | @implementation FMDatabase (FMDatabaseAdditions)
18 |
19 | #define RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(type, sel) \
20 | va_list args; \
21 | va_start(args, query); \
22 | FMResultSet *resultSet = [self executeQuery:query withArgumentsInArray:0x00 orDictionary:0x00 orVAList:args]; \
23 | va_end(args); \
24 | if (![resultSet next]) { return (type)0; } \
25 | type ret = [resultSet sel:0]; \
26 | [resultSet close]; \
27 | [resultSet setParentDB:nil]; \
28 | return ret;
29 |
30 |
31 | - (NSString*)stringForQuery:(NSString*)query, ... {
32 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSString *, stringForColumnIndex);
33 | }
34 |
35 | - (int)intForQuery:(NSString*)query, ... {
36 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(int, intForColumnIndex);
37 | }
38 |
39 | - (long)longForQuery:(NSString*)query, ... {
40 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(long, longForColumnIndex);
41 | }
42 |
43 | - (BOOL)boolForQuery:(NSString*)query, ... {
44 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(BOOL, boolForColumnIndex);
45 | }
46 |
47 | - (double)doubleForQuery:(NSString*)query, ... {
48 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(double, doubleForColumnIndex);
49 | }
50 |
51 | - (NSData*)dataForQuery:(NSString*)query, ... {
52 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSData *, dataForColumnIndex);
53 | }
54 |
55 | - (NSDate*)dateForQuery:(NSString*)query, ... {
56 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSDate *, dateForColumnIndex);
57 | }
58 |
59 |
60 | - (BOOL)tableExists:(NSString*)tableName {
61 |
62 | tableName = [tableName lowercaseString];
63 |
64 | FMResultSet *rs = [self executeQuery:@"select [sql] from sqlite_master where [type] = 'table' and lower(name) = ?", tableName];
65 |
66 | //if at least one next exists, table exists
67 | BOOL returnBool = [rs next];
68 |
69 | //close and free object
70 | [rs close];
71 |
72 | return returnBool;
73 | }
74 |
75 | /*
76 | get table with list of tables: result colums: type[STRING], name[STRING],tbl_name[STRING],rootpage[INTEGER],sql[STRING]
77 | check if table exist in database (patch from OZLB)
78 | */
79 | - (FMResultSet*)getSchema {
80 |
81 | //result colums: type[STRING], name[STRING],tbl_name[STRING],rootpage[INTEGER],sql[STRING]
82 | FMResultSet *rs = [self executeQuery:@"SELECT type, name, tbl_name, rootpage, sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE type != 'meta' AND name NOT LIKE 'sqlite_%' ORDER BY tbl_name, type DESC, name"];
83 |
84 | return rs;
85 | }
86 |
87 | /*
88 | get table schema: result colums: cid[INTEGER], name,type [STRING], notnull[INTEGER], dflt_value[],pk[INTEGER]
89 | */
90 | - (FMResultSet*)getTableSchema:(NSString*)tableName {
91 |
92 | //result colums: cid[INTEGER], name,type [STRING], notnull[INTEGER], dflt_value[],pk[INTEGER]
93 | FMResultSet *rs = [self executeQuery:[NSString stringWithFormat: @"pragma table_info('%@')", tableName]];
94 |
95 | return rs;
96 | }
97 |
98 | - (BOOL)columnExists:(NSString*)columnName inTableWithName:(NSString*)tableName {
99 |
100 | BOOL returnBool = NO;
101 |
102 | tableName = [tableName lowercaseString];
103 | columnName = [columnName lowercaseString];
104 |
105 | FMResultSet *rs = [self getTableSchema:tableName];
106 |
107 | //check if column is present in table schema
108 | while ([rs next]) {
109 | if ([[[rs stringForColumn:@"name"] lowercaseString] isEqualToString:columnName]) {
110 | returnBool = YES;
111 | break;
112 | }
113 | }
114 |
115 | //If this is not done FMDatabase instance stays out of pool
116 | [rs close];
117 |
118 | return returnBool;
119 | }
120 |
121 |
122 | #if SQLITE_VERSION_NUMBER >= 3007017
123 |
124 | - (uint32_t)applicationID {
125 |
126 | uint32_t r = 0;
127 |
128 | FMResultSet *rs = [self executeQuery:@"pragma application_id"];
129 |
130 | if ([rs next]) {
131 | r = (uint32_t)[rs longLongIntForColumnIndex:0];
132 | }
133 |
134 | [rs close];
135 |
136 | return r;
137 | }
138 |
139 | - (void)setApplicationID:(uint32_t)appID {
140 | NSString *query = [NSString stringWithFormat:@"pragma application_id=%d", appID];
141 | FMResultSet *rs = [self executeQuery:query];
142 | [rs next];
143 | [rs close];
144 | }
145 |
146 |
147 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE
148 | - (NSString*)applicationIDString {
149 | NSString *s = NSFileTypeForHFSTypeCode([self applicationID]);
150 |
151 | assert([s length] == 6);
152 |
153 | s = [s substringWithRange:NSMakeRange(1, 4)];
154 |
155 |
156 | return s;
157 |
158 | }
159 |
160 | - (void)setApplicationIDString:(NSString*)s {
161 |
162 | if ([s length] != 4) {
163 | NSLog(@"setApplicationIDString: string passed is not exactly 4 chars long. (was %ld)", [s length]);
164 | }
165 |
166 | [self setApplicationID:NSHFSTypeCodeFromFileType([NSString stringWithFormat:@"'%@'", s])];
167 | }
168 |
169 |
170 | #endif
171 |
172 | #endif
173 |
174 | - (uint32_t)userVersion {
175 | uint32_t r = 0;
176 |
177 | FMResultSet *rs = [self executeQuery:@"pragma user_version"];
178 |
179 | if ([rs next]) {
180 | r = (uint32_t)[rs longLongIntForColumnIndex:0];
181 | }
182 |
183 | [rs close];
184 | return r;
185 | }
186 |
187 | - (void)setUserVersion:(uint32_t)version {
188 | NSString *query = [NSString stringWithFormat:@"pragma user_version = %d", version];
189 | FMResultSet *rs = [self executeQuery:query];
190 | [rs next];
191 | [rs close];
192 | }
193 |
194 | #pragma clang diagnostic push
195 | #pragma clang diagnostic ignored "-Wdeprecated-implementations"
196 |
197 | - (BOOL)columnExists:(NSString*)tableName columnName:(NSString*)columnName __attribute__ ((deprecated)) {
198 | return [self columnExists:columnName inTableWithName:tableName];
199 | }
200 |
201 | #pragma clang diagnostic pop
202 |
203 |
204 | - (BOOL)validateSQL:(NSString*)sql error:(NSError**)error {
205 | sqlite3_stmt *pStmt = NULL;
206 | BOOL validationSucceeded = YES;
207 |
208 | int rc = sqlite3_prepare_v2(_db, [sql UTF8String], -1, &pStmt, 0);
209 | if (rc != SQLITE_OK) {
210 | validationSucceeded = NO;
211 | if (error) {
212 | *error = [NSError errorWithDomain:NSCocoaErrorDomain
213 | code:[self lastErrorCode]
214 | userInfo:[NSDictionary dictionaryWithObject:[self lastErrorMessage]
215 | forKey:NSLocalizedDescriptionKey]];
216 | }
217 | }
218 |
219 | sqlite3_finalize(pStmt);
220 |
221 | return validationSucceeded;
222 | }
223 |
224 | @end
225 |
--------------------------------------------------------------------------------
/CoreModel/FrameWorks/CoreFMDB/Lib/fmdb/FMDatabasePool.h:
--------------------------------------------------------------------------------
1 | //
2 | // FMDatabasePool.h
3 | // fmdb
4 | //
5 | // Created by August Mueller on 6/22/11.
6 | // Copyright 2011 Flying Meat Inc. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "sqlite3.h"
11 |
12 | @class FMDatabase;
13 |
14 | /** Pool of `` objects.
15 |
16 | ### See also
17 |
18 | - ``
19 | - ``
20 |
21 | @warning Before using `FMDatabasePool`, please consider using `` instead.
22 |
23 | If you really really really know what you're doing and `FMDatabasePool` is what
24 | you really really need (ie, you're using a read only database), OK you can use
25 | it. But just be careful not to deadlock!
26 |
27 | For an example on deadlocking, search for:
28 | `ONLY_USE_THE_POOL_IF_YOU_ARE_DOING_READS_OTHERWISE_YOULL_DEADLOCK_USE_FMDATABASEQUEUE_INSTEAD`
29 | in the main.m file.
30 | */
31 |
32 | @interface FMDatabasePool : NSObject {
33 | NSString *_path;
34 |
35 | dispatch_queue_t _lockQueue;
36 |
37 | NSMutableArray *_databaseInPool;
38 | NSMutableArray *_databaseOutPool;
39 |
40 | __unsafe_unretained id _delegate;
41 |
42 | NSUInteger _maximumNumberOfDatabasesToCreate;
43 | int _openFlags;
44 | }
45 |
46 | /** Database path */
47 |
48 | @property (atomic, retain) NSString *path;
49 |
50 | /** Delegate object */
51 |
52 | @property (atomic, assign) id delegate;
53 |
54 | /** Maximum number of databases to create */
55 |
56 | @property (atomic, assign) NSUInteger maximumNumberOfDatabasesToCreate;
57 |
58 | /** Open flags */
59 |
60 | @property (atomic, readonly) int openFlags;
61 |
62 |
63 | ///---------------------
64 | /// @name Initialization
65 | ///---------------------
66 |
67 | /** Create pool using path.
68 |
69 | @param aPath The file path of the database.
70 |
71 | @return The `FMDatabasePool` object. `nil` on error.
72 | */
73 |
74 | + (instancetype)databasePoolWithPath:(NSString*)aPath;
75 |
76 | /** Create pool using path and specified flags
77 |
78 | @param aPath The file path of the database.
79 | @param openFlags Flags passed to the openWithFlags method of the database
80 |
81 | @return The `FMDatabasePool` object. `nil` on error.
82 | */
83 |
84 | + (instancetype)databasePoolWithPath:(NSString*)aPath flags:(int)openFlags;
85 |
86 | /** Create pool using path.
87 |
88 | @param aPath The file path of the database.
89 |
90 | @return The `FMDatabasePool` object. `nil` on error.
91 | */
92 |
93 | - (instancetype)initWithPath:(NSString*)aPath;
94 |
95 | /** Create pool using path and specified flags.
96 |
97 | @param aPath The file path of the database.
98 | @param openFlags Flags passed to the openWithFlags method of the database
99 |
100 | @return The `FMDatabasePool` object. `nil` on error.
101 | */
102 |
103 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags;
104 |
105 | ///------------------------------------------------
106 | /// @name Keeping track of checked in/out databases
107 | ///------------------------------------------------
108 |
109 | /** Number of checked-in databases in pool
110 |
111 | @returns Number of databases
112 | */
113 |
114 | - (NSUInteger)countOfCheckedInDatabases;
115 |
116 | /** Number of checked-out databases in pool
117 |
118 | @returns Number of databases
119 | */
120 |
121 | - (NSUInteger)countOfCheckedOutDatabases;
122 |
123 | /** Total number of databases in pool
124 |
125 | @returns Number of databases
126 | */
127 |
128 | - (NSUInteger)countOfOpenDatabases;
129 |
130 | /** Release all databases in pool */
131 |
132 | - (void)releaseAllDatabases;
133 |
134 | ///------------------------------------------
135 | /// @name Perform database operations in pool
136 | ///------------------------------------------
137 |
138 | /** Synchronously perform database operations in pool.
139 |
140 | @param block The code to be run on the `FMDatabasePool` pool.
141 | */
142 |
143 | - (void)inDatabase:(void (^)(FMDatabase *db))block;
144 |
145 | /** Synchronously perform database operations in pool using transaction.
146 |
147 | @param block The code to be run on the `FMDatabasePool` pool.
148 | */
149 |
150 | - (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block;
151 |
152 | /** Synchronously perform database operations in pool using deferred transaction.
153 |
154 | @param block The code to be run on the `FMDatabasePool` pool.
155 | */
156 |
157 | - (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block;
158 |
159 | #if SQLITE_VERSION_NUMBER >= 3007000
160 |
161 | /** Synchronously perform database operations in pool using save point.
162 |
163 | @param block The code to be run on the `FMDatabasePool` pool.
164 |
165 | @return `NSError` object if error; `nil` if successful.
166 |
167 | @warning You can not nest these, since calling it will pull another database out of the pool and you'll get a deadlock. If you need to nest, use `<[FMDatabase startSavePointWithName:error:]>` instead.
168 | */
169 |
170 | - (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block;
171 | #endif
172 |
173 | @end
174 |
175 |
176 | /** FMDatabasePool delegate category
177 |
178 | This is a category that defines the protocol for the FMDatabasePool delegate
179 | */
180 |
181 | @interface NSObject (FMDatabasePoolDelegate)
182 |
183 | /** Asks the delegate whether database should be added to the pool.
184 |
185 | @param pool The `FMDatabasePool` object.
186 | @param database The `FMDatabase` object.
187 |
188 | @return `YES` if it should add database to pool; `NO` if not.
189 |
190 | */
191 |
192 | - (BOOL)databasePool:(FMDatabasePool*)pool shouldAddDatabaseToPool:(FMDatabase*)database;
193 |
194 | /** Tells the delegate that database was added to the pool.
195 |
196 | @param pool The `FMDatabasePool` object.
197 | @param database The `FMDatabase` object.
198 |
199 | */
200 |
201 | - (void)databasePool:(FMDatabasePool*)pool didAddDatabase:(FMDatabase*)database;
202 |
203 | @end
204 |
205 |
--------------------------------------------------------------------------------
/CoreModel/FrameWorks/CoreFMDB/Lib/fmdb/FMDatabasePool.m:
--------------------------------------------------------------------------------
1 | //
2 | // FMDatabasePool.m
3 | // fmdb
4 | //
5 | // Created by August Mueller on 6/22/11.
6 | // Copyright 2011 Flying Meat Inc. All rights reserved.
7 | //
8 |
9 | #import "FMDatabasePool.h"
10 | #import "FMDatabase.h"
11 |
12 | @interface FMDatabasePool()
13 |
14 | - (void)pushDatabaseBackInPool:(FMDatabase*)db;
15 | - (FMDatabase*)db;
16 |
17 | @end
18 |
19 |
20 | @implementation FMDatabasePool
21 | @synthesize path=_path;
22 | @synthesize delegate=_delegate;
23 | @synthesize maximumNumberOfDatabasesToCreate=_maximumNumberOfDatabasesToCreate;
24 | @synthesize openFlags=_openFlags;
25 |
26 |
27 | + (instancetype)databasePoolWithPath:(NSString*)aPath {
28 | return FMDBReturnAutoreleased([[self alloc] initWithPath:aPath]);
29 | }
30 |
31 | + (instancetype)databasePoolWithPath:(NSString*)aPath flags:(int)openFlags {
32 | return FMDBReturnAutoreleased([[self alloc] initWithPath:aPath flags:openFlags]);
33 | }
34 |
35 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags {
36 |
37 | self = [super init];
38 |
39 | if (self != nil) {
40 | _path = [aPath copy];
41 | _lockQueue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL);
42 | _databaseInPool = FMDBReturnRetained([NSMutableArray array]);
43 | _databaseOutPool = FMDBReturnRetained([NSMutableArray array]);
44 | _openFlags = openFlags;
45 | }
46 |
47 | return self;
48 | }
49 |
50 | - (instancetype)initWithPath:(NSString*)aPath
51 | {
52 | // default flags for sqlite3_open
53 | return [self initWithPath:aPath flags:SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE];
54 | }
55 |
56 | - (instancetype)init {
57 | return [self initWithPath:nil];
58 | }
59 |
60 |
61 | - (void)dealloc {
62 |
63 | _delegate = 0x00;
64 | FMDBRelease(_path);
65 | FMDBRelease(_databaseInPool);
66 | FMDBRelease(_databaseOutPool);
67 |
68 | if (_lockQueue) {
69 | FMDBDispatchQueueRelease(_lockQueue);
70 | _lockQueue = 0x00;
71 | }
72 | #if ! __has_feature(objc_arc)
73 | [super dealloc];
74 | #endif
75 | }
76 |
77 |
78 | - (void)executeLocked:(void (^)(void))aBlock {
79 | dispatch_sync(_lockQueue, aBlock);
80 | }
81 |
82 | - (void)pushDatabaseBackInPool:(FMDatabase*)db {
83 |
84 | if (!db) { // db can be null if we set an upper bound on the # of databases to create.
85 | return;
86 | }
87 |
88 | [self executeLocked:^() {
89 |
90 | if ([self->_databaseInPool containsObject:db]) {
91 | [[NSException exceptionWithName:@"Database already in pool" reason:@"The FMDatabase being put back into the pool is already present in the pool" userInfo:nil] raise];
92 | }
93 |
94 | [self->_databaseInPool addObject:db];
95 | [self->_databaseOutPool removeObject:db];
96 |
97 | }];
98 | }
99 |
100 | - (FMDatabase*)db {
101 |
102 | __block FMDatabase *db;
103 |
104 |
105 | [self executeLocked:^() {
106 | db = [self->_databaseInPool lastObject];
107 |
108 | BOOL shouldNotifyDelegate = NO;
109 |
110 | if (db) {
111 | [self->_databaseOutPool addObject:db];
112 | [self->_databaseInPool removeLastObject];
113 | }
114 | else {
115 |
116 | if (self->_maximumNumberOfDatabasesToCreate) {
117 | NSUInteger currentCount = [self->_databaseOutPool count] + [self->_databaseInPool count];
118 |
119 | if (currentCount >= self->_maximumNumberOfDatabasesToCreate) {
120 | NSLog(@"Maximum number of databases (%ld) has already been reached!", (long)currentCount);
121 | return;
122 | }
123 | }
124 |
125 | db = [FMDatabase databaseWithPath:self->_path];
126 | shouldNotifyDelegate = YES;
127 | }
128 |
129 | //This ensures that the db is opened before returning
130 | #if SQLITE_VERSION_NUMBER >= 3005000
131 | BOOL success = [db openWithFlags:self->_openFlags];
132 | #else
133 | BOOL success = [db open];
134 | #endif
135 | if (success) {
136 | if ([self->_delegate respondsToSelector:@selector(databasePool:shouldAddDatabaseToPool:)] && ![self->_delegate databasePool:self shouldAddDatabaseToPool:db]) {
137 | [db close];
138 | db = 0x00;
139 | }
140 | else {
141 | //It should not get added in the pool twice if lastObject was found
142 | if (![self->_databaseOutPool containsObject:db]) {
143 | [self->_databaseOutPool addObject:db];
144 |
145 | if (shouldNotifyDelegate && [self->_delegate respondsToSelector:@selector(databasePool:didAddDatabase:)]) {
146 | [self->_delegate databasePool:self didAddDatabase:db];
147 | }
148 | }
149 | }
150 | }
151 | else {
152 | NSLog(@"Could not open up the database at path %@", self->_path);
153 | db = 0x00;
154 | }
155 | }];
156 |
157 | return db;
158 | }
159 |
160 | - (NSUInteger)countOfCheckedInDatabases {
161 |
162 | __block NSUInteger count;
163 |
164 | [self executeLocked:^() {
165 | count = [self->_databaseInPool count];
166 | }];
167 |
168 | return count;
169 | }
170 |
171 | - (NSUInteger)countOfCheckedOutDatabases {
172 |
173 | __block NSUInteger count;
174 |
175 | [self executeLocked:^() {
176 | count = [self->_databaseOutPool count];
177 | }];
178 |
179 | return count;
180 | }
181 |
182 | - (NSUInteger)countOfOpenDatabases {
183 | __block NSUInteger count;
184 |
185 | [self executeLocked:^() {
186 | count = [self->_databaseOutPool count] + [self->_databaseInPool count];
187 | }];
188 |
189 | return count;
190 | }
191 |
192 | - (void)releaseAllDatabases {
193 | [self executeLocked:^() {
194 | [self->_databaseOutPool removeAllObjects];
195 | [self->_databaseInPool removeAllObjects];
196 | }];
197 | }
198 |
199 | - (void)inDatabase:(void (^)(FMDatabase *db))block {
200 |
201 | FMDatabase *db = [self db];
202 |
203 | block(db);
204 |
205 | [self pushDatabaseBackInPool:db];
206 | }
207 |
208 | - (void)beginTransaction:(BOOL)useDeferred withBlock:(void (^)(FMDatabase *db, BOOL *rollback))block {
209 |
210 | BOOL shouldRollback = NO;
211 |
212 | FMDatabase *db = [self db];
213 |
214 | if (useDeferred) {
215 | [db beginDeferredTransaction];
216 | }
217 | else {
218 | [db beginTransaction];
219 | }
220 |
221 |
222 | block(db, &shouldRollback);
223 |
224 | if (shouldRollback) {
225 | [db rollback];
226 | }
227 | else {
228 | [db commit];
229 | }
230 |
231 | [self pushDatabaseBackInPool:db];
232 | }
233 |
234 | - (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block {
235 | [self beginTransaction:YES withBlock:block];
236 | }
237 |
238 | - (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block {
239 | [self beginTransaction:NO withBlock:block];
240 | }
241 | #if SQLITE_VERSION_NUMBER >= 3007000
242 | - (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block {
243 |
244 | static unsigned long savePointIdx = 0;
245 |
246 | NSString *name = [NSString stringWithFormat:@"savePoint%ld", savePointIdx++];
247 |
248 | BOOL shouldRollback = NO;
249 |
250 | FMDatabase *db = [self db];
251 |
252 | NSError *err = 0x00;
253 |
254 | if (![db startSavePointWithName:name error:&err]) {
255 | [self pushDatabaseBackInPool:db];
256 | return err;
257 | }
258 |
259 | block(db, &shouldRollback);
260 |
261 | if (shouldRollback) {
262 | // We need to rollback and release this savepoint to remove it
263 | [db rollbackToSavePointWithName:name error:&err];
264 | }
265 | [db releaseSavePointWithName:name error:&err];
266 |
267 | [self pushDatabaseBackInPool:db];
268 |
269 | return err;
270 | }
271 | #endif
272 |
273 | @end
274 |
--------------------------------------------------------------------------------
/CoreModel/FrameWorks/CoreFMDB/Lib/fmdb/FMDatabaseQueue.h:
--------------------------------------------------------------------------------
1 | //
2 | // FMDatabaseQueue.h
3 | // fmdb
4 | //
5 | // Created by August Mueller on 6/22/11.
6 | // Copyright 2011 Flying Meat Inc. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "sqlite3.h"
11 |
12 | @class FMDatabase;
13 |
14 | /** To perform queries and updates on multiple threads, you'll want to use `FMDatabaseQueue`.
15 |
16 | Using a single instance of `` from multiple threads at once is a bad idea. It has always been OK to make a `` object *per thread*. Just don't share a single instance across threads, and definitely not across multiple threads at the same time.
17 |
18 | Instead, use `FMDatabaseQueue`. Here's how to use it:
19 |
20 | First, make your queue.
21 |
22 | FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
23 |
24 | Then use it like so:
25 |
26 | [queue inDatabase:^(FMDatabase *db) {
27 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
28 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
29 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];
30 |
31 | FMResultSet *rs = [db executeQuery:@"select * from foo"];
32 | while ([rs next]) {
33 | //…
34 | }
35 | }];
36 |
37 | An easy way to wrap things up in a transaction can be done like this:
38 |
39 | [queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
40 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
41 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
42 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];
43 |
44 | if (whoopsSomethingWrongHappened) {
45 | *rollback = YES;
46 | return;
47 | }
48 | // etc…
49 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];
50 | }];
51 |
52 | `FMDatabaseQueue` will run the blocks on a serialized queue (hence the name of the class). So if you call `FMDatabaseQueue`'s methods from multiple threads at the same time, they will be executed in the order they are received. This way queries and updates won't step on each other's toes, and every one is happy.
53 |
54 | ### See also
55 |
56 | - ``
57 |
58 | @warning Do not instantiate a single `` object and use it across multiple threads. Use `FMDatabaseQueue` instead.
59 |
60 | @warning The calls to `FMDatabaseQueue`'s methods are blocking. So even though you are passing along blocks, they will **not** be run on another thread.
61 |
62 | */
63 |
64 | @interface FMDatabaseQueue : NSObject {
65 | NSString *_path;
66 | dispatch_queue_t _queue;
67 | FMDatabase *_db;
68 | int _openFlags;
69 | }
70 |
71 | /** Path of database */
72 |
73 | @property (atomic, retain) NSString *path;
74 |
75 | /** Open flags */
76 |
77 | @property (atomic, readonly) int openFlags;
78 |
79 | ///----------------------------------------------------
80 | /// @name Initialization, opening, and closing of queue
81 | ///----------------------------------------------------
82 |
83 | /** Create queue using path.
84 |
85 | @param aPath The file path of the database.
86 |
87 | @return The `FMDatabaseQueue` object. `nil` on error.
88 | */
89 |
90 | + (instancetype)databaseQueueWithPath:(NSString*)aPath;
91 |
92 | /** Create queue using path and specified flags.
93 |
94 | @param aPath The file path of the database.
95 | @param openFlags Flags passed to the openWithFlags method of the database
96 |
97 | @return The `FMDatabaseQueue` object. `nil` on error.
98 | */
99 | + (instancetype)databaseQueueWithPath:(NSString*)aPath flags:(int)openFlags;
100 |
101 | /** Create queue using path.
102 |
103 | @param aPath The file path of the database.
104 |
105 | @return The `FMDatabaseQueue` object. `nil` on error.
106 | */
107 |
108 | - (instancetype)initWithPath:(NSString*)aPath;
109 |
110 | /** Create queue using path and specified flags.
111 |
112 | @param aPath The file path of the database.
113 | @param openFlags Flags passed to the openWithFlags method of the database
114 |
115 | @return The `FMDatabaseQueue` object. `nil` on error.
116 | */
117 |
118 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags;
119 |
120 | /** Returns the Class of 'FMDatabase' subclass, that will be used to instantiate database object.
121 |
122 | Subclasses can override this method to return specified Class of 'FMDatabase' subclass.
123 |
124 | @return The Class of 'FMDatabase' subclass, that will be used to instantiate database object.
125 | */
126 |
127 | + (Class)databaseClass;
128 |
129 | /** Close database used by queue. */
130 |
131 | - (void)close;
132 |
133 | ///-----------------------------------------------
134 | /// @name Dispatching database operations to queue
135 | ///-----------------------------------------------
136 |
137 | /** Synchronously perform database operations on queue.
138 |
139 | @param block The code to be run on the queue of `FMDatabaseQueue`
140 | */
141 |
142 | - (void)inDatabase:(void (^)(FMDatabase *db))block;
143 |
144 | /** Synchronously perform database operations on queue, using transactions.
145 |
146 | @param block The code to be run on the queue of `FMDatabaseQueue`
147 | */
148 |
149 | - (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block;
150 |
151 | /** Synchronously perform database operations on queue, using deferred transactions.
152 |
153 | @param block The code to be run on the queue of `FMDatabaseQueue`
154 | */
155 |
156 | - (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block;
157 |
158 | ///-----------------------------------------------
159 | /// @name Dispatching database operations to queue
160 | ///-----------------------------------------------
161 |
162 | /** Synchronously perform database operations using save point.
163 |
164 | @param block The code to be run on the queue of `FMDatabaseQueue`
165 | */
166 |
167 | #if SQLITE_VERSION_NUMBER >= 3007000
168 | // NOTE: you can not nest these, since calling it will pull another database out of the pool and you'll get a deadlock.
169 | // If you need to nest, use FMDatabase's startSavePointWithName:error: instead.
170 | - (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block;
171 | #endif
172 |
173 | @end
174 |
175 |
--------------------------------------------------------------------------------
/CoreModel/FrameWorks/CoreFMDB/Lib/fmdb/FMDatabaseQueue.m:
--------------------------------------------------------------------------------
1 | //
2 | // FMDatabaseQueue.m
3 | // fmdb
4 | //
5 | // Created by August Mueller on 6/22/11.
6 | // Copyright 2011 Flying Meat Inc. All rights reserved.
7 | //
8 |
9 | #import "FMDatabaseQueue.h"
10 | #import "FMDatabase.h"
11 |
12 | /*
13 |
14 | Note: we call [self retain]; before using dispatch_sync, just incase
15 | FMDatabaseQueue is released on another thread and we're in the middle of doing
16 | something in dispatch_sync
17 |
18 | */
19 |
20 | /*
21 | * A key used to associate the FMDatabaseQueue object with the dispatch_queue_t it uses.
22 | * This in turn is used for deadlock detection by seeing if inDatabase: is called on
23 | * the queue's dispatch queue, which should not happen and causes a deadlock.
24 | */
25 | static const void * const kDispatchQueueSpecificKey = &kDispatchQueueSpecificKey;
26 |
27 | @implementation FMDatabaseQueue
28 |
29 | @synthesize path = _path;
30 | @synthesize openFlags = _openFlags;
31 |
32 | + (instancetype)databaseQueueWithPath:(NSString*)aPath {
33 |
34 | FMDatabaseQueue *q = [[self alloc] initWithPath:aPath];
35 |
36 | FMDBAutorelease(q);
37 |
38 | return q;
39 | }
40 |
41 | + (instancetype)databaseQueueWithPath:(NSString*)aPath flags:(int)openFlags {
42 |
43 | FMDatabaseQueue *q = [[self alloc] initWithPath:aPath flags:openFlags];
44 |
45 | FMDBAutorelease(q);
46 |
47 | return q;
48 | }
49 |
50 | + (Class)databaseClass {
51 | return [FMDatabase class];
52 | }
53 |
54 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags {
55 |
56 | self = [super init];
57 |
58 | if (self != nil) {
59 |
60 | _db = [[[self class] databaseClass] databaseWithPath:aPath];
61 | FMDBRetain(_db);
62 |
63 | #if SQLITE_VERSION_NUMBER >= 3005000
64 | BOOL success = [_db openWithFlags:openFlags];
65 | #else
66 | BOOL success = [_db open];
67 | #endif
68 | if (!success) {
69 | NSLog(@"Could not create database queue for path %@", aPath);
70 | FMDBRelease(self);
71 | return 0x00;
72 | }
73 |
74 | _path = FMDBReturnRetained(aPath);
75 |
76 | _queue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL);
77 | dispatch_queue_set_specific(_queue, kDispatchQueueSpecificKey, (__bridge void *)self, NULL);
78 | _openFlags = openFlags;
79 | }
80 |
81 | return self;
82 | }
83 |
84 | - (instancetype)initWithPath:(NSString*)aPath {
85 |
86 | // default flags for sqlite3_open
87 | return [self initWithPath:aPath flags:SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE];
88 | }
89 |
90 | - (instancetype)init {
91 | return [self initWithPath:nil];
92 | }
93 |
94 |
95 | - (void)dealloc {
96 |
97 | FMDBRelease(_db);
98 | FMDBRelease(_path);
99 |
100 | if (_queue) {
101 | FMDBDispatchQueueRelease(_queue);
102 | _queue = 0x00;
103 | }
104 | #if ! __has_feature(objc_arc)
105 | [super dealloc];
106 | #endif
107 | }
108 |
109 | - (void)close {
110 | FMDBRetain(self);
111 | dispatch_sync(_queue, ^() {
112 | [self->_db close];
113 | FMDBRelease(_db);
114 | self->_db = 0x00;
115 | });
116 | FMDBRelease(self);
117 | }
118 |
119 | - (FMDatabase*)database {
120 | if (!_db) {
121 | _db = FMDBReturnRetained([FMDatabase databaseWithPath:_path]);
122 |
123 | #if SQLITE_VERSION_NUMBER >= 3005000
124 | BOOL success = [_db openWithFlags:_openFlags];
125 | #else
126 | BOOL success = [_db open];
127 | #endif
128 | if (!success) {
129 | NSLog(@"FMDatabaseQueue could not reopen database for path %@", _path);
130 | FMDBRelease(_db);
131 | _db = 0x00;
132 | return 0x00;
133 | }
134 | }
135 |
136 | return _db;
137 | }
138 |
139 | - (void)inDatabase:(void (^)(FMDatabase *db))block {
140 | /* Get the currently executing queue (which should probably be nil, but in theory could be another DB queue
141 | * and then check it against self to make sure we're not about to deadlock. */
142 | FMDatabaseQueue *currentSyncQueue = (__bridge id)dispatch_get_specific(kDispatchQueueSpecificKey);
143 | assert(currentSyncQueue != self && "inDatabase: was called reentrantly on the same queue, which would lead to a deadlock");
144 |
145 | FMDBRetain(self);
146 |
147 | dispatch_sync(_queue, ^() {
148 |
149 | FMDatabase *db = [self database];
150 | block(db);
151 |
152 | if ([db hasOpenResultSets]) {
153 | NSLog(@"Warning: there is at least one open result set around after performing [FMDatabaseQueue inDatabase:]");
154 |
155 | #if defined(DEBUG) && DEBUG
156 | NSSet *openSetCopy = FMDBReturnAutoreleased([[db valueForKey:@"_openResultSets"] copy]);
157 | for (NSValue *rsInWrappedInATastyValueMeal in openSetCopy) {
158 | FMResultSet *rs = (FMResultSet *)[rsInWrappedInATastyValueMeal pointerValue];
159 | NSLog(@"query: '%@'", [rs query]);
160 | }
161 | #endif
162 | }
163 | });
164 |
165 | FMDBRelease(self);
166 | }
167 |
168 |
169 | - (void)beginTransaction:(BOOL)useDeferred withBlock:(void (^)(FMDatabase *db, BOOL *rollback))block {
170 | FMDBRetain(self);
171 | dispatch_sync(_queue, ^() {
172 |
173 | BOOL shouldRollback = NO;
174 |
175 | if (useDeferred) {
176 | [[self database] beginDeferredTransaction];
177 | }
178 | else {
179 | [[self database] beginTransaction];
180 | }
181 |
182 | block([self database], &shouldRollback);
183 |
184 | if (shouldRollback) {
185 | [[self database] rollback];
186 | }
187 | else {
188 | [[self database] commit];
189 | }
190 | });
191 |
192 | FMDBRelease(self);
193 | }
194 |
195 | - (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block {
196 | [self beginTransaction:YES withBlock:block];
197 | }
198 |
199 | - (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block {
200 | [self beginTransaction:NO withBlock:block];
201 | }
202 |
203 | #if SQLITE_VERSION_NUMBER >= 3007000
204 | - (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block {
205 |
206 | static unsigned long savePointIdx = 0;
207 | __block NSError *err = 0x00;
208 | FMDBRetain(self);
209 | dispatch_sync(_queue, ^() {
210 |
211 | NSString *name = [NSString stringWithFormat:@"savePoint%ld", savePointIdx++];
212 |
213 | BOOL shouldRollback = NO;
214 |
215 | if ([[self database] startSavePointWithName:name error:&err]) {
216 |
217 | block([self database], &shouldRollback);
218 |
219 | if (shouldRollback) {
220 | // We need to rollback and release this savepoint to remove it
221 | [[self database] rollbackToSavePointWithName:name error:&err];
222 | }
223 | [[self database] releaseSavePointWithName:name error:&err];
224 |
225 | }
226 | });
227 | FMDBRelease(self);
228 | return err;
229 | }
230 | #endif
231 |
232 | @end
233 |
--------------------------------------------------------------------------------
/CoreModel/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
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 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/CoreModel/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 16/4/2.
6 | // Copyright © 2016年 冯成林. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/CoreModel/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 16/4/2.
6 | // Copyright © 2016年 冯成林. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 |
11 | @interface ViewController ()
12 |
13 | @end
14 |
15 | @implementation ViewController
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 | // Do any additional setup after loading the view, typically from a nib.
20 | }
21 |
22 | - (void)didReceiveMemoryWarning {
23 | [super didReceiveMemoryWarning];
24 | // Dispose of any resources that can be recreated.
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/CoreModel/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // CoreModel
4 | //
5 | // Created by 冯成林 on 16/4/2.
6 | // Copyright © 2016年 冯成林. 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 |
--------------------------------------------------------------------------------