Преглед изворни кода

Add sqlite database browser

tttpeng пре 10 година
родитељ
комит
fd2b89fd24

+ 21 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.h

@@ -0,0 +1,21 @@
+//
+//  PTDatabaseManager.h
+//  PTDatabaseReader
+//
+//  Created by Peng Tao on 15/11/23.
+//  Copyright © 2015年 Peng Tao. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface FLEXDatabaseManager : NSObject
+
+
+- (instancetype)initWithPath:(NSString*)aPath;
+
+- (BOOL)open;
+- (NSArray *)queryAllTables;
+- (NSArray *)queryAllColumnsWithTableName:(NSString *)tableName;
+- (NSArray *)queryAllDataWithTableName:(NSString *)tableName;
+
+@end

+ 159 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.m

@@ -0,0 +1,159 @@
+//
+//  PTDatabaseManager.m
+//  PTDatabaseReader
+//
+//  Created by Peng Tao on 15/11/23.
+//  Copyright © 2015年 Peng Tao. All rights reserved.
+//
+
+#import "FLEXDatabaseManager.h"
+#import <sqlite3.h>
+
+
+static NSString *const QUERY_TABLENAMES_SQL = @"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name";
+
+
+@implementation FLEXDatabaseManager
+{
+  sqlite3* _db;
+  NSString* _databasePath;
+}
+
+
+- (instancetype)initWithPath:(NSString*)aPath
+{  
+  self = [super init];
+  
+  if (self) {
+    _databasePath = [aPath copy];
+    _db           = nil;
+  }
+  return self;
+}
+
+
+- (BOOL)open {
+  if (_db) {
+    return YES;
+  }
+  int err = sqlite3_open([_databasePath UTF8String], &_db);
+  if(err != SQLITE_OK) {
+    NSLog(@"error opening!: %d", err);
+    return NO;
+  }
+  return YES;
+}
+
+- (NSArray *)queryAllTables
+{
+  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;
+}
+
+- (NSArray *)queryAllDataWithTableName:(NSString *)tableName
+{
+  NSString *sql = [NSString stringWithFormat:@"SELECT * FROM %@",tableName];
+  return [self executeQuery:sql];
+}
+
+#pragma mark -
+#pragma mark - Private
+
+- (NSArray *)executeQuery:(NSString *)sql
+{
+  NSMutableArray *resultArray = [NSMutableArray array];
+  [self open];
+  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];
+      }
+    }
+  }
+  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;
+}
+
+- (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];
+}
+
+- (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];
+}
+
+
+@end

+ 47 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.h

@@ -0,0 +1,47 @@
+//
+//  PTMultiColumnTableView.h
+//  PTMultiColumnTableViewDemo
+//
+//  Created by Peng Tao on 15/11/16.
+//  Copyright © 2015年 Peng Tao. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import "FLEXTableColumnHeader.h"
+
+@class FLEXMultiColumnTableView;
+
+@protocol FLEXMultiColumnTableViewDelegate <NSObject>
+
+@optional
+- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView labelDidTapWithText:(NSString *)text;
+- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView headerTapWithText:(NSString *)text sortType:(FLEXTableColumnHeaderSortType)type;
+
+@end
+@protocol FLEXMultiColumnTableViewDataSource <NSObject>
+
+@required
+
+- (NSInteger)numberOfColumnsInTableView:(FLEXMultiColumnTableView *)tableView;
+- (NSInteger)numberOfRowsInTableView:(FLEXMultiColumnTableView *)tableView;
+- (NSString *)columnNameInColumn:(NSInteger)column;
+- (NSString *)rowNameInRow:(NSInteger)row;
+- (NSString *)contentAtColumn:(NSInteger)column row:(NSInteger)row;
+- (NSArray *)contentAtRow:(NSInteger)row;
+
+- (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView widthForContentCellInColumn:(NSInteger)column;
+- (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView heightForContentCellInRow:(NSInteger)row;
+- (CGFloat)heightForTopHeaderInTableView:(FLEXMultiColumnTableView *)tableView;
+- (CGFloat)WidthForLeftHeaderInTableView:(FLEXMultiColumnTableView *)tableView;
+
+@end
+
+
+@interface FLEXMultiColumnTableView : UIView
+
+@property (nonatomic, weak) id<FLEXMultiColumnTableViewDataSource>dataSource;
+@property (nonatomic, weak) id<FLEXMultiColumnTableViewDelegate>delegate;
+
+- (void)reloadData;
+
+@end

+ 396 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.m

@@ -0,0 +1,396 @@
+//
+//  PTMultiColumnTableView.m
+//  PTMultiColumnTableViewDemo
+//
+//  Created by Peng Tao on 15/11/16.
+//  Copyright © 2015年 Peng Tao. All rights reserved.
+//
+
+#import "FLEXMultiColumnTableView.h"
+#import "FLEXTableContentCell.h"
+#import "FLEXTableLeftCell.h"
+
+
+typedef NS_ENUM(NSInteger,UIViewSeparatorLocation) {
+  UIViewSeparatorLocationTop,
+  UIViewSeparatorLocationLeft,
+  UIViewSeparatorLocationBottom,
+  UIViewSeparatorLocationRight
+};
+
+@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) NSDictionary *sortStatusDict;
+@property (nonatomic, strong) NSArray *rowData;
+@end
+
+static const CGFloat kColumnMargin = 1;
+
+@implementation FLEXMultiColumnTableView
+
+
+- (instancetype)initWithFrame:(CGRect)frame
+{
+  self = [super initWithFrame:frame];
+  if (self) {
+    [self loadUI];
+  }
+  return self;
+}
+
+- (void)didMoveToSuperview
+{
+  [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.dataSource numberOfColumnsInTableView:self];
+  for (int i = 0; i < rowsCount; i++) {
+    contentWidth += [self.dataSource multiColumnTableView:self widthForContentCellInColumn: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];
+}
+
+- (void)reloadData
+{
+  [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];
+}
+
+- (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;
+  
+}
+
+- (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];
+  
+}
+
+
+#pragma mark - Data
+
+- (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;
+    
+    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];
+  
+}
+
+
+- (void)loadContentData
+{
+  [self.contentTableView reloadData];
+}
+
+- (void)loadLeftViewData
+{
+  [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;
+    
+    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.dataSource rowNameInRow:indexPath.row];
+    return cell;
+  }
+}
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
+{
+  return [self.dataSource numberOfRowsInTableView:self];
+}
+
+
+- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+  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;
+  }
+}
+
+#pragma mark -
+#pragma mark UITableView Delegate
+
+- (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];
+  }
+}
+
+#pragma mark -
+#pragma mark DataSource Accessor
+
+- (NSInteger)numberOfrows
+{
+  return [self.dataSource numberOfRowsInTableView:self];
+}
+
+- (NSInteger)numberOfColumns
+{
+  return [self.dataSource numberOfColumnsInTableView:self];
+}
+
+- (NSString *)columnTitleForColumn:(NSInteger)column
+{
+  return [self.dataSource columnNameInColumn:column];
+}
+
+- (NSString *)rowTitleForRow:(NSInteger)row
+{
+  return [self.dataSource rowNameInRow:row];
+}
+
+- (NSString *)contentAtColumn:(NSInteger)column row:(NSInteger)row;
+{
+  return [self.dataSource contentAtColumn:column row:row];
+}
+
+- (CGFloat)contentWidthForColumn:(NSInteger)column
+{
+  return [self.dataSource multiColumnTableView:self widthForContentCellInColumn:column];
+}
+
+- (CGFloat)contentHeightForRow:(NSInteger)row
+{
+  return [self.dataSource multiColumnTableView:self heightForContentCellInRow:row];
+}
+
+- (CGFloat)topHeaderHeight
+{
+  return [self.dataSource heightForTopHeaderInTableView:self];
+}
+
+- (CGFloat)leftHeaderWidth
+{
+  return [self.dataSource WidthForLeftHeaderInTableView:self];
+}
+
+- (CGFloat)columnMargin
+{
+  return kColumnMargin;
+}
+
+
+
+- (void)tableContentCell:(FLEXTableContentCell *)tableView labelDidTapWithText:(NSString *)text
+{
+  if ([self.delegate respondsToSelector:@selector(multiColumnTableView:labelDidTapWithText:)]) {
+    [self.delegate multiColumnTableView:self labelDidTapWithText:text];
+  }
+}
+
+#pragma mark -
+#pragma mark - Private
+
+
+
+- (void)addSeparatorLineInView:(UIView *)view
+                      andWidth:(CGFloat)lineWidth
+                   andLocation:(UIViewSeparatorLocation)location
+                      andColor:(UIColor *)color
+{
+  CGFloat width  = view.frame.size.width;
+  CGFloat height = view.frame.size.height;
+  UIView *line = [[UIView alloc] init];
+  line.backgroundColor = color;
+  switch (location) {
+    case UIViewSeparatorLocationTop:
+      line.frame = CGRectMake(0, 0, width, lineWidth);
+      [view addSubview:line];
+      break;
+    case UIViewSeparatorLocationLeft:
+      line.frame = CGRectMake(0, 0, lineWidth, height);
+      [view addSubview:line];
+      break;
+    case UIViewSeparatorLocationBottom:
+      line.frame = CGRectMake(0, height - lineWidth, width, lineWidth);
+      [view addSubview:line];
+      break;
+    case UIViewSeparatorLocationRight:
+      line.frame = CGRectMake(width - lineWidth, 0, lineWidth, height);
+      [view addSubview:line];
+      break;
+  }
+}
+
+- (UIColor *)randomColor{
+  
+  CGFloat red = (CGFloat)random()/(CGFloat)RAND_MAX;
+  CGFloat green = (CGFloat)random()/(CGFloat)RAND_MAX;
+  CGFloat blue = (CGFloat)random()/(CGFloat)RAND_MAX;
+  return [UIColor colorWithRed:red green:green blue:blue alpha:1.0f];
+}
+
+@end

+ 25 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.h

@@ -0,0 +1,25 @@
+//
+//  FLEXTableContentHeaderCell.h
+//  UICatalog
+//
+//  Created by Peng Tao on 15/11/26.
+//  Copyright © 2015年 f. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef NS_ENUM(NSUInteger, FLEXTableColumnHeaderSortType) {
+  FLEXTableColumnHeaderSortTypeNone = 0, 
+  FLEXTableColumnHeaderSortTypeAsc,
+  FLEXTableColumnHeaderSortTypeDesc,
+};
+
+
+@interface FLEXTableColumnHeader : UIView
+
+@property (nonatomic, weak) UILabel *label;
+
+- (void)changeSortStatusWithType:(FLEXTableColumnHeaderSortType)type;
+
+@end
+

+ 62 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.m

@@ -0,0 +1,62 @@
+//
+//  FLEXTableContentHeaderCell.m
+//  UICatalog
+//
+//  Created by Peng Tao on 15/11/26.
+//  Copyright © 2015年 f. All rights reserved.
+//
+
+#import "FLEXTableColumnHeader.h"
+
+@implementation FLEXTableColumnHeader
+{
+  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;
+}
+
+- (void)changeSortStatusWithType:(FLEXTableColumnHeaderSortType)type
+{
+  switch (type) {
+    case FLEXTableColumnHeaderSortTypeNone:
+      _arrowLabel.text = @"";
+      break;
+    case FLEXTableColumnHeaderSortTypeAsc:
+      _arrowLabel.text = @"⬆️";
+      break;
+    case FLEXTableColumnHeaderSortTypeDesc:
+      _arrowLabel.text = @"⬇️";
+      break;
+    default:
+      break;
+  }
+}
+
+
+
+
+
+@end

+ 27 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentCell.h

@@ -0,0 +1,27 @@
+//
+//  FLEXTableContentCell.h
+//  UICatalog
+//
+//  Created by Peng Tao on 15/11/24.
+//  Copyright © 2015年 f. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class FLEXTableContentCell;
+@protocol FLEXTableContentCellDelegate <NSObject>
+
+@optional
+- (void)tableContentCell:(FLEXTableContentCell *)tableView labelDidTapWithText:(NSString *)text;
+
+@end
+
+@interface FLEXTableContentCell : UITableViewCell
+
+@property (nonatomic, strong)NSArray *labels;
+
+@property (nonatomic, weak) id<FLEXTableContentCellDelegate>delegate;
+
++ (instancetype)cellWithTableView:(UITableView *)tableView columnNumber:(NSInteger)number;
+
+@end

+ 66 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentCell.m

@@ -0,0 +1,66 @@
+//
+//  FLEXTableContentCell.m
+//  UICatalog
+//
+//  Created by Peng Tao on 15/11/24.
+//  Copyright © 2015年 f. All rights reserved.
+//
+
+#import "FLEXTableContentCell.h"
+#import "FLEXMultiColumnTableView.h"
+
+@interface FLEXTableContentCell ()
+
+@end
+
+@implementation FLEXTableContentCell
+
++ (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];
+    }
+    cell.labels = labels;
+  }
+  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);
+  }
+}
+
+
+- (void)labelDidTap:(UIGestureRecognizer *)gesture
+{
+  UILabel *label = (UILabel *)gesture.view;
+  if ([self.delegate respondsToSelector:@selector(tableContentCell:labelDidTapWithText:)]) {
+    [self.delegate tableContentCell:self labelDidTapWithText:label.text];
+  }
+}
+
+@end

+ 16 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.h

@@ -0,0 +1,16 @@
+//
+//  PTTableContentViewController.h
+//  PTDatabaseReader
+//
+//  Created by Peng Tao on 15/11/23.
+//  Copyright © 2015年 Peng Tao. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface FLEXTableContentViewController : UIViewController
+
+@property (nonatomic, strong) NSArray *columnsArray;
+@property (nonatomic, strong) NSArray *contensArray;
+
+@end

+ 185 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.m

@@ -0,0 +1,185 @@
+//
+//  PTTableContentViewController.m
+//  PTDatabaseReader
+//
+//  Created by Peng Tao on 15/11/23.
+//  Copyright © 2015年 Peng Tao. All rights reserved.
+//
+
+#import "FLEXTableContentViewController.h"
+#import "FLEXMultiColumnTableView.h"
+#import "FLEXWebViewController.h"
+
+
+@interface FLEXTableContentViewController ()<FLEXMultiColumnTableViewDataSource, FLEXMultiColumnTableViewDelegate>
+
+@property (nonatomic, strong)FLEXMultiColumnTableView *multiColumView;
+
+@end
+
+@implementation FLEXTableContentViewController
+
+- (instancetype)init
+{
+  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];
+  }
+  return self;
+}
+
+- (void)viewWillAppear:(BOOL)animated
+{
+  [super viewWillAppear:animated];
+  [self.multiColumView reloadData];
+  
+}
+
+#pragma mark -
+#pragma mark MultiColumnTableView DataSource
+
+- (NSInteger)numberOfColumnsInTableView:(FLEXMultiColumnTableView *)tableView
+{
+  return self.columnsArray.count;
+}
+- (NSInteger)numberOfRowsInTableView:(FLEXMultiColumnTableView *)tableView
+{
+  return self.contensArray.count;
+}
+
+
+- (NSString *)columnNameInColumn:(NSInteger)column
+{
+    return self.columnsArray[column];
+}
+
+
+- (NSString *)rowNameInRow:(NSInteger)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]]];
+    }
+  }
+  return @"this is bug";
+}
+
+- (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]]];
+    }
+    return  result;
+  }
+  return nil;
+}
+- (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView
+      heightForContentCellInRow:(NSInteger)row
+{
+  return 40;
+}
+
+- (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView
+    widthForContentCellInColumn:(NSInteger)column
+{
+  return 120;
+}
+
+
+- (CGFloat)heightForTopHeaderInTableView:(FLEXMultiColumnTableView *)tableView
+{
+  return 40;
+}
+
+- (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;
+}
+
+
+#pragma mark -
+#pragma mark MultiColumnTableView Delegate
+
+- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView labelDidTapWithText:(NSString *)text
+{
+  FLEXWebViewController * detailViewController = [[FLEXWebViewController alloc] initWithText:text];
+  [self.navigationController pushViewController:detailViewController animated:YES];
+}
+
+- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView headerTapWithText:(NSString *)text sortType:(FLEXTableColumnHeaderSortType)type
+{
+  
+  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;
+    }
+    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];
+}
+
+#pragma mark -
+#pragma mark About Transition
+
+- (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];
+}
+
+
+@end

+ 17 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.h

@@ -0,0 +1,17 @@
+//
+//  FLEXTableLeftCell.h
+//  UICatalog
+//
+//  Created by Peng Tao on 15/11/24.
+//  Copyright © 2015年 f. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface FLEXTableLeftCell : UITableViewCell
+
+@property (nonatomic, weak) UILabel *titlelabel;
+
++ (instancetype)cellWithTableView:(UITableView *)tableView;
+
+@end

+ 35 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.m

@@ -0,0 +1,35 @@
+//
+//  FLEXTableLeftCell.m
+//  UICatalog
+//
+//  Created by Peng Tao on 15/11/24.
+//  Copyright © 2015年 f. All rights reserved.
+//
+
+#import "FLEXTableLeftCell.h"
+
+@implementation FLEXTableLeftCell
+
++ (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;
+}
+
+- (void)layoutSubviews
+{
+  [super layoutSubviews];
+  self.titlelabel.frame = self.contentView.frame;
+}
+@end

+ 15 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.h

@@ -0,0 +1,15 @@
+//
+//  PTTableListViewController.h
+//  PTDatabaseReader
+//
+//  Created by Peng Tao on 15/11/23.
+//  Copyright © 2015年 Peng Tao. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface FLEXTableListViewController : UITableViewController
+
+- (instancetype)initWithPath:(NSString *)path;
+
+@end

+ 87 - 0
Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.m

@@ -0,0 +1,87 @@
+//
+//  PTTableListViewController.m
+//  PTDatabaseReader
+//
+//  Created by Peng Tao on 15/11/23.
+//  Copyright © 2015年 Peng Tao. All rights reserved.
+//
+
+#import "FLEXTableListViewController.h"
+#import "FLEXDatabaseManager.h"
+#import "FLEXTableContentViewController.h"
+
+@interface FLEXTableListViewController ()
+{
+  FLEXDatabaseManager *_dbm;
+  NSString *_databasePath;
+}
+
+@property (nonatomic, strong) NSArray *tables;
+
+@end
+
+@implementation FLEXTableListViewController
+
+
+- (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];
+}
+
+- (void)getAllTables
+{
+  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;
+}
+
+- (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;
+}
+
+
+- (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];
+}
+
+
+- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
+{  
+  return [NSString stringWithFormat:@"%lu tables", (unsigned long)self.tables.count];
+}
+
+@end

+ 5 - 1
Classes/GlobalStateExplorers/FLEXFileBrowserTableViewController.m

@@ -11,6 +11,7 @@
 #import "FLEXUtility.h"
 #import "FLEXUtility.h"
 #import "FLEXWebViewController.h"
 #import "FLEXWebViewController.h"
 #import "FLEXImagePreviewViewController.h"
 #import "FLEXImagePreviewViewController.h"
+#import "FLEXTableListViewController.h"
 
 
 @interface FLEXFileBrowserTableViewCell : UITableViewCell
 @interface FLEXFileBrowserTableViewCell : UITableViewCell
 @end
 @end
@@ -253,7 +254,10 @@
                 drillInViewController = [[FLEXWebViewController alloc] initWithText:prettyString];
                 drillInViewController = [[FLEXWebViewController alloc] initWithText:prettyString];
             } else if ([FLEXWebViewController supportsPathExtension:[subpath pathExtension]]) {
             } else if ([FLEXWebViewController supportsPathExtension:[subpath pathExtension]]) {
                 drillInViewController = [[FLEXWebViewController alloc] initWithURL:[NSURL fileURLWithPath:fullPath]];
                 drillInViewController = [[FLEXWebViewController alloc] initWithURL:[NSURL fileURLWithPath:fullPath]];
-            } else {
+            } else if ([[subpath pathExtension] isEqualToString:@"db"]) {
+              drillInViewController = [[FLEXTableListViewController alloc] initWithPath:fullPath];
+            }
+            else {
                 NSString *fileString = [NSString stringWithContentsOfFile:fullPath encoding:NSUTF8StringEncoding error:NULL];
                 NSString *fileString = [NSString stringWithContentsOfFile:fullPath encoding:NSUTF8StringEncoding error:NULL];
                 if ([fileString length] > 0) {
                 if ([fileString length] > 0) {
                     drillInViewController = [[FLEXWebViewController alloc] initWithText:fileString];
                     drillInViewController = [[FLEXWebViewController alloc] initWithText:fileString];

+ 55 - 1
Example/UICatalog.xcodeproj/project.pbxproj

@@ -45,7 +45,15 @@
 		53874F9918F36B1800510922 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 53874F9718F36B1800510922 /* Localizable.strings */; };
 		53874F9918F36B1800510922 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 53874F9718F36B1800510922 /* Localizable.strings */; };
 		650855EB1A9007D5006109A1 /* FLEXArgumentInputDateView.m in Sources */ = {isa = PBXBuildFile; fileRef = 650855EA1A9007D5006109A1 /* FLEXArgumentInputDateView.m */; };
 		650855EB1A9007D5006109A1 /* FLEXArgumentInputDateView.m in Sources */ = {isa = PBXBuildFile; fileRef = 650855EA1A9007D5006109A1 /* FLEXArgumentInputDateView.m */; };
 		65F8DC6C1A8F11020076F87B /* FLEXFileBrowserFileOperationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 65F8DC6B1A8F11020076F87B /* FLEXFileBrowserFileOperationController.m */; };
 		65F8DC6C1A8F11020076F87B /* FLEXFileBrowserFileOperationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 65F8DC6B1A8F11020076F87B /* FLEXFileBrowserFileOperationController.m */; };
-		679F6A121BD61B2400A8C94C /* FLEXCookiesTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 679F6A111BD61B2400A8C94C /* FLEXCookiesTableViewController.m */; settings = {ASSET_TAGS = (); }; };
+		679F6A121BD61B2400A8C94C /* FLEXCookiesTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 679F6A111BD61B2400A8C94C /* FLEXCookiesTableViewController.m */; };
+		779B1EED1C0C4EF6001F5E49 /* FLEXDatabaseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1EE01C0C4EF6001F5E49 /* FLEXDatabaseManager.m */; };
+		779B1EEE1C0C4EF6001F5E49 /* FLEXMultiColumnTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1EE21C0C4EF6001F5E49 /* FLEXMultiColumnTableView.m */; };
+		779B1EEF1C0C4EF6001F5E49 /* FLEXTableColumnHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1EE41C0C4EF6001F5E49 /* FLEXTableColumnHeader.m */; };
+		779B1EF01C0C4EF6001F5E49 /* FLEXTableContentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1EE61C0C4EF6001F5E49 /* FLEXTableContentCell.m */; };
+		779B1EF11C0C4EF6001F5E49 /* FLEXTableContentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1EE81C0C4EF6001F5E49 /* FLEXTableContentViewController.m */; };
+		779B1EF21C0C4EF6001F5E49 /* FLEXTableLeftCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1EEA1C0C4EF6001F5E49 /* FLEXTableLeftCell.m */; };
+		779B1EF31C0C4EF6001F5E49 /* FLEXTableListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1EEC1C0C4EF6001F5E49 /* FLEXTableListViewController.m */; };
+		779B1EF51C0C4F25001F5E49 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 779B1EF41C0C4F25001F5E49 /* libsqlite3.dylib */; };
 		9421B88D1A8BBCB200BA3E46 /* FLEXNetworkHistoryTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9421B8801A8BBCB200BA3E46 /* FLEXNetworkHistoryTableViewController.m */; };
 		9421B88D1A8BBCB200BA3E46 /* FLEXNetworkHistoryTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9421B8801A8BBCB200BA3E46 /* FLEXNetworkHistoryTableViewController.m */; };
 		9421B88E1A8BBCB200BA3E46 /* FLEXNetworkRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 9421B8821A8BBCB200BA3E46 /* FLEXNetworkRecorder.m */; };
 		9421B88E1A8BBCB200BA3E46 /* FLEXNetworkRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 9421B8821A8BBCB200BA3E46 /* FLEXNetworkRecorder.m */; };
 		9421B88F1A8BBCB200BA3E46 /* FLEXNetworkTransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = 9421B8841A8BBCB200BA3E46 /* FLEXNetworkTransaction.m */; };
 		9421B88F1A8BBCB200BA3E46 /* FLEXNetworkTransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = 9421B8841A8BBCB200BA3E46 /* FLEXNetworkTransaction.m */; };
@@ -185,6 +193,21 @@
 		65F8DC6B1A8F11020076F87B /* FLEXFileBrowserFileOperationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXFileBrowserFileOperationController.m; sourceTree = "<group>"; };
 		65F8DC6B1A8F11020076F87B /* FLEXFileBrowserFileOperationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXFileBrowserFileOperationController.m; sourceTree = "<group>"; };
 		679F6A101BD61B2400A8C94C /* FLEXCookiesTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXCookiesTableViewController.h; sourceTree = "<group>"; };
 		679F6A101BD61B2400A8C94C /* FLEXCookiesTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXCookiesTableViewController.h; sourceTree = "<group>"; };
 		679F6A111BD61B2400A8C94C /* FLEXCookiesTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXCookiesTableViewController.m; sourceTree = "<group>"; };
 		679F6A111BD61B2400A8C94C /* FLEXCookiesTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXCookiesTableViewController.m; sourceTree = "<group>"; };
+		779B1EDF1C0C4EF6001F5E49 /* FLEXDatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXDatabaseManager.h; sourceTree = "<group>"; };
+		779B1EE01C0C4EF6001F5E49 /* FLEXDatabaseManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXDatabaseManager.m; sourceTree = "<group>"; };
+		779B1EE11C0C4EF6001F5E49 /* FLEXMultiColumnTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMultiColumnTableView.h; sourceTree = "<group>"; };
+		779B1EE21C0C4EF6001F5E49 /* FLEXMultiColumnTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMultiColumnTableView.m; sourceTree = "<group>"; };
+		779B1EE31C0C4EF6001F5E49 /* FLEXTableColumnHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableColumnHeader.h; sourceTree = "<group>"; };
+		779B1EE41C0C4EF6001F5E49 /* FLEXTableColumnHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableColumnHeader.m; sourceTree = "<group>"; };
+		779B1EE51C0C4EF6001F5E49 /* FLEXTableContentCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableContentCell.h; sourceTree = "<group>"; };
+		779B1EE61C0C4EF6001F5E49 /* FLEXTableContentCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableContentCell.m; sourceTree = "<group>"; };
+		779B1EE71C0C4EF6001F5E49 /* FLEXTableContentViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableContentViewController.h; sourceTree = "<group>"; };
+		779B1EE81C0C4EF6001F5E49 /* FLEXTableContentViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableContentViewController.m; sourceTree = "<group>"; };
+		779B1EE91C0C4EF6001F5E49 /* FLEXTableLeftCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableLeftCell.h; sourceTree = "<group>"; };
+		779B1EEA1C0C4EF6001F5E49 /* FLEXTableLeftCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableLeftCell.m; sourceTree = "<group>"; };
+		779B1EEB1C0C4EF6001F5E49 /* FLEXTableListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableListViewController.h; sourceTree = "<group>"; };
+		779B1EEC1C0C4EF6001F5E49 /* FLEXTableListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableListViewController.m; sourceTree = "<group>"; };
+		779B1EF41C0C4F25001F5E49 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = ../../../../../../usr/lib/libsqlite3.dylib; sourceTree = "<group>"; };
 		9421B87F1A8BBCB200BA3E46 /* FLEXNetworkHistoryTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkHistoryTableViewController.h; sourceTree = "<group>"; };
 		9421B87F1A8BBCB200BA3E46 /* FLEXNetworkHistoryTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkHistoryTableViewController.h; sourceTree = "<group>"; };
 		9421B8801A8BBCB200BA3E46 /* FLEXNetworkHistoryTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkHistoryTableViewController.m; sourceTree = "<group>"; };
 		9421B8801A8BBCB200BA3E46 /* FLEXNetworkHistoryTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkHistoryTableViewController.m; sourceTree = "<group>"; };
 		9421B8811A8BBCB200BA3E46 /* FLEXNetworkRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkRecorder.h; sourceTree = "<group>"; };
 		9421B8811A8BBCB200BA3E46 /* FLEXNetworkRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkRecorder.h; sourceTree = "<group>"; };
@@ -319,6 +342,7 @@
 			isa = PBXFrameworksBuildPhase;
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
+				779B1EF51C0C4F25001F5E49 /* libsqlite3.dylib in Frameworks */,
 				94CB4D431A97183E0054A905 /* libz.dylib in Frameworks */,
 				94CB4D431A97183E0054A905 /* libz.dylib in Frameworks */,
 				5356824018F3656900BAAD62 /* CoreGraphics.framework in Frameworks */,
 				5356824018F3656900BAAD62 /* CoreGraphics.framework in Frameworks */,
 				5356824218F3656900BAAD62 /* UIKit.framework in Frameworks */,
 				5356824218F3656900BAAD62 /* UIKit.framework in Frameworks */,
@@ -351,6 +375,7 @@
 		5356823C18F3656900BAAD62 /* Frameworks */ = {
 		5356823C18F3656900BAAD62 /* Frameworks */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				779B1EF41C0C4F25001F5E49 /* libsqlite3.dylib */,
 				94CB4D421A97183E0054A905 /* libz.dylib */,
 				94CB4D421A97183E0054A905 /* libz.dylib */,
 				5356823D18F3656900BAAD62 /* Foundation.framework */,
 				5356823D18F3656900BAAD62 /* Foundation.framework */,
 				5356823F18F3656900BAAD62 /* CoreGraphics.framework */,
 				5356823F18F3656900BAAD62 /* CoreGraphics.framework */,
@@ -456,6 +481,27 @@
 			name = Application;
 			name = Application;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		779B1EDE1C0C4EF6001F5E49 /* DatabaseBrowser */ = {
+			isa = PBXGroup;
+			children = (
+				779B1EDF1C0C4EF6001F5E49 /* FLEXDatabaseManager.h */,
+				779B1EE01C0C4EF6001F5E49 /* FLEXDatabaseManager.m */,
+				779B1EE11C0C4EF6001F5E49 /* FLEXMultiColumnTableView.h */,
+				779B1EE21C0C4EF6001F5E49 /* FLEXMultiColumnTableView.m */,
+				779B1EE31C0C4EF6001F5E49 /* FLEXTableColumnHeader.h */,
+				779B1EE41C0C4EF6001F5E49 /* FLEXTableColumnHeader.m */,
+				779B1EE51C0C4EF6001F5E49 /* FLEXTableContentCell.h */,
+				779B1EE61C0C4EF6001F5E49 /* FLEXTableContentCell.m */,
+				779B1EE71C0C4EF6001F5E49 /* FLEXTableContentViewController.h */,
+				779B1EE81C0C4EF6001F5E49 /* FLEXTableContentViewController.m */,
+				779B1EE91C0C4EF6001F5E49 /* FLEXTableLeftCell.h */,
+				779B1EEA1C0C4EF6001F5E49 /* FLEXTableLeftCell.m */,
+				779B1EEB1C0C4EF6001F5E49 /* FLEXTableListViewController.h */,
+				779B1EEC1C0C4EF6001F5E49 /* FLEXTableListViewController.m */,
+			);
+			path = DatabaseBrowser;
+			sourceTree = "<group>";
+		};
 		9421B87E1A8BBCB200BA3E46 /* Network */ = {
 		9421B87E1A8BBCB200BA3E46 /* Network */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
@@ -639,6 +685,7 @@
 		944F7473197B458C009AB039 /* Global State Explorers */ = {
 		944F7473197B458C009AB039 /* Global State Explorers */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				779B1EDE1C0C4EF6001F5E49 /* DatabaseBrowser */,
 				946C6EC61A75986C006545C2 /* System Log */,
 				946C6EC61A75986C006545C2 /* System Log */,
 				944F7474197B458C009AB039 /* FLEXClassesTableViewController.h */,
 				944F7474197B458C009AB039 /* FLEXClassesTableViewController.h */,
 				944F7475197B458C009AB039 /* FLEXClassesTableViewController.m */,
 				944F7475197B458C009AB039 /* FLEXClassesTableViewController.m */,
@@ -779,6 +826,7 @@
 			isa = PBXSourcesBuildPhase;
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
+				779B1EEF1C0C4EF6001F5E49 /* FLEXTableColumnHeader.m in Sources */,
 				944F749B197B458C009AB039 /* FLEXArgumentInputNotSupportedView.m in Sources */,
 				944F749B197B458C009AB039 /* FLEXArgumentInputNotSupportedView.m in Sources */,
 				535682AE18F3670300BAAD62 /* AAPLDatePickerController.m in Sources */,
 				535682AE18F3670300BAAD62 /* AAPLDatePickerController.m in Sources */,
 				946C6ECC1A759928006545C2 /* FLEXSystemLogTableViewController.m in Sources */,
 				946C6ECC1A759928006545C2 /* FLEXSystemLogTableViewController.m in Sources */,
@@ -804,6 +852,7 @@
 				944F74B5197B458C009AB039 /* FLEXHierarchyTableViewCell.m in Sources */,
 				944F74B5197B458C009AB039 /* FLEXHierarchyTableViewCell.m in Sources */,
 				944F74AD197B458C009AB039 /* FLEXWindow.m in Sources */,
 				944F74AD197B458C009AB039 /* FLEXWindow.m in Sources */,
 				944F749D197B458C009AB039 /* FLEXArgumentInputStringView.m in Sources */,
 				944F749D197B458C009AB039 /* FLEXArgumentInputStringView.m in Sources */,
+				779B1EF11C0C4EF6001F5E49 /* FLEXTableContentViewController.m in Sources */,
 				944F74A9197B458C009AB039 /* FLEXExplorerToolbar.m in Sources */,
 				944F74A9197B458C009AB039 /* FLEXExplorerToolbar.m in Sources */,
 				944F74A8197B458C009AB039 /* FLEXPropertyEditorViewController.m in Sources */,
 				944F74A8197B458C009AB039 /* FLEXPropertyEditorViewController.m in Sources */,
 				944F74B0197B458C009AB039 /* FLEXGlobalsTableViewController.m in Sources */,
 				944F74B0197B458C009AB039 /* FLEXGlobalsTableViewController.m in Sources */,
@@ -820,6 +869,7 @@
 				944F74A5197B458C009AB039 /* FLEXFieldEditorViewController.m in Sources */,
 				944F74A5197B458C009AB039 /* FLEXFieldEditorViewController.m in Sources */,
 				944F7489197B458C009AB039 /* FLEXArrayExplorerViewController.m in Sources */,
 				944F7489197B458C009AB039 /* FLEXArrayExplorerViewController.m in Sources */,
 				535682B418F3670300BAAD62 /* AAPLPickerViewController.m in Sources */,
 				535682B418F3670300BAAD62 /* AAPLPickerViewController.m in Sources */,
+				779B1EF01C0C4EF6001F5E49 /* FLEXTableContentCell.m in Sources */,
 				946C6EC91A7598D3006545C2 /* FLEXSystemLogTableViewCell.m in Sources */,
 				946C6EC91A7598D3006545C2 /* FLEXSystemLogTableViewCell.m in Sources */,
 				535682BE18F3670300BAAD62 /* AAPLWebViewController.m in Sources */,
 				535682BE18F3670300BAAD62 /* AAPLWebViewController.m in Sources */,
 				944F7490197B458C009AB039 /* FLEXObjectExplorerViewController.m in Sources */,
 				944F7490197B458C009AB039 /* FLEXObjectExplorerViewController.m in Sources */,
@@ -853,16 +903,20 @@
 				535682AD18F3670300BAAD62 /* AAPLCustomToolbarViewController.m in Sources */,
 				535682AD18F3670300BAAD62 /* AAPLCustomToolbarViewController.m in Sources */,
 				944F748F197B458C009AB039 /* FLEXObjectExplorerFactory.m in Sources */,
 				944F748F197B458C009AB039 /* FLEXObjectExplorerFactory.m in Sources */,
 				944F748D197B458C009AB039 /* FLEXDictionaryExplorerViewController.m in Sources */,
 				944F748D197B458C009AB039 /* FLEXDictionaryExplorerViewController.m in Sources */,
+				779B1EEE1C0C4EF6001F5E49 /* FLEXMultiColumnTableView.m in Sources */,
 				535682A818F3670300BAAD62 /* AAPLActivityIndicatorViewController.m in Sources */,
 				535682A818F3670300BAAD62 /* AAPLActivityIndicatorViewController.m in Sources */,
 				944F74A4197B458C009AB039 /* FLEXFieldEditorView.m in Sources */,
 				944F74A4197B458C009AB039 /* FLEXFieldEditorView.m in Sources */,
 				944F74A7197B458C009AB039 /* FLEXMethodCallingViewController.m in Sources */,
 				944F74A7197B458C009AB039 /* FLEXMethodCallingViewController.m in Sources */,
+				779B1EED1C0C4EF6001F5E49 /* FLEXDatabaseManager.m in Sources */,
 				535682B818F3670300BAAD62 /* AAPLSplitViewControllerDelegate.m in Sources */,
 				535682B818F3670300BAAD62 /* AAPLSplitViewControllerDelegate.m in Sources */,
+				779B1EF21C0C4EF6001F5E49 /* FLEXTableLeftCell.m in Sources */,
 				D03647D919847248007D2A1B /* FLEXGlobalsTableViewControllerEntry.m in Sources */,
 				D03647D919847248007D2A1B /* FLEXGlobalsTableViewControllerEntry.m in Sources */,
 				535682AC18F3670300BAAD62 /* AAPLCustomSearchBarViewController.m in Sources */,
 				535682AC18F3670300BAAD62 /* AAPLCustomSearchBarViewController.m in Sources */,
 				535682A718F3670300BAAD62 /* AAPLActionSheetViewController.m in Sources */,
 				535682A718F3670300BAAD62 /* AAPLActionSheetViewController.m in Sources */,
 				01985ABC1984DE9500A65332 /* FLEXArgumentInputFontsPickerView.m in Sources */,
 				01985ABC1984DE9500A65332 /* FLEXArgumentInputFontsPickerView.m in Sources */,
 				944F74AA197B458C009AB039 /* FLEXExplorerViewController.m in Sources */,
 				944F74AA197B458C009AB039 /* FLEXExplorerViewController.m in Sources */,
 				944F7492197B458C009AB039 /* FLEXViewControllerExplorerViewController.m in Sources */,
 				944F7492197B458C009AB039 /* FLEXViewControllerExplorerViewController.m in Sources */,
+				779B1EF31C0C4EF6001F5E49 /* FLEXTableListViewController.m in Sources */,
 				5356824A18F3656900BAAD62 /* main.m in Sources */,
 				5356824A18F3656900BAAD62 /* main.m in Sources */,
 				679F6A121BD61B2400A8C94C /* FLEXCookiesTableViewController.m in Sources */,
 				679F6A121BD61B2400A8C94C /* FLEXCookiesTableViewController.m in Sources */,
 				535682B118F3670300BAAD62 /* AAPLImageViewController.m in Sources */,
 				535682B118F3670300BAAD62 /* AAPLImageViewController.m in Sources */,

+ 70 - 2
FLEX.xcodeproj/project.pbxproj

@@ -136,8 +136,23 @@
 		3A4C95421B5B21410088C3F2 /* FLEXNetworkObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A4C94C21B5B21410088C3F2 /* FLEXNetworkObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		3A4C95421B5B21410088C3F2 /* FLEXNetworkObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A4C94C21B5B21410088C3F2 /* FLEXNetworkObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		3A4C95431B5B21410088C3F2 /* FLEXNetworkObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A4C94C31B5B21410088C3F2 /* FLEXNetworkObserver.m */; };
 		3A4C95431B5B21410088C3F2 /* FLEXNetworkObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A4C94C31B5B21410088C3F2 /* FLEXNetworkObserver.m */; };
 		3A4C95471B5B217D0088C3F2 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A4C95461B5B217D0088C3F2 /* libz.dylib */; };
 		3A4C95471B5B217D0088C3F2 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A4C95461B5B217D0088C3F2 /* libz.dylib */; };
-		679F64861BD53B7B00A8C94C /* FLEXCookiesTableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 679F64841BD53B7B00A8C94C /* FLEXCookiesTableViewController.h */; settings = {ASSET_TAGS = (); }; };
-		679F64871BD53B7B00A8C94C /* FLEXCookiesTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 679F64851BD53B7B00A8C94C /* FLEXCookiesTableViewController.m */; settings = {ASSET_TAGS = (); }; };
+		679F64861BD53B7B00A8C94C /* FLEXCookiesTableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 679F64841BD53B7B00A8C94C /* FLEXCookiesTableViewController.h */; };
+		679F64871BD53B7B00A8C94C /* FLEXCookiesTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 679F64851BD53B7B00A8C94C /* FLEXCookiesTableViewController.m */; };
+		779B1ECE1C0C4D7C001F5E49 /* FLEXDatabaseManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 779B1EC01C0C4D7C001F5E49 /* FLEXDatabaseManager.h */; };
+		779B1ECF1C0C4D7C001F5E49 /* FLEXDatabaseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1EC11C0C4D7C001F5E49 /* FLEXDatabaseManager.m */; };
+		779B1ED01C0C4D7C001F5E49 /* FLEXMultiColumnTableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 779B1EC21C0C4D7C001F5E49 /* FLEXMultiColumnTableView.h */; };
+		779B1ED11C0C4D7C001F5E49 /* FLEXMultiColumnTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1EC31C0C4D7C001F5E49 /* FLEXMultiColumnTableView.m */; };
+		779B1ED21C0C4D7C001F5E49 /* FLEXTableColumnHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 779B1EC41C0C4D7C001F5E49 /* FLEXTableColumnHeader.h */; };
+		779B1ED31C0C4D7C001F5E49 /* FLEXTableColumnHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1EC51C0C4D7C001F5E49 /* FLEXTableColumnHeader.m */; };
+		779B1ED41C0C4D7C001F5E49 /* FLEXTableContentCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 779B1EC61C0C4D7C001F5E49 /* FLEXTableContentCell.h */; };
+		779B1ED51C0C4D7C001F5E49 /* FLEXTableContentCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1EC71C0C4D7C001F5E49 /* FLEXTableContentCell.m */; };
+		779B1ED61C0C4D7C001F5E49 /* FLEXTableContentViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 779B1EC81C0C4D7C001F5E49 /* FLEXTableContentViewController.h */; };
+		779B1ED71C0C4D7C001F5E49 /* FLEXTableContentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1EC91C0C4D7C001F5E49 /* FLEXTableContentViewController.m */; };
+		779B1ED81C0C4D7C001F5E49 /* FLEXTableLeftCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 779B1ECA1C0C4D7C001F5E49 /* FLEXTableLeftCell.h */; };
+		779B1ED91C0C4D7C001F5E49 /* FLEXTableLeftCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1ECB1C0C4D7C001F5E49 /* FLEXTableLeftCell.m */; };
+		779B1EDA1C0C4D7C001F5E49 /* FLEXTableListViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 779B1ECC1C0C4D7C001F5E49 /* FLEXTableListViewController.h */; };
+		779B1EDB1C0C4D7C001F5E49 /* FLEXTableListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 779B1ECD1C0C4D7C001F5E49 /* FLEXTableListViewController.m */; };
+		779B1EDD1C0C4EAD001F5E49 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 779B1EDC1C0C4EAD001F5E49 /* libsqlite3.dylib */; };
 		942DCD871BAE0CA300DB5DC2 /* FLEXKeyboardShortcutManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 942DCD831BAE0AD300DB5DC2 /* FLEXKeyboardShortcutManager.m */; };
 		942DCD871BAE0CA300DB5DC2 /* FLEXKeyboardShortcutManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 942DCD831BAE0AD300DB5DC2 /* FLEXKeyboardShortcutManager.m */; };
 		94AAF0381BAF2E1F00DE8760 /* FLEXKeyboardHelpViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 94AAF0361BAF2E1F00DE8760 /* FLEXKeyboardHelpViewController.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		94AAF0381BAF2E1F00DE8760 /* FLEXKeyboardHelpViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 94AAF0361BAF2E1F00DE8760 /* FLEXKeyboardHelpViewController.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		94AAF0391BAF2E1F00DE8760 /* FLEXKeyboardHelpViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 94AAF0371BAF2E1F00DE8760 /* FLEXKeyboardHelpViewController.m */; };
 		94AAF0391BAF2E1F00DE8760 /* FLEXKeyboardHelpViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 94AAF0371BAF2E1F00DE8760 /* FLEXKeyboardHelpViewController.m */; };
@@ -279,6 +294,21 @@
 		3A4C95461B5B217D0088C3F2 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
 		3A4C95461B5B217D0088C3F2 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
 		679F64841BD53B7B00A8C94C /* FLEXCookiesTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXCookiesTableViewController.h; sourceTree = "<group>"; };
 		679F64841BD53B7B00A8C94C /* FLEXCookiesTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXCookiesTableViewController.h; sourceTree = "<group>"; };
 		679F64851BD53B7B00A8C94C /* FLEXCookiesTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXCookiesTableViewController.m; sourceTree = "<group>"; };
 		679F64851BD53B7B00A8C94C /* FLEXCookiesTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXCookiesTableViewController.m; sourceTree = "<group>"; };
+		779B1EC01C0C4D7C001F5E49 /* FLEXDatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXDatabaseManager.h; sourceTree = "<group>"; };
+		779B1EC11C0C4D7C001F5E49 /* FLEXDatabaseManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXDatabaseManager.m; sourceTree = "<group>"; };
+		779B1EC21C0C4D7C001F5E49 /* FLEXMultiColumnTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMultiColumnTableView.h; sourceTree = "<group>"; };
+		779B1EC31C0C4D7C001F5E49 /* FLEXMultiColumnTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMultiColumnTableView.m; sourceTree = "<group>"; };
+		779B1EC41C0C4D7C001F5E49 /* FLEXTableColumnHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableColumnHeader.h; sourceTree = "<group>"; };
+		779B1EC51C0C4D7C001F5E49 /* FLEXTableColumnHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableColumnHeader.m; sourceTree = "<group>"; };
+		779B1EC61C0C4D7C001F5E49 /* FLEXTableContentCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableContentCell.h; sourceTree = "<group>"; };
+		779B1EC71C0C4D7C001F5E49 /* FLEXTableContentCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableContentCell.m; sourceTree = "<group>"; };
+		779B1EC81C0C4D7C001F5E49 /* FLEXTableContentViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableContentViewController.h; sourceTree = "<group>"; };
+		779B1EC91C0C4D7C001F5E49 /* FLEXTableContentViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableContentViewController.m; sourceTree = "<group>"; };
+		779B1ECA1C0C4D7C001F5E49 /* FLEXTableLeftCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableLeftCell.h; sourceTree = "<group>"; };
+		779B1ECB1C0C4D7C001F5E49 /* FLEXTableLeftCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableLeftCell.m; sourceTree = "<group>"; };
+		779B1ECC1C0C4D7C001F5E49 /* FLEXTableListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableListViewController.h; sourceTree = "<group>"; };
+		779B1ECD1C0C4D7C001F5E49 /* FLEXTableListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableListViewController.m; sourceTree = "<group>"; };
+		779B1EDC1C0C4EAD001F5E49 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = ../../../../../usr/lib/libsqlite3.dylib; sourceTree = "<group>"; };
 		942DCD821BAE0AD300DB5DC2 /* FLEXKeyboardShortcutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKeyboardShortcutManager.h; sourceTree = "<group>"; };
 		942DCD821BAE0AD300DB5DC2 /* FLEXKeyboardShortcutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKeyboardShortcutManager.h; sourceTree = "<group>"; };
 		942DCD831BAE0AD300DB5DC2 /* FLEXKeyboardShortcutManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXKeyboardShortcutManager.m; sourceTree = "<group>"; };
 		942DCD831BAE0AD300DB5DC2 /* FLEXKeyboardShortcutManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXKeyboardShortcutManager.m; sourceTree = "<group>"; };
 		94AAF0361BAF2E1F00DE8760 /* FLEXKeyboardHelpViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKeyboardHelpViewController.h; sourceTree = "<group>"; };
 		94AAF0361BAF2E1F00DE8760 /* FLEXKeyboardHelpViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKeyboardHelpViewController.h; sourceTree = "<group>"; };
@@ -290,6 +320,7 @@
 			isa = PBXFrameworksBuildPhase;
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
+				779B1EDD1C0C4EAD001F5E49 /* libsqlite3.dylib in Frameworks */,
 				3A4C95471B5B217D0088C3F2 /* libz.dylib in Frameworks */,
 				3A4C95471B5B217D0088C3F2 /* libz.dylib in Frameworks */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -478,6 +509,7 @@
 		3A4C949A1B5B21410088C3F2 /* GlobalStateExplorers */ = {
 		3A4C949A1B5B21410088C3F2 /* GlobalStateExplorers */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				779B1EBF1C0C4D7C001F5E49 /* DatabaseBrowser */,
 				3A4C949B1B5B21410088C3F2 /* FLEXClassesTableViewController.h */,
 				3A4C949B1B5B21410088C3F2 /* FLEXClassesTableViewController.h */,
 				3A4C949C1B5B21410088C3F2 /* FLEXClassesTableViewController.m */,
 				3A4C949C1B5B21410088C3F2 /* FLEXClassesTableViewController.m */,
 				3A4C949D1B5B21410088C3F2 /* FLEXFileBrowserFileOperationController.h */,
 				3A4C949D1B5B21410088C3F2 /* FLEXFileBrowserFileOperationController.h */,
@@ -549,11 +581,33 @@
 		3A4C95451B5B216C0088C3F2 /* Frameworks */ = {
 		3A4C95451B5B216C0088C3F2 /* Frameworks */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				779B1EDC1C0C4EAD001F5E49 /* libsqlite3.dylib */,
 				3A4C95461B5B217D0088C3F2 /* libz.dylib */,
 				3A4C95461B5B217D0088C3F2 /* libz.dylib */,
 			);
 			);
 			name = Frameworks;
 			name = Frameworks;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		779B1EBF1C0C4D7C001F5E49 /* DatabaseBrowser */ = {
+			isa = PBXGroup;
+			children = (
+				779B1EC01C0C4D7C001F5E49 /* FLEXDatabaseManager.h */,
+				779B1EC11C0C4D7C001F5E49 /* FLEXDatabaseManager.m */,
+				779B1EC21C0C4D7C001F5E49 /* FLEXMultiColumnTableView.h */,
+				779B1EC31C0C4D7C001F5E49 /* FLEXMultiColumnTableView.m */,
+				779B1EC41C0C4D7C001F5E49 /* FLEXTableColumnHeader.h */,
+				779B1EC51C0C4D7C001F5E49 /* FLEXTableColumnHeader.m */,
+				779B1EC61C0C4D7C001F5E49 /* FLEXTableContentCell.h */,
+				779B1EC71C0C4D7C001F5E49 /* FLEXTableContentCell.m */,
+				779B1EC81C0C4D7C001F5E49 /* FLEXTableContentViewController.h */,
+				779B1EC91C0C4D7C001F5E49 /* FLEXTableContentViewController.m */,
+				779B1ECA1C0C4D7C001F5E49 /* FLEXTableLeftCell.h */,
+				779B1ECB1C0C4D7C001F5E49 /* FLEXTableLeftCell.m */,
+				779B1ECC1C0C4D7C001F5E49 /* FLEXTableListViewController.h */,
+				779B1ECD1C0C4D7C001F5E49 /* FLEXTableListViewController.m */,
+			);
+			path = DatabaseBrowser;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 /* End PBXGroup section */
 
 
 /* Begin PBXHeadersBuildPhase section */
 /* Begin PBXHeadersBuildPhase section */
@@ -561,12 +615,14 @@
 			isa = PBXHeadersBuildPhase;
 			isa = PBXHeadersBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
+				779B1EDA1C0C4D7C001F5E49 /* FLEXTableListViewController.h in Headers */,
 				3A4C94ED1B5B21410088C3F2 /* FLEXArgumentInputColorView.h in Headers */,
 				3A4C94ED1B5B21410088C3F2 /* FLEXArgumentInputColorView.h in Headers */,
 				3A4C94EB1B5B21410088C3F2 /* FLEXImagePreviewViewController.h in Headers */,
 				3A4C94EB1B5B21410088C3F2 /* FLEXImagePreviewViewController.h in Headers */,
 				3A4C95381B5B21410088C3F2 /* FLEXNetworkRecorder.h in Headers */,
 				3A4C95381B5B21410088C3F2 /* FLEXNetworkRecorder.h in Headers */,
 				3A4C94251B5B20570088C3F2 /* FLEX.h in Headers */,
 				3A4C94251B5B20570088C3F2 /* FLEX.h in Headers */,
 				3A4C95051B5B21410088C3F2 /* FLEXArgumentInputViewFactory.h in Headers */,
 				3A4C95051B5B21410088C3F2 /* FLEXArgumentInputViewFactory.h in Headers */,
 				3A4C951E1B5B21410088C3F2 /* FLEXClassesTableViewController.h in Headers */,
 				3A4C951E1B5B21410088C3F2 /* FLEXClassesTableViewController.h in Headers */,
+				779B1ED21C0C4D7C001F5E49 /* FLEXTableColumnHeader.h in Headers */,
 				3A4C94FD1B5B21410088C3F2 /* FLEXArgumentInputStructView.h in Headers */,
 				3A4C94FD1B5B21410088C3F2 /* FLEXArgumentInputStructView.h in Headers */,
 				3A4C95201B5B21410088C3F2 /* FLEXFileBrowserFileOperationController.h in Headers */,
 				3A4C95201B5B21410088C3F2 /* FLEXFileBrowserFileOperationController.h in Headers */,
 				3A4C953E1B5B21410088C3F2 /* FLEXNetworkTransactionDetailTableViewController.h in Headers */,
 				3A4C953E1B5B21410088C3F2 /* FLEXNetworkTransactionDetailTableViewController.h in Headers */,
@@ -580,6 +636,7 @@
 				3A4C94DF1B5B21410088C3F2 /* FLEXMultilineTableViewCell.h in Headers */,
 				3A4C94DF1B5B21410088C3F2 /* FLEXMultilineTableViewCell.h in Headers */,
 				3A4C953A1B5B21410088C3F2 /* FLEXNetworkSettingsTableViewController.h in Headers */,
 				3A4C953A1B5B21410088C3F2 /* FLEXNetworkSettingsTableViewController.h in Headers */,
 				3A4C94D11B5B21410088C3F2 /* FLEXLayerExplorerViewController.h in Headers */,
 				3A4C94D11B5B21410088C3F2 /* FLEXLayerExplorerViewController.h in Headers */,
+				779B1ED01C0C4D7C001F5E49 /* FLEXMultiColumnTableView.h in Headers */,
 				3A4C94D31B5B21410088C3F2 /* FLEXObjectExplorerFactory.h in Headers */,
 				3A4C94D31B5B21410088C3F2 /* FLEXObjectExplorerFactory.h in Headers */,
 				3A4C94E31B5B21410088C3F2 /* FLEXRuntimeUtility.h in Headers */,
 				3A4C94E31B5B21410088C3F2 /* FLEXRuntimeUtility.h in Headers */,
 				3A4C95341B5B21410088C3F2 /* FLEXSystemLogTableViewController.h in Headers */,
 				3A4C95341B5B21410088C3F2 /* FLEXSystemLogTableViewController.h in Headers */,
@@ -591,6 +648,7 @@
 				3A4C950F1B5B21410088C3F2 /* FLEXMethodCallingViewController.h in Headers */,
 				3A4C950F1B5B21410088C3F2 /* FLEXMethodCallingViewController.h in Headers */,
 				3A4C94F51B5B21410088C3F2 /* FLEXArgumentInputJSONObjectView.h in Headers */,
 				3A4C94F51B5B21410088C3F2 /* FLEXArgumentInputJSONObjectView.h in Headers */,
 				3A4C94F11B5B21410088C3F2 /* FLEXArgumentInputFontsPickerView.h in Headers */,
 				3A4C94F11B5B21410088C3F2 /* FLEXArgumentInputFontsPickerView.h in Headers */,
+				779B1ED61C0C4D7C001F5E49 /* FLEXTableContentViewController.h in Headers */,
 				3A4C94C91B5B21410088C3F2 /* FLEXDefaultsExplorerViewController.h in Headers */,
 				3A4C94C91B5B21410088C3F2 /* FLEXDefaultsExplorerViewController.h in Headers */,
 				3A4C95221B5B21410088C3F2 /* FLEXFileBrowserSearchOperation.h in Headers */,
 				3A4C95221B5B21410088C3F2 /* FLEXFileBrowserSearchOperation.h in Headers */,
 				3A4C94FF1B5B21410088C3F2 /* FLEXArgumentInputSwitchView.h in Headers */,
 				3A4C94FF1B5B21410088C3F2 /* FLEXArgumentInputSwitchView.h in Headers */,
@@ -601,9 +659,11 @@
 				3A4C94C51B5B21410088C3F2 /* FLEXArrayExplorerViewController.h in Headers */,
 				3A4C94C51B5B21410088C3F2 /* FLEXArrayExplorerViewController.h in Headers */,
 				3A4C94CB1B5B21410088C3F2 /* FLEXDictionaryExplorerViewController.h in Headers */,
 				3A4C94CB1B5B21410088C3F2 /* FLEXDictionaryExplorerViewController.h in Headers */,
 				3A4C95071B5B21410088C3F2 /* FLEXDefaultEditorViewController.h in Headers */,
 				3A4C95071B5B21410088C3F2 /* FLEXDefaultEditorViewController.h in Headers */,
+				779B1ECE1C0C4D7C001F5E49 /* FLEXDatabaseManager.h in Headers */,
 				3A4C94D51B5B21410088C3F2 /* FLEXObjectExplorerViewController.h in Headers */,
 				3A4C94D51B5B21410088C3F2 /* FLEXObjectExplorerViewController.h in Headers */,
 				3A4C95011B5B21410088C3F2 /* FLEXArgumentInputTextView.h in Headers */,
 				3A4C95011B5B21410088C3F2 /* FLEXArgumentInputTextView.h in Headers */,
 				3A4C952A1B5B21410088C3F2 /* FLEXLibrariesTableViewController.h in Headers */,
 				3A4C952A1B5B21410088C3F2 /* FLEXLibrariesTableViewController.h in Headers */,
+				779B1ED41C0C4D7C001F5E49 /* FLEXTableContentCell.h in Headers */,
 				3A4C952C1B5B21410088C3F2 /* FLEXLiveObjectsTableViewController.h in Headers */,
 				3A4C952C1B5B21410088C3F2 /* FLEXLiveObjectsTableViewController.h in Headers */,
 				3A4C94EF1B5B21410088C3F2 /* FLEXArgumentInputDateView.h in Headers */,
 				3A4C94EF1B5B21410088C3F2 /* FLEXArgumentInputDateView.h in Headers */,
 				3A4C94C71B5B21410088C3F2 /* FLEXClassExplorerViewController.h in Headers */,
 				3A4C94C71B5B21410088C3F2 /* FLEXClassExplorerViewController.h in Headers */,
@@ -629,6 +689,7 @@
 				94AAF0381BAF2E1F00DE8760 /* FLEXKeyboardHelpViewController.h in Headers */,
 				94AAF0381BAF2E1F00DE8760 /* FLEXKeyboardHelpViewController.h in Headers */,
 				94AAF03A1BAF2F0300DE8760 /* FLEXKeyboardShortcutManager.h in Headers */,
 				94AAF03A1BAF2F0300DE8760 /* FLEXKeyboardShortcutManager.h in Headers */,
 				3A4C94E11B5B21410088C3F2 /* FLEXResources.h in Headers */,
 				3A4C94E11B5B21410088C3F2 /* FLEXResources.h in Headers */,
+				779B1ED81C0C4D7C001F5E49 /* FLEXTableLeftCell.h in Headers */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
@@ -712,6 +773,7 @@
 				3A4C951F1B5B21410088C3F2 /* FLEXClassesTableViewController.m in Sources */,
 				3A4C951F1B5B21410088C3F2 /* FLEXClassesTableViewController.m in Sources */,
 				3A4C94C61B5B21410088C3F2 /* FLEXArrayExplorerViewController.m in Sources */,
 				3A4C94C61B5B21410088C3F2 /* FLEXArrayExplorerViewController.m in Sources */,
 				3A4C95081B5B21410088C3F2 /* FLEXDefaultEditorViewController.m in Sources */,
 				3A4C95081B5B21410088C3F2 /* FLEXDefaultEditorViewController.m in Sources */,
+				779B1ED11C0C4D7C001F5E49 /* FLEXMultiColumnTableView.m in Sources */,
 				3A4C94EE1B5B21410088C3F2 /* FLEXArgumentInputColorView.m in Sources */,
 				3A4C94EE1B5B21410088C3F2 /* FLEXArgumentInputColorView.m in Sources */,
 				3A4C94F01B5B21410088C3F2 /* FLEXArgumentInputDateView.m in Sources */,
 				3A4C94F01B5B21410088C3F2 /* FLEXArgumentInputDateView.m in Sources */,
 				3A4C94CA1B5B21410088C3F2 /* FLEXDefaultsExplorerViewController.m in Sources */,
 				3A4C94CA1B5B21410088C3F2 /* FLEXDefaultsExplorerViewController.m in Sources */,
@@ -722,6 +784,7 @@
 				3A4C94E01B5B21410088C3F2 /* FLEXMultilineTableViewCell.m in Sources */,
 				3A4C94E01B5B21410088C3F2 /* FLEXMultilineTableViewCell.m in Sources */,
 				3A4C95431B5B21410088C3F2 /* FLEXNetworkObserver.m in Sources */,
 				3A4C95431B5B21410088C3F2 /* FLEXNetworkObserver.m in Sources */,
 				3A4C94D21B5B21410088C3F2 /* FLEXLayerExplorerViewController.m in Sources */,
 				3A4C94D21B5B21410088C3F2 /* FLEXLayerExplorerViewController.m in Sources */,
+				779B1EDB1C0C4D7C001F5E49 /* FLEXTableListViewController.m in Sources */,
 				3A4C94E41B5B21410088C3F2 /* FLEXRuntimeUtility.m in Sources */,
 				3A4C94E41B5B21410088C3F2 /* FLEXRuntimeUtility.m in Sources */,
 				3A4C94D41B5B21410088C3F2 /* FLEXObjectExplorerFactory.m in Sources */,
 				3A4C94D41B5B21410088C3F2 /* FLEXObjectExplorerFactory.m in Sources */,
 				3A4C952F1B5B21410088C3F2 /* FLEXWebViewController.m in Sources */,
 				3A4C952F1B5B21410088C3F2 /* FLEXWebViewController.m in Sources */,
@@ -734,6 +797,7 @@
 				3A4C94DE1B5B21410088C3F2 /* FLEXHeapEnumerator.m in Sources */,
 				3A4C94DE1B5B21410088C3F2 /* FLEXHeapEnumerator.m in Sources */,
 				3A4C95251B5B21410088C3F2 /* FLEXFileBrowserTableViewController.m in Sources */,
 				3A4C95251B5B21410088C3F2 /* FLEXFileBrowserTableViewController.m in Sources */,
 				3A4C94DA1B5B21410088C3F2 /* FLEXViewControllerExplorerViewController.m in Sources */,
 				3A4C94DA1B5B21410088C3F2 /* FLEXViewControllerExplorerViewController.m in Sources */,
+				779B1ED51C0C4D7C001F5E49 /* FLEXTableContentCell.m in Sources */,
 				3A4C94E21B5B21410088C3F2 /* FLEXResources.m in Sources */,
 				3A4C94E21B5B21410088C3F2 /* FLEXResources.m in Sources */,
 				3A4C94D81B5B21410088C3F2 /* FLEXSetExplorerViewController.m in Sources */,
 				3A4C94D81B5B21410088C3F2 /* FLEXSetExplorerViewController.m in Sources */,
 				3A4C95311B5B21410088C3F2 /* FLEXSystemLogMessage.m in Sources */,
 				3A4C95311B5B21410088C3F2 /* FLEXSystemLogMessage.m in Sources */,
@@ -744,14 +808,18 @@
 				3A4C95351B5B21410088C3F2 /* FLEXSystemLogTableViewController.m in Sources */,
 				3A4C95351B5B21410088C3F2 /* FLEXSystemLogTableViewController.m in Sources */,
 				3A4C95271B5B21410088C3F2 /* FLEXGlobalsTableViewController.m in Sources */,
 				3A4C95271B5B21410088C3F2 /* FLEXGlobalsTableViewController.m in Sources */,
 				3A4C95161B5B21410088C3F2 /* FLEXExplorerViewController.m in Sources */,
 				3A4C95161B5B21410088C3F2 /* FLEXExplorerViewController.m in Sources */,
+				779B1ED31C0C4D7C001F5E49 /* FLEXTableColumnHeader.m in Sources */,
 				3A4C94EA1B5B21410088C3F2 /* FLEXHierarchyTableViewController.m in Sources */,
 				3A4C94EA1B5B21410088C3F2 /* FLEXHierarchyTableViewController.m in Sources */,
 				3A4C95331B5B21410088C3F2 /* FLEXSystemLogTableViewCell.m in Sources */,
 				3A4C95331B5B21410088C3F2 /* FLEXSystemLogTableViewCell.m in Sources */,
 				3A4C95191B5B21410088C3F2 /* FLEXManager.m in Sources */,
 				3A4C95191B5B21410088C3F2 /* FLEXManager.m in Sources */,
 				3A4C95021B5B21410088C3F2 /* FLEXArgumentInputTextView.m in Sources */,
 				3A4C95021B5B21410088C3F2 /* FLEXArgumentInputTextView.m in Sources */,
 				3A4C94FA1B5B21410088C3F2 /* FLEXArgumentInputNumberView.m in Sources */,
 				3A4C94FA1B5B21410088C3F2 /* FLEXArgumentInputNumberView.m in Sources */,
+				779B1ED71C0C4D7C001F5E49 /* FLEXTableContentViewController.m in Sources */,
 				3A4C95001B5B21410088C3F2 /* FLEXArgumentInputSwitchView.m in Sources */,
 				3A4C95001B5B21410088C3F2 /* FLEXArgumentInputSwitchView.m in Sources */,
 				3A4C94CC1B5B21410088C3F2 /* FLEXDictionaryExplorerViewController.m in Sources */,
 				3A4C94CC1B5B21410088C3F2 /* FLEXDictionaryExplorerViewController.m in Sources */,
 				3A4C953F1B5B21410088C3F2 /* FLEXNetworkTransactionDetailTableViewController.m in Sources */,
 				3A4C953F1B5B21410088C3F2 /* FLEXNetworkTransactionDetailTableViewController.m in Sources */,
+				779B1ED91C0C4D7C001F5E49 /* FLEXTableLeftCell.m in Sources */,
+				779B1ECF1C0C4D7C001F5E49 /* FLEXDatabaseManager.m in Sources */,
 				3A4C94E61B5B21410088C3F2 /* FLEXUtility.m in Sources */,
 				3A4C94E61B5B21410088C3F2 /* FLEXUtility.m in Sources */,
 				3A4C95231B5B21410088C3F2 /* FLEXFileBrowserSearchOperation.m in Sources */,
 				3A4C95231B5B21410088C3F2 /* FLEXFileBrowserSearchOperation.m in Sources */,
 				3A4C950C1B5B21410088C3F2 /* FLEXFieldEditorViewController.m in Sources */,
 				3A4C950C1B5B21410088C3F2 /* FLEXFieldEditorViewController.m in Sources */,