├── Cartfile ├── Podfile ├── YYDebugDatabase ├── Car.db ├── Contact.db ├── module1 │ └── Car.db ├── module2 │ └── Car.db ├── ViewController.h ├── AppDelegate.h ├── main.m ├── ViewController.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── Base.lproj │ ├── Main.storyboard │ └── LaunchScreen.storyboard └── AppDelegate.m ├── DebugDatabase ├── Web.bundle │ ├── favicon.ico │ ├── custom.css │ ├── select.dataTables.min.css │ ├── responsive.dataTables.min.css │ ├── appinfo.html │ ├── index.html │ ├── buttons.dataTables.min.css │ ├── dataTables.responsive.min.js │ ├── dataTables.select.min.js │ ├── jquery.dataTables.min.css │ ├── dataTables.buttons.min.js │ └── app.js ├── NSString+json.h ├── NSMutableArray+safe.h ├── DebugDatabaseManager.h ├── iOSDebugDatabase.h ├── NSURL+scheme.h ├── Info.plist ├── NSMutableDictionary+safe.h ├── DatabaseUtil.h ├── NSString+json.m ├── NSMutableArray+safe.m ├── NSURL+scheme.m ├── NSMutableDictionary+safe.m ├── DebugDatabaseManager.m └── DatabaseUtil.m ├── SwiftDebugDatabase ├── SwiftDebugDatabase │ ├── Car.db │ ├── Contact.db │ ├── SwiftDebugDatabase-Bridging-Header.h │ ├── ViewController.swift │ ├── Info.plist │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ └── AppDelegate.swift ├── Podfile ├── SwiftDebugDatabase.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── xcuserdata │ │ └── wentian.xcuserdatad │ │ │ └── xcschemes │ │ │ ├── xcschememanagement.plist │ │ │ └── SwiftDebugDatabase.xcscheme │ └── project.pbxproj └── SwiftDebugDatabase.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ └── wentian.xcuserdatad │ └── xcdebugger │ └── Breakpoints_v2.xcbkptlist ├── .gitignore ├── YYDebugDatabase.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcuserdata │ └── wentian.xcuserdatad │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── YYDebugDatabase.xcscheme └── xcshareddata │ └── xcschemes │ └── iOSDebugDatabase-iOS.xcscheme ├── YYDebugDatabase.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── LICENSE ├── YYDebugDatabase.podspec └── README.md /Cartfile: -------------------------------------------------------------------------------- 1 | 2 | github "swisspol/GCDWebServer" 3 | github "ccgus/fmdb" 4 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | target 'YYDebugDatabase' do 2 | pod "GCDWebServer" 3 | pod 'FMDB' 4 | end 5 | -------------------------------------------------------------------------------- /YYDebugDatabase/Car.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y500/iOSDebugDatabase/HEAD/YYDebugDatabase/Car.db -------------------------------------------------------------------------------- /YYDebugDatabase/Contact.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y500/iOSDebugDatabase/HEAD/YYDebugDatabase/Contact.db -------------------------------------------------------------------------------- /YYDebugDatabase/module1/Car.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y500/iOSDebugDatabase/HEAD/YYDebugDatabase/module1/Car.db -------------------------------------------------------------------------------- /YYDebugDatabase/module2/Car.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y500/iOSDebugDatabase/HEAD/YYDebugDatabase/module2/Car.db -------------------------------------------------------------------------------- /DebugDatabase/Web.bundle/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y500/iOSDebugDatabase/HEAD/DebugDatabase/Web.bundle/favicon.ico -------------------------------------------------------------------------------- /SwiftDebugDatabase/SwiftDebugDatabase/Car.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y500/iOSDebugDatabase/HEAD/SwiftDebugDatabase/SwiftDebugDatabase/Car.db -------------------------------------------------------------------------------- /SwiftDebugDatabase/SwiftDebugDatabase/Contact.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/y500/iOSDebugDatabase/HEAD/SwiftDebugDatabase/SwiftDebugDatabase/Contact.db -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #workspace 2 | 3 | */xcuserdata/* 4 | 5 | #cocoapods 6 | Pods/ 7 | Podfile.lock 8 | 9 | build/ 10 | 11 | 12 | *.xcodeproj/*.xcworkspace 13 | -------------------------------------------------------------------------------- /SwiftDebugDatabase/Podfile: -------------------------------------------------------------------------------- 1 | target 'SwiftDebugDatabase' do 2 | use_frameworks! 3 | pod 'YYDebugDatabase', :git => 'https://github.com/y500/iOSDebugDatabase.git' 4 | end 5 | 6 | -------------------------------------------------------------------------------- /SwiftDebugDatabase/SwiftDebugDatabase/SwiftDebugDatabase-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | -------------------------------------------------------------------------------- /YYDebugDatabase.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftDebugDatabase/SwiftDebugDatabase.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /YYDebugDatabase/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // YYDebugDatabase 4 | // 5 | // Created by wentian on 17/8/9. 6 | // Copyright © 2017年 wentian. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /YYDebugDatabase.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /YYDebugDatabase.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SwiftDebugDatabase/SwiftDebugDatabase.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /YYDebugDatabase/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // YYDebugDatabase 4 | // 5 | // Created by wentian on 17/8/9. 6 | // Copyright © 2017年 wentian. 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 | -------------------------------------------------------------------------------- /YYDebugDatabase/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // YYDebugDatabase 4 | // 5 | // Created by wentian on 17/8/9. 6 | // Copyright © 2017年 wentian. 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 | -------------------------------------------------------------------------------- /DebugDatabase/NSString+json.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+json.h 3 | // YYDebugDatabase 4 | // 5 | // Created by wentian on 17/8/12. 6 | // Copyright © 2017年 wentian. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (json) 12 | 13 | -(id)JSONObject; 14 | 15 | @end 16 | 17 | @interface NSString (URLEncode) 18 | - (NSString *)urlEncode; 19 | - (NSString *)URLDecode; 20 | @end 21 | -------------------------------------------------------------------------------- /DebugDatabase/NSMutableArray+safe.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableArray+safe.h 3 | // categories 4 | // 5 | // Created by wentian on 17/6/1. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface NSMutableArray (safe) 12 | 13 | - (void)safe_addObject:(id)anObject; 14 | 15 | @end 16 | 17 | // NSArray 18 | id yy_arrGetObject(NSArray *arr, NSUInteger index, Class aClass); 19 | NSDictionary * yy_arrGetDic(NSArray *arr, NSUInteger index); 20 | NSString * yy_arrGetString(NSArray *arr, NSUInteger index); 21 | NSArray * yy_arrGetArray(NSArray *arr, NSUInteger index); 22 | -------------------------------------------------------------------------------- /YYDebugDatabase/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // YYDebugDatabase 4 | // 5 | // Created by wentian on 17/8/9. 6 | // Copyright © 2017年 wentian. 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 | 23 | - (void)didReceiveMemoryWarning { 24 | [super didReceiveMemoryWarning]; 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /DebugDatabase/DebugDatabaseManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // DebugDatabaseManager.h 3 | // YYDebugDatabase 4 | // 5 | // Created by wentian on 17/8/10. 6 | // Copyright © 2017年 wentian. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #ifdef COCOAPODS 12 | #import 13 | #else 14 | #import 15 | #endif 16 | 17 | @interface DebugDatabaseManager : GCDWebServer 18 | 19 | + (instancetype)shared; 20 | 21 | - (void)startServerOnPort:(NSInteger)port directories:(NSArray*)directories; 22 | 23 | //默认目录为cache目录和document目录 24 | - (void)startServerOnPort:(NSInteger)port; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /DebugDatabase/iOSDebugDatabase.h: -------------------------------------------------------------------------------- 1 | // 2 | // iOSDebugDatabase.h 3 | // iOSDebugDatabase 4 | // 5 | // Created by Jan Chaloupecky on 16.12.17. 6 | // Copyright © 2017 wentian. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for iOSDebugDatabase. 12 | FOUNDATION_EXPORT double iOSDebugDatabaseVersionNumber; 13 | 14 | //! Project version string for iOSDebugDatabase. 15 | FOUNDATION_EXPORT const unsigned char iOSDebugDatabaseVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like 18 | #import 19 | 20 | 21 | -------------------------------------------------------------------------------- /SwiftDebugDatabase/SwiftDebugDatabase/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SwiftDebugDatabase 4 | // 5 | // Created by wentian on 17/10/19. 6 | // Copyright © 2017年 wentian. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /SwiftDebugDatabase/SwiftDebugDatabase.xcodeproj/xcuserdata/wentian.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SwiftDebugDatabase.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | E8D7933E1F989FC6007BECF8 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | If you are using iOSDebugDatabase in your project, I'd love to hear about it. Let Gus know 2 | by sending an email to yanqizhou@126.com. 3 | 4 | Copyright (C) 2016 y500 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and limitations under the License. 14 | -------------------------------------------------------------------------------- /DebugDatabase/NSURL+scheme.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSURL+scheme.h 3 | // OpenPlatform 4 | // 5 | // Created by wentian on 17/8/10. 6 | // Copyright © 2017年 wentian. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSURL (scheme) 12 | 13 | /** 14 | scheme://user:pass@host:1/path/path2/file.html;params?query#fragment 15 | 16 | schemeStr: 符合scheme://user:pass@host:1/path/path2/file.html;params?query的 17 | URL, 不需要的字段可为空 18 | queryParams: 用来构造query字段,自动做转义处理 19 | */ 20 | +(NSURL *)urlWith:(NSString *)schemeStr queryParams:(NSDictionary *)params; 21 | 22 | /** 23 | scheme://user:pass@host:1/path/path2/file.html;params?query#fragment 24 | 25 | 把query内容以NSDictionary返回,返回结果自动做反转义处理。 26 | */ 27 | -(NSDictionary *)queryParams; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /DebugDatabase/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /YYDebugDatabase.xcodeproj/xcuserdata/wentian.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | DebugDatabaseWeb.xcscheme 8 | 9 | orderHint 10 | 4 11 | 12 | YYDebugDatabase.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | E84AE5EA1F3ADDE3003A9EB7 21 | 22 | primary 23 | 24 | 25 | E8E069911F40944F00477064 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /DebugDatabase/NSMutableDictionary+safe.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableDictionary+safe.h 3 | // categories 4 | // 5 | // Created by wentian on 17/6/1. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface NSMutableDictionary (safe) 12 | 13 | - (void)safe_setObject:(id)anObject forKey:(id)aKey; 14 | 15 | @end 16 | 17 | // NSDictionary 18 | id yy_dicGetObject(NSDictionary * dic, id aKey, Class aClass); 19 | 20 | NSDictionary * yy_dicGetDicYY(NSDictionary *dic, id aKey); 21 | NSArray * yy_dicGetArrayYY(NSDictionary *dic, id aKey); 22 | NSArray * yy_dicGetArraySafe(NSDictionary *dic, id aKey); 23 | 24 | NSString * yy_dicGetString(NSDictionary *dic, id aKey); 25 | NSString * yy_dicGetStringSafe(NSDictionary *dic, id aKey); 26 | 27 | int yy_dicGetInt(NSDictionary *dic, id aKey, int nDefault); 28 | float yy_dicGetFloat(NSDictionary *dic, id aKey, float fDefault); 29 | BOOL yy_dicGetBool(NSDictionary *dic, id aKey, BOOL bDefault); 30 | -------------------------------------------------------------------------------- /DebugDatabase/DatabaseUtil.h: -------------------------------------------------------------------------------- 1 | // 2 | // DatabaseUtil.h 3 | // YYDebugDatabase 4 | // 5 | // Created by wentian on 17/8/11. 6 | // Copyright © 2017年 wentian. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "NSMutableDictionary+safe.h" 11 | #import "NSMutableArray+safe.h" 12 | 13 | @interface DatabaseUtil : NSObject 14 | 15 | + (instancetype)shared; 16 | 17 | - (BOOL)openDatabase:(NSString*)dbPath; 18 | - (BOOL)closeDatabase; 19 | - (NSArray*)allTables; 20 | - (NSArray*)tableInfo:(NSString*)tableName; 21 | - (NSDictionary*)rowsInTable:(NSString*)tableName; 22 | - (BOOL)updateRecordInDatabase:(NSString*)database tableName:(NSString*)tableName data:(NSDictionary*)data condition:(NSDictionary*)condition; 23 | - (BOOL)deleteRecordInDatabase:(NSString *)database tableName:(NSString *)tableName condition:(NSDictionary *)condition limit:(NSString *)limit; 24 | - (NSDictionary*)executeQueryInDatabase:(NSString*)database tableName:(NSString*)tableName operator:(NSString*)operator query:(NSString*)query; 25 | - (NSDictionary*)userDefaultData; 26 | - (NSDictionary*)getAppInfoData; 27 | @end 28 | -------------------------------------------------------------------------------- /YYDebugDatabase.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint YYDebugDatabase.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'YYDebugDatabase' 11 | s.version = '2.1.1' 12 | s.summary = 'easy way to process splite database' 13 | 14 | s.homepage = 'https://y500.me' 15 | s.license = { :type => 'None', :file => 'LICENSE' } 16 | s.author = { 'y500' => 'yanqizhou@126.com' } 17 | s.source = { :git => 'https://github.com/y500/YYDebugDatabase.git', :tag => s.version.to_s } 18 | 19 | s.ios.deployment_target = '7.0' 20 | 21 | s.dependency 'GCDWebServer' 22 | s.dependency 'FMDB' 23 | 24 | s.source_files = 'DebugDatabase/**/*.{h,m}', 'DebugDatabase/*.{h,m}' 25 | s.public_header_files = 'DebugDatabase/DebugDatabaseManager.h' 26 | s.resource = "DebugDatabase/Web.bundle" 27 | 28 | s.requires_arc = true 29 | s.frameworks = 'Foundation' 30 | s.library = 'sqlite3' 31 | 32 | end 33 | -------------------------------------------------------------------------------- /DebugDatabase/NSString+json.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+json.m 3 | // YYDebugDatabase 4 | // 5 | // Created by wentian on 17/8/12. 6 | // Copyright © 2017年 wentian. All rights reserved. 7 | // 8 | 9 | #import "NSString+json.h" 10 | 11 | @implementation NSString (json) 12 | 13 | -(id)JSONObject{ 14 | NSError *errorJson; 15 | NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:[self dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&errorJson]; 16 | if (errorJson != nil) { 17 | NSLog(@"fail to get dictioanry from JSON: %@, error: %@", self, errorJson); 18 | } 19 | return jsonDict; 20 | } 21 | 22 | @end 23 | 24 | @implementation NSString (URLEncode) 25 | 26 | - (NSString *)urlEncode { 27 | NSString * encodedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8)); 28 | return encodedString; 29 | } 30 | 31 | - (NSString *)URLDecode { 32 | NSString *result = [(NSString *)self stringByReplacingOccurrencesOfString:@"+" withString:@" "]; 33 | result = [result stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 34 | return result; 35 | } 36 | 37 | 38 | @end 39 | 40 | -------------------------------------------------------------------------------- /DebugDatabase/Web.bundle/custom.css: -------------------------------------------------------------------------------- 1 | .padding-fifty { 2 | padding-top: 50px; 3 | } 4 | 5 | .padding-twenty { 6 | padding-top: 20px; 7 | } 8 | 9 | .display-none { 10 | display: none; 11 | } 12 | 13 | .list-group-item { 14 | word-break: break-all; 15 | } 16 | 17 | .list-group-item.selected { 18 | background: #dff0d8 !important; 19 | color: #3c763d !important; 20 | font-weight: bold; 21 | } 22 | 23 | #snackbar { 24 | visibility: hidden; 25 | min-width: 250px; 26 | margin-left: -125px; 27 | background-color: #5cb85c; 28 | color: #fff; 29 | text-align: center; 30 | border-radius: 2px; 31 | padding: 16px; 32 | position: fixed; 33 | z-index: 1; 34 | left: 50%; 35 | bottom: 30px; 36 | font-size: 17px; 37 | } 38 | 39 | #snackbar.show { 40 | visibility: visible; 41 | -webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s; 42 | animation: fadein 0.5s, fadeout 0.5s 2.5s; 43 | } 44 | 45 | @-webkit-keyframes fadein { 46 | from {bottom: 0; opacity: 0;} 47 | to {bottom: 30px; opacity: 1;} 48 | } 49 | 50 | @keyframes fadein { 51 | from {bottom: 0; opacity: 0;} 52 | to {bottom: 30px; opacity: 1;} 53 | } 54 | 55 | @-webkit-keyframes fadeout { 56 | from {bottom: 30px; opacity: 1;} 57 | to {bottom: 0; opacity: 0;} 58 | } -------------------------------------------------------------------------------- /YYDebugDatabase/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 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /DebugDatabase/NSMutableArray+safe.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableArray+safe.m 3 | // categories 4 | // 5 | // Created by wentian on 17/6/1. 6 | // 7 | // 8 | 9 | #import "NSMutableArray+safe.h" 10 | 11 | @implementation NSMutableArray (safe) 12 | 13 | - (void)safe_addObject:(id)anObject { 14 | if (anObject) { 15 | [self addObject:anObject]; 16 | } 17 | } 18 | 19 | @end 20 | 21 | // - - - - 22 | id yy_arrGetObject(NSArray *arr, NSUInteger index, Class aClass) { 23 | NSDictionary *result = nil; 24 | if (index < arr.count) { 25 | result = [arr objectAtIndex:index]; 26 | if (result && [result isKindOfClass:aClass]) { 27 | return result; 28 | } 29 | } 30 | return nil; 31 | } 32 | 33 | // - - - 34 | NSDictionary * yy_arrGetDic(NSArray *arr, NSUInteger index) { 35 | NSDictionary *result = nil; 36 | if ( index 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 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /YYDebugDatabase/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 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | NSAppTransportSecurity 24 | 25 | NSAllowsArbitraryLoads 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIMainStoryboardFile 31 | Main 32 | UIRequiredDeviceCapabilities 33 | 34 | armv7 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /SwiftDebugDatabase/SwiftDebugDatabase.xcworkspace/xcuserdata/wentian.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /YYDebugDatabase/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 | -------------------------------------------------------------------------------- /SwiftDebugDatabase/SwiftDebugDatabase/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 | -------------------------------------------------------------------------------- /YYDebugDatabase/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 | -------------------------------------------------------------------------------- /SwiftDebugDatabase/SwiftDebugDatabase/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 | -------------------------------------------------------------------------------- /SwiftDebugDatabase/SwiftDebugDatabase/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /SwiftDebugDatabase/SwiftDebugDatabase/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SwiftDebugDatabase 4 | // 5 | // Created by wentian on 17/10/19. 6 | // Copyright © 2017年 wentian. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import YYDebugDatabase 11 | import Foundation 12 | 13 | @UIApplicationMain 14 | class AppDelegate: UIResponder, UIApplicationDelegate { 15 | 16 | var window: UIWindow? 17 | 18 | 19 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 20 | // Override point for customization after application launch. 21 | 22 | let directory:String = (Bundle.main.resourcePath)!; 23 | DebugDatabaseManager.shared().startServer(onPort: 9002, directories: [directory]); 24 | 25 | return true 26 | } 27 | 28 | func applicationWillResignActive(_ application: UIApplication) { 29 | // 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. 30 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 31 | } 32 | 33 | func applicationDidEnterBackground(_ application: UIApplication) { 34 | // 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. 35 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 36 | } 37 | 38 | func applicationWillEnterForeground(_ application: UIApplication) { 39 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 40 | } 41 | 42 | func applicationDidBecomeActive(_ application: UIApplication) { 43 | // 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. 44 | } 45 | 46 | func applicationWillTerminate(_ application: UIApplication) { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | } 52 | 53 | -------------------------------------------------------------------------------- /DebugDatabase/NSURL+scheme.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSURL+scheme.m 3 | // OpenPlatform 4 | // 5 | // Created by wentian on 17/8/10. 6 | // Copyright © 2017年 wentian. All rights reserved. 7 | // 8 | 9 | #import "NSURL+scheme.h" 10 | #import 11 | 12 | @implementation NSURL (scheme) 13 | 14 | +(NSURL *)urlWith:(NSString *)schemeStr queryParams:(NSDictionary *)params { 15 | NSURL *url = [NSURL URLWithString:schemeStr]; 16 | NSString *prefix = url.query ? @"&" : @"?"; 17 | 18 | NSMutableArray* keyValuePairs = [NSMutableArray array]; 19 | for (NSString* key in [params allKeys]) { 20 | id value = [params objectForKey:key]; 21 | if(![value isKindOfClass:[NSString class]]) { 22 | NSLog(@"warning: %@ is not NSString Class", value); 23 | } 24 | 25 | CFStringRef escapedStr = CFURLCreateStringByAddingPercentEscapes(NULL, 26 | (CFStringRef)value, 27 | NULL, 28 | (CFStringRef)@"!*'();:@&=+$,/?%#[]", 29 | kCFStringEncodingUTF8); 30 | [keyValuePairs addObject:[NSString stringWithFormat:@"%@=%@", key, escapedStr]]; 31 | CFRelease(escapedStr); 32 | } 33 | NSString *queryStr = [keyValuePairs componentsJoinedByString:@"&"]; 34 | 35 | NSString *urlString = [NSString stringWithFormat:@"%@%@%@", schemeStr, prefix, queryStr]; 36 | return [NSURL URLWithString:urlString]; 37 | } 38 | 39 | -(NSDictionary *)queryParams { 40 | if(!self.query) { 41 | return nil; 42 | } 43 | 44 | NSMutableDictionary *ret = [NSMutableDictionary dictionary]; 45 | NSArray *keyValuePairs = [self.query componentsSeparatedByString:@"&"]; 46 | for(id kv in keyValuePairs) { 47 | NSArray *kvPair = [kv componentsSeparatedByString:@"="]; 48 | NSString *key = [kvPair objectAtIndex:0]; 49 | NSString *value = [kvPair objectAtIndex:1]; 50 | CFStringRef origStr = 51 | CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, 52 | (CFStringRef)(value), 53 | CFSTR(""), 54 | kCFStringEncodingUTF8); 55 | [ret setValue:(__bridge NSString*)(origStr) forKey:key]; 56 | if (origStr) { 57 | CFRelease(origStr); 58 | } 59 | } 60 | 61 | return ret; 62 | } 63 | @end 64 | -------------------------------------------------------------------------------- /YYDebugDatabase.xcodeproj/xcshareddata/xcschemes/iOSDebugDatabase-iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 72 | 73 | 74 | 75 | 77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /YYDebugDatabase/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // YYDebugDatabase 4 | // 5 | // Created by wentian on 17/8/9. 6 | // Copyright © 2017年 wentian. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "DebugDatabaseManager.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | // Override point for customization after application launch. 21 | 22 | NSFileManager*fileManager =[NSFileManager defaultManager]; 23 | NSError*error; 24 | NSArray*paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES); 25 | NSString*documentsDirectory =[paths objectAtIndex:0]; 26 | 27 | NSString*txtPath =[documentsDirectory stringByAppendingPathComponent:@"document.db"]; 28 | 29 | if([fileManager fileExistsAtPath:txtPath]== NO){ 30 | NSString*resourcePath =[[NSBundle mainBundle] pathForResource:@"Car" ofType:@"db"]; 31 | [fileManager copyItemAtPath:resourcePath toPath:txtPath error:&error]; 32 | NSLog(@"%@", error); 33 | } 34 | 35 | NSString *resourceDirectory = [[NSBundle mainBundle] resourcePath]; 36 | NSString *databaseDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/database"]; 37 | NSString *documentDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; 38 | NSString *cacheDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Cache"]; 39 | [[DebugDatabaseManager shared] startServerOnPort:9002 directories:@[resourceDirectory, databaseDirectory, documentDirectory, cacheDirectory]]; 40 | 41 | return YES; 42 | } 43 | 44 | 45 | - (void)applicationWillResignActive:(UIApplication *)application { 46 | // 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. 47 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 48 | } 49 | 50 | 51 | - (void)applicationDidEnterBackground:(UIApplication *)application { 52 | // 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. 53 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 54 | } 55 | 56 | 57 | - (void)applicationWillEnterForeground:(UIApplication *)application { 58 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 59 | } 60 | 61 | 62 | - (void)applicationDidBecomeActive:(UIApplication *)application { 63 | // 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. 64 | } 65 | 66 | 67 | - (void)applicationWillTerminate:(UIApplication *)application { 68 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 69 | } 70 | 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /DebugDatabase/Web.bundle/select.dataTables.min.css: -------------------------------------------------------------------------------- 1 | table.dataTable tbody>tr.selected,table.dataTable tbody>tr>.selected{background-color:#B0BED9}table.dataTable.stripe tbody>tr.odd.selected,table.dataTable.stripe tbody>tr.odd>.selected,table.dataTable.display tbody>tr.odd.selected,table.dataTable.display tbody>tr.odd>.selected{background-color:#acbad4}table.dataTable.hover tbody>tr.selected:hover,table.dataTable.hover tbody>tr>.selected:hover,table.dataTable.display tbody>tr.selected:hover,table.dataTable.display tbody>tr>.selected:hover{background-color:#aab7d1}table.dataTable.order-column tbody>tr.selected>.sorting_1,table.dataTable.order-column tbody>tr.selected>.sorting_2,table.dataTable.order-column tbody>tr.selected>.sorting_3,table.dataTable.order-column tbody>tr>.selected,table.dataTable.display tbody>tr.selected>.sorting_1,table.dataTable.display tbody>tr.selected>.sorting_2,table.dataTable.display tbody>tr.selected>.sorting_3,table.dataTable.display tbody>tr>.selected{background-color:#acbad5}table.dataTable.display tbody>tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe tbody>tr.odd.selected>.sorting_1{background-color:#a6b4cd}table.dataTable.display tbody>tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe tbody>tr.odd.selected>.sorting_2{background-color:#a8b5cf}table.dataTable.display tbody>tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe tbody>tr.odd.selected>.sorting_3{background-color:#a9b7d1}table.dataTable.display tbody>tr.even.selected>.sorting_1,table.dataTable.order-column.stripe tbody>tr.even.selected>.sorting_1{background-color:#acbad5}table.dataTable.display tbody>tr.even.selected>.sorting_2,table.dataTable.order-column.stripe tbody>tr.even.selected>.sorting_2{background-color:#aebcd6}table.dataTable.display tbody>tr.even.selected>.sorting_3,table.dataTable.order-column.stripe tbody>tr.even.selected>.sorting_3{background-color:#afbdd8}table.dataTable.display tbody>tr.odd>.selected,table.dataTable.order-column.stripe tbody>tr.odd>.selected{background-color:#a6b4cd}table.dataTable.display tbody>tr.even>.selected,table.dataTable.order-column.stripe tbody>tr.even>.selected{background-color:#acbad5}table.dataTable.display tbody>tr.selected:hover>.sorting_1,table.dataTable.order-column.hover tbody>tr.selected:hover>.sorting_1{background-color:#a2aec7}table.dataTable.display tbody>tr.selected:hover>.sorting_2,table.dataTable.order-column.hover tbody>tr.selected:hover>.sorting_2{background-color:#a3b0c9}table.dataTable.display tbody>tr.selected:hover>.sorting_3,table.dataTable.order-column.hover tbody>tr.selected:hover>.sorting_3{background-color:#a5b2cb}table.dataTable.display tbody>tr:hover>.selected,table.dataTable.display tbody>tr>.selected:hover,table.dataTable.order-column.hover tbody>tr:hover>.selected,table.dataTable.order-column.hover tbody>tr>.selected:hover{background-color:#a2aec7}table.dataTable td.select-checkbox{position:relative}table.dataTable td.select-checkbox:before,table.dataTable td.select-checkbox:after{display:block;position:absolute;top:1.2em;left:50%;width:12px;height:12px;box-sizing:border-box}table.dataTable td.select-checkbox:before{content:' ';margin-top:-6px;margin-left:-6px;border:1px solid black;border-radius:3px}table.dataTable tr.selected td.select-checkbox:after{content:'\2714';margin-top:-11px;margin-left:-4px;text-align:center;text-shadow:1px 1px #B0BED9, -1px -1px #B0BED9, 1px -1px #B0BED9, -1px 1px #B0BED9}div.dataTables_wrapper span.select-info,div.dataTables_wrapper span.select-item{margin-left:0.5em}@media screen and (max-width: 640px){div.dataTables_wrapper span.select-info,div.dataTables_wrapper span.select-item{margin-left:0;display:block}} 2 | -------------------------------------------------------------------------------- /DebugDatabase/NSMutableDictionary+safe.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableDictionary+safe.m 3 | // categories 4 | // 5 | // Created by wentian on 17/6/1. 6 | // 7 | // 8 | 9 | #import "NSMutableDictionary+safe.h" 10 | 11 | @implementation NSMutableDictionary (safe) 12 | 13 | - (void)safe_setObject:(id)anObject forKey:(id)aKey { 14 | if (aKey) { 15 | if (!anObject) { 16 | [self removeObjectForKey:aKey]; 17 | } 18 | else { 19 | [self setObject:anObject forKey:aKey]; 20 | } 21 | } 22 | } 23 | 24 | @end 25 | 26 | // - - - 27 | id yy_dicGetObject(NSDictionary * dic, id aKey, Class aClass) { 28 | id result = [dic objectForKey:aKey]; 29 | if (result && [result isKindOfClass:aClass]) { 30 | return result; 31 | } 32 | return nil; 33 | } 34 | 35 | // - - - 36 | NSDictionary * yy_dicGetDic(NSDictionary *dic, id aKey) { 37 | return (NSDictionary *)yy_dicGetObject(dic, aKey, [NSDictionary class]); 38 | } 39 | 40 | NSArray * yy_dicGetArray(NSDictionary *dic, id aKey) { 41 | return (NSArray *)yy_dicGetObject(dic, aKey, [NSArray class]); 42 | } 43 | 44 | NSArray * yy_dicGetArraySafe(NSDictionary *dic, id aKey) { 45 | if ([dic objectForKey:aKey] && ![[dic objectForKey:aKey] isKindOfClass:[NSArray class]]) 46 | { 47 | return [NSArray arrayWithObject:[dic objectForKey:aKey]]; 48 | } 49 | return yy_dicGetArray(dic, aKey); 50 | } 51 | 52 | // - - - 53 | NSString * yy_dicGetString(NSDictionary *dic, id aKey) { 54 | if (dic == nil || ![dic isKindOfClass:[NSDictionary class]]) { 55 | return nil; 56 | } 57 | id result = [dic objectForKey:aKey]; 58 | if (result && [result isKindOfClass:[NSNumber class]]) { 59 | return [NSString stringWithFormat:@"%@",result]; 60 | } else if (result && [result isKindOfClass:[NSString class]]) { 61 | return (NSString *)result; 62 | } 63 | return nil; 64 | } 65 | 66 | NSString * yy_dicGetStringSafe(NSDictionary *dic, id aKey) { 67 | if (yy_dicGetString(dic, aKey) && yy_dicGetString(dic, aKey).length > 0) { 68 | return yy_dicGetString(dic, aKey); 69 | } 70 | return @""; 71 | } 72 | 73 | // - - - 74 | int yy_dicGetInt(NSDictionary *dic, id aKey, int nDefault) { 75 | if (dic) { 76 | id result = [dic objectForKey:aKey]; 77 | if (result && [result isKindOfClass:[NSNumber class]]) { 78 | return [(NSNumber *)result intValue]; 79 | } 80 | else if (result && [result isKindOfClass:[NSString class]]) { 81 | return [(NSString *)result intValue]; 82 | } 83 | } 84 | return nDefault; 85 | } 86 | 87 | float yy_dicGetFloat(NSDictionary *dic, id aKey, float fDefault) { 88 | if (dic) { 89 | id result = [dic objectForKey:aKey]; 90 | if (result && [result isKindOfClass:[NSNumber class]]) { 91 | return [(NSNumber *)result floatValue]; 92 | } 93 | else if (result && [result isKindOfClass:[NSString class]]) { 94 | return [(NSString *)result floatValue]; 95 | } 96 | } 97 | return fDefault; 98 | } 99 | 100 | BOOL yy_dicGetBool(NSDictionary *dic, id aKey, BOOL bDefault) { 101 | if (dic) { 102 | id result = [dic objectForKey:aKey]; 103 | if (result && [result isKindOfClass:[NSNumber class]]) { 104 | return [(NSNumber *)result boolValue]; 105 | } 106 | else if (result && [result isKindOfClass:[NSString class]]) { 107 | return [(NSString *)result boolValue]; 108 | } 109 | } 110 | return bDefault; 111 | } 112 | -------------------------------------------------------------------------------- /DebugDatabase/Web.bundle/responsive.dataTables.min.css: -------------------------------------------------------------------------------- 1 | table.dataTable.dtr-inline.collapsed>tbody>tr>td.child,table.dataTable.dtr-inline.collapsed>tbody>tr>th.child,table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty{cursor:default !important}table.dataTable.dtr-inline.collapsed>tbody>tr>td.child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>th.child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty:before{display:none !important}table.dataTable.dtr-inline.collapsed>tbody>tr>td:first-child,table.dataTable.dtr-inline.collapsed>tbody>tr>th:first-child{position:relative;padding-left:30px;cursor:pointer}table.dataTable.dtr-inline.collapsed>tbody>tr>td:first-child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>th:first-child:before{top:8px;left:4px;height:16px;width:16px;display:block;position:absolute;color:white;border:2px solid white;border-radius:16px;box-shadow:0 0 3px #444;box-sizing:content-box;text-align:left;font-family:'Courier New', Courier, monospace;text-indent:4px;line-height:16px;content:'+';background-color:#31b131}table.dataTable.dtr-inline.collapsed>tbody>tr.parent>td:first-child:before,table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th:first-child:before{content:'-';background-color:#d33333}table.dataTable.dtr-inline.collapsed>tbody>tr.child td:before{display:none}table.dataTable.dtr-inline.collapsed.compact>tbody>tr>td:first-child,table.dataTable.dtr-inline.collapsed.compact>tbody>tr>th:first-child{padding-left:27px}table.dataTable.dtr-inline.collapsed.compact>tbody>tr>td:first-child:before,table.dataTable.dtr-inline.collapsed.compact>tbody>tr>th:first-child:before{top:5px;left:4px;height:14px;width:14px;border-radius:14px;line-height:14px;text-indent:3px}table.dataTable.dtr-column>tbody>tr>td.control,table.dataTable.dtr-column>tbody>tr>th.control{position:relative;cursor:pointer}table.dataTable.dtr-column>tbody>tr>td.control:before,table.dataTable.dtr-column>tbody>tr>th.control:before{top:50%;left:50%;height:16px;width:16px;margin-top:-10px;margin-left:-10px;display:block;position:absolute;color:white;border:2px solid white;border-radius:16px;box-shadow:0 0 3px #444;box-sizing:content-box;text-align:left;font-family:'Courier New', Courier, monospace;text-indent:4px;line-height:16px;content:'+';background-color:#31b131}table.dataTable.dtr-column>tbody>tr.parent td.control:before,table.dataTable.dtr-column>tbody>tr.parent th.control:before{content:'-';background-color:#d33333}table.dataTable>tbody>tr.child{padding:0.5em 1em}table.dataTable>tbody>tr.child:hover{background:transparent !important}table.dataTable>tbody>tr.child ul{display:inline-block;list-style-type:none;margin:0;padding:0}table.dataTable>tbody>tr.child ul li{border-bottom:1px solid #efefef;padding:0.5em 0}table.dataTable>tbody>tr.child ul li:first-child{padding-top:0}table.dataTable>tbody>tr.child ul li:last-child{border-bottom:none}table.dataTable>tbody>tr.child span.dtr-title{display:inline-block;min-width:75px;font-weight:bold}div.dtr-modal{position:fixed;box-sizing:border-box;top:0;left:0;height:100%;width:100%;z-index:100;padding:10em 1em}div.dtr-modal div.dtr-modal-display{position:absolute;top:0;left:0;bottom:0;right:0;width:50%;height:50%;overflow:auto;margin:auto;z-index:102;overflow:auto;background-color:#f5f5f7;border:1px solid black;border-radius:0.5em;box-shadow:0 12px 30px rgba(0,0,0,0.6)}div.dtr-modal div.dtr-modal-content{position:relative;padding:1em}div.dtr-modal div.dtr-modal-close{position:absolute;top:6px;right:6px;width:22px;height:22px;border:1px solid #eaeaea;background-color:#f9f9f9;text-align:center;border-radius:3px;cursor:pointer;z-index:12}div.dtr-modal div.dtr-modal-close:hover{background-color:#eaeaea}div.dtr-modal div.dtr-modal-background{position:fixed;top:0;left:0;right:0;bottom:0;z-index:101;background:rgba(0,0,0,0.6)}@media screen and (max-width: 767px){div.dtr-modal div.dtr-modal-display{width:95%}} 2 | -------------------------------------------------------------------------------- /YYDebugDatabase.xcodeproj/xcuserdata/wentian.xcuserdatad/xcschemes/YYDebugDatabase.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 | -------------------------------------------------------------------------------- /SwiftDebugDatabase/SwiftDebugDatabase.xcodeproj/xcuserdata/wentian.xcuserdatad/xcschemes/SwiftDebugDatabase.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /DebugDatabase/Web.bundle/appinfo.html: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | YYDebugDatabase - iOS Database Debugging 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 80 | 81 | 82 |
83 |
84 | 85 |
86 |
87 |
App Infomation
88 |
89 |
90 |
91 |
92 |
93 |
Userdefault
94 |
95 |
96 |
97 | 98 |
Data Updated Successfully
99 | 100 |
101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # YYDebugDatabase 2 | 3 | ### YYDebugDatabase is a powerful library for debugging databases in iOS applications. Which like [Android Debug database](https://github.com/amitshekhariitbhu/Android-Debug-Database) 4 | 5 | ### YYDebugDatabase allows you to view and edit databases directly in your browser in a very simple way. 6 | 7 | ### What can YYDebugDatabase do? 8 | - [x] See all the databases. 9 | - [x] Run any sql query on the given database to update and delete your data. 10 | - [x] Directly edit the database values. 11 | - [x] Directly add a row in the database. 12 | - [x] Delete database rows. 13 | - [x] Search in your data. 14 | - [x] Sort data. 15 | - [x] Download database. 16 | 17 | 18 | # Release 2.0.0: 19 | * **Replace CocoaAsyncSocket with GCDWebServer, which is higher level server that more convenient.** 20 | * **Satisfy with Firefox, Safari, Chrome.** 21 | * **Use bonjourname as the server address, for example: http://y500.local, http://macbook.local:9002...** 22 | * **print link address and bonjour name of the server in the console** 23 | 24 | 25 | # Installation 26 | 27 | #### Podfile 28 | 29 | To integrate YYDebugDatabase into your Xcode project using CocoaPods, specify it in your `Podfile`: 30 | 31 | ```ruby 32 | pod 'YYDebugDatabase' 33 | ``` 34 | 35 | If use Swift, remember to add `use_frameworks!` 36 | 37 | ```ruby 38 | use_frameworks! 39 | pod 'YYDebugDatabase' 40 | ``` 41 | 42 | #### Carthage 43 | 44 | - Cartfile 45 | 46 | ``` 47 | github "y500/iOSDebugDatabase" 48 | ``` 49 | 50 | - run `carthage update` 51 | 52 | - Add all three `.frameworks` to your target "Embedd Frameworks" Build Phase: 53 | - `iOSDebugDatabase.framework` 54 | - `FMDB.framework` 55 | - `GCDWebServers.framework` 56 | 57 | 58 | #### Not build in Release 59 | 60 | First, add configurations in Podfile. 61 | 62 | ```ruby 63 | pod 'YYDebugDatabase', :configurations => ['Debug'] 64 | ``` 65 | 66 | 67 | Then, run the following command: 68 | 69 | ```bash 70 | $ pod install 71 | ``` 72 | 73 | # USage 74 | 75 | import at AppDelegate.m: 76 | 77 | ```objc 78 | #import DebugDatabaseManager.h 79 | ``` 80 | 81 | making one line code at `application:didFinishLaunchingWithOptions`: 82 | 83 | ```objc 84 | [[DebugDatabaseManager shared] startServerOnPort:9002]; 85 | ``` 86 | #### Not run in Release 87 | 88 | ```objc 89 | #ifdef DEBUG 90 | [[DebugDatabaseManager shared] startServerOnPort:9002]; 91 | #end 92 | ``` 93 | 94 | If use Swift: 95 | 96 | import at Appdelegate.swift: 97 | 98 | ```swift 99 | import YYDebugDatabase 100 | ``` 101 | making one line code at `application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?)`: 102 | 103 | ```Swift: 104 | DebugDatabaseManager.shared().startServer(onPort: 9002); 105 | ``` 106 | 107 | # Advanced 108 | 109 | It only shows the databasesin in Documents directory and Library/Cache directory by default, if you want show databases in other directories, you can use: 110 | 111 | ```objc 112 | - (void)startServerOnPort:(NSInteger)port directories:(NSArray*)directories 113 | ``` 114 | for example: 115 | 116 | ```objc 117 | NSString *resourceDirectory = [[NSBundle mainBundle] resourcePath]; 118 | NSString *databaseDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/database"]; 119 | NSString *documentDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; 120 | NSString *cacheDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Cache"]; 121 | [[DebugDatabaseManager shared] startServerOnPort:9002 directories:@[resourceDirectory, databaseDirectory, documentDirectory, cacheDirectory]]; 122 | ``` 123 | If use Swift: 124 | 125 | ```swift 126 | let directory:String = (Bundle.main.resourcePath)!; 127 | let documentsPath:String = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] 128 | let cachePath:String = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0] 129 | DebugDatabaseManager.shared().startServer(onPort: 9002, directories: [directory, documentsPath, cachePath]); 130 | ``` 131 | 132 | That’s all(you can look at the Demo for details), just start the application : 133 | 134 | Now open the provided link in your browser, and you will see like this: 135 | 136 | ![](http://notiimg.y500.me/693916a699a78a1c01da2d93126c0ed71.png) 137 | 138 | query: 139 | 140 | ![](http://notiimg.y500.me/21dd97948e85cf928751ef6d2b7d92662.png) 141 | 142 | edit: 143 | 144 | ![](http://notiimg.y500.me/b081fa0e1842a05c23321d08f7cec6683.png) 145 | 146 | delete: 147 | 148 | ![](http://notiimg.y500.me/d0c7cb82ae6aadf790dc57da6c6e888f4.png) 149 | 150 | 151 | Important: 152 | - Your iPhone and laptop should be connected to the same Network (Wifi or LAN). 153 | - the host of you link address is the iPhone's net address. 154 | - If you use Simulator you can use address: http://127.0.0.1:9002. 155 | - the port must be same as you write in Appdelegate.m 156 | 157 | ###other more: 158 | 159 | you can find the address and bojourname address in the console like below: 160 | ``` 161 | [INFO] DebugDatabaseManager started on port 9002 and reachable at http://192.168.0.67:9002/ 162 | [INFO] DebugDatabaseManager now locally reachable at http://y500.local:9002/ 163 | ``` 164 | 165 | 166 | ### License 167 | ``` 168 | Copyright (C) 2016 y500 169 | 170 | Licensed under the Apache License, Version 2.0 (the "License"); 171 | you may not use this file except in compliance with the License. 172 | You may obtain a copy of the License at 173 | 174 | http://www.apache.org/licenses/LICENSE-2.0 175 | 176 | Unless required by applicable law or agreed to in writing, software 177 | distributed under the License is distributed on an "AS IS" BASIS, 178 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 179 | See the License for the specific language governing permissions and 180 | limitations under the License. 181 | ``` 182 | 183 | -------------------------------------------------------------------------------- /DebugDatabase/Web.bundle/index.html: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | YYDebugDatabase - iOS Database Debugging 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 80 | 81 | 82 |
83 | 84 |
85 |
86 |
87 | 88 | 89 |
90 | 93 | 97 |
98 |
99 | 100 | 101 |
102 | 103 |
104 |
105 |
Databases
106 |
107 |
108 |
109 |
110 | 111 |
112 |
113 |
Tables
114 |
115 |
116 |
117 |
118 | 119 |
120 |
121 |
Data
122 |
123 |
124 |
125 | 126 |
Data Updated Successfully
127 | 128 |
129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /DebugDatabase/Web.bundle/buttons.dataTables.min.css: -------------------------------------------------------------------------------- 1 | div.dt-button-info{position:fixed;top:50%;left:50%;width:400px;margin-top:-100px;margin-left:-200px;background-color:white;border:2px solid #111;box-shadow:3px 3px 8px rgba(0,0,0,0.3);border-radius:3px;text-align:center;z-index:21}div.dt-button-info h2{padding:0.5em;margin:0;font-weight:normal;border-bottom:1px solid #ddd;background-color:#f3f3f3}div.dt-button-info>div{padding:1em}button.dt-button,div.dt-button,a.dt-button{position:relative;display:inline-block;box-sizing:border-box;margin-right:0.333em;padding:0.5em 1em;border:1px solid #999;border-radius:2px;cursor:pointer;font-size:0.88em;color:black;white-space:nowrap;overflow:hidden;background-color:#e9e9e9;background-image:-webkit-linear-gradient(top, #fff 0%, #e9e9e9 100%);background-image:-moz-linear-gradient(top, #fff 0%, #e9e9e9 100%);background-image:-ms-linear-gradient(top, #fff 0%, #e9e9e9 100%);background-image:-o-linear-gradient(top, #fff 0%, #e9e9e9 100%);background-image:linear-gradient(top, #fff 0%, #e9e9e9 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='white', EndColorStr='#e9e9e9');-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-decoration:none;outline:none}button.dt-button.disabled,div.dt-button.disabled,a.dt-button.disabled{color:#999;border:1px solid #d0d0d0;cursor:default;background-color:#f9f9f9;background-image:-webkit-linear-gradient(top, #fff 0%, #f9f9f9 100%);background-image:-moz-linear-gradient(top, #fff 0%, #f9f9f9 100%);background-image:-ms-linear-gradient(top, #fff 0%, #f9f9f9 100%);background-image:-o-linear-gradient(top, #fff 0%, #f9f9f9 100%);background-image:linear-gradient(top, #fff 0%, #f9f9f9 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#ffffff', EndColorStr='#f9f9f9')}button.dt-button:active:not(.disabled),button.dt-button.active:not(.disabled),div.dt-button:active:not(.disabled),div.dt-button.active:not(.disabled),a.dt-button:active:not(.disabled),a.dt-button.active:not(.disabled){background-color:#e2e2e2;background-image:-webkit-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);background-image:-moz-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);background-image:-ms-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);background-image:-o-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);background-image:linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f3f3f3', EndColorStr='#e2e2e2');box-shadow:inset 1px 1px 3px #999999}button.dt-button:active:not(.disabled):hover:not(.disabled),button.dt-button.active:not(.disabled):hover:not(.disabled),div.dt-button:active:not(.disabled):hover:not(.disabled),div.dt-button.active:not(.disabled):hover:not(.disabled),a.dt-button:active:not(.disabled):hover:not(.disabled),a.dt-button.active:not(.disabled):hover:not(.disabled){box-shadow:inset 1px 1px 3px #999999;background-color:#cccccc;background-image:-webkit-linear-gradient(top, #eaeaea 0%, #ccc 100%);background-image:-moz-linear-gradient(top, #eaeaea 0%, #ccc 100%);background-image:-ms-linear-gradient(top, #eaeaea 0%, #ccc 100%);background-image:-o-linear-gradient(top, #eaeaea 0%, #ccc 100%);background-image:linear-gradient(top, #eaeaea 0%, #ccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#eaeaea', EndColorStr='#cccccc')}button.dt-button:hover,div.dt-button:hover,a.dt-button:hover{text-decoration:none}button.dt-button:hover:not(.disabled),div.dt-button:hover:not(.disabled),a.dt-button:hover:not(.disabled){border:1px solid #666;background-color:#e0e0e0;background-image:-webkit-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);background-image:-moz-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);background-image:-ms-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);background-image:-o-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);background-image:linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f9f9f9', EndColorStr='#e0e0e0')}button.dt-button:focus:not(.disabled),div.dt-button:focus:not(.disabled),a.dt-button:focus:not(.disabled){border:1px solid #426c9e;text-shadow:0 1px 0 #c4def1;outline:none;background-color:#79ace9;background-image:-webkit-linear-gradient(top, #bddef4 0%, #79ace9 100%);background-image:-moz-linear-gradient(top, #bddef4 0%, #79ace9 100%);background-image:-ms-linear-gradient(top, #bddef4 0%, #79ace9 100%);background-image:-o-linear-gradient(top, #bddef4 0%, #79ace9 100%);background-image:linear-gradient(top, #bddef4 0%, #79ace9 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#bddef4', EndColorStr='#79ace9')}.dt-button embed{outline:none}div.dt-buttons{position:relative;float:left}div.dt-buttons.buttons-right{float:right}div.dt-button-collection{position:absolute;top:0;left:0;width:150px;margin-top:3px;padding:8px 8px 4px 8px;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.4);background-color:white;overflow:hidden;z-index:2002;border-radius:5px;box-shadow:3px 3px 5px rgba(0,0,0,0.3);z-index:2002;-webkit-column-gap:8px;-moz-column-gap:8px;-ms-column-gap:8px;-o-column-gap:8px;column-gap:8px}div.dt-button-collection button.dt-button,div.dt-button-collection div.dt-button,div.dt-button-collection a.dt-button{position:relative;left:0;right:0;display:block;float:none;margin-bottom:4px;margin-right:0}div.dt-button-collection button.dt-button:active:not(.disabled),div.dt-button-collection button.dt-button.active:not(.disabled),div.dt-button-collection div.dt-button:active:not(.disabled),div.dt-button-collection div.dt-button.active:not(.disabled),div.dt-button-collection a.dt-button:active:not(.disabled),div.dt-button-collection a.dt-button.active:not(.disabled){background-color:#dadada;background-image:-webkit-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background-image:-moz-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background-image:-ms-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background-image:-o-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background-image:linear-gradient(top, #f0f0f0 0%, #dadada 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f0f0f0', EndColorStr='#dadada');box-shadow:inset 1px 1px 3px #666}div.dt-button-collection.fixed{position:fixed;top:50%;left:50%;margin-left:-75px;border-radius:0}div.dt-button-collection.fixed.two-column{margin-left:-150px}div.dt-button-collection.fixed.three-column{margin-left:-225px}div.dt-button-collection.fixed.four-column{margin-left:-300px}div.dt-button-collection>*{-webkit-column-break-inside:avoid;break-inside:avoid}div.dt-button-collection.two-column{width:300px;padding-bottom:1px;-webkit-column-count:2;-moz-column-count:2;-ms-column-count:2;-o-column-count:2;column-count:2}div.dt-button-collection.three-column{width:450px;padding-bottom:1px;-webkit-column-count:3;-moz-column-count:3;-ms-column-count:3;-o-column-count:3;column-count:3}div.dt-button-collection.four-column{width:600px;padding-bottom:1px;-webkit-column-count:4;-moz-column-count:4;-ms-column-count:4;-o-column-count:4;column-count:4}div.dt-button-background{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.7);background:-ms-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%);background:-moz-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%);background:-o-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%);background:-webkit-gradient(radial, center center, 0, center center, 497, color-stop(0, rgba(0,0,0,0.3)), color-stop(1, rgba(0,0,0,0.7)));background:-webkit-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%);background:radial-gradient(ellipse farthest-corner at center, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%);z-index:2001}@media screen and (max-width: 640px){div.dt-buttons{float:none !important;text-align:center}} 2 | -------------------------------------------------------------------------------- /DebugDatabase/Web.bundle/dataTables.responsive.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Responsive 2.0.2 3 | 2014-2016 SpryMedia Ltd - datatables.net/license 4 | */ 5 | (function(c){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(j){return c(j,window,document)}):"object"===typeof exports?module.exports=function(j,k){j||(j=window);if(!k||!k.fn.dataTable)k=require("datatables.net")(j,k).$;return c(k,j,j.document)}:c(jQuery,window,document)})(function(c,j,k,p){var n=c.fn.dataTable,l=function(a,b){if(!n.versionCheck||!n.versionCheck("1.10.3"))throw"DataTables Responsive requires DataTables 1.10.3 or newer";this.s={dt:new n.Api(a),columns:[], 6 | current:[]};this.s.dt.settings()[0].responsive||(b&&"string"===typeof b.details?b.details={type:b.details}:b&&!1===b.details?b.details={type:!1}:b&&!0===b.details&&(b.details={type:"inline"}),this.c=c.extend(!0,{},l.defaults,n.defaults.responsive,b),a.responsive=this,this._constructor())};c.extend(l.prototype,{_constructor:function(){var a=this,b=this.s.dt,d=b.settings()[0],e=c(j).width();b.settings()[0]._responsive=this;c(j).on("resize.dtr orientationchange.dtr",n.util.throttle(function(){var b= 7 | c(j).width();b!==e&&(a._resize(),e=b)}));d.oApi._fnCallbackReg(d,"aoRowCreatedCallback",function(e){-1!==c.inArray(!1,a.s.current)&&c("td, th",e).each(function(e){e=b.column.index("toData",e);!1===a.s.current[e]&&c(this).css("display","none")})});b.on("destroy.dtr",function(){b.off(".dtr");c(b.table().body()).off(".dtr");c(j).off("resize.dtr orientationchange.dtr");c.each(a.s.current,function(b,e){!1===e&&a._setColumnVis(b,!0)})});this.c.breakpoints.sort(function(a,b){return a.width 8 | b.width?-1:0});this._classLogic();this._resizeAuto();d=this.c.details;!1!==d.type&&(a._detailsInit(),b.on("column-visibility.dtr",function(){a._classLogic();a._resizeAuto();a._resize()}),b.on("draw.dtr",function(){a._redrawChildren()}),c(b.table().node()).addClass("dtr-"+d.type));b.on("column-reorder.dtr",function(){a._classLogic();a._resizeAuto();a._resize()});b.on("column-sizing.dtr",function(){a._resize()});b.on("init.dtr",function(){a._resizeAuto();a._resize();c.inArray(false,a.s.current)&&b.columns.adjust()}); 9 | this._resize()},_columnsVisiblity:function(a){var b=this.s.dt,d=this.s.columns,e,f,g=d.map(function(a,b){return{columnIdx:b,priority:a.priority}}).sort(function(a,b){return a.priority!==b.priority?a.priority-b.priority:a.columnIdx-b.columnIdx}),h=c.map(d,function(b){return b.auto&&null===b.minWidth?!1:!0===b.auto?"-":-1!==c.inArray(a,b.includeIn)}),m=0;e=0;for(f=h.length;eb-d[i].minWidth?(m=!0,h[i]=!1):h[i]=!0,b-=d[i].minWidth)}g=!1;e=0;for(f=d.length;e= 12 | g&&f(c,b[d].name)}else{if("not-"===i){d=0;for(i=b.length;d").append(h).appendTo(f)}c("").append(g).appendTo(e);"inline"===this.c.details.type&&c(d).addClass("dtr-inline collapsed");d=c("
").css({width:1,height:1,overflow:"hidden"}).append(d);d.insertBefore(a.table().node()); 19 | g.each(function(c){c=a.column.index("fromVisible",c);b[c].minWidth=this.offsetWidth||0});d.remove()}},_setColumnVis:function(a,b){var d=this.s.dt,e=b?"":"none";c(d.column(a).header()).css("display",e);c(d.column(a).footer()).css("display",e);d.column(a).nodes().to$().css("display",e)},_tabIndexes:function(){var a=this.s.dt,b=a.cells({page:"current"}).nodes().to$(),d=a.settings()[0],e=this.c.details.target;b.filter("[data-dtr-keyboard]").removeData("[data-dtr-keyboard]");c("number"===typeof e?":eq("+ 20 | e+")":e,a.rows({page:"current"}).nodes()).attr("tabIndex",d.iTabIndex).data("dtr-keyboard",1)}});l.breakpoints=[{name:"desktop",width:Infinity},{name:"tablet-l",width:1024},{name:"tablet-p",width:768},{name:"mobile-l",width:480},{name:"mobile-p",width:320}];l.display={childRow:function(a,b,d){if(b){if(c(a.node()).hasClass("parent"))return a.child(d(),"child").show(),!0}else{if(a.child.isShown())return a.child(!1),c(a.node()).removeClass("parent"),!1;a.child(d(),"child").show();c(a.node()).addClass("parent"); 21 | return!0}},childRowImmediate:function(a,b,d){if(!b&&a.child.isShown()||!a.responsive.hasHidden())return a.child(!1),c(a.node()).removeClass("parent"),!1;a.child(d(),"child").show();c(a.node()).addClass("parent");return!0},modal:function(a){return function(b,d,e){if(d)c("div.dtr-modal-content").empty().append(e());else{var f=function(){g.remove();c(k).off("keypress.dtr")},g=c('
').append(c('
').append(c('
').append(e())).append(c('
×
').click(function(){f()}))).append(c('
').click(function(){f()})).appendTo("body"); 22 | c(k).on("keyup.dtr",function(a){27===a.keyCode&&(a.stopPropagation(),f())})}a&&a.header&&c("div.dtr-modal-content").prepend("

"+a.header(b)+"

")}}};l.defaults={breakpoints:l.breakpoints,auto:!0,details:{display:l.display.childRow,renderer:function(a,b,d){return(a=c.map(d,function(a){return a.hidden?'
  • '+a.title+' '+a.data+"
  • ": 23 | ""}).join(""))?c('
      ').append(a):!1},target:0,type:"inline"},orthogonal:"display"};var o=c.fn.dataTable.Api;o.register("responsive()",function(){return this});o.register("responsive.index()",function(a){a=c(a);return{column:a.data("dtr-index"),row:a.parent().data("dtr-index")}});o.register("responsive.rebuild()",function(){return this.iterator("table",function(a){a._responsive&&a._responsive._classLogic()})});o.register("responsive.recalc()",function(){return this.iterator("table", 24 | function(a){a._responsive&&(a._responsive._resizeAuto(),a._responsive._resize())})});o.register("responsive.hasHidden()",function(){var a=this.context[0];return a._responsive?-1!==c.inArray(!1,a._responsive.s.current):!1});l.version="2.0.2";c.fn.dataTable.Responsive=l;c.fn.DataTable.Responsive=l;c(k).on("preInit.dt.dtr",function(a,b){if("dt"===a.namespace&&(c(b.nTable).hasClass("responsive")||c(b.nTable).hasClass("dt-responsive")||b.oInit.responsive||n.defaults.responsive)){var d=b.oInit.responsive; 25 | !1!==d&&new l(b,c.isPlainObject(d)?d:{})}});return l}); 26 | -------------------------------------------------------------------------------- /DebugDatabase/Web.bundle/dataTables.select.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Select for DataTables 1.1.2 3 | 2015-2016 SpryMedia Ltd - datatables.net/license/mit 4 | */ 5 | (function(e){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(j){return e(j,window,document)}):"object"===typeof exports?module.exports=function(j,l){j||(j=window);if(!l||!l.fn.dataTable)l=require("datatables.net")(j,l).$;return e(l,j,j.document)}:e(jQuery,window,document)})(function(e,j,l,i){function s(a){var b=a.settings()[0]._select.selector;e(a.table().body()).off("mousedown.dtSelect",b).off("mouseup.dtSelect",b).off("click.dtSelect",b);e("body").off("click.dtSelect")} 6 | function u(a){var b=e(a.table().body()),c=a.settings()[0],d=c._select.selector;b.on("mousedown.dtSelect",d,function(c){if(c.shiftKey)b.css("-moz-user-select","none").one("selectstart.dtSelect",d,function(){return!1})}).on("mouseup.dtSelect",d,function(){b.css("-moz-user-select","")}).on("click.dtSelect",d,function(c){var b=a.select.items();if(!j.getSelection||!j.getSelection().toString()){var d=a.settings()[0];if(e(c.target).closest("div.dataTables_wrapper")[0]==a.table().container()){var m=e(c.target).closest("td, th"), 7 | h=a.cell(m).index();a.cell(m).any()&&("row"===b?(b=h.row,t(c,a,d,"row",b)):"column"===b?(b=a.cell(m).index().column,t(c,a,d,"column",b)):"cell"===b&&(b=a.cell(m).index(),t(c,a,d,"cell",b)),d._select_lastCell=h)}}});e("body").on("click.dtSelect",function(b){c._select.blurable&&!e(b.target).parents().filter(a.table().container()).length&&(e(b.target).parents("div.DTE").length||q(c,!0))})}function k(a,b,c,d){if(!d||a.flatten().length)c.unshift(a),e(a.table().node()).triggerHandler(b+".dt",c)}function v(a){var b= 8 | a.settings()[0];if(b._select.info&&b.aanFeatures.i){var c=e(''),d=function(b,d){c.append(e('').append(a.i18n("select."+b+"s",{_:"%d "+b+"s selected","0":"",1:"1 "+b+" selected"},d)))};d("row",a.rows({selected:!0}).flatten().length);d("column",a.columns({selected:!0}).flatten().length);d("cell",a.cells({selected:!0}).flatten().length);e.each(b.aanFeatures.i,function(b,a){var a=e(a),d=a.children("span.select-info");d.length&&d.remove();""!==c.text()&& 9 | a.append(c)})}}function q(a,b){if(b||"single"===a._select.style){var c=new h.Api(a);c.rows({selected:!0}).deselect();c.columns({selected:!0}).deselect();c.cells({selected:!0}).deselect()}}function t(a,b,c,d,f){var n=b.select.style(),g=b[d](f,{selected:!0}).any();"os"===n?a.ctrlKey||a.metaKey?b[d](f).select(!g):a.shiftKey?"cell"===d?(d=c._select_lastCell||null,g=function(c,a){if(c>a)var d=a,a=c,c=d;var f=!1;return b.columns(":visible").indexes().filter(function(b){b===c&&(f=!0);return b===a?(f=!1, 10 | !0):f})},a=function(c,a){var d=b.rows({search:"applied"}).indexes();if(d.indexOf(c)>d.indexOf(a))var f=a,a=c,c=f;var g=!1;return d.filter(function(b){b===c&&(g=!0);return b===a?(g=!1,!0):g})},!b.cells({selected:!0}).any()&&!d?(g=g(0,f.column),d=a(0,f.row)):(g=g(d.column,f.column),d=a(d.row,f.row)),d=b.cells(d,g).flatten(),b.cells(f,{selected:!0}).any()?b.cells(d).deselect():b.cells(d).select()):(a=c._select_lastCell?c._select_lastCell[d]:null,g=b[d+"s"]({search:"applied"}).indexes(),a=e.inArray(a, 11 | g),c=e.inArray(f,g),!b[d+"s"]({selected:!0}).any()&&-1===a?g.splice(e.inArray(f,g)+1,g.length):(a>c&&(n=c,c=a,a=n),g.splice(c+1,g.length),g.splice(0,a)),b[d](f,{selected:!0}).any())?(g.splice(e.inArray(f,g),1),b[d+"s"](g).deselect()):b[d+"s"](g).select():(a=b[d+"s"]({selected:!0}),g&&1===a.flatten().length?b[d](f).deselect():(a.deselect(),b[d](f).select())):b[d](f).select(!g)}function r(a,b){return function(c){return c.i18n("buttons."+a,b)}}var h=e.fn.dataTable;h.select={};h.select.version="1.1.2"; 12 | h.select.init=function(a){var b=a.settings()[0],c=b.oInit.select,d=h.defaults.select,c=c===i?d:c,d="row",f="api",n=!1,g=!0,m="td, th",j="selected";b._select={};if(!0===c)f="os";else if("string"===typeof c)f=c;else if(e.isPlainObject(c)&&(c.blurable!==i&&(n=c.blurable),c.info!==i&&(g=c.info),c.items!==i&&(d=c.items),c.style!==i&&(f=c.style),c.selector!==i&&(m=c.selector),c.className!==i))j=c.className;a.select.selector(m);a.select.items(d);a.select.style(f);a.select.blurable(n);a.select.info(g);b._select.className= 13 | j;e.fn.dataTable.ext.order["select-checkbox"]=function(b,c){return this.api().column(c,{order:"index"}).nodes().map(function(c){return"row"===b._select.items?e(c).parent().hasClass(b._select.className):"cell"===b._select.items?e(c).hasClass(b._select.className):!1})};e(a.table().node()).hasClass("selectable")&&a.select.style("os")};e.each([{type:"row",prop:"aoData"},{type:"column",prop:"aoColumns"}],function(a,b){h.ext.selector[b.type].push(function(c,a,f){var a=a.selected,e,g=[];if(a===i)return f; 14 | for(var h=0,j=f.length;h.sorting_1,table.dataTable.order-column tbody tr>.sorting_2,table.dataTable.order-column tbody tr>.sorting_3,table.dataTable.display tbody tr>.sorting_1,table.dataTable.display tbody tr>.sorting_2,table.dataTable.display tbody tr>.sorting_3{background-color:#fafafa}table.dataTable.order-column tbody tr.selected>.sorting_1,table.dataTable.order-column tbody tr.selected>.sorting_2,table.dataTable.order-column tbody tr.selected>.sorting_3,table.dataTable.display tbody tr.selected>.sorting_1,table.dataTable.display tbody tr.selected>.sorting_2,table.dataTable.display tbody tr.selected>.sorting_3{background-color:#acbad5}table.dataTable.display tbody tr.odd>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd>.sorting_1{background-color:#f1f1f1}table.dataTable.display tbody tr.odd>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd>.sorting_2{background-color:#f3f3f3}table.dataTable.display tbody tr.odd>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd>.sorting_3{background-color:whitesmoke}table.dataTable.display tbody tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1{background-color:#a6b4cd}table.dataTable.display tbody tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2{background-color:#a8b5cf}table.dataTable.display tbody tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3{background-color:#a9b7d1}table.dataTable.display tbody tr.even>.sorting_1,table.dataTable.order-column.stripe tbody tr.even>.sorting_1{background-color:#fafafa}table.dataTable.display tbody tr.even>.sorting_2,table.dataTable.order-column.stripe tbody tr.even>.sorting_2{background-color:#fcfcfc}table.dataTable.display tbody tr.even>.sorting_3,table.dataTable.order-column.stripe tbody tr.even>.sorting_3{background-color:#fefefe}table.dataTable.display tbody tr.even.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1{background-color:#acbad5}table.dataTable.display tbody tr.even.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2{background-color:#aebcd6}table.dataTable.display tbody tr.even.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3{background-color:#afbdd8}table.dataTable.display tbody tr:hover>.sorting_1,table.dataTable.order-column.hover tbody tr:hover>.sorting_1{background-color:#eaeaea}table.dataTable.display tbody tr:hover>.sorting_2,table.dataTable.order-column.hover tbody tr:hover>.sorting_2{background-color:#ececec}table.dataTable.display tbody tr:hover>.sorting_3,table.dataTable.order-column.hover tbody tr:hover>.sorting_3{background-color:#efefef}table.dataTable.display tbody tr:hover.selected>.sorting_1,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{background-color:#a2aec7}table.dataTable.display tbody tr:hover.selected>.sorting_2,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{background-color:#a3b0c9}table.dataTable.display tbody tr:hover.selected>.sorting_3,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{background-color:#a5b2cb}table.dataTable.no-footer{border-bottom:1px solid #111}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable.compact thead th,table.dataTable.compact thead td{padding:4px 17px 4px 4px}table.dataTable.compact tfoot th,table.dataTable.compact tfoot td{padding:4px}table.dataTable.compact tbody th,table.dataTable.compact tbody td{padding:4px}table.dataTable th.dt-left,table.dataTable td.dt-left{text-align:left}table.dataTable th.dt-center,table.dataTable td.dt-center,table.dataTable td.dataTables_empty{text-align:center}table.dataTable th.dt-right,table.dataTable td.dt-right{text-align:right}table.dataTable th.dt-justify,table.dataTable td.dt-justify{text-align:justify}table.dataTable th.dt-nowrap,table.dataTable td.dt-nowrap{white-space:nowrap}table.dataTable thead th.dt-head-left,table.dataTable thead td.dt-head-left,table.dataTable tfoot th.dt-head-left,table.dataTable tfoot td.dt-head-left{text-align:left}table.dataTable thead th.dt-head-center,table.dataTable thead td.dt-head-center,table.dataTable tfoot th.dt-head-center,table.dataTable tfoot td.dt-head-center{text-align:center}table.dataTable thead th.dt-head-right,table.dataTable thead td.dt-head-right,table.dataTable tfoot th.dt-head-right,table.dataTable tfoot td.dt-head-right{text-align:right}table.dataTable thead th.dt-head-justify,table.dataTable thead td.dt-head-justify,table.dataTable tfoot th.dt-head-justify,table.dataTable tfoot td.dt-head-justify{text-align:justify}table.dataTable thead th.dt-head-nowrap,table.dataTable thead td.dt-head-nowrap,table.dataTable tfoot th.dt-head-nowrap,table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}table.dataTable tbody th.dt-body-left,table.dataTable tbody td.dt-body-left{text-align:left}table.dataTable tbody th.dt-body-center,table.dataTable tbody td.dt-body-center{text-align:center}table.dataTable tbody th.dt-body-right,table.dataTable tbody td.dt-body-right{text-align:right}table.dataTable tbody th.dt-body-justify,table.dataTable tbody td.dt-body-justify{text-align:justify}table.dataTable tbody th.dt-body-nowrap,table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}table.dataTable,table.dataTable th,table.dataTable td{-webkit-box-sizing:content-box;box-sizing:content-box}.dataTables_wrapper{position:relative;clear:both;*zoom:1;zoom:1}.dataTables_wrapper .dataTables_length{float:left}.dataTables_wrapper .dataTables_filter{float:right;text-align:right}.dataTables_wrapper .dataTables_filter input{margin-left:0.5em}.dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:0.755em}.dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:0.25em}.dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:0.5em 1em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;*cursor:hand;color:#333 !important;border:1px solid transparent;border-radius:2px}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:#333 !important;border:1px solid #979797;background-color:white;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(100%, #dcdcdc));background:-webkit-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-moz-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-ms-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-o-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:linear-gradient(to bottom, #fff 0%, #dcdcdc 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666 !important;border:1px solid transparent;background:transparent;box-shadow:none}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:white !important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));background:-webkit-linear-gradient(top, #585858 0%, #111 100%);background:-moz-linear-gradient(top, #585858 0%, #111 100%);background:-ms-linear-gradient(top, #585858 0%, #111 100%);background:-o-linear-gradient(top, #585858 0%, #111 100%);background:linear-gradient(to bottom, #585858 0%, #111 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:none;background-color:#2b2b2b;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));background:-webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);box-shadow:inset 0 0 3px #111}.dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.dataTables_wrapper .dataTables_processing{position:absolute;top:50%;left:50%;width:100%;height:40px;margin-left:-50%;margin-top:-25px;padding-top:20px;text-align:center;font-size:1.2em;background-color:white;background:-webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0)));background:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%)}.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_processing,.dataTables_wrapper .dataTables_paginate{color:#333}.dataTables_wrapper .dataTables_scroll{clear:both}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{*margin-top:-1px;-webkit-overflow-scrolling:touch}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td{vertical-align:middle}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td>div.dataTables_sizing{height:0;overflow:hidden;margin:0 !important;padding:0 !important}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid #111}.dataTables_wrapper.no-footer div.dataTables_scrollHead table,.dataTables_wrapper.no-footer div.dataTables_scrollBody table{border-bottom:none}.dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width: 767px){.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.dataTables_wrapper .dataTables_paginate{margin-top:0.5em}}@media screen and (max-width: 640px){.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter{float:none;text-align:center}.dataTables_wrapper .dataTables_filter{margin-top:0.5em}} 2 | -------------------------------------------------------------------------------- /DebugDatabase/Web.bundle/dataTables.buttons.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Buttons for DataTables 1.1.2 3 | ©2015 SpryMedia Ltd - datatables.net/license 4 | */ 5 | (function(e){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(p){return e(p,window,document)}):"object"===typeof exports?module.exports=function(p,o){p||(p=window);if(!o||!o.fn.dataTable)o=require("datatables.net")(p,o).$;return e(o,p,p.document)}:e(jQuery,window,document)})(function(e,p,o,n){var j=e.fn.dataTable,t=0,u=0,l=j.ext.buttons,m=function(a,b){!0===b&&(b={});e.isArray(b)&&(b={buttons:b});this.c=e.extend(!0,{},m.defaults,b);b.buttons&&(this.c.buttons=b.buttons); 6 | this.s={dt:new j.Api(a),buttons:[],subButtons:[],listenKeys:"",namespace:"dtb"+t++};this.dom={container:e("<"+this.c.dom.container.tag+"/>").addClass(this.c.dom.container.className)};this._constructor()};e.extend(m.prototype,{action:function(a,b){var c=this._indexToButton(a).conf;if(b===n)return c.action;c.action=b;return this},active:function(a,b){var c=this._indexToButton(a),d=this.c.dom.button.active;if(b===n)return c.node.hasClass(d);c.node.toggleClass(d,b===n?!0:b);return this},add:function(a, 7 | b){if("string"===typeof a&&-1!==a.indexOf("-")){var c=a.split("-");this.c.buttons[1*c[0]].buttons.splice(1*c[1],0,b)}else this.c.buttons.splice(1*a,0,b);this.dom.container.empty();this._buildButtons(this.c.buttons);return this},container:function(){return this.dom.container},disable:function(a){this._indexToButton(a).node.addClass(this.c.dom.button.disabled);return this},destroy:function(){e("body").off("keyup."+this.s.namespace);var a=this.s.buttons,b=this.s.subButtons,c,d,f;c=0;for(a=a.length;c< 8 | a;c++){this.removePrep(c);d=0;for(f=b[c].length;d").addClass(g.className),this._buildButtons(k.buttons,k._collection,f));k.init&&k.init.call(d.button(r),d,r,k);f++}}}},_buildButton:function(a,b){var c=this.c.dom.button,d=this.c.dom.buttonLiner,f=this.c.dom.collection, 14 | h=this.s.dt,i=function(b){return"function"===typeof b?b(h,g,a):b};b&&f.button&&(c=f.button);b&&f.buttonLiner&&(d=f.buttonLiner);if(a.available&&!a.available(h,a))return!1;var k=function(a,b,c,d){d.action.call(b.button(c),a,b,c,d);e(b.table().node()).triggerHandler("buttons-action.dt",[b.button(c),b,c,d])},g=e("<"+c.tag+"/>").addClass(c.className).attr("tabindex",this.s.dt.settings()[0].iTabIndex).attr("aria-controls",this.s.dt.table().node().id).on("click.dtb",function(b){b.preventDefault();!g.hasClass(c.disabled)&& 15 | a.action&&k(b,h,g,a);g.blur()}).on("keyup.dtb",function(b){b.keyCode===13&&!g.hasClass(c.disabled)&&a.action&&k(b,h,g,a)});d.tag?g.append(e("<"+d.tag+"/>").html(i(a.text)).addClass(d.className)):g.html(i(a.text));!1===a.enabled&&g.addClass(c.disabled);a.className&&g.addClass(a.className);a.titleAttr&&g.attr("title",a.titleAttr);a.namespace||(a.namespace=".dt-button-"+u++);d=(d=this.c.dom.buttonContainer)&&d.tag?e("<"+d.tag+"/>").addClass(d.className).append(g):g;this._addKey(a);return{node:g,inserter:d}}, 16 | _indexToButton:function(a){if("number"===typeof a||-1===a.indexOf("-"))return this.s.buttons[1*a];a=a.split("-");return this.s.subButtons[1*a[0]][1*a[1]]},_keypress:function(a,b){var c,d,f,h;f=this.s.buttons;var i=this.s.subButtons,k=function(c,d){if(c.key)if(c.key===a)d.click();else if(e.isPlainObject(c.key)&&c.key.key===a&&(!c.key.shiftKey||b.shiftKey))if(!c.key.altKey||b.altKey)if(!c.key.ctrlKey||b.ctrlKey)(!c.key.metaKey||b.metaKey)&&d.click()};c=0;for(d=f.length;c").addClass(b).css("display","none").appendTo("body").fadeIn(c):e("body > div."+b).fadeOut(c,function(){e(this).remove()})};m.instanceSelector=function(a,b){if(!a)return e.map(b,function(a){return a.inst});var c=[],d=e.map(b,function(a){return a.name}),f=function(a){if(e.isArray(a))for(var i=0,k=a.length;if&&d._collection.css("left",a.left-(c-f))):(a=d._collection.height()/2,a>e(p).height()/2&&(a=e(p).height()/2),d._collection.css("marginTop",-1*a));d.background&&m.background(!0,d.backgroundClassName,d.fade);setTimeout(function(){e("div.dt-button-background").on("click.dtb-collection",function(){});e("body").on("click.dtb-collection",function(a){if(!e(a.target).parents().andSelf().filter(d._collection).length){d._collection.fadeOut(d.fade, 25 | function(){d._collection.detach()});e("div.dt-button-background").off("click.dtb-collection");m.background(false,d.backgroundClassName,d.fade);e("body").off("click.dtb-collection");b.off("buttons-action.b-internal")}})},10);if(d.autoClose)b.on("buttons-action.b-internal",function(){e("div.dt-button-background").click()})},background:!0,collectionLayout:"",backgroundClassName:"dt-button-background",autoClose:!1,fade:400},copy:function(a,b){if(l.copyHtml5)return"copyHtml5";if(l.copyFlash&&l.copyFlash.available(a, 26 | b))return"copyFlash"},csv:function(a,b){if(l.csvHtml5&&l.csvHtml5.available(a,b))return"csvHtml5";if(l.csvFlash&&l.csvFlash.available(a,b))return"csvFlash"},excel:function(a,b){if(l.excelHtml5&&l.excelHtml5.available(a,b))return"excelHtml5";if(l.excelFlash&&l.excelFlash.available(a,b))return"excelFlash"},pdf:function(a,b){if(l.pdfHtml5&&l.pdfHtml5.available(a,b))return"pdfHtml5";if(l.pdfFlash&&l.pdfFlash.available(a,b))return"pdfFlash"},pageLength:function(a){var a=a.settings()[0].aLengthMenu,b=e.isArray(a[0])? 27 | a[0]:a,c=e.isArray(a[0])?a[1]:a,d=function(a){return a.i18n("buttons.pageLength",{"-1":"Show all rows",_:"Show %d rows"},a.page.len())};return{extend:"collection",text:d,className:"buttons-page-length",autoClose:!0,buttons:e.map(b,function(a,b){return{text:c[b],action:function(b,c){c.page.len(a).draw()},init:function(b,c,d){var e=this,c=function(){e.active(b.page.len()===a)};b.on("length.dt"+d.namespace,c);c()},destroy:function(a,b,c){a.off("length.dt"+c.namespace)}}}),init:function(a,b,c){var e= 28 | this;a.on("length.dt"+c.namespace,function(){e.text(d(a))})},destroy:function(a,b,c){a.off("length.dt"+c.namespace)}}}});j.Api.register("buttons()",function(a,b){b===n&&(b=a,a=n);return this.iterator(!0,"table",function(c){if(c._buttons)return m.buttonSelector(m.instanceSelector(a,c._buttons),b)},!0)});j.Api.register("button()",function(a,b){var c=this.buttons(a,b);1').html(a?"

      "+a+"

      ":"").append(e("
      ")["string"===typeof b?"html":"append"](b)).css("display","none").appendTo("body").fadeIn();c!==n&&0!==c&&(q=setTimeout(function(){d.buttons.info(!1)}, 33 | c));return this});j.Api.register("buttons.exportData()",function(a){if(this.context.length){for(var b=new j.Api(this.context[0]),c=e.extend(!0,{},{rows:null,columns:"",modifier:{search:"applied",order:"applied"},orthogonal:"display",stripHtml:!0,stripNewlines:!0,decodeEntities:!0,trim:!0,format:{header:function(a){return d(a)},footer:function(a){return d(a)},body:function(a){return d(a)}}},a),d=function(a){if("string"!==typeof a)return a;c.stripHtml&&(a=a.replace(/<.*?>/g,""));c.trim&&(a=a.replace(/^\s+|\s+$/g, 34 | ""));c.stripNewlines&&(a=a.replace(/\n/g," "));c.decodeEntities&&(s.innerHTML=a,a=s.value);return a},a=b.columns(c.columns).indexes().map(function(a){return c.format.header(b.column(a).header().innerHTML,a)}).toArray(),f=b.table().footer()?b.columns(c.columns).indexes().map(function(a){var d=b.column(a).footer();return c.format.footer(d?d.innerHTML:"",a)}).toArray():null,h=b.rows(c.rows,c.modifier).indexes().toArray(),h=b.cells(h,c.columns).render(c.orthogonal).toArray(),i=a.length,k=0")[0];e.fn.dataTable.Buttons=m;e.fn.DataTable.Buttons=m;e(o).on("init.dt plugin-init.dt",function(a,b){if("dt"===a.namespace){var c=b.oInit.buttons||j.defaults.buttons;c&&!b._buttons&&(new m(b,c)).container()}});j.ext.feature.push({fnInit:function(a){var a=new j.Api(a),b=a.init().buttons||j.defaults.buttons;return(new m(a,b)).container()},cFeature:"B"}); 36 | return m}); 37 | -------------------------------------------------------------------------------- /DebugDatabase/Web.bundle/app.js: -------------------------------------------------------------------------------- 1 | $( document ).ready(function() { 2 | $("#query").keypress(function(e){ 3 | if(e.which == 13) { 4 | queryFunction(); 5 | } 6 | }); 7 | //update currently selected database 8 | $( document ).on( "click", "#db-list .list-group-item", function() { 9 | $("#db-list .list-group-item").each(function() { 10 | $(this).removeClass('selected'); 11 | }); 12 | $(this).addClass('selected'); 13 | }); 14 | 15 | //update currently table database 16 | $( document ).on( "click", "#table-list .list-group-item", function() { 17 | $("#table-list .list-group-item").each(function() { 18 | $(this).removeClass('selected'); 19 | }); 20 | $(this).addClass('selected'); 21 | }); 22 | 23 | 24 | }); 25 | 26 | 27 | 28 | var currentDatabaseName; 29 | 30 | function getData(tableName) { 31 | 32 | $.ajax({url: "allTableRecords?tableName="+tableName+"&database="+currentDatabaseName, success: function(result){ 33 | 34 | // result = JSON.parse(result); 35 | inflateData(result); 36 | 37 | }}); 38 | 39 | } 40 | 41 | function queryFunction() { 42 | 43 | var query = $('#query').val(); 44 | 45 | $.ajax({url: "query?query="+escape(query)+"&database="+currentDatabaseName, success: function(result){ 46 | 47 | // result = JSON.parse(result); 48 | inflateData(result); 49 | 50 | }}); 51 | 52 | } 53 | 54 | function downloadDb() { 55 | if (currentDatabaseName) { 56 | $.ajax({url: "downloadDb?database=" + currentDatabaseName, success: function(){ 57 | window.location = "downloadDb?database=" + currentDatabaseName; 58 | }}); 59 | } 60 | } 61 | 62 | 63 | function getDBList() { 64 | 65 | $.ajax({url: "databaseList", success: function(result){ 66 | 67 | var dbList = result.rows; 68 | $('#db-list').empty(); 69 | var isSelectionDone = false; 70 | for(var count = 0; count < dbList.length; count++){ 71 | if(dbList[count].indexOf("journal") == -1){ 72 | $("#db-list").append("" +dbList[count] + ""); 73 | if(!isSelectionDone){ 74 | isSelectionDone = true; 75 | $('#db-list').find('a').trigger('click'); 76 | } 77 | } 78 | } 79 | 80 | }}); 81 | 82 | } 83 | 84 | function openDatabaseAndGetTableList(db) { 85 | 86 | if("NSUserDefault" == db) { 87 | $('#run-query').removeClass('active'); 88 | $('#run-query').addClass('disabled'); 89 | // $('#selected-db-info').removeClass('active'); 90 | // $('#selected-db-info').addClass('disabled'); 91 | $('#selected-db-info').removeClass('disabled'); 92 | $('#selected-db-info').addClass('active'); 93 | currentDatabaseName = "NSUserDefault"; 94 | $("#selected-db-info").text("Export NSUserDefault"); 95 | } else { 96 | $('#run-query').removeClass('disabled'); 97 | $('#run-query').addClass('active'); 98 | $('#selected-db-info').removeClass('disabled'); 99 | $('#selected-db-info').addClass('active'); 100 | currentDatabaseName = db; 101 | $("#selected-db-info").text("Export Selected Database : "+db); 102 | } 103 | 104 | 105 | $.ajax({url: "tableList?database="+db, success: function(result){ 106 | 107 | // result = JSON.parse(result); 108 | var tableList = result.rows; 109 | var dbVersion = result.dbVersion; 110 | if("NSUserDefault" != db) { 111 | $("#selected-db-info").text("Export Selected Database : "+db +" Version : "+dbVersion); 112 | } 113 | $('#table-list').empty() 114 | for(var count = 0; count < tableList.length; count++){ 115 | var tableName = tableList[count]; 116 | $("#table-list").append("" +tableName + ""); 117 | } 118 | 119 | }}); 120 | 121 | } 122 | 123 | function inflateData(result){ 124 | 125 | if(result.isSuccessful){ 126 | 127 | if(!result.isSelectQuery){ 128 | showSuccessInfo("Query Executed Successfully"); 129 | return; 130 | } 131 | 132 | var columnHeader = result.tableInfos; 133 | 134 | // set function to return cell data for different usages like set, display, filter, search etc.. 135 | for(var i = 0; i < columnHeader.length; i++) { 136 | columnHeader[i]['targets'] = i; 137 | columnHeader[i]['data'] = function(row, type, val, meta) { 138 | var dataType = row[meta.col].dataType; 139 | if (type == "sort" && dataType == "boolean") { 140 | return row[meta.col].value ? 1 : 0; 141 | } 142 | return row[meta.col].value; 143 | } 144 | } 145 | var columnData = result.rows; 146 | var tableId = "#db-data"; 147 | if ($.fn.DataTable.isDataTable(tableId) ) { 148 | $(tableId).DataTable().destroy(); 149 | } 150 | 151 | $("#db-data-div").remove(); 152 | $("#parent-data-div").append('
      '); 153 | 154 | if (result.userDefault) { 155 | $(tableId).dataTable({ 156 | "data": columnData, 157 | "columnDefs": columnHeader, 158 | 'bPaginate': true, 159 | 'searching': true, 160 | 'bFilter': true, 161 | 'bInfo': true, 162 | "bSort" : true, 163 | "scrollX": true, 164 | "iDisplayLength": 10 165 | }) 166 | }else { 167 | $(tableId).dataTable({ 168 | "data": columnData, 169 | "columnDefs": columnHeader, 170 | 'bPaginate': true, 171 | 'searching': true, 172 | 'bFilter': true, 173 | 'bInfo': true, 174 | "bSort" : true, 175 | "scrollX": true, 176 | "iDisplayLength": 10, 177 | "dom": "Bfrtip", 178 | select: 'single', 179 | altEditor: true, // Enable altEditor 180 | buttons: [ 181 | { 182 | extend: 'selected', // Bind to Selected row 183 | text: 'Edit', 184 | name: 'edit' // do not change name 185 | }, 186 | { 187 | extend: 'selected', 188 | text: 'Delete', 189 | name: 'delete' 190 | } 191 | ] 192 | }) 193 | } 194 | 195 | //attach row-updated listener 196 | $(tableId).on('update-row.dt', function (e, updatedRowData, callback) { 197 | var updatedRowDataArray = JSON.parse(updatedRowData); 198 | //add value for each column 199 | var data = columnHeader; 200 | for(var i = 0; i < data.length; i++) { 201 | data[i].value = updatedRowDataArray[i].value; 202 | data[i].dataType = updatedRowDataArray[i].dataType; 203 | } 204 | //send update table data request to server 205 | updateTableData(data, callback); 206 | }); 207 | 208 | 209 | //attach delete-updated listener 210 | $(tableId).on('delete-row.dt', function (e, updatedRowData, callback) { 211 | var deleteRowDataArray = JSON.parse(updatedRowData); 212 | 213 | console.log(deleteRowDataArray); 214 | 215 | //add value for each column 216 | var data = columnHeader; 217 | for(var i = 0; i < data.length; i++) { 218 | data[i].value = deleteRowDataArray[i].value; 219 | data[i].dataType = deleteRowDataArray[i].dataType; 220 | 221 | } 222 | 223 | //send delete table data request to server 224 | deleteTableData(data, callback); 225 | }); 226 | 227 | // hack to fix alignment issue when scrollX is enabled 228 | $(".dataTables_scrollHeadInner").css({"width":"100%"}); 229 | $(".table ").css({"width":"100%"}); 230 | }else{ 231 | if(!result.isSelectQuery){ 232 | showErrorInfo("Query Execution Failed"); 233 | }else { 234 | if(result.errorMessage){ 235 | showErrorInfo(result.errorMessage); 236 | }else{ 237 | showErrorInfo("Some Error Occurred"); 238 | } 239 | } 240 | } 241 | 242 | } 243 | 244 | function inflateAppInfoData(result){ 245 | 246 | if(result.isSuccessful){ 247 | 248 | if(!result.isSelectQuery){ 249 | showSuccessInfo("Query Executed Successfully"); 250 | return; 251 | } 252 | 253 | var columnHeader = result.tableInfos; 254 | 255 | // set function to return cell data for different usages like set, display, filter, search etc.. 256 | for(var i = 0; i < columnHeader.length; i++) { 257 | columnHeader[i]['targets'] = i; 258 | columnHeader[i]['data'] = function(row, type, val, meta) { 259 | var dataType = row[meta.col].dataType; 260 | if (type == "sort" && dataType == "boolean") { 261 | return row[meta.col].value ? 1 : 0; 262 | } 263 | return row[meta.col].value; 264 | } 265 | } 266 | var columnData = result.rows; 267 | var tableId = "#db-appinfo"; 268 | if ($.fn.DataTable.isDataTable(tableId) ) { 269 | $(tableId).DataTable().destroy(); 270 | } 271 | 272 | $("#db-appinfo-div").remove(); 273 | $("#parent-appinfo-div").append('
      '); 274 | 275 | $(tableId).dataTable({ 276 | "data": columnData, 277 | "columnDefs": columnHeader, 278 | 'bPaginate': false, 279 | 'searching': false, 280 | 'bFilter': false, 281 | 'bInfo': false, 282 | "bSort" : false, 283 | "scrollX": true, 284 | "iDisplayLength": 99, 285 | "fnDrawCallback": function (oSettings) { 286 | $(oSettings.nTHead).hide(); 287 | } 288 | }) 289 | 290 | // hack to fix alignment issue when scrollX is enabled 291 | $(".dataTables_scrollHeadInner").css({"width":"100%"}); 292 | $(".table ").css({"width":"100%"}); 293 | }else{ 294 | if(!result.isSelectQuery){ 295 | showErrorInfo("Query Execution Failed"); 296 | }else { 297 | if(result.errorMessage){ 298 | showErrorInfo(result.errorMessage); 299 | }else{ 300 | showErrorInfo("Some Error Occurred"); 301 | } 302 | } 303 | } 304 | 305 | } 306 | 307 | //send update database request to server 308 | function updateTableData(updatedData, callback) { 309 | //get currently selected element 310 | var selectedTableElement = $("#table-list .list-group-item.selected"); 311 | 312 | var filteredUpdatedData = updatedData.map(function(columnData){ 313 | return { 314 | title: columnData.title, 315 | isPrimary: columnData.isPrimary, 316 | value: columnData.value, 317 | dataType: columnData.dataType 318 | } 319 | }); 320 | //build request parameters 321 | var requestParameters = {}; 322 | requestParameters.database = selectedTableElement.attr('data-db-name'); 323 | requestParameters.tableName = selectedTableElement.attr('data-table-name');; 324 | requestParameters.updatedData = encodeURIComponent(JSON.stringify(filteredUpdatedData)); 325 | 326 | //execute request 327 | $.ajax({ 328 | url: "updateRecord", 329 | type: 'GET', 330 | data: requestParameters, 331 | success: function(response) { 332 | console.log(response); 333 | console.log(response.isSuccessful); 334 | // response = JSON.parse(response); 335 | if(response.isSuccessful){ 336 | console.log("Data updated successfully"); 337 | callback(true); 338 | showSuccessInfo("Data Updated Successfully"); 339 | } else { 340 | console.log("Data updated failed"); 341 | callback(false); 342 | } 343 | } 344 | }) 345 | } 346 | 347 | 348 | function deleteTableData(deleteData, callback) { 349 | 350 | var selectedTableElement = $("#table-list .list-group-item.selected"); 351 | var filteredUpdatedData = deleteData.map(function(columnData){ 352 | return { 353 | title: columnData.title, 354 | isPrimary: columnData.isPrimary, 355 | value: columnData.value, 356 | dataType: columnData.dataType 357 | } 358 | }); 359 | 360 | console.log(filteredUpdatedData); 361 | 362 | //build request parameters 363 | var requestParameters = {}; 364 | requestParameters.database = selectedTableElement.attr('data-db-name'); 365 | requestParameters.tableName = selectedTableElement.attr('data-table-name');; 366 | requestParameters.deleteData = encodeURIComponent(JSON.stringify(filteredUpdatedData)); 367 | 368 | //execute request 369 | $.ajax({ 370 | url: "deleteRecord", 371 | type: 'GET', 372 | data: requestParameters, 373 | success: function(response) { 374 | // response = JSON.parse(response); 375 | if(response.isSuccessful){ 376 | console.log("Data deleted successfully"); 377 | callback(true); 378 | showSuccessInfo("Data Deleted Successfully"); 379 | } else { 380 | console.log("Data delete failed"); 381 | callback(false); 382 | } 383 | } 384 | }) 385 | } 386 | 387 | function showSuccessInfo(message){ 388 | var snackbarId = "snackbar"; 389 | var snackbarElement = $("#"+snackbarId); 390 | snackbarElement.addClass("show"); 391 | snackbarElement.css({"backgroundColor": "#5cb85c"}); 392 | snackbarElement.html(message) 393 | setTimeout(function(){ 394 | snackbarElement.removeClass("show"); 395 | }, 3000); 396 | } 397 | 398 | function showErrorInfo(message){ 399 | var snackbarId = "snackbar"; 400 | var snackbarElement = $("#"+snackbarId); 401 | snackbarElement.addClass("show"); 402 | snackbarElement.css({"backgroundColor": "#d9534f"}); 403 | snackbarElement.html(message) 404 | setTimeout(function(){ 405 | snackbarElement.removeClass("show"); 406 | }, 3000); 407 | } 408 | 409 | function getUserDefault() { 410 | $.ajax({url: "getUserDefault", success: function(result){ 411 | inflateData(result); 412 | }}); 413 | } 414 | 415 | function getAppInfo() { 416 | $.ajax({url: "getAppInfo", success: function(result){ 417 | inflateAppInfoData(result); 418 | getUserDefault(); 419 | }}); 420 | } 421 | -------------------------------------------------------------------------------- /DebugDatabase/DebugDatabaseManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // DebugDatabaseManager.m 3 | // YYDebugDatabase 4 | // 5 | // Created by wentian on 17/8/10. 6 | // Copyright © 2017年 wentian. All rights reserved. 7 | // 8 | 9 | #import "DebugDatabaseManager.h" 10 | #import "NSURL+scheme.h" 11 | #import "DatabaseUtil.h" 12 | #import "NSString+json.h" 13 | #ifdef COCOAPODS 14 | #import 15 | #import 16 | #else 17 | #import 18 | #import 19 | #endif 20 | 21 | 22 | @interface DebugDatabaseManager () 23 | 24 | @property(nonatomic, strong) NSDictionary *databasePaths; 25 | 26 | @end 27 | 28 | @implementation DebugDatabaseManager 29 | 30 | + (instancetype)shared { 31 | static dispatch_once_t oneceToken; 32 | static DebugDatabaseManager *debugDatabaseManager; 33 | dispatch_once(&oneceToken, ^{ 34 | debugDatabaseManager = [[DebugDatabaseManager alloc] init]; 35 | }); 36 | return debugDatabaseManager; 37 | } 38 | 39 | - (id)init { 40 | self = [super init]; 41 | if (self) { 42 | NSURL *bundleURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"Web" withExtension:@"bundle"]; 43 | NSBundle *bundle = [NSBundle bundleWithURL:bundleURL]; 44 | 45 | [self addGETHandlerForBasePath:@"/" directoryPath:[bundle resourcePath] indexFilename:@"index.html" cacheAge:0 allowRangeRequests:YES]; 46 | 47 | // home page 48 | [self addHandlerForMethod:@"GET" 49 | path:@"/" 50 | requestClass:[GCDWebServerRequest class] 51 | processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) { 52 | 53 | NSString *indexPath = [bundle pathForResource:@"index" ofType:@"html"]; 54 | return [GCDWebServerDataResponse responseWithHTMLTemplate:indexPath variables:@{}]; 55 | }]; 56 | 57 | [self setupAdvanceRoutes]; 58 | } 59 | return self; 60 | } 61 | 62 | - (void)setupAdvanceRoutes { 63 | 64 | __weak typeof(self)weakSelf = self; 65 | 66 | [self addHandlerForMethod:@"GET" 67 | path:@"/databaseList" 68 | requestClass:[GCDWebServerRequest class] 69 | processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) { 70 | return [GCDWebServerDataResponse responseWithJSONObject:@{@"rows" : weakSelf.databasePaths.allKeys ?: [NSNull null]}]; 71 | }]; 72 | 73 | [self addHandlerForMethod:@"GET" 74 | path:@"/tableList" 75 | requestClass:[GCDWebServerRequest class] 76 | processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) { 77 | 78 | NSDictionary *params = request.URL.queryParams; 79 | NSString *dbName = [params objectForKey:@"database"]; 80 | [[DatabaseUtil shared] openDatabase:[weakSelf.databasePaths objectForKey:dbName]]; 81 | NSArray *array = [[DatabaseUtil shared] allTables]; 82 | [[DatabaseUtil shared] closeDatabase]; 83 | 84 | return [GCDWebServerDataResponse responseWithJSONObject:@{@"rows" : array?:[NSNull null]}]; 85 | }]; 86 | 87 | [self addHandlerForMethod:@"GET" 88 | path:@"/allTableRecords" 89 | requestClass:[GCDWebServerRequest class] 90 | processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) { 91 | 92 | NSDictionary *params = request.URL.queryParams; 93 | NSString *dbName = [params objectForKey:@"database"]; 94 | NSString *tableName = [params objectForKey:@"tableName"]; 95 | 96 | [[DatabaseUtil shared] openDatabase:[weakSelf.databasePaths objectForKey:dbName]]; 97 | NSDictionary *rows = [[DatabaseUtil shared] rowsInTable:tableName]; 98 | [[DatabaseUtil shared] closeDatabase]; 99 | 100 | return [GCDWebServerDataResponse responseWithJSONObject:rows?:[NSNull null]]; 101 | }]; 102 | 103 | [self addHandlerForMethod:@"GET" 104 | path:@"/updateRecord" 105 | requestClass:[GCDWebServerRequest class] 106 | processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) { 107 | 108 | NSDictionary *params = request.URL.queryParams; 109 | NSString *dbName = [params objectForKey:@"database"]; 110 | NSString *tableName = [params objectForKey:@"tableName"]; 111 | 112 | NSDictionary *updateData =[[yy_dicGetString(params, @"updatedData") URLDecode] JSONObject]; 113 | 114 | BOOL isSuccess; 115 | 116 | if (updateData.count == 0 || dbName.length == 0 || tableName.length == 0) { 117 | isSuccess = NO; 118 | }else { 119 | NSMutableDictionary *contentValues = [NSMutableDictionary dictionary]; 120 | NSMutableDictionary *where = [NSMutableDictionary dictionary]; 121 | for (NSDictionary *columnDic in updateData) { 122 | if (yy_dicGetBool(columnDic, @"isPrimary", NO)) { 123 | [where setObject:[columnDic objectForKey:@"value"]?:[NSNull null] forKey:yy_dicGetStringSafe(columnDic, @"title")]; 124 | } else { 125 | [contentValues setObject:[columnDic objectForKey:@"value"]?:[NSNull null] forKey:[columnDic objectForKey:@"title"]]; 126 | } 127 | } 128 | 129 | [[DatabaseUtil shared] openDatabase:yy_dicGetString(weakSelf.databasePaths, dbName)]; 130 | isSuccess = [[DatabaseUtil shared] updateRecordInDatabase:dbName tableName:tableName data:contentValues condition:where]; 131 | [[DatabaseUtil shared] closeDatabase]; 132 | 133 | } 134 | 135 | return [GCDWebServerDataResponse responseWithJSONObject:@{@"isSuccessful" : @(isSuccess)}]; 136 | }]; 137 | 138 | [self addHandlerForMethod:@"GET" 139 | path:@"/deleteRecord" 140 | requestClass:[GCDWebServerRequest class] 141 | processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) { 142 | 143 | NSDictionary *params = request.URL.queryParams; 144 | NSString *dbName = [params objectForKey:@"database"]; 145 | NSString *tableName = [params objectForKey:@"tableName"]; 146 | 147 | NSDictionary *deleteData =[[yy_dicGetString(params, @"deleteData") URLDecode] JSONObject]; 148 | 149 | BOOL isSuccess; 150 | 151 | if (deleteData.count == 0 || dbName.length == 0 || tableName.length == 0) { 152 | isSuccess = NO; 153 | }else { 154 | NSMutableDictionary *where = [NSMutableDictionary dictionary]; 155 | for (NSDictionary *columnDic in deleteData) { 156 | if (yy_dicGetBool(columnDic, @"isPrimary", NO)) { 157 | [where setObject:[columnDic objectForKey:@"value"]?:[NSNull null] forKey:yy_dicGetStringSafe(columnDic, @"title")]; 158 | } 159 | } 160 | 161 | [[DatabaseUtil shared] openDatabase:yy_dicGetString(weakSelf.databasePaths, dbName)]; 162 | isSuccess = [[DatabaseUtil shared] deleteRecordInDatabase:dbName tableName:tableName condition:where limit:nil]; 163 | [[DatabaseUtil shared] closeDatabase]; 164 | 165 | } 166 | 167 | return [GCDWebServerDataResponse responseWithJSONObject:@{@"isSuccessful" : @(isSuccess)}]; 168 | }]; 169 | 170 | [self addHandlerForMethod:@"GET" 171 | path:@"/query" 172 | requestClass:[GCDWebServerRequest class] 173 | processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) { 174 | 175 | NSDictionary *params = request.URL.queryParams; 176 | NSString *dbName = [params objectForKey:@"database"]; 177 | NSString *query = [yy_dicGetString(params, @"query") URLDecode]; 178 | NSString *tableName = [weakSelf getTableNameFromQuery:query]; 179 | NSString *operator = [weakSelf getOperatorFromQuery:query]; 180 | 181 | [[DatabaseUtil shared] openDatabase:yy_dicGetString(weakSelf.databasePaths, dbName)]; 182 | NSDictionary *resultData = [[DatabaseUtil shared] executeQueryInDatabase:dbName tableName:tableName operator:operator query:query]; 183 | [[DatabaseUtil shared] closeDatabase]; 184 | 185 | return [GCDWebServerDataResponse responseWithJSONObject:resultData?:[NSNull null]]; 186 | }]; 187 | 188 | [self addHandlerForMethod:@"GET" 189 | path:@"/downloadDb" 190 | requestClass:[GCDWebServerRequest class] 191 | processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) { 192 | 193 | NSString *dbName = [request.URL.queryParams objectForKey:@"database"]; 194 | return [GCDWebServerDataResponse responseWithData:[NSData dataWithContentsOfFile:yy_dicGetString(weakSelf.databasePaths, dbName)] contentType:@"application/octet-stream"]; 195 | }]; 196 | 197 | [self addHandlerForMethod:@"GET" 198 | path:@"/getUserDefault" 199 | requestClass:[GCDWebServerRequest class] 200 | processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) { 201 | 202 | NSMutableDictionary *userData = [[DatabaseUtil shared] userDefaultData].mutableCopy; 203 | 204 | [userData safe_setObject:@YES forKey:@"userDefault"]; 205 | 206 | return [GCDWebServerDataResponse responseWithJSONObject:userData]; 207 | }]; 208 | 209 | [self addHandlerForMethod:@"GET" 210 | path:@"/getAppInfo" 211 | requestClass:[GCDWebServerRequest class] 212 | processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) { 213 | 214 | NSDictionary *appInfo = [[DatabaseUtil shared] getAppInfoData]; 215 | 216 | return [GCDWebServerDataResponse responseWithJSONObject:appInfo]; 217 | }]; 218 | } 219 | 220 | - (void)startServerOnPort:(NSInteger)port directories:(NSArray *)directories { 221 | 222 | _databasePaths = [self getAllDBPathsWithDirectories:directories]; 223 | 224 | [self startWithPort:port bonjourName:@""]; 225 | 226 | NSLog(@"Visit %@ in your web browser", self.serverURL); 227 | 228 | } 229 | 230 | - (void)startServerOnPort:(NSInteger)port { 231 | NSString *cacheDir = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"]; 232 | NSString *documentDir = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; 233 | [self startServerOnPort:port directories:@[cacheDir, documentDir]]; 234 | } 235 | 236 | - (NSDictionary*)getAllDBPathsWithDirectories:(NSArray*)directories { 237 | NSMutableDictionary *paths = @{}.mutableCopy; 238 | 239 | for (NSString *directory in directories) { 240 | NSArray *dirList = [[[NSFileManager defaultManager] subpathsAtPath:directory] pathsMatchingExtensions:[self supportedDatabaseSuffixs]]; 241 | 242 | for (NSString *subPath in dirList) { 243 | if ([self checkDatabaseFile:subPath]) { 244 | // [paths setObject:[directory stringByAppendingPathComponent:subPath] forKey:subPath.lastPathComponent]; 245 | 246 | // added by seven 247 | [self addToDbQueryPathesSupportDuplicatedFilename:paths 248 | object:[directory stringByAppendingPathComponent:subPath] 249 | key:subPath.lastPathComponent]; 250 | } 251 | } 252 | 253 | if ([self checkDatabaseFile:directory]) { 254 | // [paths setObject:directory forKey:directory.lastPathComponent]; 255 | 256 | // added by seven 257 | [self addToDbQueryPathesSupportDuplicatedFilename:paths 258 | object:directory 259 | key:directory.lastPathComponent]; 260 | } 261 | } 262 | 263 | return paths; 264 | } 265 | 266 | // added by seven 267 | - (void)addToDbQueryPathesSupportDuplicatedFilename:(NSMutableDictionary *)paths object:(NSString *)dbPath key:(NSString *)dbKeyName { 268 | // Key exists, appending the last directory path component 269 | if ([paths objectForKey:dbKeyName]) { 270 | NSString *dbDir = [dbPath stringByDeletingLastPathComponent]; 271 | NSArray *dbDirPathComponents = [dbDir componentsSeparatedByString:@"/"]; 272 | 273 | NSString *lastPathComponent = [dbDirPathComponents lastObject]; 274 | 275 | if (lastPathComponent && lastPathComponent.length) { 276 | dbKeyName = [NSString stringWithFormat:@"%@/%@", lastPathComponent, dbKeyName]; 277 | } 278 | } 279 | 280 | [paths setObject:dbPath forKey:dbKeyName]; 281 | } 282 | 283 | - (BOOL)checkDatabaseFile:(NSString*)fileName { 284 | for (NSString *suffix in [self supportedDatabaseSuffixs]) { 285 | if ([fileName hasSuffix:suffix]) { 286 | return YES; 287 | } 288 | } 289 | return NO; 290 | } 291 | 292 | - (NSArray*)supportedDatabaseSuffixs { 293 | return @[@"sqlite", @"SQLITE", @"db", @"DB", @"sqlite3", @"SQLITE3"]; 294 | } 295 | 296 | - (NSString*)getTableNameFromQuery:(NSString*)query { 297 | NSArray *words = [query componentsSeparatedByString:@" "]; 298 | NSString *operator = [[words firstObject] lowercaseString]; 299 | NSInteger fromIndex = 0; 300 | NSString *table; 301 | 302 | for (int i =0;i<[words count];i++) { 303 | NSString *word = [words objectAtIndex:i]; 304 | if ([operator isEqualToString:@"select"] || [operator isEqualToString:@"delete"]) { 305 | if ([word isEqualToString:@"from"]) { 306 | fromIndex = i; 307 | } 308 | if (i == fromIndex+1) { 309 | if([word stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length==0){ 310 | fromIndex ++; 311 | }else{ 312 | table = word; 313 | } 314 | } 315 | }else if ([operator isEqualToString:@"update"]) { 316 | if ([word isEqualToString:@"update"]) { 317 | fromIndex = i; 318 | } 319 | if (i == fromIndex+1) { 320 | if([word stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length==0){ 321 | fromIndex ++; 322 | }else{ 323 | table = word; 324 | } 325 | } 326 | } 327 | } 328 | return table; 329 | } 330 | 331 | - (NSString*)getOperatorFromQuery:(NSString*)query { 332 | NSArray *words = [query componentsSeparatedByString:@" "]; 333 | NSString *operator = [[words firstObject] lowercaseString]; 334 | 335 | return operator; 336 | } 337 | 338 | @end 339 | -------------------------------------------------------------------------------- /DebugDatabase/DatabaseUtil.m: -------------------------------------------------------------------------------- 1 | // 2 | // DatabaseUtil.m 3 | // YYDebugDatabase 4 | // 5 | // Created by wentian on 17/8/11. 6 | // Copyright © 2017年 wentian. All rights reserved. 7 | // 8 | 9 | #import "DatabaseUtil.h" 10 | #import 11 | 12 | #ifdef COCOAPODS 13 | #import "FMDB.h" 14 | #else 15 | #import 16 | #endif 17 | 18 | 19 | 20 | @interface DatabaseUtil () 21 | 22 | @property(nonatomic) sqlite3 *db; 23 | @property(nonatomic, ) NSString *dbPath; 24 | @property(nonatomic, copy) NSString *dbName; 25 | @property(nonatomic, strong) FMDatabase *fmdb; 26 | 27 | @end 28 | 29 | @implementation DatabaseUtil 30 | 31 | + (instancetype)shared { 32 | static dispatch_once_t onceToken; 33 | static DatabaseUtil *dbUtil; 34 | dispatch_once(&onceToken, ^{ 35 | dbUtil = [[self alloc] init]; 36 | }); 37 | return dbUtil; 38 | } 39 | 40 | - (BOOL)openDatabase:(NSString*)dbPath { 41 | 42 | if (self.dbPath && _db && ![dbPath isEqualToString:self.dbPath]){ 43 | [self closeDatabase]; 44 | } 45 | 46 | _dbPath = dbPath; 47 | _dbName = [_dbPath lastPathComponent]; 48 | 49 | NSString *dbDir = [_dbPath stringByDeletingLastPathComponent]; 50 | if (![[NSFileManager defaultManager] fileExistsAtPath:dbDir]) { 51 | return NO; 52 | } 53 | 54 | self.fmdb = [FMDatabase databaseWithPath:dbPath]; 55 | 56 | if (![self.fmdb open]) { 57 | NSLog(@"Could not open db %@.", dbPath); 58 | return NO; 59 | } 60 | 61 | return YES; 62 | 63 | } 64 | 65 | - (BOOL)closeDatabase { 66 | if (self.fmdb != nil){ 67 | [self.fmdb close]; 68 | } 69 | 70 | return YES; 71 | } 72 | 73 | - (NSArray*)allTables { 74 | 75 | NSString *sql = @"SELECT tbl_name FROM sqlite_master WHERE type = 'table'"; 76 | FMResultSet *rs = [self.fmdb executeQuery:sql]; 77 | 78 | NSMutableArray *tables = @[].mutableCopy; 79 | 80 | while ([rs next]) { 81 | [tables safe_addObject:[rs stringForColumn:@"tbl_name"]]; 82 | } 83 | 84 | return tables; 85 | } 86 | 87 | - (NSArray*)tableInfo:(NSString*)tableName { 88 | FMResultSet *rs = [self.fmdb getTableSchema:tableName]; 89 | 90 | NSMutableArray *infos = @[].mutableCopy; 91 | 92 | while ([rs next]) { 93 | [infos safe_addObject:rs.resultDictionary?:[NSNull null]]; 94 | } 95 | return infos; 96 | } 97 | 98 | - (NSDictionary*)rowsInTable:(NSString*)tableName { 99 | 100 | NSMutableDictionary *tableData = [NSMutableDictionary dictionary]; 101 | [tableData safe_setObject:@(1) forKey:@"isSelectQuery"]; 102 | [tableData safe_setObject:@(1) forKey:@"isSuccessful"]; 103 | 104 | //标题 105 | FMResultSet *infors = [self.fmdb getTableSchema:tableName]; 106 | 107 | NSMutableArray *tableInfoResult = [NSMutableArray array]; 108 | 109 | NSMutableArray *columnKeys = [NSMutableArray arrayWithCapacity:10]; 110 | 111 | while ([infors next]) { 112 | NSMutableDictionary *info = [NSMutableDictionary dictionary]; 113 | [info safe_setObject:@([infors boolForColumn:@"pk"]) forKey:@"isPrimary"]; 114 | // [info safe_setObject:[NSString stringWithFormat:@"%@[%@]", [infors stringForColumn:@"name"]?:@"", [infors stringForColumn:@"type"]] forKey:@"titleDisplay"]; 115 | [info safe_setObject:[NSString stringWithFormat:@"%@", [infors stringForColumn:@"name"]?:@""] forKey:@"title"]; 116 | [info safe_setObject:[infors stringForColumn:@"type"] forKey:@"dataType"]; 117 | [tableInfoResult safe_addObject:info]; 118 | 119 | [columnKeys addObject:[infors stringForColumn:@"name"]?:@""]; 120 | } 121 | [tableData safe_setObject:tableInfoResult forKey:@"tableInfos"]; 122 | 123 | BOOL isEditable = tableName != nil && [tableData objectForKey:@"tableInfos"] != nil; 124 | [tableData safe_setObject:@(isEditable) forKey:@"isEditable"]; 125 | 126 | 127 | //数据 128 | NSString *sql = [NSString stringWithFormat:@"select * from %@",tableName]; 129 | FMResultSet *rs = [self.fmdb executeQuery:sql]; 130 | NSMutableArray *rows = @[].mutableCopy; 131 | 132 | while ([rs next]) { 133 | NSMutableArray *row = @[].mutableCopy; 134 | 135 | for ( int i = 0; i < tableInfoResult.count; i++) { 136 | NSMutableDictionary *columnData = [NSMutableDictionary dictionaryWithCapacity:10]; 137 | NSString *columName = [columnKeys objectAtIndex:i]; 138 | NSString *type = [[tableInfoResult objectAtIndex:i] objectForKey:@"dataType"]; 139 | 140 | if ([[type lowercaseString] isEqualToString:@"integer"]) { 141 | [columnData safe_setObject:@"integer" forKey:@"dataType"]; 142 | }else if ([[type lowercaseString] isEqualToString:@"real"]) { 143 | [columnData safe_setObject:@"float" forKey:@"dataType"]; 144 | }else if ([[type lowercaseString] isEqualToString:@"text"]) { 145 | [columnData safe_setObject:@"text" forKey:@"dataType"]; 146 | }else if ([[type lowercaseString] isEqualToString:@"blob"]) { 147 | [columnData safe_setObject:@"blob" forKey:@"dataType"]; 148 | }else if ([[type lowercaseString] isEqualToString:@"null"]) { 149 | [columnData safe_setObject:@"null" forKey:@"dataType"]; 150 | }else { 151 | [columnData safe_setObject:@"text" forKey:@"dataType"]; 152 | } 153 | 154 | if ([[type lowercaseString] isEqualToString:@"blob"]) { 155 | [columnData safe_setObject:@"blob" forKey:@"value"]; 156 | }else if ([[type lowercaseString] isEqualToString:@"guid"]){ 157 | 158 | 159 | id data = [rs respondsToSelector:@selector(objectForColumn:)] ? [rs performSelector:@selector(objectForColumn:) withObject:columName] : [rs performSelector:@selector(objectForColumnName:) withObject:columName]; 160 | const unsigned char *bytes = (const unsigned char *)[data bytes]; 161 | NSMutableString *hex = [NSMutableString new]; 162 | for (NSInteger i = 0; i < [data length]; i++) { 163 | [hex appendFormat:@"%02x", bytes[i]]; 164 | } 165 | 166 | [columnData safe_setObject:hex?:[NSNull null] forKey:@"value"]; 167 | }else { 168 | id obj = [rs respondsToSelector:@selector(objectForColumn:)] ? [rs performSelector:@selector(objectForColumn:) withObject:columName] : [rs performSelector:@selector(objectForColumnName:) withObject:columName]; 169 | [columnData safe_setObject:obj?:[NSNull null] forKey:@"value"]; 170 | } 171 | 172 | 173 | 174 | [row safe_addObject:columnData]; 175 | } 176 | 177 | [rows safe_addObject:row]; 178 | } 179 | 180 | [tableData safe_setObject:rows forKey:@"rows"]; 181 | return tableData; 182 | } 183 | 184 | - (BOOL)updateRecordInDatabase:(NSString *)database tableName:(NSString *)tableName data:(NSDictionary *)data condition:(NSDictionary *)condition { 185 | 186 | NSMutableArray *fields = @[].mutableCopy; 187 | 188 | for (NSString *key in data.allKeys) { 189 | [fields safe_addObject:[NSString stringWithFormat:@"%@ = '%@'", key, [data objectForKey:key]]]; 190 | } 191 | NSString *values = [fields componentsJoinedByString:@","]; 192 | 193 | NSString *where = @"1"; 194 | 195 | if ([condition isKindOfClass:[NSDictionary class]] && condition.count > 0) { 196 | NSMutableArray *conArray = @[].mutableCopy; 197 | 198 | for (NSString *key in condition.allKeys) { 199 | [conArray safe_addObject:[NSString stringWithFormat:@"%@ = '%@'", key, [condition objectForKey:key]]]; 200 | } 201 | 202 | where = [conArray componentsJoinedByString:@" AND "]; 203 | } 204 | 205 | NSString *sqlString = [NSString stringWithFormat:@"UPDATE \"%@\" SET %@ WHERE %@",tableName,values,where]; 206 | return [self.fmdb executeQuery:sqlString]; 207 | } 208 | 209 | - (BOOL)deleteRecordInDatabase:(NSString *)database tableName:(NSString *)tableName condition:(NSDictionary *)condition limit:(NSString *)limit { 210 | NSString *where = @"1"; 211 | NSString *limitString =@""; 212 | if (limit.length > 0) { 213 | limitString = [NSString stringWithFormat:@"LIMIT %@",limit]; 214 | } 215 | 216 | if ([condition isKindOfClass:[NSDictionary class]] && condition.count > 0) { 217 | NSMutableArray *conArray = @[].mutableCopy; 218 | 219 | for (NSString *key in condition.allKeys) { 220 | [conArray safe_addObject:[NSString stringWithFormat:@"%@ = '%@'", key, [condition objectForKey:key]]]; 221 | } 222 | 223 | where = [conArray componentsJoinedByString:@" AND "]; 224 | } 225 | 226 | NSString *sqlString =[NSString stringWithFormat:@"DELETE FROM \"%@\" WHERE %@ %@",tableName,where,limitString]; 227 | NSLog(@"delete %@",sqlString); 228 | return [self.fmdb executeUpdate:sqlString]; 229 | } 230 | 231 | - (NSDictionary*)executeQueryInDatabase:(NSString*)database tableName:(NSString*)tableName operator:(NSString*)operator query:(NSString*)query { 232 | 233 | if ([operator isEqualToString:@"select"]) { 234 | 235 | NSMutableDictionary *tableData = [NSMutableDictionary dictionary]; 236 | [tableData safe_setObject:@(1) forKey:@"isSelectQuery"]; 237 | [tableData safe_setObject:@(1) forKey:@"isSuccessful"]; 238 | 239 | 240 | //数据 241 | NSString *sql = query; 242 | FMResultSet *rs = [self.fmdb executeQuery:sql]; 243 | NSMutableArray *rows = @[].mutableCopy; 244 | 245 | //标题 246 | FMResultSet *infors = [self.fmdb getTableSchema:tableName]; 247 | 248 | NSMutableArray *tableInfoResult = [NSMutableArray array]; 249 | 250 | while ([infors next]) { 251 | NSMutableDictionary *info = [NSMutableDictionary dictionary]; 252 | 253 | NSString *columnName = [infors stringForColumn:@"name"]; 254 | 255 | if ([rs.columnNameToIndexMap.allKeys containsObject:columnName]) { 256 | [info safe_setObject:@([infors boolForColumn:@"pk"]) forKey:@"isPrimary"]; 257 | [info safe_setObject:[infors stringForColumn:@"name"]?:@"" forKey:@"title"]; 258 | [info safe_setObject:[infors stringForColumn:@"type"] forKey:@"dataType"]; 259 | [tableInfoResult safe_addObject:info]; 260 | } 261 | } 262 | [tableData safe_setObject:tableInfoResult forKey:@"tableInfos"]; 263 | 264 | BOOL isEditable = tableName != nil && [tableData objectForKey:@"tableInfos"] != nil; 265 | [tableData safe_setObject:@(isEditable) forKey:@"isEditable"]; 266 | 267 | while ([rs next]) { 268 | NSMutableArray *row = @[].mutableCopy; 269 | 270 | for ( int i = 0; i < tableInfoResult.count; i++) { 271 | NSMutableDictionary *columnData = [NSMutableDictionary dictionaryWithCapacity:10]; 272 | NSString *columName = [[tableInfoResult objectAtIndex:i] objectForKey:@"title"]; 273 | NSString *type = [[tableInfoResult objectAtIndex:i] objectForKey:@"dataType"]; 274 | 275 | if ([[type lowercaseString] isEqualToString:@"integer"]) { 276 | [columnData safe_setObject:@"integer" forKey:@"dataType"]; 277 | [columnData safe_setObject:@([rs intForColumn:columName]) forKey:@"value"]; 278 | }else if ([[type lowercaseString] isEqualToString:@"real"]) { 279 | [columnData safe_setObject:@"float" forKey:@"dataType"]; 280 | [columnData safe_setObject:@([rs doubleForColumn:columName]) forKey:@"value"]; 281 | }else if ([[type lowercaseString] isEqualToString:@"text"]) { 282 | [columnData safe_setObject:@"text" forKey:@"dataType"]; 283 | [columnData safe_setObject:[rs stringForColumn:columName]?:@"" forKey:@"value"]; 284 | }else if ([[type lowercaseString] isEqualToString:@"blob"]) { 285 | [columnData safe_setObject:@"blob" forKey:@"dataType"]; 286 | [columnData safe_setObject:@"blob" forKey:@"value"]; 287 | }else if ([[type lowercaseString] isEqualToString:@"null"]) { 288 | [columnData safe_setObject:@"null" forKey:@"dataType"]; 289 | [columnData safe_setObject:[NSNull null] forKey:@"value"]; 290 | }else { 291 | [columnData safe_setObject:@"text" forKey:@"dataType"]; 292 | [columnData safe_setObject:[rs stringForColumn:columName] forKey:@"value"]; 293 | } 294 | 295 | [row safe_addObject:columnData]; 296 | } 297 | 298 | [rows safe_addObject:row]; 299 | } 300 | 301 | [tableData safe_setObject:rows forKey:@"rows"]; 302 | return tableData; 303 | 304 | }else { 305 | BOOL result = [self.fmdb executeUpdate:query]; 306 | NSDictionary *respone; 307 | if (result) { 308 | respone = @{@"isSelectQuery":@(true),@"isSuccessful":@(true)}; 309 | }else{ 310 | respone = @{@"isSelectQuery":@(true),@"isSuccessful":@(false),@"errorMessage":@"Database Opration faild!"}; 311 | } 312 | 313 | return respone; 314 | } 315 | } 316 | 317 | - (NSDictionary*)userDefaultData { 318 | 319 | NSMutableDictionary *tableData = [NSMutableDictionary dictionary]; 320 | [tableData safe_setObject:@(1) forKey:@"isSelectQuery"]; 321 | [tableData safe_setObject:@(1) forKey:@"isSuccessful"]; 322 | 323 | NSMutableArray *tableInfoResult = [NSMutableArray array]; 324 | [tableInfoResult safe_addObject:@{@"title": @"key", @"isPrimary" : @(1), @"dataType" : @"text"}]; 325 | [tableInfoResult safe_addObject:@{@"title": @"value", @"isPrimary" : @(0), @"dataType" : @"text"}]; 326 | 327 | [tableData safe_setObject:tableInfoResult forKey:@"tableInfos"]; 328 | 329 | [tableData safe_setObject:@(NO) forKey:@"isEditable"]; 330 | 331 | NSMutableArray *rows = @[].mutableCopy; 332 | 333 | NSDictionary *userData = [[NSUserDefaults standardUserDefaults]dictionaryRepresentation]; 334 | 335 | for (NSString *key in userData.allKeys) { 336 | NSMutableArray *row = @[].mutableCopy; 337 | 338 | [row safe_addObject:@{@"dataType" : @"text", @"value" : key?key:@""}]; 339 | 340 | id value = [userData objectForKey:key]; 341 | 342 | if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]]) { 343 | [row safe_addObject:@{@"dataType" : @"text", @"value" : yy_dicGetStringSafe(userData, key)}]; 344 | }else { 345 | [row safe_addObject:@{@"dataType" : @"text", @"value" : [value description]?:@""}]; 346 | } 347 | 348 | [rows addObject:row]; 349 | } 350 | [tableData safe_setObject:rows forKey:@"rows"]; 351 | 352 | return tableData; 353 | } 354 | 355 | - (NSDictionary*)getAppInfoData { 356 | NSMutableDictionary *tableData = [NSMutableDictionary dictionary]; 357 | [tableData safe_setObject:@(1) forKey:@"isSelectQuery"]; 358 | [tableData safe_setObject:@(1) forKey:@"isSuccessful"]; 359 | 360 | NSMutableArray *tableInfoResult = [NSMutableArray array]; 361 | [tableInfoResult safe_addObject:@{@"title": @"property name", @"isPrimary" : @(1), @"dataType" : @"text"}]; 362 | [tableInfoResult safe_addObject:@{@"title": @"property value", @"isPrimary" : @(0), @"dataType" : @"text"}]; 363 | 364 | [tableData safe_setObject:tableInfoResult forKey:@"tableInfos"]; 365 | 366 | [tableData safe_setObject:@(NO) forKey:@"isEditable"]; 367 | 368 | NSMutableArray *rows = @[].mutableCopy; 369 | 370 | NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary]; 371 | //app name 372 | NSString *displayName = yy_dicGetStringSafe(infoDic, @"CFBundleDisplayName"); 373 | NSMutableArray *displayRow = @[].mutableCopy; 374 | [displayRow safe_addObject:@{@"dataType": @"text", @"value": @"Display Name"}]; 375 | [displayRow safe_addObject:@{@"dataType": @"text", @"value": displayName}]; 376 | [rows safe_addObject:displayRow]; 377 | 378 | //app bundle identifier 379 | NSString *bundleIdentifer = yy_dicGetStringSafe(infoDic, kCFBundleIdentifierKey); 380 | NSMutableArray *bundleRow = @[].mutableCopy; 381 | [bundleRow safe_addObject:@{@"dataType": @"text", @"value": @"Bundle Identifer"}]; 382 | [bundleRow safe_addObject:@{@"dataType": @"text", @"value": bundleIdentifer}]; 383 | [rows safe_addObject:bundleRow]; 384 | 385 | //app version 386 | NSString *version = yy_dicGetStringSafe(infoDic, @"CFBundleShortVersionString"); 387 | NSMutableArray *versionRow = @[].mutableCopy; 388 | [versionRow safe_addObject:@{@"dataType": @"text", @"value": @"Version"}]; 389 | [versionRow safe_addObject:@{@"dataType": @"text", @"value": version}]; 390 | [rows safe_addObject:versionRow]; 391 | 392 | //app build number 393 | NSString *build = yy_dicGetStringSafe(infoDic, kCFBundleVersionKey); 394 | NSMutableArray *buildRow = @[].mutableCopy; 395 | [buildRow safe_addObject:@{@"dataType": @"text", @"value": @"Build"}]; 396 | [buildRow safe_addObject:@{@"dataType": @"text", @"value": build}]; 397 | [rows safe_addObject:buildRow]; 398 | 399 | //document path 400 | NSArray *pathSearch = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 401 | NSString *documentsPath = [pathSearch objectAtIndex:0]; 402 | NSMutableArray *documentRow = @[].mutableCopy; 403 | [documentRow safe_addObject:@{@"dataType": @"text", @"value": @"Documents"}]; 404 | [documentRow safe_addObject:@{@"dataType": @"text", @"value": documentsPath?documentsPath:@""}]; 405 | [rows safe_addObject:documentRow]; 406 | 407 | //cache path 408 | NSArray *pathSearchCache = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 409 | NSString *cachePath = [pathSearchCache objectAtIndex:0]; 410 | NSMutableArray *cacheRow = @[].mutableCopy; 411 | [cacheRow safe_addObject:@{@"dataType": @"text", @"value": @"Cache"}]; 412 | [cacheRow safe_addObject:@{@"dataType": @"text", @"value": cachePath?cachePath:@""}]; 413 | [rows safe_addObject:cacheRow]; 414 | 415 | [tableData safe_setObject:rows forKey:@"rows"]; 416 | 417 | return tableData; 418 | } 419 | 420 | @end 421 | -------------------------------------------------------------------------------- /SwiftDebugDatabase/SwiftDebugDatabase.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 890087A98215BEBBADE1B09B /* Pods_SwiftDebugDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 904706ED44B957A2CBC04667 /* Pods_SwiftDebugDatabase.framework */; }; 11 | E8D793431F989FC6007BECF8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8D793421F989FC6007BECF8 /* AppDelegate.swift */; }; 12 | E8D793451F989FC6007BECF8 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8D793441F989FC6007BECF8 /* ViewController.swift */; }; 13 | E8D793481F989FC6007BECF8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E8D793461F989FC6007BECF8 /* Main.storyboard */; }; 14 | E8D7934A1F989FC6007BECF8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E8D793491F989FC6007BECF8 /* Assets.xcassets */; }; 15 | E8D7934D1F989FC6007BECF8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E8D7934B1F989FC6007BECF8 /* LaunchScreen.storyboard */; }; 16 | E8D7935A1F98CB9B007BECF8 /* Car.db in Resources */ = {isa = PBXBuildFile; fileRef = E8D793581F98CB9B007BECF8 /* Car.db */; }; 17 | E8D7935B1F98CB9B007BECF8 /* Contact.db in Resources */ = {isa = PBXBuildFile; fileRef = E8D793591F98CB9B007BECF8 /* Contact.db */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | 1F8F48773FE00BCC112D95F3 /* Pods-SwiftDebugDatabase.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftDebugDatabase.release.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftDebugDatabase/Pods-SwiftDebugDatabase.release.xcconfig"; sourceTree = ""; }; 22 | 8762A7EE912A5A63FF30A543 /* Pods-SwiftDebugDatabase.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftDebugDatabase.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftDebugDatabase/Pods-SwiftDebugDatabase.debug.xcconfig"; sourceTree = ""; }; 23 | 904706ED44B957A2CBC04667 /* Pods_SwiftDebugDatabase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SwiftDebugDatabase.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 24 | E8D7933F1F989FC6007BECF8 /* SwiftDebugDatabase.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftDebugDatabase.app; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | E8D793421F989FC6007BECF8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 26 | E8D793441F989FC6007BECF8 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 27 | E8D793471F989FC6007BECF8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 28 | E8D793491F989FC6007BECF8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 29 | E8D7934C1F989FC6007BECF8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 30 | E8D7934E1F989FC6007BECF8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 31 | E8D793541F98A70B007BECF8 /* SwiftDebugDatabase-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SwiftDebugDatabase-Bridging-Header.h"; sourceTree = ""; }; 32 | E8D793581F98CB9B007BECF8 /* Car.db */ = {isa = PBXFileReference; lastKnownFileType = file; path = Car.db; sourceTree = ""; }; 33 | E8D793591F98CB9B007BECF8 /* Contact.db */ = {isa = PBXFileReference; lastKnownFileType = file; path = Contact.db; sourceTree = ""; }; 34 | /* End PBXFileReference section */ 35 | 36 | /* Begin PBXFrameworksBuildPhase section */ 37 | E8D7933C1F989FC6007BECF8 /* Frameworks */ = { 38 | isa = PBXFrameworksBuildPhase; 39 | buildActionMask = 2147483647; 40 | files = ( 41 | 890087A98215BEBBADE1B09B /* Pods_SwiftDebugDatabase.framework in Frameworks */, 42 | ); 43 | runOnlyForDeploymentPostprocessing = 0; 44 | }; 45 | /* End PBXFrameworksBuildPhase section */ 46 | 47 | /* Begin PBXGroup section */ 48 | 5625056D58A531FF9860CD57 /* Frameworks */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | 904706ED44B957A2CBC04667 /* Pods_SwiftDebugDatabase.framework */, 52 | ); 53 | name = Frameworks; 54 | sourceTree = ""; 55 | }; 56 | 6066B93AB1E6BAF1C7918047 /* Pods */ = { 57 | isa = PBXGroup; 58 | children = ( 59 | 8762A7EE912A5A63FF30A543 /* Pods-SwiftDebugDatabase.debug.xcconfig */, 60 | 1F8F48773FE00BCC112D95F3 /* Pods-SwiftDebugDatabase.release.xcconfig */, 61 | ); 62 | name = Pods; 63 | sourceTree = ""; 64 | }; 65 | E8D793361F989FC6007BECF8 = { 66 | isa = PBXGroup; 67 | children = ( 68 | E8D793411F989FC6007BECF8 /* SwiftDebugDatabase */, 69 | E8D793401F989FC6007BECF8 /* Products */, 70 | 6066B93AB1E6BAF1C7918047 /* Pods */, 71 | 5625056D58A531FF9860CD57 /* Frameworks */, 72 | ); 73 | sourceTree = ""; 74 | }; 75 | E8D793401F989FC6007BECF8 /* Products */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | E8D7933F1F989FC6007BECF8 /* SwiftDebugDatabase.app */, 79 | ); 80 | name = Products; 81 | sourceTree = ""; 82 | }; 83 | E8D793411F989FC6007BECF8 /* SwiftDebugDatabase */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | E8D793421F989FC6007BECF8 /* AppDelegate.swift */, 87 | E8D793441F989FC6007BECF8 /* ViewController.swift */, 88 | E8D793461F989FC6007BECF8 /* Main.storyboard */, 89 | E8D793491F989FC6007BECF8 /* Assets.xcassets */, 90 | E8D7934B1F989FC6007BECF8 /* LaunchScreen.storyboard */, 91 | E8D7934E1F989FC6007BECF8 /* Info.plist */, 92 | E8D793541F98A70B007BECF8 /* SwiftDebugDatabase-Bridging-Header.h */, 93 | E8D793581F98CB9B007BECF8 /* Car.db */, 94 | E8D793591F98CB9B007BECF8 /* Contact.db */, 95 | ); 96 | path = SwiftDebugDatabase; 97 | sourceTree = ""; 98 | }; 99 | /* End PBXGroup section */ 100 | 101 | /* Begin PBXNativeTarget section */ 102 | E8D7933E1F989FC6007BECF8 /* SwiftDebugDatabase */ = { 103 | isa = PBXNativeTarget; 104 | buildConfigurationList = E8D793511F989FC6007BECF8 /* Build configuration list for PBXNativeTarget "SwiftDebugDatabase" */; 105 | buildPhases = ( 106 | A4616A3758088F0F2A12B55B /* [CP] Check Pods Manifest.lock */, 107 | E8D7933B1F989FC6007BECF8 /* Sources */, 108 | E8D7933C1F989FC6007BECF8 /* Frameworks */, 109 | E8D7933D1F989FC6007BECF8 /* Resources */, 110 | 47901D4B59E16DD3D15F9DDE /* [CP] Embed Pods Frameworks */, 111 | FC57E8102C3B1796DA971053 /* [CP] Copy Pods Resources */, 112 | ); 113 | buildRules = ( 114 | ); 115 | dependencies = ( 116 | ); 117 | name = SwiftDebugDatabase; 118 | productName = SwiftDebugDatabase; 119 | productReference = E8D7933F1F989FC6007BECF8 /* SwiftDebugDatabase.app */; 120 | productType = "com.apple.product-type.application"; 121 | }; 122 | /* End PBXNativeTarget section */ 123 | 124 | /* Begin PBXProject section */ 125 | E8D793371F989FC6007BECF8 /* Project object */ = { 126 | isa = PBXProject; 127 | attributes = { 128 | LastSwiftUpdateCheck = 0820; 129 | LastUpgradeCheck = 0920; 130 | ORGANIZATIONNAME = wentian; 131 | TargetAttributes = { 132 | E8D7933E1F989FC6007BECF8 = { 133 | CreatedOnToolsVersion = 8.2.1; 134 | DevelopmentTeam = DUD9TSG469; 135 | LastSwiftMigration = 0820; 136 | ProvisioningStyle = Automatic; 137 | }; 138 | }; 139 | }; 140 | buildConfigurationList = E8D7933A1F989FC6007BECF8 /* Build configuration list for PBXProject "SwiftDebugDatabase" */; 141 | compatibilityVersion = "Xcode 3.2"; 142 | developmentRegion = English; 143 | hasScannedForEncodings = 0; 144 | knownRegions = ( 145 | en, 146 | Base, 147 | ); 148 | mainGroup = E8D793361F989FC6007BECF8; 149 | productRefGroup = E8D793401F989FC6007BECF8 /* Products */; 150 | projectDirPath = ""; 151 | projectRoot = ""; 152 | targets = ( 153 | E8D7933E1F989FC6007BECF8 /* SwiftDebugDatabase */, 154 | ); 155 | }; 156 | /* End PBXProject section */ 157 | 158 | /* Begin PBXResourcesBuildPhase section */ 159 | E8D7933D1F989FC6007BECF8 /* Resources */ = { 160 | isa = PBXResourcesBuildPhase; 161 | buildActionMask = 2147483647; 162 | files = ( 163 | E8D7935A1F98CB9B007BECF8 /* Car.db in Resources */, 164 | E8D7934D1F989FC6007BECF8 /* LaunchScreen.storyboard in Resources */, 165 | E8D7934A1F989FC6007BECF8 /* Assets.xcassets in Resources */, 166 | E8D7935B1F98CB9B007BECF8 /* Contact.db in Resources */, 167 | E8D793481F989FC6007BECF8 /* Main.storyboard in Resources */, 168 | ); 169 | runOnlyForDeploymentPostprocessing = 0; 170 | }; 171 | /* End PBXResourcesBuildPhase section */ 172 | 173 | /* Begin PBXShellScriptBuildPhase section */ 174 | 47901D4B59E16DD3D15F9DDE /* [CP] Embed Pods Frameworks */ = { 175 | isa = PBXShellScriptBuildPhase; 176 | buildActionMask = 2147483647; 177 | files = ( 178 | ); 179 | inputPaths = ( 180 | "${SRCROOT}/Pods/Target Support Files/Pods-SwiftDebugDatabase/Pods-SwiftDebugDatabase-frameworks.sh", 181 | "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework", 182 | "${BUILT_PRODUCTS_DIR}/GCDWebServer/GCDWebServer.framework", 183 | "${BUILT_PRODUCTS_DIR}/YYDebugDatabase/YYDebugDatabase.framework", 184 | ); 185 | name = "[CP] Embed Pods Frameworks"; 186 | outputPaths = ( 187 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework", 188 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GCDWebServer.framework", 189 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYDebugDatabase.framework", 190 | ); 191 | runOnlyForDeploymentPostprocessing = 0; 192 | shellPath = /bin/sh; 193 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SwiftDebugDatabase/Pods-SwiftDebugDatabase-frameworks.sh\"\n"; 194 | showEnvVarsInLog = 0; 195 | }; 196 | A4616A3758088F0F2A12B55B /* [CP] Check Pods Manifest.lock */ = { 197 | isa = PBXShellScriptBuildPhase; 198 | buildActionMask = 2147483647; 199 | files = ( 200 | ); 201 | inputPaths = ( 202 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 203 | "${PODS_ROOT}/Manifest.lock", 204 | ); 205 | name = "[CP] Check Pods Manifest.lock"; 206 | outputPaths = ( 207 | "$(DERIVED_FILE_DIR)/Pods-SwiftDebugDatabase-checkManifestLockResult.txt", 208 | ); 209 | runOnlyForDeploymentPostprocessing = 0; 210 | shellPath = /bin/sh; 211 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 212 | showEnvVarsInLog = 0; 213 | }; 214 | FC57E8102C3B1796DA971053 /* [CP] Copy Pods Resources */ = { 215 | isa = PBXShellScriptBuildPhase; 216 | buildActionMask = 2147483647; 217 | files = ( 218 | ); 219 | inputPaths = ( 220 | ); 221 | name = "[CP] Copy Pods Resources"; 222 | outputPaths = ( 223 | ); 224 | runOnlyForDeploymentPostprocessing = 0; 225 | shellPath = /bin/sh; 226 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SwiftDebugDatabase/Pods-SwiftDebugDatabase-resources.sh\"\n"; 227 | showEnvVarsInLog = 0; 228 | }; 229 | /* End PBXShellScriptBuildPhase section */ 230 | 231 | /* Begin PBXSourcesBuildPhase section */ 232 | E8D7933B1F989FC6007BECF8 /* Sources */ = { 233 | isa = PBXSourcesBuildPhase; 234 | buildActionMask = 2147483647; 235 | files = ( 236 | E8D793451F989FC6007BECF8 /* ViewController.swift in Sources */, 237 | E8D793431F989FC6007BECF8 /* AppDelegate.swift in Sources */, 238 | ); 239 | runOnlyForDeploymentPostprocessing = 0; 240 | }; 241 | /* End PBXSourcesBuildPhase section */ 242 | 243 | /* Begin PBXVariantGroup section */ 244 | E8D793461F989FC6007BECF8 /* Main.storyboard */ = { 245 | isa = PBXVariantGroup; 246 | children = ( 247 | E8D793471F989FC6007BECF8 /* Base */, 248 | ); 249 | name = Main.storyboard; 250 | sourceTree = ""; 251 | }; 252 | E8D7934B1F989FC6007BECF8 /* LaunchScreen.storyboard */ = { 253 | isa = PBXVariantGroup; 254 | children = ( 255 | E8D7934C1F989FC6007BECF8 /* Base */, 256 | ); 257 | name = LaunchScreen.storyboard; 258 | sourceTree = ""; 259 | }; 260 | /* End PBXVariantGroup section */ 261 | 262 | /* Begin XCBuildConfiguration section */ 263 | E8D7934F1F989FC6007BECF8 /* Debug */ = { 264 | isa = XCBuildConfiguration; 265 | buildSettings = { 266 | ALWAYS_SEARCH_USER_PATHS = NO; 267 | CLANG_ANALYZER_NONNULL = YES; 268 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 269 | CLANG_CXX_LIBRARY = "libc++"; 270 | CLANG_ENABLE_MODULES = YES; 271 | CLANG_ENABLE_OBJC_ARC = YES; 272 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 273 | CLANG_WARN_BOOL_CONVERSION = YES; 274 | CLANG_WARN_COMMA = YES; 275 | CLANG_WARN_CONSTANT_CONVERSION = YES; 276 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 277 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 278 | CLANG_WARN_EMPTY_BODY = YES; 279 | CLANG_WARN_ENUM_CONVERSION = YES; 280 | CLANG_WARN_INFINITE_RECURSION = YES; 281 | CLANG_WARN_INT_CONVERSION = YES; 282 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 283 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 284 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 285 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 286 | CLANG_WARN_STRICT_PROTOTYPES = YES; 287 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 288 | CLANG_WARN_UNREACHABLE_CODE = YES; 289 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 290 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 291 | COPY_PHASE_STRIP = NO; 292 | DEBUG_INFORMATION_FORMAT = dwarf; 293 | ENABLE_STRICT_OBJC_MSGSEND = YES; 294 | ENABLE_TESTABILITY = YES; 295 | GCC_C_LANGUAGE_STANDARD = gnu99; 296 | GCC_DYNAMIC_NO_PIC = NO; 297 | GCC_NO_COMMON_BLOCKS = YES; 298 | GCC_OPTIMIZATION_LEVEL = 0; 299 | GCC_PREPROCESSOR_DEFINITIONS = ( 300 | "DEBUG=1", 301 | "$(inherited)", 302 | ); 303 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 304 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 305 | GCC_WARN_UNDECLARED_SELECTOR = YES; 306 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 307 | GCC_WARN_UNUSED_FUNCTION = YES; 308 | GCC_WARN_UNUSED_VARIABLE = YES; 309 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 310 | MTL_ENABLE_DEBUG_INFO = YES; 311 | ONLY_ACTIVE_ARCH = YES; 312 | SDKROOT = iphoneos; 313 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 314 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 315 | TARGETED_DEVICE_FAMILY = "1,2"; 316 | }; 317 | name = Debug; 318 | }; 319 | E8D793501F989FC6007BECF8 /* Release */ = { 320 | isa = XCBuildConfiguration; 321 | buildSettings = { 322 | ALWAYS_SEARCH_USER_PATHS = NO; 323 | CLANG_ANALYZER_NONNULL = YES; 324 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 325 | CLANG_CXX_LIBRARY = "libc++"; 326 | CLANG_ENABLE_MODULES = YES; 327 | CLANG_ENABLE_OBJC_ARC = YES; 328 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 329 | CLANG_WARN_BOOL_CONVERSION = YES; 330 | CLANG_WARN_COMMA = YES; 331 | CLANG_WARN_CONSTANT_CONVERSION = YES; 332 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 333 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 334 | CLANG_WARN_EMPTY_BODY = YES; 335 | CLANG_WARN_ENUM_CONVERSION = YES; 336 | CLANG_WARN_INFINITE_RECURSION = YES; 337 | CLANG_WARN_INT_CONVERSION = YES; 338 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 339 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 340 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 341 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 342 | CLANG_WARN_STRICT_PROTOTYPES = YES; 343 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 344 | CLANG_WARN_UNREACHABLE_CODE = YES; 345 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 346 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 347 | COPY_PHASE_STRIP = NO; 348 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 349 | ENABLE_NS_ASSERTIONS = NO; 350 | ENABLE_STRICT_OBJC_MSGSEND = YES; 351 | GCC_C_LANGUAGE_STANDARD = gnu99; 352 | GCC_NO_COMMON_BLOCKS = YES; 353 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 354 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 355 | GCC_WARN_UNDECLARED_SELECTOR = YES; 356 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 357 | GCC_WARN_UNUSED_FUNCTION = YES; 358 | GCC_WARN_UNUSED_VARIABLE = YES; 359 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 360 | MTL_ENABLE_DEBUG_INFO = NO; 361 | SDKROOT = iphoneos; 362 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 363 | TARGETED_DEVICE_FAMILY = "1,2"; 364 | VALIDATE_PRODUCT = YES; 365 | }; 366 | name = Release; 367 | }; 368 | E8D793521F989FC6007BECF8 /* Debug */ = { 369 | isa = XCBuildConfiguration; 370 | baseConfigurationReference = 8762A7EE912A5A63FF30A543 /* Pods-SwiftDebugDatabase.debug.xcconfig */; 371 | buildSettings = { 372 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 373 | CLANG_ENABLE_MODULES = YES; 374 | DEVELOPMENT_TEAM = DUD9TSG469; 375 | INFOPLIST_FILE = SwiftDebugDatabase/Info.plist; 376 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 377 | PRODUCT_BUNDLE_IDENTIFIER = swift.debug.database.SwiftDebugDatabase; 378 | PRODUCT_NAME = "$(TARGET_NAME)"; 379 | SWIFT_OBJC_BRIDGING_HEADER = "SwiftDebugDatabase/SwiftDebugDatabase-Bridging-Header.h"; 380 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 381 | SWIFT_VERSION = 3.0; 382 | }; 383 | name = Debug; 384 | }; 385 | E8D793531F989FC6007BECF8 /* Release */ = { 386 | isa = XCBuildConfiguration; 387 | baseConfigurationReference = 1F8F48773FE00BCC112D95F3 /* Pods-SwiftDebugDatabase.release.xcconfig */; 388 | buildSettings = { 389 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 390 | CLANG_ENABLE_MODULES = YES; 391 | DEVELOPMENT_TEAM = DUD9TSG469; 392 | INFOPLIST_FILE = SwiftDebugDatabase/Info.plist; 393 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 394 | PRODUCT_BUNDLE_IDENTIFIER = swift.debug.database.SwiftDebugDatabase; 395 | PRODUCT_NAME = "$(TARGET_NAME)"; 396 | SWIFT_OBJC_BRIDGING_HEADER = "SwiftDebugDatabase/SwiftDebugDatabase-Bridging-Header.h"; 397 | SWIFT_VERSION = 3.0; 398 | }; 399 | name = Release; 400 | }; 401 | /* End XCBuildConfiguration section */ 402 | 403 | /* Begin XCConfigurationList section */ 404 | E8D7933A1F989FC6007BECF8 /* Build configuration list for PBXProject "SwiftDebugDatabase" */ = { 405 | isa = XCConfigurationList; 406 | buildConfigurations = ( 407 | E8D7934F1F989FC6007BECF8 /* Debug */, 408 | E8D793501F989FC6007BECF8 /* Release */, 409 | ); 410 | defaultConfigurationIsVisible = 0; 411 | defaultConfigurationName = Release; 412 | }; 413 | E8D793511F989FC6007BECF8 /* Build configuration list for PBXNativeTarget "SwiftDebugDatabase" */ = { 414 | isa = XCConfigurationList; 415 | buildConfigurations = ( 416 | E8D793521F989FC6007BECF8 /* Debug */, 417 | E8D793531F989FC6007BECF8 /* Release */, 418 | ); 419 | defaultConfigurationIsVisible = 0; 420 | defaultConfigurationName = Release; 421 | }; 422 | /* End XCConfigurationList section */ 423 | }; 424 | rootObject = E8D793371F989FC6007BECF8 /* Project object */; 425 | } 426 | --------------------------------------------------------------------------------