Bläddra i källkod

Fix some problems about database browser

Taavo 10 år sedan
förälder
incheckning
4ffc992872

+ 7 - 2
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.h

@@ -1,10 +1,15 @@
 //
 //  PTDatabaseManager.h
-//  PTDatabaseReader
+//  Derived from:
+//
+//  FMDatabase.h
+//  FMDB( https://github.com/ccgus/fmdb )
 //
 //  Created by Peng Tao on 15/11/23.
-//  Copyright © 2015年 Peng Tao. All rights reserved.
 //
+//  Licensed to Flying Meat Inc. under one or more contributor license agreements.
+//  See the LICENSE file distributed with this work for the terms under
+//  which Flying Meat Inc. licenses this file to you.
 
 #import <Foundation/Foundation.h>
 

+ 128 - 127
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.m

@@ -6,6 +6,8 @@
 //  Copyright © 2015年 Peng Tao. All rights reserved.
 //
 
+
+
 #import "FLEXDatabaseManager.h"
 #import <sqlite3.h>
 
@@ -15,89 +17,88 @@ static NSString *const QUERY_TABLENAMES_SQL = @"SELECT name FROM sqlite_master W
 
 @implementation FLEXDatabaseManager
 {
-  sqlite3* _db;
-  NSString* _databasePath;
+    sqlite3* _db;
+    NSString* _databasePath;
 }
 
 
 - (instancetype)initWithPath:(NSString*)aPath
-{  
-  self = [super init];
-  
-  if (self) {
-    _databasePath = [aPath copy];
-    _db           = nil;
-  }
-  return self;
+{
+    self = [super init];
+    
+    if (self) {
+        _databasePath = [aPath copy];
+    }
+    return self;
 }
 
 
 - (BOOL)open {
-  if (_db) {
+    if (_db) {
+        return YES;
+    }
+    int err = sqlite3_open([_databasePath UTF8String], &_db);
+    if(err != SQLITE_OK) {
+        NSLog(@"error opening!: %d", err);
+        return NO;
+    }
     return YES;
-  }
-  int err = sqlite3_open([_databasePath UTF8String], &_db);
-  if(err != SQLITE_OK) {
-    NSLog(@"error opening!: %d", err);
-    return NO;
-  }
-  return YES;
 }
 
 - (BOOL)close {
-  if (!_db) {
-    return YES;
-  }
-  
-  int  rc;
-  BOOL retry;
-  BOOL triedFinalizingOpenStatements = NO;
-  
-  do {
-    retry   = NO;
-    rc      = sqlite3_close(_db);
-    if (SQLITE_BUSY == rc || SQLITE_LOCKED == rc) {
-      if (!triedFinalizingOpenStatements) {
-        triedFinalizingOpenStatements = YES;
-        sqlite3_stmt *pStmt;
-        while ((pStmt = sqlite3_next_stmt(_db, nil)) !=0) {
-          NSLog(@"Closing leaked statement");
-          sqlite3_finalize(pStmt);
-          retry = YES;
-        }
-      }
+    if (!_db) {
+        return YES;
     }
-    else if (SQLITE_OK != rc) {
-      NSLog(@"error closing!: %d", rc);
+    
+    int  rc;
+    BOOL retry;
+    BOOL triedFinalizingOpenStatements = NO;
+    
+    do {
+        retry   = NO;
+        rc      = sqlite3_close(_db);
+        if (SQLITE_BUSY == rc || SQLITE_LOCKED == rc) {
+            if (!triedFinalizingOpenStatements) {
+                triedFinalizingOpenStatements = YES;
+                sqlite3_stmt *pStmt;
+                while ((pStmt = sqlite3_next_stmt(_db, nil)) !=0) {
+                    NSLog(@"Closing leaked statement");
+                    sqlite3_finalize(pStmt);
+                    retry = YES;
+                }
+            }
+        }
+        else if (SQLITE_OK != rc) {
+            NSLog(@"error closing!: %d", rc);
+        }
     }
-  }
-  while (retry);
-  
-  _db = nil;
-  return YES;
+    while (retry);
+    
+    _db = nil;
+    return YES;
 }
 
 
 - (NSArray *)queryAllTables
 {
-  return [self executeQuery:QUERY_TABLENAMES_SQL];
+    return [self executeQuery:QUERY_TABLENAMES_SQL];
 }
 
 - (NSArray *)queryAllColumnsWithTableName:(NSString *)tableName
 {
-  NSString *sql = [NSString stringWithFormat:@"PRAGMA table_info('%@')",tableName];
-  NSArray *resultArray =  [self executeQuery:sql];
-  NSMutableArray *array = [NSMutableArray array];
-  for (NSDictionary *dict in resultArray) {
-    [array addObject:dict[@"name"]];
-  }
-  return array;
+    NSString *sql = [NSString stringWithFormat:@"PRAGMA table_info('%@')",tableName];
+    NSArray *resultArray =  [self executeQuery:sql];
+    NSMutableArray *array = [NSMutableArray array];
+    for (NSDictionary *dict in resultArray) {
+        [array addObject:dict[@"name"]];
+    }
+    return array;
 }
 
 - (NSArray *)queryAllDataWithTableName:(NSString *)tableName
 {
-  NSString *sql = [NSString stringWithFormat:@"SELECT * FROM %@",tableName];
-  return [self executeQuery:sql];
+    NSString *sql = [NSString stringWithFormat:@"SELECT * FROM %@",tableName];
+    return [self executeQuery:sql];
 }
 
 #pragma mark -
@@ -105,89 +106,89 @@ static NSString *const QUERY_TABLENAMES_SQL = @"SELECT name FROM sqlite_master W
 
 - (NSArray *)executeQuery:(NSString *)sql
 {
-  [self open];
-  NSMutableArray *resultArray = [NSMutableArray array];
-  sqlite3_stmt *pstmt;
-  if (sqlite3_prepare_v2(_db, [sql UTF8String], -1, &pstmt, 0) == SQLITE_OK) {
-    while (sqlite3_step(pstmt) == SQLITE_ROW) {
-      NSUInteger num_cols = (NSUInteger)sqlite3_data_count(pstmt);
-      if (num_cols > 0) {
-        NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:num_cols];
-        
-        int columnCount = sqlite3_column_count(pstmt);
-        
-        int columnIdx = 0;
-        for (columnIdx = 0; columnIdx < columnCount; columnIdx++) {
-          
-          NSString *columnName = [NSString stringWithUTF8String:sqlite3_column_name(pstmt, columnIdx)];
-          id objectValue = [self objectForColumnIndex:columnIdx stmt:pstmt];
-          [dict setObject:objectValue forKey:columnName];
+    [self open];
+    NSMutableArray *resultArray = [NSMutableArray array];
+    sqlite3_stmt *pstmt;
+    if (sqlite3_prepare_v2(_db, [sql UTF8String], -1, &pstmt, 0) == SQLITE_OK) {
+        while (sqlite3_step(pstmt) == SQLITE_ROW) {
+            NSUInteger num_cols = (NSUInteger)sqlite3_data_count(pstmt);
+            if (num_cols > 0) {
+                NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:num_cols];
+                
+                int columnCount = sqlite3_column_count(pstmt);
+                
+                int columnIdx = 0;
+                for (columnIdx = 0; columnIdx < columnCount; columnIdx++) {
+                    
+                    NSString *columnName = [NSString stringWithUTF8String:sqlite3_column_name(pstmt, columnIdx)];
+                    id objectValue = [self objectForColumnIndex:columnIdx stmt:pstmt];
+                    [dict setObject:objectValue forKey:columnName];
+                }
+                [resultArray addObject:dict];
+            }
         }
-        [resultArray addObject:dict];
-      }
     }
-  }
-  [self close];
-  return resultArray;
+    [self close];
+    return resultArray;
 }
 
 
 - (id)objectForColumnIndex:(int)columnIdx stmt:(sqlite3_stmt*)stmt {
-  int columnType = sqlite3_column_type(stmt, columnIdx);
-  
-  id returnValue = nil;
-  
-  if (columnType == SQLITE_INTEGER) {
-    returnValue =  [NSNumber numberWithLongLong:sqlite3_column_int64(stmt, columnIdx)];
-  }
-  else if (columnType == SQLITE_FLOAT) {
-    returnValue = [NSNumber numberWithDouble:sqlite3_column_double(stmt, columnIdx)];
-  }
-  else if (columnType == SQLITE_BLOB) {
-    returnValue = [self dataForColumnIndex:columnIdx stmt:stmt];
-  }
-  else {
-    //default to a string for everything else
-    returnValue = [self stringForColumnIndex:columnIdx stmt:stmt];
-  }
-  
-  if (returnValue == nil) {
-    returnValue = [NSNull null];
-  }
-  
-  return returnValue;
+    int columnType = sqlite3_column_type(stmt, columnIdx);
+    
+    id returnValue = nil;
+    
+    if (columnType == SQLITE_INTEGER) {
+        returnValue =  [NSNumber numberWithLongLong:sqlite3_column_int64(stmt, columnIdx)];
+    }
+    else if (columnType == SQLITE_FLOAT) {
+        returnValue = [NSNumber numberWithDouble:sqlite3_column_double(stmt, columnIdx)];
+    }
+    else if (columnType == SQLITE_BLOB) {
+        returnValue = [self dataForColumnIndex:columnIdx stmt:stmt];
+    }
+    else {
+        //default to a string for everything else
+        returnValue = [self stringForColumnIndex:columnIdx stmt:stmt];
+    }
+    
+    if (returnValue == nil) {
+        returnValue = [NSNull null];
+    }
+    
+    return returnValue;
 }
 
 - (NSString *)stringForColumnIndex:(int)columnIdx stmt:(sqlite3_stmt *)stmt {
-  
-  if (sqlite3_column_type(stmt, columnIdx) == SQLITE_NULL || (columnIdx < 0)) {
-    return nil;
-  }
-  
-  const char *c = (const char *)sqlite3_column_text(stmt, columnIdx);
-  
-  if (!c) {
-    // null row.
-    return nil;
-  }
-  
-  return [NSString stringWithUTF8String:c];
+    
+    if (sqlite3_column_type(stmt, columnIdx) == SQLITE_NULL || (columnIdx < 0)) {
+        return nil;
+    }
+    
+    const char *c = (const char *)sqlite3_column_text(stmt, columnIdx);
+    
+    if (!c) {
+        // null row.
+        return nil;
+    }
+    
+    return [NSString stringWithUTF8String:c];
 }
 
 - (NSData *)dataForColumnIndex:(int)columnIdx stmt:(sqlite3_stmt *)stmt{
-  
-  if (sqlite3_column_type(stmt, columnIdx) == SQLITE_NULL || (columnIdx < 0)) {
-    return nil;
-  }
-  
-  const char *dataBuffer = sqlite3_column_blob(stmt, columnIdx);
-  int dataSize = sqlite3_column_bytes(stmt, columnIdx);
-  
-  if (dataBuffer == NULL) {
-    return nil;
-  }
-  
-  return [NSData dataWithBytes:(const void *)dataBuffer length:(NSUInteger)dataSize];
+    
+    if (sqlite3_column_type(stmt, columnIdx) == SQLITE_NULL || (columnIdx < 0)) {
+        return nil;
+    }
+    
+    const char *dataBuffer = sqlite3_column_blob(stmt, columnIdx);
+    int dataSize = sqlite3_column_bytes(stmt, columnIdx);
+    
+    if (dataBuffer == NULL) {
+        return nil;
+    }
+    
+    return [NSData dataWithBytes:(const void *)dataBuffer length:(NSUInteger)dataSize];
 }
 
 

+ 5 - 4
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.h

@@ -13,11 +13,12 @@
 
 @protocol FLEXMultiColumnTableViewDelegate <NSObject>
 
-@optional
-- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView labelDidTapWithText:(NSString *)text;
-- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView headerTapWithText:(NSString *)text sortType:(FLEXTableColumnHeaderSortType)type;
+@required
+- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView didTapLabelWithText:(NSString *)text;
+- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView didTapHeaderWithText:(NSString *)text sortType:(FLEXTableColumnHeaderSortType)sortType;
 
 @end
+
 @protocol FLEXMultiColumnTableViewDataSource <NSObject>
 
 @required
@@ -32,7 +33,7 @@
 - (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView widthForContentCellInColumn:(NSInteger)column;
 - (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView heightForContentCellInRow:(NSInteger)row;
 - (CGFloat)heightForTopHeaderInTableView:(FLEXMultiColumnTableView *)tableView;
-- (CGFloat)WidthForLeftHeaderInTableView:(FLEXMultiColumnTableView *)tableView;
+- (CGFloat)widthForLeftHeaderInTableView:(FLEXMultiColumnTableView *)tableView;
 
 @end
 

+ 184 - 188
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.m

@@ -13,11 +13,11 @@
 @interface FLEXMultiColumnTableView ()
 <UITableViewDataSource, UITableViewDelegate,UIScrollViewDelegate, FLEXTableContentCellDelegate>
 
-@property (nonatomic, weak) UIScrollView *contentScrollView;
-@property (nonatomic, weak) UIScrollView *headerScrollView;
-@property (nonatomic, weak) UITableView  *leftTableView;
-@property (nonatomic, weak) UITableView  *contentTableView;
-@property (nonatomic, weak) UIView       *leftHeader;
+@property (nonatomic, strong) UIScrollView *contentScrollView;
+@property (nonatomic, strong) UIScrollView *headerScrollView;
+@property (nonatomic, strong) UITableView  *leftTableView;
+@property (nonatomic, strong) UITableView  *contentTableView;
+@property (nonatomic, strong) UIView       *leftHeader;
 
 @property (nonatomic, strong) NSDictionary *sortStatusDict;
 @property (nonatomic, strong) NSArray *rowData;
@@ -30,104 +30,104 @@ static const CGFloat kColumnMargin = 1;
 
 - (instancetype)initWithFrame:(CGRect)frame
 {
-  self = [super initWithFrame:frame];
-  if (self) {
-    [self loadUI];
-  }
-  return self;
+    self = [super initWithFrame:frame];
+    if (self) {
+        [self loadUI];
+    }
+    return self;
 }
 
 - (void)didMoveToSuperview
 {
-  [super didMoveToSuperview];
-  [self reloadData];
+    [super didMoveToSuperview];
+    [self reloadData];
 }
 
 - (void)layoutSubviews
 {
-  [super layoutSubviews];
-  
-  CGFloat width  = self.frame.size.width;
-  CGFloat height = self.frame.size.height;
-  CGFloat topheaderHeight = [self topHeaderHeight];
-  CGFloat leftHeaderWidth = [self leftHeaderWidth];
-  
-  CGFloat contentWidth = 0.0;
-  NSInteger rowsCount = [self numberOfColumns];
-  for (int i = 0; i < rowsCount; i++) {
-    contentWidth += [self contentWidthForColumn:i];
-  }
-  
-  self.leftTableView.frame           = CGRectMake(0, topheaderHeight, leftHeaderWidth, height - topheaderHeight);
-  self.headerScrollView.frame        = CGRectMake(leftHeaderWidth, 0, width - leftHeaderWidth, topheaderHeight);
-  self.headerScrollView.contentSize  = CGSizeMake( self.contentTableView.frame.size.width, self.headerScrollView.frame.size.height);
-  self.contentTableView.frame        = CGRectMake(0, 0, contentWidth + [self numberOfColumns] * [self columnMargin] , height - topheaderHeight);
-  self.contentScrollView.frame       = CGRectMake(leftHeaderWidth, topheaderHeight, width - leftHeaderWidth, height - topheaderHeight);
-  self.contentScrollView.contentSize = self.contentTableView.frame.size;
-  self.leftHeader.frame              = CGRectMake(0, 0, [self leftHeaderWidth], [self topHeaderHeight]);
+    [super layoutSubviews];
+    
+    CGFloat width  = self.frame.size.width;
+    CGFloat height = self.frame.size.height;
+    CGFloat topheaderHeight = [self topHeaderHeight];
+    CGFloat leftHeaderWidth = [self leftHeaderWidth];
+    
+    CGFloat contentWidth = 0.0;
+    NSInteger rowsCount = [self numberOfColumns];
+    for (int i = 0; i < rowsCount; i++) {
+        contentWidth += [self contentWidthForColumn:i];
+    }
+    
+    self.leftTableView.frame           = CGRectMake(0, topheaderHeight, leftHeaderWidth, height - topheaderHeight);
+    self.headerScrollView.frame        = CGRectMake(leftHeaderWidth, 0, width - leftHeaderWidth, topheaderHeight);
+    self.headerScrollView.contentSize  = CGSizeMake( self.contentTableView.frame.size.width, self.headerScrollView.frame.size.height);
+    self.contentTableView.frame        = CGRectMake(0, 0, contentWidth + [self numberOfColumns] * [self columnMargin] , height - topheaderHeight);
+    self.contentScrollView.frame       = CGRectMake(leftHeaderWidth, topheaderHeight, width - leftHeaderWidth, height - topheaderHeight);
+    self.contentScrollView.contentSize = self.contentTableView.frame.size;
+    self.leftHeader.frame              = CGRectMake(0, 0, [self leftHeaderWidth], [self topHeaderHeight]);
 }
 
 
 - (void)loadUI
 {
-  [self loadHeaderScrollView];
-  [self loadContentScrollView];
-  [self loadLeftView];
+    [self loadHeaderScrollView];
+    [self loadContentScrollView];
+    [self loadLeftView];
 }
 
 - (void)reloadData
 {
-  [self loadLeftViewData];
-  [self loadContentData];
-  [self loadHeaderData];
+    [self loadLeftViewData];
+    [self loadContentData];
+    [self loadHeaderData];
 }
 
 #pragma mark - UI
 
 - (void)loadHeaderScrollView
 {
-  UIScrollView *headerScrollView = [[UIScrollView alloc] init];
-  headerScrollView.delegate      = self;
-  self.headerScrollView          = headerScrollView;
-  self.headerScrollView.backgroundColor =  [UIColor colorWithWhite:0.803 alpha:0.850];
-  
-  [self addSubview:headerScrollView];
+    UIScrollView *headerScrollView = [[UIScrollView alloc] init];
+    headerScrollView.delegate      = self;
+    self.headerScrollView          = headerScrollView;
+    self.headerScrollView.backgroundColor =  [UIColor colorWithWhite:0.803 alpha:0.850];
+    
+    [self addSubview:headerScrollView];
 }
 
 - (void)loadContentScrollView
 {
-  
-  UIScrollView *scrollView = [[UIScrollView alloc] init];
-  scrollView.bounces       = NO;
-  scrollView.delegate      = self;
-  
-  UITableView *tableView   = [[UITableView alloc] init];
-  tableView.delegate       = self;
-  tableView.dataSource     = self;
-  tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
-  
-  [self addSubview:scrollView];
-  [scrollView addSubview:tableView];
-  
-  self.contentScrollView = scrollView;
-  self.contentTableView    = tableView;
-  
+    
+    UIScrollView *scrollView = [[UIScrollView alloc] init];
+    scrollView.bounces       = NO;
+    scrollView.delegate      = self;
+    
+    UITableView *tableView   = [[UITableView alloc] init];
+    tableView.delegate       = self;
+    tableView.dataSource     = self;
+    tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+    
+    [self addSubview:scrollView];
+    [scrollView addSubview:tableView];
+    
+    self.contentScrollView = scrollView;
+    self.contentTableView    = tableView;
+    
 }
 
 - (void)loadLeftView
 {
-  UITableView *leftTableView = [[UITableView alloc] init];
-  leftTableView.delegate       = self;
-  leftTableView.dataSource     = self;
-  leftTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
-  self.leftTableView           = leftTableView;
-  [self addSubview:leftTableView];
-  
-  UIView *leftHeader = [[UIView alloc] init];
-  leftHeader.backgroundColor = [UIColor colorWithWhite:0.950 alpha:0.668];
-  self.leftHeader            = leftHeader;
-  [self addSubview:leftHeader];
-  
+    UITableView *leftTableView = [[UITableView alloc] init];
+    leftTableView.delegate       = self;
+    leftTableView.dataSource     = self;
+    leftTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+    self.leftTableView           = leftTableView;
+    [self addSubview:leftTableView];
+    
+    UIView *leftHeader = [[UIView alloc] init];
+    leftHeader.backgroundColor = [UIColor colorWithWhite:0.950 alpha:0.668];
+    self.leftHeader            = leftHeader;
+    [self addSubview:leftHeader];
+    
 }
 
 
@@ -135,132 +135,131 @@ static const CGFloat kColumnMargin = 1;
 
 - (void)loadHeaderData
 {
-  NSArray *subviews = self.headerScrollView.subviews;
-  
-  for (UIView *subview in subviews) {
-    [subview removeFromSuperview];
-  }
-  CGFloat x = 0.0;
-  CGFloat w = 0.0;
-  for (int i = 0; i < [self numberOfColumns] ; i++) {
-    w = [self contentWidthForColumn:i] + [self columnMargin];
-    
-    FLEXTableColumnHeader *cell = [[FLEXTableColumnHeader alloc] initWithFrame:CGRectMake(x, 0, w, [self topHeaderHeight] - 1)];
-    cell.label.text = [self columnTitleForColumn:i];
-    [self.headerScrollView addSubview:cell];
-    
-    FLEXTableColumnHeaderSortType type = [self.sortStatusDict[[self columnTitleForColumn:i]] integerValue];
-    [cell changeSortStatusWithType:type];
-    
-    UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self
-                                                                              action:@selector(contentHeaderTap:)];
-    [cell addGestureRecognizer:gesture];
-    cell.userInteractionEnabled = YES;
+    NSArray *subviews = self.headerScrollView.subviews;
     
-    x = x + w;
-  }
+    for (UIView *subview in subviews) {
+        [subview removeFromSuperview];
+    }
+    CGFloat x = 0.0;
+    CGFloat w = 0.0;
+    for (int i = 0; i < [self numberOfColumns] ; i++) {
+        w = [self contentWidthForColumn:i] + [self columnMargin];
+        
+        FLEXTableColumnHeader *cell = [[FLEXTableColumnHeader alloc] initWithFrame:CGRectMake(x, 0, w, [self topHeaderHeight] - 1)];
+        cell.label.text = [self columnTitleForColumn:i];
+        [self.headerScrollView addSubview:cell];
+        
+        FLEXTableColumnHeaderSortType type = [self.sortStatusDict[[self columnTitleForColumn:i]] integerValue];
+        [cell changeSortStatusWithType:type];
+        
+        UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self
+                                                                                  action:@selector(contentHeaderTap:)];
+        [cell addGestureRecognizer:gesture];
+        cell.userInteractionEnabled = YES;
+        
+        x = x + w;
+    }
 }
 
 - (void)contentHeaderTap:(UIGestureRecognizer *)gesture
 {
-  FLEXTableColumnHeader *header = (FLEXTableColumnHeader *)gesture.view;
-  NSString *string = header.label.text;
-  FLEXTableColumnHeaderSortType currentType = [self.sortStatusDict[string] integerValue];
-  FLEXTableColumnHeaderSortType newType ;
-  
-  switch (currentType) {
-    case FLEXTableColumnHeaderSortTypeNone:
-      newType = FLEXTableColumnHeaderSortTypeAsc;
-      break;
-    case FLEXTableColumnHeaderSortTypeAsc:
-      newType = FLEXTableColumnHeaderSortTypeDesc;
-      break;
-    case FLEXTableColumnHeaderSortTypeDesc:
-      newType = FLEXTableColumnHeaderSortTypeAsc;
-      break;
-  }
-  
-  self.sortStatusDict = @{header.label.text : @(newType)};
-  [header changeSortStatusWithType:newType];
-  [self.delegate multiColumnTableView:self headerTapWithText:string sortType:newType];
-  
+    FLEXTableColumnHeader *header = (FLEXTableColumnHeader *)gesture.view;
+    NSString *string = header.label.text;
+    FLEXTableColumnHeaderSortType currentType = [self.sortStatusDict[string] integerValue];
+    FLEXTableColumnHeaderSortType newType ;
+    
+    switch (currentType) {
+        case FLEXTableColumnHeaderSortTypeNone:
+            newType = FLEXTableColumnHeaderSortTypeAsc;
+            break;
+        case FLEXTableColumnHeaderSortTypeAsc:
+            newType = FLEXTableColumnHeaderSortTypeDesc;
+            break;
+        case FLEXTableColumnHeaderSortTypeDesc:
+            newType = FLEXTableColumnHeaderSortTypeAsc;
+            break;
+    }
+    
+    self.sortStatusDict = @{header.label.text : @(newType)};
+    [header changeSortStatusWithType:newType];
+    [self.delegate multiColumnTableView:self didTapHeaderWithText:string sortType:newType];
+    
 }
 
-
 - (void)loadContentData
 {
-  [self.contentTableView reloadData];
+    [self.contentTableView reloadData];
 }
 
 - (void)loadLeftViewData
 {
-  [self.leftTableView reloadData];
+    [self.leftTableView reloadData];
 }
 
 - (UITableViewCell *)tableView:(UITableView *)tableView
          cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
-  UIColor *backgroundColor = [UIColor whiteColor];
-  if (indexPath.row % 2 != 0) {
-    backgroundColor = [UIColor colorWithWhite:0.950 alpha:0.750];
-  }
-  
-  if (tableView != self.leftTableView) {
-    self.rowData = [self.dataSource contentAtRow:indexPath.row];
-    FLEXTableContentCell *cell = [FLEXTableContentCell cellWithTableView:tableView
-                                                            columnNumber:[self numberOfColumns]];
-    cell.contentView.backgroundColor = backgroundColor;
-    cell.delegate = self;
+    UIColor *backgroundColor = [UIColor whiteColor];
+    if (indexPath.row % 2 != 0) {
+        backgroundColor = [UIColor colorWithWhite:0.950 alpha:0.750];
+    }
     
-    for (int i = 0 ; i < cell.labels.count; i++) {
-      
-      UILabel *label  = cell.labels[i];
-      label.textColor = [UIColor blackColor];
-      
-      NSString *content = [NSString stringWithFormat:@"%@",self.rowData[i]];
-      if ([content isEqualToString:@"<null>"]) {
-        label.textColor = [UIColor lightGrayColor];
-        content = @"NULL";
-      }
-      label.text            = content;
-      label.backgroundColor = backgroundColor;
+    if (tableView != self.leftTableView) {
+        self.rowData = [self.dataSource contentAtRow:indexPath.row];
+        FLEXTableContentCell *cell = [FLEXTableContentCell cellWithTableView:tableView
+                                                                columnNumber:[self numberOfColumns]];
+        cell.contentView.backgroundColor = backgroundColor;
+        cell.delegate = self;
+        
+        for (int i = 0 ; i < cell.labels.count; i++) {
+            
+            UILabel *label  = cell.labels[i];
+            label.textColor = [UIColor blackColor];
+            
+            NSString *content = [NSString stringWithFormat:@"%@",self.rowData[i]];
+            if ([content isEqualToString:@"<null>"]) {
+                label.textColor = [UIColor lightGrayColor];
+                content = @"NULL";
+            }
+            label.text            = content;
+            label.backgroundColor = backgroundColor;
+        }
+        return cell;
+    }
+    else {
+        FLEXTableLeftCell *cell          = [FLEXTableLeftCell cellWithTableView:tableView];
+        cell.contentView.backgroundColor = backgroundColor;
+        cell.titlelabel.text             = [self rowTitleForRow:indexPath.row];
+        return cell;
     }
-    return cell;
-  }
-  else {
-    FLEXTableLeftCell *cell          = [FLEXTableLeftCell cellWithTableView:tableView];
-    cell.contentView.backgroundColor = backgroundColor;
-    cell.titlelabel.text             = [self rowTitleForRow:indexPath.row];
-    return cell;
-  }
 }
 
 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 {
-  return [self.dataSource numberOfRowsInTableView:self];
+    return [self.dataSource numberOfRowsInTableView:self];
 }
 
 
 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
 {
-  return [self.dataSource multiColumnTableView:self heightForContentCellInRow:indexPath.row];
+    return [self.dataSource multiColumnTableView:self heightForContentCellInRow:indexPath.row];
 }
 
 
 - (void)scrollViewDidScroll:(UIScrollView *)scrollView
 {
-  if (scrollView == self.contentScrollView) {
-    self.headerScrollView.contentOffset = scrollView.contentOffset;
-  }
-  else if (scrollView == self.headerScrollView) {
-    self.contentScrollView.contentOffset = scrollView.contentOffset;
-  }
-  else if (scrollView == self.leftTableView) {
-    self.contentTableView.contentOffset = scrollView.contentOffset;
-  }
-  else if (scrollView == self.contentTableView) {
-    self.leftTableView.contentOffset = scrollView.contentOffset;
-  }
+    if (scrollView == self.contentScrollView) {
+        self.headerScrollView.contentOffset = scrollView.contentOffset;
+    }
+    else if (scrollView == self.headerScrollView) {
+        self.contentScrollView.contentOffset = scrollView.contentOffset;
+    }
+    else if (scrollView == self.leftTableView) {
+        self.contentTableView.contentOffset = scrollView.contentOffset;
+    }
+    else if (scrollView == self.contentTableView) {
+        self.leftTableView.contentOffset = scrollView.contentOffset;
+    }
 }
 
 #pragma mark -
@@ -268,16 +267,16 @@ static const CGFloat kColumnMargin = 1;
 
 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
 {
-  if (tableView == self.leftTableView) {
-    [self.contentTableView selectRowAtIndexPath:indexPath
-                                       animated:NO
-                                 scrollPosition:UITableViewScrollPositionNone];
-  }
-  else if (tableView == self.contentTableView) {
-    [self.leftTableView selectRowAtIndexPath:indexPath
-                                    animated:NO
-                              scrollPosition:UITableViewScrollPositionNone];
-  }
+    if (tableView == self.leftTableView) {
+        [self.contentTableView selectRowAtIndexPath:indexPath
+                                           animated:NO
+                                     scrollPosition:UITableViewScrollPositionNone];
+    }
+    else if (tableView == self.contentTableView) {
+        [self.leftTableView selectRowAtIndexPath:indexPath
+                                        animated:NO
+                                  scrollPosition:UITableViewScrollPositionNone];
+    }
 }
 
 #pragma mark -
@@ -285,61 +284,58 @@ static const CGFloat kColumnMargin = 1;
 
 - (NSInteger)numberOfrows
 {
-  return [self.dataSource numberOfRowsInTableView:self];
+    return [self.dataSource numberOfRowsInTableView:self];
 }
 
 - (NSInteger)numberOfColumns
 {
-  return [self.dataSource numberOfColumnsInTableView:self];
+    return [self.dataSource numberOfColumnsInTableView:self];
 }
 
 - (NSString *)columnTitleForColumn:(NSInteger)column
 {
-  return [self.dataSource columnNameInColumn:column];
+    return [self.dataSource columnNameInColumn:column];
 }
 
 - (NSString *)rowTitleForRow:(NSInteger)row
 {
-  return [self.dataSource rowNameInRow:row];
+    return [self.dataSource rowNameInRow:row];
 }
 
 - (NSString *)contentAtColumn:(NSInteger)column row:(NSInteger)row;
 {
-  return [self.dataSource contentAtColumn:column row:row];
+    return [self.dataSource contentAtColumn:column row:row];
 }
 
 - (CGFloat)contentWidthForColumn:(NSInteger)column
 {
-  return [self.dataSource multiColumnTableView:self widthForContentCellInColumn:column];
+    return [self.dataSource multiColumnTableView:self widthForContentCellInColumn:column];
 }
 
 - (CGFloat)contentHeightForRow:(NSInteger)row
 {
-  return [self.dataSource multiColumnTableView:self heightForContentCellInRow:row];
+    return [self.dataSource multiColumnTableView:self heightForContentCellInRow:row];
 }
 
 - (CGFloat)topHeaderHeight
 {
-  return [self.dataSource heightForTopHeaderInTableView:self];
+    return [self.dataSource heightForTopHeaderInTableView:self];
 }
 
 - (CGFloat)leftHeaderWidth
 {
-  return [self.dataSource WidthForLeftHeaderInTableView:self];
+    return [self.dataSource widthForLeftHeaderInTableView:self];
 }
 
 - (CGFloat)columnMargin
 {
-  return kColumnMargin;
+    return kColumnMargin;
 }
 
 
-
 - (void)tableContentCell:(FLEXTableContentCell *)tableView labelDidTapWithText:(NSString *)text
 {
-  if ([self.delegate respondsToSelector:@selector(multiColumnTableView:labelDidTapWithText:)]) {
-    [self.delegate multiColumnTableView:self labelDidTapWithText:text];
-  }
+    [self.delegate multiColumnTableView:self didTapLabelWithText:text];
 }
 
 @end

+ 4 - 4
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.h

@@ -9,14 +9,14 @@
 #import <UIKit/UIKit.h>
 
 typedef NS_ENUM(NSUInteger, FLEXTableColumnHeaderSortType) {
-  FLEXTableColumnHeaderSortTypeNone = 0, 
-  FLEXTableColumnHeaderSortTypeAsc,
-  FLEXTableColumnHeaderSortTypeDesc,
+    FLEXTableColumnHeaderSortTypeNone = 0,
+    FLEXTableColumnHeaderSortTypeAsc,
+    FLEXTableColumnHeaderSortTypeDesc,
 };
 
 @interface FLEXTableColumnHeader : UIView
 
-@property (nonatomic, weak) UILabel *label;
+@property (nonatomic, strong) UILabel *label;
 
 - (void)changeSortStatusWithType:(FLEXTableColumnHeaderSortType)type;
 

+ 32 - 34
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.m

@@ -10,49 +10,47 @@
 
 @implementation FLEXTableColumnHeader
 {
-  UILabel *_arrowLabel;
+    UILabel *_arrowLabel;
 }
 
 
 - (instancetype)initWithFrame:(CGRect)frame
 {
-  self = [super initWithFrame:frame];
-  if (self) {      
-    self.backgroundColor = [UIColor whiteColor];
-    
-    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5, 0, frame.size.width - 25, frame.size.height)];
-    label.font = [UIFont systemFontOfSize:13.0];
-    [self addSubview:label];
-    self.label = label;
-
-    
-    _arrowLabel = [[UILabel alloc] initWithFrame:CGRectMake(frame.size.width - 20, 0, 20, frame.size.height)];
-    _arrowLabel.font = [UIFont systemFontOfSize:13.0];
-    [self addSubview:_arrowLabel];
-    
-    UIView *line = [[UIView alloc] initWithFrame:CGRectMake(frame.size.width - 1, 2, 1, frame.size.height - 4)];
-    line.backgroundColor = [UIColor colorWithWhite:0.803 alpha:0.850];
-    [self addSubview:line];
-    
-  }
-  return self;
+    self = [super initWithFrame:frame];
+    if (self) {
+        self.backgroundColor = [UIColor whiteColor];
+        
+        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5, 0, frame.size.width - 25, frame.size.height)];
+        label.font = [UIFont systemFontOfSize:13.0];
+        [self addSubview:label];
+        self.label = label;
+        
+        
+        _arrowLabel = [[UILabel alloc] initWithFrame:CGRectMake(frame.size.width - 20, 0, 20, frame.size.height)];
+        _arrowLabel.font = [UIFont systemFontOfSize:13.0];
+        [self addSubview:_arrowLabel];
+        
+        UIView *line = [[UIView alloc] initWithFrame:CGRectMake(frame.size.width - 1, 2, 1, frame.size.height - 4)];
+        line.backgroundColor = [UIColor colorWithWhite:0.803 alpha:0.850];
+        [self addSubview:line];
+        
+    }
+    return self;
 }
 
 - (void)changeSortStatusWithType:(FLEXTableColumnHeaderSortType)type
 {
-  switch (type) {
-    case FLEXTableColumnHeaderSortTypeNone:
-      _arrowLabel.text = @"";
-      break;
-    case FLEXTableColumnHeaderSortTypeAsc:
-      _arrowLabel.text = @"⬆️";
-      break;
-    case FLEXTableColumnHeaderSortTypeDesc:
-      _arrowLabel.text = @"⬇️";
-      break;
-    default:
-      break;
-  }
+    switch (type) {
+        case FLEXTableColumnHeaderSortTypeNone:
+            _arrowLabel.text = @"";
+            break;
+        case FLEXTableColumnHeaderSortTypeAsc:
+            _arrowLabel.text = @"⬆️";
+            break;
+        case FLEXTableColumnHeaderSortTypeDesc:
+            _arrowLabel.text = @"⬇️";
+            break;
+    }
 }
 
 

+ 34 - 34
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentCell.m

@@ -17,50 +17,50 @@
 
 + (instancetype)cellWithTableView:(UITableView *)tableView columnNumber:(NSInteger)number;
 {
-  static NSString *identifier = @"FLEXTableContentCell";
-  FLEXTableContentCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
-  if (!cell) {
-    cell = [[FLEXTableContentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
-    NSMutableArray *labels = [NSMutableArray array];
-    for (int i = 0; i < number ; i++) {
-      UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
-      label.backgroundColor = [UIColor whiteColor];
-      label.font            = [UIFont systemFontOfSize:13.0];
-      label.textAlignment   = NSTextAlignmentLeft;
-      label.backgroundColor = [UIColor greenColor];
-      [labels addObject:label];
-      
-      UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:cell
-                                                                                action:@selector(labelDidTap:)];
-      [label addGestureRecognizer:gesture];
-      label.userInteractionEnabled = YES;
-
-      [cell.contentView addSubview:label];
-      cell.contentView.backgroundColor = [UIColor whiteColor];
+    static NSString *identifier = @"FLEXTableContentCell";
+    FLEXTableContentCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
+    if (!cell) {
+        cell = [[FLEXTableContentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
+        NSMutableArray *labels = [NSMutableArray array];
+        for (int i = 0; i < number ; i++) {
+            UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
+            label.backgroundColor = [UIColor whiteColor];
+            label.font            = [UIFont systemFontOfSize:13.0];
+            label.textAlignment   = NSTextAlignmentLeft;
+            label.backgroundColor = [UIColor greenColor];
+            [labels addObject:label];
+            
+            UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:cell
+                                                                                      action:@selector(labelDidTap:)];
+            [label addGestureRecognizer:gesture];
+            label.userInteractionEnabled = YES;
+            
+            [cell.contentView addSubview:label];
+            cell.contentView.backgroundColor = [UIColor whiteColor];
+        }
+        cell.labels = labels;
     }
-    cell.labels = labels;
-  }
-  return cell;
+    return cell;
 }
 
 - (void)layoutSubviews
 {
-  [super layoutSubviews];
-  CGFloat labelWidth  = self.contentView.frame.size.width / self.labels.count;
-  CGFloat labelHeight = self.contentView.frame.size.height;
-  for (int i = 0; i < self.labels.count; i++) {
-    UILabel *label = self.labels[i];
-    label.frame = CGRectMake(labelWidth * i + 5, 0, (labelWidth - 10), labelHeight);
-  }
+    [super layoutSubviews];
+    CGFloat labelWidth  = self.contentView.frame.size.width / self.labels.count;
+    CGFloat labelHeight = self.contentView.frame.size.height;
+    for (int i = 0; i < self.labels.count; i++) {
+        UILabel *label = self.labels[i];
+        label.frame = CGRectMake(labelWidth * i + 5, 0, (labelWidth - 10), labelHeight);
+    }
 }
 
 
 - (void)labelDidTap:(UIGestureRecognizer *)gesture
 {
-  UILabel *label = (UILabel *)gesture.view;
-  if ([self.delegate respondsToSelector:@selector(tableContentCell:labelDidTapWithText:)]) {
-    [self.delegate tableContentCell:self labelDidTapWithText:label.text];
-  }
+    UILabel *label = (UILabel *)gesture.view;
+    if ([self.delegate respondsToSelector:@selector(tableContentCell:labelDidTapWithText:)]) {
+        [self.delegate tableContentCell:self labelDidTapWithText:label.text];
+    }
 }
 
 @end

+ 1 - 1
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.h

@@ -11,6 +11,6 @@
 @interface FLEXTableContentViewController : UIViewController
 
 @property (nonatomic, strong) NSArray *columnsArray;
-@property (nonatomic, strong) NSArray *contensArray;
+@property (nonatomic, strong) NSArray *contentsArray;
 
 @end

+ 84 - 83
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.m

@@ -21,34 +21,34 @@
 
 - (instancetype)init
 {
-  self = [super init];
-  if (self) {
-    
-    CGRect rectStatus = [UIApplication sharedApplication].statusBarFrame;
-    CGFloat y = 64;
-    if (rectStatus.size.height == 0) {
-      y = 32;
+    self = [super init];
+    if (self) {
+        
+        CGRect rectStatus = [UIApplication sharedApplication].statusBarFrame;
+        CGFloat y = 64;
+        if (rectStatus.size.height == 0) {
+            y = 32;
+        }
+        _multiColumView = [[FLEXMultiColumnTableView alloc] initWithFrame:
+                           CGRectMake(0, y, self.view.frame.size.width, self.view.frame.size.height - y)];
+        
+        _multiColumView.autoresizingMask          = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+        _multiColumView.backgroundColor           = [UIColor whiteColor];
+        _multiColumView.dataSource                = self;
+        _multiColumView.delegate                  = self;
+        self.automaticallyAdjustsScrollViewInsets = NO;
+        
+        
+        [self.view addSubview:_multiColumView];
     }
-    _multiColumView = [[FLEXMultiColumnTableView alloc] initWithFrame:
-                       CGRectMake(0, y, self.view.frame.size.width, self.view.frame.size.height - y)];
-    
-    _multiColumView.autoresizingMask          = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
-    _multiColumView.backgroundColor           = [UIColor whiteColor];
-    _multiColumView.dataSource                = self;
-    _multiColumView.delegate                  = self;
-    self.automaticallyAdjustsScrollViewInsets = NO;
-    
-    
-    [self.view addSubview:_multiColumView];
-  }
-  return self;
+    return self;
 }
 
 - (void)viewWillAppear:(BOOL)animated
 {
-  [super viewWillAppear:animated];
-  [self.multiColumView reloadData];
-  
+    [super viewWillAppear:animated];
+    [self.multiColumView reloadData];
+    
 }
 
 #pragma mark -
@@ -56,11 +56,11 @@
 
 - (NSInteger)numberOfColumnsInTableView:(FLEXMultiColumnTableView *)tableView
 {
-  return self.columnsArray.count;
+    return self.columnsArray.count;
 }
 - (NSInteger)numberOfRowsInTableView:(FLEXMultiColumnTableView *)tableView
 {
-  return self.contensArray.count;
+    return self.contentsArray.count;
 }
 
 
@@ -72,91 +72,92 @@
 
 - (NSString *)rowNameInRow:(NSInteger)row
 {
-  return [NSString stringWithFormat:@"%ld",(long)row];
+    return [NSString stringWithFormat:@"%ld",(long)row];
 }
 
 - (NSString *)contentAtColumn:(NSInteger)column row:(NSInteger)row
 {
-  if (self.contensArray.count > row) {
-    NSDictionary *dic = self.contensArray[row];
-    if (self.contensArray.count > column) {
-      return [NSString stringWithFormat:@"%@",[dic objectForKey:self.columnsArray[column]]];
+    if (self.contentsArray.count > row) {
+        NSDictionary *dic = self.contentsArray[row];
+        if (self.contentsArray.count > column) {
+            return [NSString stringWithFormat:@"%@",[dic objectForKey:self.columnsArray[column]]];
+        }
     }
-  }
-  return @"";
+    return @"";
 }
 
 - (NSArray *)contentAtRow:(NSInteger)row
 {
-  NSMutableArray *result = [NSMutableArray array];
-  if (self.contensArray.count > row) {
-    NSDictionary *dic = self.contensArray[row];
-    for (int i = 0; i < self.columnsArray.count; i ++) {
-      [result addObject:dic[self.columnsArray[i]]];
+    NSMutableArray *result = [NSMutableArray array];
+    if (self.contentsArray.count > row) {
+        NSDictionary *dic = self.contentsArray[row];
+        for (int i = 0; i < self.columnsArray.count; i ++) {
+            [result addObject:dic[self.columnsArray[i]]];
+        }
+        return  result;
     }
-    return  result;
-  }
-  return nil;
+    return nil;
 }
 
 - (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView
       heightForContentCellInRow:(NSInteger)row
 {
-  return 40;
+    return 40;
 }
 
 - (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView
     widthForContentCellInColumn:(NSInteger)column
 {
-  return 120;
+    return 120;
 }
 
 - (CGFloat)heightForTopHeaderInTableView:(FLEXMultiColumnTableView *)tableView
 {
-  return 40;
+    return 40;
 }
 
-- (CGFloat)WidthForLeftHeaderInTableView:(FLEXMultiColumnTableView *)tableView
+- (CGFloat)widthForLeftHeaderInTableView:(FLEXMultiColumnTableView *)tableView
 {
-  NSString *str = [NSString stringWithFormat:@"%lu",(unsigned long)self.contensArray.count];
-  NSDictionary *attrs = @{@"NSFontAttributeName":[UIFont systemFontOfSize:17.0]};
-  CGSize size =   [str boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, 14)
-                                    options:NSStringDrawingUsesLineFragmentOrigin
-                                 attributes:attrs context:nil].size;
-  return size.width + 20;
+    NSString *str = [NSString stringWithFormat:@"%lu",(unsigned long)self.contentsArray.count];
+    NSDictionary *attrs = @{@"NSFontAttributeName":[UIFont systemFontOfSize:17.0]};
+    CGSize size =   [str boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, 14)
+                                      options:NSStringDrawingUsesLineFragmentOrigin
+                                   attributes:attrs context:nil].size;
+    return size.width + 20;
 }
 
 #pragma mark -
 #pragma mark MultiColumnTableView Delegate
 
-- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView labelDidTapWithText:(NSString *)text
+
+- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView didTapLabelWithText:(NSString *)text
 {
-  FLEXWebViewController * detailViewController = [[FLEXWebViewController alloc] initWithText:text];
-  [self.navigationController pushViewController:detailViewController animated:YES];
+    FLEXWebViewController * detailViewController = [[FLEXWebViewController alloc] initWithText:text];
+    [self.navigationController pushViewController:detailViewController animated:YES];
 }
 
-- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView headerTapWithText:(NSString *)text sortType:(FLEXTableColumnHeaderSortType)type
+- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView didTapHeaderWithText:(NSString *)text sortType:(FLEXTableColumnHeaderSortType)sortType
 {
-  
-  NSArray *sortContentData = [self.contensArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
     
-    if ([obj1 objectForKey:text] == [NSNull null]) {
-      return 0;
-    }
-    if ([obj2 objectForKey:text] == [NSNull null]) {
-      return 1;
+    NSArray *sortContentData = [self.contentsArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
+        
+        if ([obj1 objectForKey:text] == [NSNull null]) {
+            return NSOrderedAscending;
+        }
+        if ([obj2 objectForKey:text] == [NSNull null]) {
+            return NSOrderedDescending;
+        }
+        NSComparisonResult result =  [[obj1 objectForKey:text] compare:[obj2 objectForKey:text]];
+        
+        return result;
+    }];
+    if (sortType == FLEXTableColumnHeaderSortTypeDesc) {
+        NSEnumerator *contentReverseEvumerator = [sortContentData reverseObjectEnumerator];
+        sortContentData = [NSArray arrayWithArray:[contentReverseEvumerator allObjects]];
     }
-    NSComparisonResult result =  [[obj1 objectForKey:text] compare:[obj2 objectForKey:text]];
     
-    return result;
-  }];
-  if (type == FLEXTableColumnHeaderSortTypeDesc) {    
-    NSEnumerator *contentReverseEvumerator = [sortContentData reverseObjectEnumerator];
-    sortContentData = [NSArray arrayWithArray:[contentReverseEvumerator allObjects]];
-  }
-  
-  self.contensArray = sortContentData;
-  [self.multiColumView reloadData];
+    self.contentsArray = sortContentData;
+    [self.multiColumView reloadData];
 }
 
 #pragma mark -
@@ -165,18 +166,18 @@
 - (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection
               withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator
 {
-  [super willTransitionToTraitCollection:newCollection
-               withTransitionCoordinator:coordinator];
-  [coordinator animateAlongsideTransition:^(id <UIViewControllerTransitionCoordinatorContext> context) {
-    if (newCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) {
-      
-      _multiColumView.frame = CGRectMake(0, 32, self.view.frame.size.width, self.view.frame.size.height - 32);
-    }
-    else {
-      _multiColumView.frame = CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 64);
-    }
-    [self.view setNeedsLayout];
-  } completion:nil];
+    [super willTransitionToTraitCollection:newCollection
+                 withTransitionCoordinator:coordinator];
+    [coordinator animateAlongsideTransition:^(id <UIViewControllerTransitionCoordinatorContext> context) {
+        if (newCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) {
+            
+            _multiColumView.frame = CGRectMake(0, 32, self.view.frame.size.width, self.view.frame.size.height - 32);
+        }
+        else {
+            _multiColumView.frame = CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 64);
+        }
+        [self.view setNeedsLayout];
+    } completion:nil];
 }
 
 

+ 1 - 1
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.h

@@ -10,7 +10,7 @@
 
 @interface FLEXTableLeftCell : UITableViewCell
 
-@property (nonatomic, weak) UILabel *titlelabel;
+@property (nonatomic, strong) UILabel *titlelabel;
 
 + (instancetype)cellWithTableView:(UITableView *)tableView;
 

+ 15 - 15
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.m

@@ -12,24 +12,24 @@
 
 + (instancetype)cellWithTableView:(UITableView *)tableView
 {
-  static NSString *identifier = @"FLEXTableLeftCell";
-  FLEXTableLeftCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
-  
-  if (!cell) {
-    cell = [[FLEXTableLeftCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
-    UILabel *textLabel               = [[UILabel alloc] initWithFrame:CGRectZero];
-    textLabel.textAlignment          = NSTextAlignmentCenter;
-    textLabel.font                   = [UIFont systemFontOfSize:13.0];
-    textLabel.backgroundColor = [UIColor clearColor];
-    [cell.contentView addSubview:textLabel];
-    cell.titlelabel = textLabel;
-  }
-  return cell;
+    static NSString *identifier = @"FLEXTableLeftCell";
+    FLEXTableLeftCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
+    
+    if (!cell) {
+        cell = [[FLEXTableLeftCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
+        UILabel *textLabel               = [[UILabel alloc] initWithFrame:CGRectZero];
+        textLabel.textAlignment          = NSTextAlignmentCenter;
+        textLabel.font                   = [UIFont systemFontOfSize:13.0];
+        textLabel.backgroundColor = [UIColor clearColor];
+        [cell.contentView addSubview:textLabel];
+        cell.titlelabel = textLabel;
+    }
+    return cell;
 }
 
 - (void)layoutSubviews
 {
-  [super layoutSubviews];
-  self.titlelabel.frame = self.contentView.frame;
+    [super layoutSubviews];
+    self.titlelabel.frame = self.contentView.frame;
 }
 @end

+ 33 - 38
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.m

@@ -12,8 +12,8 @@
 
 @interface FLEXTableListViewController ()
 {
-  FLEXDatabaseManager *_dbm;
-  NSString *_databasePath;
+    FLEXDatabaseManager *_dbm;
+    NSString *_databasePath;
 }
 
 @property (nonatomic, strong) NSArray *tables;
@@ -25,63 +25,58 @@
 
 - (instancetype)initWithPath:(NSString *)path
 {
-  self = [super initWithStyle:UITableViewStyleGrouped];
-  if (self) {
-    _databasePath = [path copy];
-    _dbm = [[FLEXDatabaseManager alloc] initWithPath:path];
-    [_dbm open];
-    [self getAllTables];
-  }
-  return self;
-}
-
-- (void)viewDidLoad
-{
-  [super viewDidLoad];
+    self = [super initWithStyle:UITableViewStyleGrouped];
+    if (self) {
+        _databasePath = [path copy];
+        _dbm = [[FLEXDatabaseManager alloc] initWithPath:path];
+        [_dbm open];
+        [self getAllTables];
+    }
+    return self;
 }
 
 - (void)getAllTables
 {
-  NSArray *resultArray = [_dbm queryAllTables];
-  NSMutableArray *array = [NSMutableArray array];
-  for (NSDictionary *dict in resultArray) {
-    [array addObject:dict[@"name"]];
-  }
-  self.tables = array;
+    NSArray *resultArray = [_dbm queryAllTables];
+    NSMutableArray *array = [NSMutableArray array];
+    for (NSDictionary *dict in resultArray) {
+        [array addObject:dict[@"name"]];
+    }
+    self.tables = array;
 }
 
 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 {
-  return self.tables.count;
+    return self.tables.count;
 }
 
 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
-  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FLEXTableListViewControllerCell"];
-  if (!cell) {
-    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
-                                  reuseIdentifier:@"FLEXTableListViewControllerCell"];
-  }
-  cell.textLabel.text = self.tables[indexPath.row];
-  return cell;
+    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FLEXTableListViewControllerCell"];
+    if (!cell) {
+        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
+                                      reuseIdentifier:@"FLEXTableListViewControllerCell"];
+    }
+    cell.textLabel.text = self.tables[indexPath.row];
+    return cell;
 }
 
 
 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
 {
-  FLEXTableContentViewController *contentViewController = [[FLEXTableContentViewController alloc] init];
-  
-  contentViewController.contensArray = [_dbm queryAllDataWithTableName:self.tables[indexPath.row]];
-  contentViewController.columnsArray = [_dbm queryAllColumnsWithTableName:self.tables[indexPath.row]];
- 
-  contentViewController.title = self.tables[indexPath.row];
-  [self.navigationController pushViewController:contentViewController animated:YES];
+    FLEXTableContentViewController *contentViewController = [[FLEXTableContentViewController alloc] init];
+    
+    contentViewController.contentsArray = [_dbm queryAllDataWithTableName:self.tables[indexPath.row]];
+    contentViewController.columnsArray = [_dbm queryAllColumnsWithTableName:self.tables[indexPath.row]];
+    
+    contentViewController.title = self.tables[indexPath.row];
+    [self.navigationController pushViewController:contentViewController animated:YES];
 }
 
 
 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
-{  
-  return [NSString stringWithFormat:@"%lu tables", (unsigned long)self.tables.count];
+{
+    return [NSString stringWithFormat:@"%lu tables", (unsigned long)self.tables.count];
 }
 
 @end

+ 21 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/LICENSE

@@ -0,0 +1,21 @@
+
+FMDB
+Copyright (c) 2008-2014 Flying Meat Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 4 - 0
FLEX.xcodeproj/project.pbxproj

@@ -7,6 +7,7 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		04F1CA191C137CF1000A52B0 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 04F1CA181C137CF1000A52B0 /* LICENSE */; };
 		3A4C94251B5B20570088C3F2 /* FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A4C94241B5B20570088C3F2 /* FLEX.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		3A4C94C51B5B21410088C3F2 /* FLEXArrayExplorerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A4C943C1B5B21410088C3F2 /* FLEXArrayExplorerViewController.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		3A4C94C61B5B21410088C3F2 /* FLEXArrayExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A4C943D1B5B21410088C3F2 /* FLEXArrayExplorerViewController.m */; };
@@ -160,6 +161,7 @@
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
+		04F1CA181C137CF1000A52B0 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
 		3A4C941F1B5B20570088C3F2 /* FLEX.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FLEX.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		3A4C94231B5B20570088C3F2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		3A4C94241B5B20570088C3F2 /* FLEX.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FLEX.h; sourceTree = "<group>"; };
@@ -604,6 +606,7 @@
 				779B1ECB1C0C4D7C001F5E49 /* FLEXTableLeftCell.m */,
 				779B1ECC1C0C4D7C001F5E49 /* FLEXTableListViewController.h */,
 				779B1ECD1C0C4D7C001F5E49 /* FLEXTableListViewController.m */,
+				04F1CA181C137CF1000A52B0 /* LICENSE */,
 			);
 			path = DatabaseBrowser;
 			sourceTree = "<group>";
@@ -751,6 +754,7 @@
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				04F1CA191C137CF1000A52B0 /* LICENSE in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 2 - 0
README.md

@@ -142,6 +142,8 @@ FLEX builds on ideas and inspiration from open source tools that came before it.
 - [Gist](https://gist.github.com/samdmarshall/17f4e66b5e2e579fd396) from [@samdmarshall](https://github.com/samdmarshall): another example of enumerating malloc blocks.
 - [Non-pointer isa](http://www.sealiesoftware.com/blog/archive/2013/09/24/objc_explain_Non-pointer_isa.html): an explanation of changes to the isa field on iOS for ARM64 and mention of the useful `objc_debug_isa_class_mask` variable.
 - [GZIP](https://github.com/nicklockwood/GZIP): A library for compressing/decompressing data on iOS using libz.
+- [FMDB](https://github.com/ccgus/fmdb): This is an Objective-C wrapper around SQLite
+