// // LHSqlite.m // LHDBDemo // // Created by 3wchina01 on 16/3/22. // Copyright © 2016年 李浩. All rights reserved. // #import "LHSqlite.h" #import #import #import #import "NSObject+LHModel.h" #define Lock OSSpinLockLock(&(self->_lock)) #define UnLock OSSpinLockUnlock(&(self->_lock)) #define TryLock OSSpinLockTry(&(self->_lock)) @implementation LHSqlite{ @package OSSpinLock _lock; sqlite3* _db; } static NSError* errorForDataBase(NSString* sqlString,sqlite3* db) { NSError* error = [NSError errorWithDomain:[NSString stringWithUTF8String:sqlite3_errmsg(db)] code:sqlite3_errcode(db) userInfo:@{@"sqlString":sqlString}]; return error; } static NSObject* dataWithDataType(int type,sqlite3_stmt * statement,int index) { if (type == SQLITE_INTEGER) { int value = sqlite3_column_int(statement, index); return [NSNumber numberWithInt:value]; }else if (type == SQLITE_FLOAT) { float value = sqlite3_column_double(statement, index); return [NSNumber numberWithFloat:value]; }else if (type == SQLITE_BLOB) { const void *value = sqlite3_column_blob(statement, index); int bytes = sqlite3_column_bytes(statement, index); return [NSData dataWithBytes:value length:bytes]; }else if (type == SQLITE_NULL) { return nil; }else if (type == SQLITE_TEXT) { return [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, index)]; }else { return nil; } } - (instancetype)initWithPath:(NSString*)dbPath { self = [super init]; if (self) { _sqlPath = dbPath; _lock = OS_SPINLOCK_INIT; } return self; } + (instancetype)sqliteWithPath:(NSString*)dbPath { LHSqlite* sqlite = [[LHSqlite alloc] initWithPath:dbPath]; return sqlite; } + (instancetype)shareInstance { static LHSqlite* sqlite = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sqlite = [LHSqlite sqliteWithPath:nil]; }); return sqlite; } - (BOOL)openDB { if (sqlite3_open([self.sqlPath UTF8String], &_db) == SQLITE_OK) { return YES; }else{ sqlite3_close(_db); return NO; } } - (void)executeSQLWithSqlstring:(NSString*)sqlString object:(id)model executeType:(LHSqliteType)type success:(success)successBlock fail:(fail)failBlock { Lock; if (![self openDB]) { if (failBlock) { failBlock([NSError errorWithDomain:@"打开数据库失败" code:0 userInfo:@{}]); } UnLock; return; } sqlite3_stmt* stmt; if (type == LHSqliteTypeWrite) { [self writeToDB:sqlString stmt:stmt model:model complete:^(NSError *error) { UnLock; if (failBlock) { failBlock(error); } }]; }else { [self readFromDB:sqlString stmt:stmt success:^(NSArray *result) { UnLock; if (successBlock) { successBlock(result); } } fail:^(NSError *error) { UnLock; if (failBlock) { failBlock(error); } }]; } sqlite3_close(_db); } - (void)writeToDB:(NSString*)sqlString stmt:(sqlite3_stmt*)stmt model:(id)model complete:(fail)complete { NSDictionary* modelDic = [model lh_ModelToDictionary]; if (sqlite3_prepare_v2(_db, [sqlString UTF8String], -1, &stmt, nil) != SQLITE_OK) { if (complete) { complete(errorForDataBase(sqlString, _db)); }else UnLock; sqlite3_finalize(stmt); return; } for (int i=0; i