//
//  DBConfigureCenter.m
//  zhuxun
//
//  Created by winsoft on 17/4/24.
//
//

#import "DBConfigureCenter.h"
#import <objc/runtime.h>

@implementation DBConfigureCenter

/*
 数据库升级,字段变更核心语法:
 
 if (![db columnExists:@"需要增加的字段" inTableWithName:@"表名"]){
 
    //插入
    NSString *alertStr = [NSString stringWithFormat:@"ALTER TABLE %@ ADD %@ %@",@"表名",@"字段名",@"类型(eg:integer)"]
 
    worked = [db executeUpdate:alertStr];
 
    FMDBQuickCheck(worked);
 
 }else{
 
 暂sqlite原生不支持删除字段.
    //删除
    ALTER->DELETE?
 
 }
 
 */

//自动升级
+ (NSArray<DBStructModel *> *)sqlCloumnCheckWithClassName:(Class )className
{
    //字段及name校验
    Class cls = className;
    
    
    //　遍历成员变量列表，其中每个变量都是Ivar类型的结构体
    NSMutableArray *standardSQLArray = [NSMutableArray array];
    
    if (className == NULL) {
        return nil;
    }
    
    unsigned int outCount, j;
    objc_property_t *properties = class_copyPropertyList(cls, &outCount);
    for (j = 0; j < outCount; j++) {
        objc_property_t property = properties[j];
        const char  *propName = property_getName(property);
        if(propName) {
            const char *propType = getPropertyType(property);
            
            if (!propType || propType == NULL) {
                continue;
            }
            
            NSString *propertyName = [NSString stringWithUTF8String:propName];
            NSString *propertyType = [NSString stringWithUTF8String:propType];
            NSString *sqlType = [self getValueTypeWithValue:propertyType];
        
            [standardSQLArray addObject:[DBStructModel dbStructModelWithName:propertyName type:sqlType]];
            
        }
        
        
    }
    free(properties);
    
    return standardSQLArray;
}

+ (NSString *)getDBTableWithTableName:(NSString *)tableName className:(Class )className
{
    Class cls = className;
    
    
    //　遍历成员变量列表，其中每个变量都是Ivar类型的结构体
    NSMutableArray *standardSQLArray = [NSMutableArray array];
  
    if (className == NULL) {
        return nil;
    }
    
    unsigned int outCount, j;
    objc_property_t *properties = class_copyPropertyList(cls, &outCount);
    for (j = 0; j < outCount; j++) {
        objc_property_t property = properties[j];
        const char  *propName = property_getName(property);
        if(propName) {
            const char *propType = getPropertyType(property);
            
            if (!property || propType == NULL) {
                continue;
            }
            NSString *propertyName = [NSString stringWithUTF8String:propName];
            NSString *propertyType = [NSString stringWithUTF8String:propType];
            
            NSString *oneStandardSQL = [NSString stringWithFormat:@"%@ %@",propertyName,[self getValueTypeWithValue:propertyType]];
            NSLog(@"propertyName %@ propertyType %@", propertyName, propertyType);
            [standardSQLArray addObject:oneStandardSQL];
            
        }
        
        
    }
    free(properties);
    
    NSString *fullSql = [standardSQLArray componentsJoinedByString:@","];
    
    return [NSString stringWithFormat:@"create table if not exists %@(%@);",tableName,fullSql];
   
 
}

+ (NSString *)getValueTypeWithValue:(NSString *)valueStr
{
    if ([valueStr isEqualToString:@"B"]) {
        return @"bool";
    }else if ([valueStr isEqualToString:@"q"] || [valueStr isEqualToString:@"NSNumber"] || [valueStr isEqualToString:@"i"])
    {
        return @"integer";
    }else if ([valueStr isEqualToString:@"NSString"])
    {
        return @"text";
    }else if ([valueStr isEqualToString:@"d"])
    {
        return @"float";
    }else if ([valueStr isEqualToString:@"NSDate"])
    {
        return @"date";
    }else return @"bolb";
}

+ (NSString *)getKeysArrayStrWithClassName:(Class)className
{
    Class cls = className;
    
    
    //　遍历成员变量列表，其中每个变量都是Ivar类型的结构体
    NSMutableArray *standardSQLArray = [NSMutableArray array];
    
    if (className == NULL) {
        return nil;
    }
    
    unsigned int outCount, j;
    objc_property_t *properties = class_copyPropertyList(cls, &outCount);
    for (j = 0; j < outCount; j++) {
        objc_property_t property = properties[j];
        const char  *propName = property_getName(property);
        const char *propType = getPropertyType(property);
        
        if (!property || propType == NULL) {
            continue;
        }
        
        if(propName) {
            NSString *propertyName = [NSString stringWithUTF8String:propName];

            [standardSQLArray addObject:propertyName];
            
        }
        
        
    }
    free(properties);
    
    NSString *fullSql = [standardSQLArray componentsJoinedByString:@","];
    
    return fullSql;
}

//获取属性的方法
static const char  *getPropertyType(objc_property_t property) {
    const char  *attributes = property_getAttributes(property);
    //printf("attributes=%s\n", attributes);
    char buffer[1 + strlen(attributes)];
    strcpy(buffer, attributes);
    char *state = buffer, *attribute;
    while ((attribute = strsep(&state, ",")) != NULL) {
        if (attribute[0] == 'T' && attribute[1] != '@') {
            // it's a C primitive type:
            
            // if you want a list of what will be returned for these primitives, search online for
            // "objective-c" "Property Attribute Description Examples"
            // apple docs list plenty of examples of what you get for int "i", long "l", unsigned "I", struct, etc.
            
            NSString *name = [[NSString alloc] initWithBytes:attribute + 1 length:strlen(attribute) - 1 encoding:NSASCIIStringEncoding];
            return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding];
        }
        else if (attribute[0] == 'T' && attribute[1] == '@' && strlen(attribute) == 2) {
            // it's an ObjC id type:
            return "id";
        }
        else if (attribute[0] == 'T' && attribute[1] == '@') {
            // it's another ObjC object type:
            NSString *name = [[NSString alloc] initWithBytes:attribute + 3 length:strlen(attribute) - 4 encoding:NSASCIIStringEncoding];
            return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding];
        }
    }
    return "";
}
@end
