PageRenderTime 41ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/rhoconnect-client/ObjectiveC/RhoConnectClient.m

https://gitlab.com/gaurav1981/rhoconnect-client
Objective C | 640 lines | 502 code | 125 blank | 13 comment | 38 complexity | ac699963e1a20c87017cf429573d67ff MD5 | raw file
Possible License(s): MIT, BSD-3-Clause
  1. //
  2. // RhoConnectClient.m
  3. // RhoCoonectClientTest
  4. //
  5. // Created by evgeny vovchenko on 8/23/10.
  6. // Copyright 2010 RhoMobile. All rights reserved.
  7. //
  8. #import "RhoConnectClient.h"
  9. #include "sync/SyncThread.h"
  10. #include "common/RhoConf.h"
  11. #import "common/RhodesAppBase.h"
  12. #include "logging/RhoLogConf.h"
  13. #import "logging/RhoLog.h"
  14. #undef DEFAULT_LOGCATEGORY
  15. #define DEFAULT_LOGCATEGORY "RhoConnectClient"
  16. @interface CCallbackData : NSObject {
  17. }
  18. @property(assign) NSThread *targetThread;
  19. @property SEL targetMethod;
  20. @property(assign) id targetObject;
  21. - (id)init:(SEL)selector target:(id)target thread:(NSThread *)thread;
  22. @end
  23. @implementation CCallbackData
  24. @synthesize targetThread;
  25. @synthesize targetMethod;
  26. @synthesize targetObject;
  27. - (id)init:(SEL)selector target:(id)target thread:(NSThread *)thread
  28. {
  29. self = [super init];
  30. targetMethod = selector;
  31. targetObject = target;
  32. targetThread = thread;
  33. return self;
  34. }
  35. @end
  36. int callback_impl(const char *szNotify, void *data)
  37. {
  38. RHO_CONNECT_NOTIFY oNotify = { 0 };
  39. rho_connectclient_parsenotify(szNotify, &oNotify);
  40. RhoConnectNotify *notify = [[RhoConnectNotify alloc] init:&oNotify];
  41. CCallbackData *callbackObj = data;
  42. if (callbackObj.targetThread != [NSThread currentThread])
  43. {
  44. [ callbackObj.targetObject performSelector:callbackObj.targetMethod onThread:callbackObj.targetThread withObject:notify waitUntilDone:TRUE];
  45. }
  46. else
  47. {
  48. [ callbackObj.targetObject performSelector:callbackObj.targetMethod withObject:notify];
  49. }
  50. [callbackObj autorelease];
  51. [notify autorelease];
  52. return 0;
  53. }
  54. int callback_object_impl(const char *szNotify, void *data)
  55. {
  56. RHO_CONNECT_OBJECT_NOTIFY oNotify = { 0 };
  57. rho_connectclient_parse_objectnotify(szNotify, &oNotify);
  58. RhoConnectObjectNotify *notify = [[RhoConnectObjectNotify alloc] init:&oNotify];
  59. CCallbackData *callbackObj = data;
  60. if (callbackObj.targetThread != [NSThread currentThread])
  61. {
  62. [ callbackObj.targetObject performSelector:callbackObj.targetMethod onThread:callbackObj.targetThread withObject:notify waitUntilDone:TRUE];
  63. }
  64. else
  65. {
  66. [ callbackObj.targetObject performSelector:callbackObj.targetMethod withObject:notify];
  67. }
  68. [callbackObj autorelease];
  69. [notify autorelease];
  70. return 0;
  71. }
  72. int callback_send_log_impl(const char *szNotify, void *data)
  73. {
  74. return 0;
  75. }
  76. void rho_free_callbackdata(void *pData)
  77. {
  78. // CCallbackData* callbackObj = pData;
  79. // [callbackObj release];
  80. }
  81. @implementation RhoConnectClient
  82. @synthesize threaded_mode;
  83. @synthesize poll_interval;
  84. @synthesize log_severity;
  85. @synthesize sync_server;
  86. @synthesize bulksync_state;
  87. @synthesize log_server;
  88. @synthesize log_name;
  89. - (id)init
  90. {
  91. self = [super init];
  92. // initRhoconnectClient();
  93. return self;
  94. }
  95. - (void)dealloc
  96. {
  97. rho_connectclient_destroy();
  98. [sync_server release];
  99. [log_server release];
  100. [log_name release];
  101. [super dealloc];
  102. }
  103. - (void)setSyncServer:(NSString *)server
  104. {
  105. sync_server = [server retain];
  106. rho_sync_set_syncserver([server cStringUsingEncoding:[NSString defaultCStringEncoding]]);
  107. }
  108. - (void)setThreadedMode:(BOOL)mode
  109. {
  110. threaded_mode = mode;
  111. rho_sync_set_threaded_mode(mode ? 1 : 0);
  112. }
  113. - (void)setPollInterval:(int)interval
  114. {
  115. poll_interval = interval;
  116. rho_sync_set_pollinterval(interval);
  117. }
  118. - (void)setLogSeverity:(int)severity
  119. {
  120. log_severity = severity;
  121. rho_logconf_setSeverity(log_severity);
  122. }
  123. - (void)setBulkSyncState:(int)state
  124. {
  125. rho_conf_setInt("bulksync_state", state);
  126. }
  127. - (int)getBulkSyncState
  128. {
  129. return rho_conf_getInt("bulksync_state");
  130. }
  131. - (void)setConfigString:(NSString *)name param:(NSString *)param
  132. {
  133. if ([name compare:@"MinSeverity"] == 0)
  134. {
  135. rho_logconf_setSeverity([param intValue]);
  136. }
  137. else
  138. {
  139. rho_conf_setString([name cStringUsingEncoding:[NSString defaultCStringEncoding]],
  140. [param cStringUsingEncoding:[NSString defaultCStringEncoding]]);
  141. }
  142. }
  143. - (NSString *)getConfigString:(NSString *)name
  144. {
  145. NSString *ret;
  146. char *res = rho_conf_getString([name cStringUsingEncoding:[NSString defaultCStringEncoding]]);
  147. if (res)
  148. {
  149. ret = [NSString stringWithUTF8String:res];
  150. rho_conf_freeString(res);
  151. }
  152. else
  153. {
  154. ret = [NSString stringWithUTF8String:""];
  155. }
  156. return ret;
  157. }
  158. - (void)setLogServer:(NSString *)server
  159. {
  160. log_server = [server retain];
  161. rho_conf_setString("logserver", [ log_server cStringUsingEncoding:[ NSString defaultCStringEncoding ]]);
  162. }
  163. - (void)setLogName:(NSString *)name
  164. {
  165. log_name = [name retain];
  166. rho_conf_setString("logname", [ log_name cStringUsingEncoding:[ NSString defaultCStringEncoding ]]);
  167. }
  168. - (void)addModels:(NSMutableArray *)models
  169. {
  170. RHOM_MODEL rhom_models[models.count];
  171. int nModel = 0;
  172. for (RhomModel *model in models)
  173. {
  174. rho_connectclient_initmodel(&rhom_models[nModel]);
  175. rhom_models[nModel].name = [model.name cStringUsingEncoding:[NSString defaultCStringEncoding]];
  176. rhom_models[nModel].partition = [model.partition cStringUsingEncoding:[NSString defaultCStringEncoding]];
  177. rhom_models[nModel].sync_type = model.sync_type;
  178. rhom_models[nModel].type = model.model_type;
  179. if (model.associations != NULL)
  180. {
  181. for (NSString *key in model.associations)
  182. {
  183. rho_connectclient_hash_put(rhom_models[nModel].associations,
  184. [key cStringUsingEncoding:[NSString defaultCStringEncoding]],
  185. [[model.associations objectForKey:key] cStringUsingEncoding:[NSString defaultCStringEncoding]]
  186. );
  187. }
  188. }
  189. if (0 < [model.blob_attribs length])
  190. {
  191. rhom_models[nModel].blob_attribs = [model.blob_attribs cStringUsingEncoding:[NSString defaultCStringEncoding]];
  192. }
  193. nModel++;
  194. }
  195. rho_connectclient_init(rhom_models, models.count);
  196. int i = 0;
  197. for (RhomModel *model in models)
  198. {
  199. model.source_id = rhom_models[i].source_id;
  200. rho_connectclient_destroymodel(&rhom_models[i]);
  201. i++;
  202. }
  203. [self setThreadedMode:FALSE];
  204. [self setPollInterval:0];
  205. }
  206. - (void)updateModels:(NSMutableArray *)models
  207. {
  208. RHOM_MODEL rhom_models[models.count];
  209. int nModel = 0;
  210. for (RhomModel *model in models)
  211. {
  212. rho_connectclient_initmodel(&rhom_models[nModel]);
  213. rhom_models[nModel].name = [model.name cStringUsingEncoding:[NSString defaultCStringEncoding]];
  214. rhom_models[nModel].sync_type = model.sync_type;
  215. rhom_models[nModel].type = model.model_type;
  216. nModel++;
  217. }
  218. rho_connectclient_updatemodels(rhom_models, models.count);
  219. int i = 0;
  220. for (RhomModel *model in models)
  221. {
  222. model.source_id = rhom_models[i].source_id;
  223. rho_connectclient_destroymodel(&rhom_models[i]);
  224. i++;
  225. }
  226. }
  227. - (void)setSourceProperty:(int)nSrcID szPropName:(NSString *)szPropName szPropValue:(NSString *)szPropValue
  228. {
  229. rho_sync_set_source_property(nSrcID, [szPropName cStringUsingEncoding:[NSString defaultCStringEncoding]],
  230. [szPropValue cStringUsingEncoding:[NSString defaultCStringEncoding]]);
  231. }
  232. - (void)database_full_reset_and_logout
  233. {
  234. rho_connectclient_database_full_reset_and_logout();
  235. }
  236. - (void)database_client_reset
  237. {
  238. rho_connectclient_database_client_reset();
  239. }
  240. - (NSString *)database_export:(NSString *)partition
  241. {
  242. NSString *ret;
  243. char *res = rho_connectclient_database_export([partition cStringUsingEncoding:[NSString defaultCStringEncoding]]);
  244. if (res != 0)
  245. {
  246. ret = [NSString stringWithUTF8String:res];
  247. free(res);
  248. }
  249. else
  250. {
  251. ret = [NSString stringWithUTF8String:""];
  252. }
  253. return ret;
  254. }
  255. - (BOOL)database_import:(NSString *)partition zip:(NSString *)zip
  256. {
  257. int res = rho_connectclient_database_import([partition cStringUsingEncoding:[NSString defaultCStringEncoding]], [zip cStringUsingEncoding:[NSString defaultCStringEncoding]]);
  258. return res == 0 ? FALSE : TRUE;
  259. }
  260. - (BOOL)is_logged_in
  261. {
  262. return rho_sync_logged_in() == 1 ? TRUE : FALSE;
  263. }
  264. - (RhoConnectNotify *)loginWithUser:(NSString *)user pwd:(NSString *)pwd
  265. {
  266. char *res = (char *)rho_sync_login_c([user cStringUsingEncoding:[NSString defaultCStringEncoding]],
  267. [pwd cStringUsingEncoding:[NSString defaultCStringEncoding]], NULL, NULL);
  268. RHO_CONNECT_NOTIFY oNotify = { 0 };
  269. rho_connectclient_parsenotify(res, &oNotify);
  270. rho_sync_free_string(res);
  271. return [[[RhoConnectNotify alloc] init:&oNotify] autorelease];
  272. }
  273. - (void)loginWithUser:(NSString *)user pwd:(NSString *)pwd callback:(SEL)callback target:(id)target
  274. {
  275. rho_sync_login_c([user cStringUsingEncoding:NSUTF8StringEncoding],
  276. [pwd cStringUsingEncoding:NSUTF8StringEncoding],
  277. callback_impl, [[CCallbackData alloc] init:callback target:target thread:[NSThread currentThread]]
  278. );
  279. }
  280. - (void)logout
  281. {
  282. rho_sync_logout();
  283. }
  284. + (void)setNotification:(SEL)callback target:(id)target
  285. {
  286. rho_sync_set_notification_c(-1, callback_impl,
  287. [[CCallbackData alloc] init:callback target:target thread:[NSThread currentThread]]);
  288. }
  289. - (void)setNotification:(SEL)callback target:(id)target
  290. {
  291. rho_sync_set_notification_c(-1, callback_impl,
  292. [[CCallbackData alloc] init:callback target:target thread:[NSThread currentThread]]);
  293. }
  294. + (void)setModelNotification:(int)nSrcID callback:(SEL)callback target:(id)target
  295. {
  296. rho_sync_set_notification_c(nSrcID, callback_impl,
  297. [[CCallbackData alloc] init:callback target:target thread:[NSThread currentThread]]);
  298. }
  299. - (void)clearNotification
  300. {
  301. rho_sync_clear_notification(-1);
  302. }
  303. - (void)setObjectNotification:(SEL)callback target:(id)target
  304. {
  305. rho_sync_setobjectnotify_url_c(callback_object_impl,
  306. [[ CCallbackData alloc] init:callback target:target thread:[NSThread currentThread]]);
  307. }
  308. - (void)clearObjectNotification
  309. {
  310. rho_sync_clear_object_notification();
  311. }
  312. - (void)addObjectNotify:(int)nSrcID szObject:(NSString *)szObject
  313. {
  314. rho_sync_addobjectnotify(nSrcID, [szObject cStringUsingEncoding:[NSString defaultCStringEncoding]]);
  315. }
  316. - (RhoConnectNotify *)syncAll
  317. {
  318. char *res = (char *)rho_sync_doSyncAllSources(0, "", false);
  319. RHO_CONNECT_NOTIFY oNotify = { 0 };
  320. rho_connectclient_parsenotify(res, &oNotify);
  321. rho_sync_free_string(res);
  322. return [[[RhoConnectNotify alloc] init:&oNotify] autorelease];
  323. }
  324. - (BOOL)is_syncing
  325. {
  326. return rho_sync_issyncing() == 1 ? TRUE : FALSE;
  327. }
  328. - (void)stop_sync
  329. {
  330. rho_sync_stop();
  331. }
  332. - (RhoConnectNotify *)search:(NSArray *)models from:(NSString *)from params:(NSString *)params sync_changes:(BOOL)sync_changes progress_step:(int)progress_step
  333. {
  334. unsigned long ar_sources = rho_connectclient_strarray_create();
  335. for (RhomModel *model in models)
  336. {
  337. rho_connectclient_strarray_add(ar_sources, [model.name cStringUsingEncoding:[NSString defaultCStringEncoding]]);
  338. }
  339. char *res = (char *)rho_sync_doSearchByNames(ar_sources,
  340. [from cStringUsingEncoding:[NSString defaultCStringEncoding]],
  341. [params cStringUsingEncoding:[NSString defaultCStringEncoding]],
  342. sync_changes ? 1 : 0,
  343. progress_step, "", "");
  344. rho_connectclient_strarray_delete(ar_sources);
  345. RHO_CONNECT_NOTIFY oNotify = { 0 };
  346. rho_connectclient_parsenotify(res, &oNotify);
  347. rho_sync_free_string(res);
  348. return [[[RhoConnectNotify alloc] init:&oNotify] autorelease];
  349. }
  350. - (void)onCreateError:(RhoConnectNotify *)notify action:(NSString *)action
  351. {
  352. rho_connectclient_on_sync_create_error(
  353. [notify.source_name cStringUsingEncoding:[NSString defaultCStringEncoding]],
  354. [notify getNotifyPtr],
  355. [action cStringUsingEncoding:[NSString defaultCStringEncoding]]
  356. );
  357. }
  358. - (void)onUpdateError:(RhoConnectNotify *)notify action:(NSString *)action
  359. {
  360. rho_connectclient_on_sync_update_error(
  361. [notify.source_name cStringUsingEncoding:[NSString defaultCStringEncoding]],
  362. [notify getNotifyPtr],
  363. [action cStringUsingEncoding:[NSString defaultCStringEncoding]]
  364. );
  365. }
  366. - (void)onDeleteError:(RhoConnectNotify *)notify action:(NSString *)action
  367. {
  368. rho_connectclient_on_sync_delete_error(
  369. [notify.source_name cStringUsingEncoding:[NSString defaultCStringEncoding]],
  370. [notify getNotifyPtr],
  371. [action cStringUsingEncoding:[NSString defaultCStringEncoding]]
  372. );
  373. }
  374. - (void)sendLog
  375. {
  376. rho_conf_send_log_in_same_thread();
  377. }
  378. void copyFromMainBundle(NSFileManager *fileManager, NSString *source, NSString *target, BOOL remove);
  379. void createFolder(NSFileManager *fileManager, NSString *target, BOOL remove);
  380. const char * rho_native_rhopath();
  381. + (void)initDatabase
  382. {
  383. NSFileManager *fileManager = [NSFileManager defaultManager];
  384. NSString *bundleRoot = [[NSBundle mainBundle] resourcePath];
  385. NSString *rhoRoot = [NSString stringWithUTF8String:rho_native_rhopath()];
  386. NSString *dirs[] = { @"db" };
  387. copyFromMainBundle(fileManager,
  388. [bundleRoot stringByAppendingPathComponent:dirs[0]],
  389. [rhoRoot stringByAppendingPathComponent:dirs[0]],
  390. NO);
  391. createFolder(fileManager, [self blobPath], NO);
  392. }
  393. + (NSString *)storagePath
  394. {
  395. return [NSString stringWithUTF8String:rho_native_rhopath()];
  396. }
  397. + (NSString *)pathForStorageFile:(NSString *)file
  398. {
  399. return [[self storagePath] stringByAppendingString:file];
  400. }
  401. + (NSString *)blobFolder
  402. {
  403. return @"db/db-files/";
  404. }
  405. + (NSString *)blobPath
  406. {
  407. return [[self storagePath] stringByAppendingString:[self blobFolder]];
  408. }
  409. + (NSString *)pathForBlob:(NSString *)uri
  410. {
  411. return [[self storagePath] stringByAppendingString:uri];
  412. }
  413. + (void)fromMainBundle:(NSFileManager *)fileManager copyFile:(NSString *)source toStorage:(NSString *)target forceRemove:(BOOL)remove
  414. {
  415. NSString *bundleRoot = [[NSBundle mainBundle] resourcePath];
  416. copyFromMainBundle(fileManager, [bundleRoot stringByAppendingPathComponent:source], [self pathForStorageFile:target], remove);
  417. }
  418. @end
  419. const char * rho_native_rhopath()
  420. {
  421. static bool loaded = FALSE;
  422. static char root[FILENAME_MAX];
  423. if (!loaded)
  424. {
  425. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  426. NSString *documentsDirectory = // [paths objectAtIndex:0];
  427. [ [paths objectAtIndex:0] stringByAppendingString:@"/"];
  428. [documentsDirectory getFileSystemRepresentation:root maxLength:sizeof(root)];
  429. loaded = TRUE;
  430. }
  431. return root;
  432. }
  433. const char * rho_native_rhodbpath()
  434. {
  435. return rho_native_rhopath();
  436. }
  437. void copyFromMainBundle(NSFileManager *fileManager, NSString *source, NSString *target, BOOL remove)
  438. {
  439. BOOL dir;
  440. if (![fileManager fileExistsAtPath:source isDirectory:&dir])
  441. {
  442. // NSAssert1(0, @"Source item '%@' does not exists in bundle", source);
  443. return;
  444. }
  445. if (!remove && dir)
  446. {
  447. if (![fileManager fileExistsAtPath:target])
  448. {
  449. [fileManager createDirectoryAtPath:target attributes:nil];
  450. }
  451. NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtPath:source];
  452. NSString *child;
  453. while (nil != (child = [enumerator nextObject]))
  454. copyFromMainBundle(fileManager, [source stringByAppendingPathComponent:child],
  455. [target stringByAppendingPathComponent:child], NO);
  456. }
  457. else
  458. {
  459. NSError *error;
  460. if ([fileManager fileExistsAtPath:target] && ![fileManager removeItemAtPath:target error:&error])
  461. {
  462. // NSAssert2(0, @"Failed to remove '%@': %@", target, [error localizedDescription]);
  463. return;
  464. }
  465. if (![fileManager copyItemAtPath:source toPath:target error:&error])
  466. {
  467. // NSAssert3(0, @"Failed to copy '%@' to '%@': %@", source, target, [error localizedDescription]);
  468. return;
  469. }
  470. }
  471. }
  472. void createFolder(NSFileManager *fileManager, NSString *target, BOOL remove)
  473. {
  474. BOOL dir;
  475. [fileManager fileExistsAtPath:target isDirectory:&dir];
  476. if (!remove && dir)
  477. {
  478. return;
  479. }
  480. NSError *error;
  481. if (remove)
  482. {
  483. if (![fileManager removeItemAtPath:target error:&error])
  484. {
  485. return;
  486. }
  487. }
  488. if (![fileManager createDirectoryAtPath:target withIntermediateDirectories:YES attributes:nil error:&error])
  489. {
  490. return;
  491. }
  492. }
  493. int rho_net_ping_network(const char *szHost)
  494. {
  495. RAWLOG_INFO("PING network.");
  496. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  497. NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
  498. NSString *linkString = [NSString stringWithUTF8String:szHost];
  499. [request setURL:[NSURL URLWithString:linkString]];
  500. [request setTimeoutInterval:10];
  501. NSError *error = nil;
  502. NSHTTPURLResponse *response;
  503. NSData *returnData = NULL;
  504. returnData = [ NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error ];
  505. if (!returnData)
  506. {
  507. RAWLOG_ERROR2("PING network FAILED. NSError: %d. NSErrorInfo : %s", [error code], [[error localizedDescription] UTF8String]);
  508. }
  509. else
  510. {
  511. RAWLOG_INFO("PING network SUCCEEDED.");
  512. }
  513. [pool release];
  514. return returnData == NULL ? 0 : 1;
  515. }