PageRenderTime 336ms CodeModel.GetById 332ms app.highlight 1ms RepoModel.GetById 1ms app.codeStats 0ms

/ExportWindowController.mm

http://github.com/bububa/MongoHub-Mac
Objective C++ | 292 lines | 265 code | 17 blank | 10 comment | 47 complexity | e8400e700b12ebc2fb9c25688e08429d MD5 | raw file
  1//
  2//  ExportWindowController.m
  3//  MongoHub
  4//
  5//  Created by Syd on 10-6-22.
  6//  Copyright 2010 ThePeppersStudio.COM. All rights reserved.
  7//
  8
  9#import "ExportWindowController.h"
 10#import "Configure.h"
 11#import "DatabasesArrayController.h"
 12#import "Database.h"
 13#import "Connection.h"
 14#import "NSString+Extras.h"
 15#import "MongoDB.h"
 16#import <MCPKit_bundled/MCPKit_bundled.h>
 17#import "FieldMapTableController.h"
 18#import "FieldMapDataObject.h"
 19
 20@implementation ExportWindowController
 21
 22@synthesize dbname;
 23@synthesize conn;
 24@synthesize db;
 25@synthesize mongoDB;
 26@synthesize databasesArrayController;
 27@synthesize managedObjectContext;
 28@synthesize dbsArrayController;
 29@synthesize tablesArrayController;
 30@synthesize hostTextField;
 31@synthesize portTextField;
 32@synthesize userTextField;
 33@synthesize passwdTextField;
 34@synthesize collectionTextField;
 35@synthesize progressIndicator;
 36@synthesize tablesPopUpButton;
 37@synthesize fieldMapTableController;
 38
 39- (id)init {
 40    if (![super initWithWindowNibName:@"Export"]) return nil;
 41    return self;
 42}
 43
 44- (void)dealloc {
 45    [dbname release];
 46    [managedObjectContext release];
 47    [databasesArrayController release];
 48    [conn release];
 49    [db release];
 50    [mongoDB release];
 51    [dbsArrayController release];
 52    [tablesArrayController release];
 53    [hostTextField release];
 54    [portTextField release];
 55    [userTextField release];
 56    [passwdTextField release];
 57    [collectionTextField release];
 58    [progressIndicator release];
 59    [tablesPopUpButton release];
 60    [fieldMapTableController release];
 61    [super dealloc];
 62}
 63
 64- (void)windowDidLoad {
 65    //NSLog(@"New Connection Window Loaded");
 66    [super windowDidLoad];
 67}
 68
 69- (void)windowWillClose:(NSNotification *)notification {
 70    [[NSNotificationCenter defaultCenter] postNotificationName:kExportWindowWillClose object:dbname];
 71    dbname = nil;
 72    db = nil;
 73    [self initInterface];
 74}
 75
 76- (IBAction)export:(id)sender {
 77    [progressIndicator setUsesThreadedAnimation:YES];
 78    [progressIndicator startAnimation: self];
 79    [progressIndicator setDoubleValue:0];
 80    NSString *collection = [[NSString alloc] initWithString:[collectionTextField stringValue]];
 81    if (![collection isPresent]) {
 82        NSRunAlertPanel(@"Error", @"Collection name could not be empty!", @"OK", nil, nil);
 83        return;
 84    }
 85    NSString *tablename = [[NSString alloc] initWithString:[tablesPopUpButton titleOfSelectedItem]];
 86    
 87    NSString *user=nil;
 88    NSString *password=nil;
 89    Database *mongodb = [databasesArrayController dbInfo:conn name:dbname];
 90    if (mongodb) {
 91        user = mongodb.user;
 92        password = mongodb.password;
 93    }
 94    [mongodb release];
 95    long long int total = [self exportCount:collection user:user password:password];
 96    if (total == 0) {
 97        return;
 98    }
 99    NSString *query = [[NSString alloc] initWithFormat:@"select * from %@ limit 1", tablename];
100    MCPResult *theResult = [db queryString:query];
101    [query release];
102    NSDictionary *fieldTypes = [theResult fetchTypesAsDictionary];
103    
104    mongo::BSONObjBuilder fieldsBSONBuilder;
105    for(FieldMapDataObject *field in fieldMapTableController.nsMutaryDataObj)
106    {
107        fieldsBSONBuilder.append([field.mongoKey UTF8String], 1);
108    }
109    mongo::BSONObj fieldsBSONObj = fieldsBSONBuilder.obj();
110    std::auto_ptr<mongo::DBClientCursor> cursor = [mongoDB findAllCursorInDB:dbname collection:collection user:user password:password fields:fieldsBSONObj];
111    int i = 1;
112    while( cursor->more() )
113    {
114        mongo::BSONObj b = cursor->next();
115        [self doExportToTable:tablename data:b fieldTypes:fieldTypes];
116        [progressIndicator setDoubleValue:(double)i/total];
117        i ++;
118    }
119    [progressIndicator stopAnimation: self];
120    [tablename release];
121    [collection release];
122}
123
124- (long long int)exportCount:(NSString *)collection user:(NSString *)user password:(NSString *)password
125{
126    long long int result = [mongoDB countInDB:dbname collection:collection user:user password:password critical:nil];
127    return result;
128}
129
130- (void)doExportToTable:(NSString *)tableName data:(mongo::BSONObj) bsonObj fieldTypes:(NSDictionary *)fieldTypes
131{
132    int fieldsCount = [fieldMapTableController.nsMutaryDataObj count];
133    NSMutableArray *fields = [[NSMutableArray alloc] initWithCapacity:fieldsCount];
134    NSMutableArray *values = [[NSMutableArray alloc] initWithCapacity:fieldsCount];
135    for(FieldMapDataObject *field in fieldMapTableController.nsMutaryDataObj)
136    {
137        id value;
138        mongo::BSONElement e = bsonObj.getFieldDotted([field.mongoKey UTF8String]);
139        if (e.eoo() == true) {
140            continue;
141        }
142        if (e.type() == mongo::jstNULL) {
143            continue;
144        }else if (e.type() == mongo::Array) {
145            continue;
146        }else if (e.type() == mongo::Object) {
147            continue;
148        }else if (e.type() == mongo::Bool)  {
149            if (e.boolean()) {
150                value = [[NSString alloc] initWithString:@"1" ];
151            }else {
152                value = [[NSString alloc] initWithString:@"0"];
153            }
154        }else if (e.type() == mongo::NumberDouble) {
155            value = [[NSNumber alloc] initWithDouble: e.numberDouble()];
156        }else if (e.type() == mongo::NumberInt) {
157            NSString *ft = [fieldTypes objectForKey:field.sqlKey];
158            if ([ft isEqualToString:@"date"] || [ft isEqualToString:@"datetime"]) {
159                value = [[NSDate alloc] initWithTimeIntervalSince1970:e.numberInt()];
160            }else {
161                value = [[NSNumber alloc] initWithInt: e.numberInt()];
162            }
163        }else if (e.type() == mongo::Date) {
164            mongo::Date_t dt = (time_t)e.date();
165            time_t timestamp = dt / 1000;
166            value = [[NSDate alloc] initWithTimeIntervalSince1970:timestamp];
167        }else if (e.type() == mongo::Timestamp) {
168            time_t timestamp = (time_t)e.timestampTime();
169            value = [[NSDate alloc] initWithTimeIntervalSince1970:timestamp];
170        }else if (e.type() == mongo::BinData) {
171            int binlen;
172            const char* data = e.binData(binlen);
173            value = [[NSData alloc] initWithBytes:data length:binlen];
174        }else if (e.type() == mongo::NumberLong) {
175            NSString *ft = [fieldTypes objectForKey:field.sqlKey];
176            if ([ft isEqualToString:@"date"] || [ft isEqualToString:@"datetime"]) {
177                value = [[NSDate alloc] initWithTimeIntervalSince1970:e.numberLong()];
178            }else {
179                value = [[NSNumber alloc] initWithLong: e.numberLong()];
180            }
181        }else if ([field.mongoKey isEqualToString:@"_id" ]) {
182            if (e.type() == mongo::jstOID)
183            {
184                value = [[NSString alloc] initWithUTF8String: e.__oid().str().c_str()];
185            }else {
186                value = [[NSString alloc] initWithUTF8String: e.str().c_str()];
187            }
188        }else {
189            value = [[NSString alloc] initWithUTF8String:e.str().c_str()];
190        }
191        NSString *sqlKey = [[NSString alloc] initWithString:field.sqlKey];
192        NSString *quotedValue = [[NSString alloc] initWithString:[db quoteObject:value]];
193        [value release];
194        [fields addObject:sqlKey];
195        [values addObject:quotedValue];
196        [quotedValue release];
197        [sqlKey release];
198    }
199    if ([fields count] > 0) {
200        NSString *query = [[NSString alloc] initWithFormat:@"INSERT INTO %@ (%@) values (%@)", tableName, [fields componentsJoinedByString:@","], [values componentsJoinedByString:@","]];
201        //NSLog(@"query: %@", query);
202        [db queryString:query];
203        [query release];
204    }
205    [fields release];
206    [values release];
207}
208
209- (IBAction)connect:(id)sender {
210    if (db) {
211        [self initInterface];
212        [db release];
213    }
214    db = [[MCPConnection alloc] initToHost:[hostTextField stringValue] withLogin:[userTextField stringValue] password:[passwdTextField stringValue] usingPort:[portTextField intValue] ];
215    NSLog(@"Connect: %d", [db isConnected]);
216    if (![db isConnected])
217    {
218        NSRunAlertPanel(@"Error", @"Could not connect to the mysql server!", @"OK", nil, nil);
219    }
220    [db queryString:@"SET NAMES utf8"];
221    [db queryString:@"SET CHARACTER SET utf8"];
222    [db queryString:@"SET COLLATION_CONNECTION='utf8_general_ci'"];
223    [db setEncoding:NSUTF8StringEncoding];
224    MCPResult *dbs = [db listDBs];
225    NSArray *row;
226    NSMutableArray *databases = [[NSMutableArray alloc] initWithCapacity:[dbs numOfRows]];
227    while (row = [dbs fetchRowAsArray]) {
228        NSDictionary *database = [[NSDictionary alloc] initWithObjectsAndKeys:[row objectAtIndex:0], @"name", nil];
229        [databases addObject:database];
230        [database release];
231    }
232    [dbsArrayController setContent:databases];
233    [databases release];
234    //[self showTables:nil];
235}
236
237- (IBAction)showTables:(id)sender
238{
239    NSString *dbn;
240    if (sender == nil && [[dbsArrayController arrangedObjects] count] > 0) {
241        dbn = [[[dbsArrayController arrangedObjects] objectAtIndex:0] objectForKey:@"name"];
242    }else {
243        NSPopUpButton *pb = sender;
244        dbn = [[NSString alloc] initWithString:[pb titleOfSelectedItem]];
245    }
246    if (![dbn isPresent]) {
247        [dbn release];
248        return;
249    }
250    [db selectDB:dbn];
251    [dbn release];
252    MCPResult *tbs = [db listTables];
253    NSArray *row;
254    NSMutableArray *tables = [[NSMutableArray alloc] initWithCapacity:[tbs numOfRows]];
255    while (row = [tbs fetchRowAsArray]) {
256        NSDictionary *table = [[NSDictionary alloc] initWithObjectsAndKeys:[row objectAtIndex:0], @"name", nil];
257        [tables addObject:table];
258        [table release];
259    }
260    [tablesArrayController setContent:tables];
261    [tables release];
262    [self showFields:nil];
263}
264
265- (IBAction)showFields:(id)sender
266{
267    NSString *tablename = [[NSString alloc] initWithString:[tablesPopUpButton titleOfSelectedItem]];
268    MCPResult *theResult = [db queryString:[NSString stringWithFormat:@"select * from %@ limit 1", tablename]];
269    [tablename release];
270    NSArray *theFields = [theResult fetchFieldNames];
271    NSMutableArray *fields = [[NSMutableArray alloc] initWithCapacity:[theFields count] ];
272    for (int i=0; i<[theFields count]; i++) {
273        NSString *fieldName = [theFields objectAtIndex:i];
274        FieldMapDataObject *fd = [[FieldMapDataObject alloc] initWithSqlKey:fieldName andMongoKey:fieldName];
275        [fields addObject:fd];
276        [fd release];
277    }
278    [fieldMapTableController setNsMutaryDataObj:fields];
279    [fieldMapTableController.idTableView reloadData];
280    [fields release];
281}
282
283- (void)initInterface
284{
285    [dbsArrayController setContent:nil];
286    [tablesArrayController setContent:nil];
287    [progressIndicator setDoubleValue:0.0];
288    [fieldMapTableController.nsMutaryDataObj removeAllObjects];
289    [fieldMapTableController.idTableView reloadData];
290}
291
292@end