-
Notifications
You must be signed in to change notification settings - Fork 237
/
synchronization.txt
698 lines (523 loc) · 26.4 KB
/
synchronization.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
Synchronization with Rhodes
===
As we've shown in the [Rhom section](/rhodes/rhom), adding synchronized data via [RhoConnect](/rhoconnect/introduction) to your Rhodes application is as simple as generating a model and enabling a `:sync` flag. This triggers the internal Rhodes sync system called the **`SyncEngine`** to synchronize data for the model and transparently handle bi-directional updates between the Rhodes application and the RhoConnect server.
This section covers in detail how the `SyncEngine` works in Rhodes and how you can use its flexible APIs to build data-rich native applications.
## Sync Workflow
The `SyncEngine` interacts with RhoConnect over http(s) using [JSON](http://www.json.org/) as a data exchange format. With the exception of [bulk sync](/rhoconnect/bulk-sync), pages of synchronized data, or "sync pages" as we will refer to them here, are sent as JSON from RhoConnect to the `SyncEngine`.
Below is a simplified diagram of the `SyncEngine` workflow:
<a href="https://img.skitch.com/20110121-8qqyi7n2mg9fampmhcpqb5g9fi.png"><img height="80%" src="https://img.skitch.com/20110121-8qqyi7n2mg9fampmhcpqb5g9fi.png"/></a>
This workflow consists of the following steps:
* `SyncEngine` sends authentication request to RhoConnect via [`SyncEngine.login`](#syncengine-api). RhoConnect calls [`Application.authenticate`](/rhoconnect/authentication) with supplied credentials and returns `true` or `false`.
* If this is a new client (i.e. fresh install or reset), the `SyncEngine` will initialize with RhoConnect:
* It requests a new unique id (client id) from RhoConnect. This id will be referenced throughout the sync process.
* It will register platform information with RhoConnect. If this is a [push-enabled application](/rhodes/device-caps#push-notifications) application, the `SyncEngine` will send additional information like device push pin.
* `SyncEngine` requests sync pages from RhoConnect, one model(or [Rhom](/rhodes/rhom) model) at a time. The order the models are synchronized is determined by the model's [`:sync_priority`](/rhodes/rhom#property-bag), or determined automatically by the `SyncEngine`.
## Sync Authentication
When you generate a Rhodes application, you'll notice there is an included directory called `app/Settings`. This contains a default `settings_controller.rb` and some views to manage authentication with [RhoConnect](/rhoconnect/introduction).
### `login`
In `settings_controller.rb#do_login`, the `SyncEngine.login` method is called:
:::ruby
SyncEngine.login(
@params['login'],
@params['password'],
url_for(:action => :login_callback)
)
Here login is called with the `login` and `password` provided by the `login.erb` form. A `:login_callback` action is declared to handle the asynchronous result of the `SyncEngine.login` request.
### `login_callback`
When `SyncEngine.login` completes, the callback declared is executed and receives parameters including success or failure and error messages (if any).
:::ruby
def login_callback
error_code = @params['error_code'].to_i
if error_code == 0
# run sync if we were successful
WebView.navigate Rho::RhoConfig.options_path
SyncEngine.dosync
else
if error_code == Rho::RhoError::ERR_CUSTOMSYNCSERVER
@msg = @params['error_message']
end
if not @msg or @msg.length == 0
@msg = Rho::RhoError.new(error_code).message
end
WebView.navigate(
url_for(:action => :login, :query => {:msg => @msg})
)
end
end
This sample checks the login `error_code`, if it is `0`, perform a full sync and render the settings page. Otherwise, it sets up an error message and re-displays the login page with an error.
### `application.rb#on_sync_user_changed`
If the `SyncEngine` already knows about a logged-in user and a new user logs in, then the `on_sync_user_changed` hook is called (if it exists) before the `login_callback`. This is useful, for example, if you want to re-initialize personalized settings for a new user.
:::ruby
require 'rho/rhoapplication'
class AppApplication < Rho::RhoApplication
def initialize
super
end
def on_sync_user_changed
super
MyCoolApp.reset_user_preferences!
end
end
**NOTE: If `on_sync_user_changed`, data for all sync-enabled models will be removed. To remove data for all local models as well:**
:::ruby
def on_sync_user_changed
super
Rhom::Rhom.database_local_reset
end
Other auth-related methods are described in the [`SyncEngine` API section](/rhodes/synchronization#syncengine-api).
## Notifications
The `SyncEngine` system uses notifications to provide information about the sync process to a Rhodes application. Notifications can be setup once for the duration of runtime or each time a sync is triggered. One a sync is processing for a model, notifications are called with parameters containing sync process state. Your application can use this information to display different wait pages, progress bars, etc.
To set a notification for a model, you can use the following method:
:::ruby
SyncEngine.set_notification(
Account.get_source_id,
url_for(:action => :sync_notify),
"sync_complete=true"
)
Which is the same as:
:::ruby
Account.set_notification(
url_for(:action => :sync_notify),
"sync_complete=true"
)
In this example, once the sync process for the `Account` model is complete, the view will be directed to the `sync_notify` action (with params 'sync_complete=true') if user is on the same page.
**NOTE: In these examples, after the sync is complete the notifications are removed.**
You can also set a notification for all models:
:::ruby
SyncEngine.set_notification(
-1, url_for(:action => :sync_notify),
"sync_complete=true"
)
**NOTE: This notification will not be removed automatically.**
### Notification Parameters
When the notification is called, it will receive a variable called `@params`, just like a normal Rhodes controller action.
#### Common Parameters
These parameters are included in all notifications.
* `@params["source_id"]` - The id of the current model that is synchronizing.
* `@params["source_name"]` - Name of the model (i.e. "Product")
* `@params["sync_type"]` - Type of sync used for this model: "incremental" or "bulk"
* `@params["status"]` - Status of the current sync process: "in_progress", "error", "ok", "complete", "schema-changed"
#### "in_progress" - incremental sync
* `@params["total_count"]` - Total number of records that exist for this RhoConnect source.
* `@params["processed_count"]` - Number of records included in the sync page.
* `@params["cumulative_count"]` - Number of records the `SyncEngine` has processed so far for this source.
#### "in_progress" - bulk sync
* `@params["bulk_status"]` - The state of the bulk sync process:
"start": when bulk sync start and when specific partition is start syncing
"download": when client start downloading database from server
"change_db": when client start applying new database
"ok": when sync of partition finished without error
"complete": when bulk sync finished for all partitions without errors
* `@params["partition"]` - Current bulk sync partition.
#### "error"
* `@params["error_code"]` - HTTP response code of the RhoConnect server error: 401, 500, 404, etc.
* `@params["error_message"]` - Response body (if any)
* `@params["server_errors"]` - Hash of Type objects of RhoConnect adapter error (if exists): "login-error", "query-error", "create-error", "update-error", "delete-error", "logoff-error"
For "login-error", "query-error", "logoff-error": Type object is hash contains 'message' from server: @params["server_errors"]["query-error"]['message']
For "create-error", "update-error", "delete-error": Type object is hash each containing an "object" as a key (that failed to create) and a corresponding "message" and "attributes": @params["server_errors"]["create-error"][object]['message'], @params["server_errors"]["create-error"][object]['attributes']
**NOTE: "create-error" has to be handled in sync callback. Otherwise sync will stop on this model. To fix create errors you should call Model.on_sync_create_error or SyncEngine.on_sync_create_error**
#### "ok"
* `@params["total_count"]` - Total number of records that exist for this RhoConnect source.
* `@params["processed_count"]` - Number of records included in the last sync page.
* `@params["cumulative_count"]` - Number of records the `SyncEngine` has processed so far for this source.
#### "complete"
This status returns only when the `SyncEngine` process is complete.
#### "schema-changed"
This status returns for bulk-sync models that use [`FixedSchema`](/rhom#fixed-schema) when the schema has changed in the RhoConnect server.
**NOTE: In this scenario the sync callback should notify the user with a wait screen and start the bulk sync process.**
### Server error processing on client
#### create-error
has to be handled in sync callback. Otherwise sync will stop on this model. To fix create errors you should call Model.on_sync_create_error or SyncEngine.on_sync_create_error:
:::ruby
SyncEngine.on_sync_create_error( src_name, objects, action )
Model.on_sync_create_error( objects, action )
* objects - One or more error objects
* action - May be :delete or :recreate. :delete just remove object from client, :recreate will push this object to server again at next sync.
#### update-error
If not handled, local modifications, which were failing on server, will never sync to server again.
So sync will work fine, but nobody will know about these changes.
:::ruby
SyncEngine.on_sync_update_error( src_name, objects, action, rollback_objects = nil )
Model.on_sync_update_error( objects, action, rollback_objects = nil)
* objects - One or more error objects
* action - May be :retry or :rollback. :retry will push update object operation to server again at next sync, :rollback will write rollback_objects to client database.
* rollback_objects - contains objects attributes before failed update and sends by server. should be specified for :rollback action.
#### delete-error
If not handled, local modifications, which were failing on server, will never sync to server again.
So sync will work fine, but nobody will know about these changes.
:::ruby
SyncEngine.on_sync_delete_error( src_name, objects, action )
Model.on_sync_delete_error( objects, action )
* objects - One or more error objects
* action - May be :retry - will push delete object operation to server again at next sync.
For example:
:::ruby
SyncEngine.on_sync_create_error( @params['source_name'],
@params['server_errors']['create-error'], :delete)
SyncEngine.on_sync_update_error( @params['source_name'],
@params['server_errors']['update-error'], :retry)
SyncEngine.on_sync_update_error( @params['source_name'],
@params['server_errors']['update-error'], :rollback, @params['server_errors']['update-rollback'] )
SyncEngine.on_sync_delete_error( @params['source_name'],
@params['server_errors']['delete-error'], :retry)
#### unknown-client error
Unknown client error return by server after resetting server database, removing particular client id from database or any other cases when server cannot find client id(sync server unique id of device).
Note that login session may still exist on server, so in this case client does not have to login again, just create new client id.
Processing of this error contain 2 steps:
* When unknown client error is come from server, client should call database_client_reset and start new sync, to register new client id:
rho_error = Rho::RhoError.new(err_code)
if err_code == Rho::RhoError::ERR_CUSTOMSYNCSERVER
@msg = @params['error_message']
end
@msg = rho_error.message unless @msg and @msg.length > 0
if rho_error.unknown_client?(@params['error_message'])
Rhom::Rhom.database_client_reset
SyncEngine.dosync
end
* If login session also deleted or expired on the server, then customer has to login again:
rho_error = Rho::RhoError.new(err_code)
if err_code == Rho::RhoError::ERR_CUSTOMSYNCSERVER
@msg = @params['error_message']
end
@msg = rho_error.message unless @msg and @msg.length > 0
if err_code == Rho::RhoError::ERR_UNATHORIZED
WebView.navigate(
url_for(
:action => :login,
:query => { :msg => "Server credentials expired!" }
)
)
end
### Notification Example
Here is a simple example of a sync notification method that uses some of the parameters described above:
:::ruby
def sync_notify
status = @params['status'] ? @params['status'] : ""
bulk_sync? = @params['sync_type'] == 'bulk'
if status == "in_progress"
# do nothing
elsif status == "complete" or status == "ok"
WebView.navigate Rho::RhoConfig.start_path
elsif status == "error"
if @params['server_errors'] &&
@params['server_errors']['create-error']
SyncEngine.on_sync_create_error( @params['source_name'],
@params['server_errors']['create-error'], :delete)
end
err_code = @params['error_code'].to_i
rho_error = Rho::RhoError.new(err_code)
if err_code == Rho::RhoError::ERR_CUSTOMSYNCSERVER
@msg = @params['error_message']
end
@msg = rho_error.message unless @msg and @msg.length > 0
if rho_error.unknown_client?(@params['error_message'])
Rhom::Rhom.database_client_reset
SyncEngine.dosync
elsif err_code == Rho::RhoError::ERR_UNATHORIZED
WebView.navigate(
url_for(
:action => :login,
:query => { :msg => "Server credentials expired!" }
)
)
else
WebView.navigate(
url_for(
:action => :err_sync,
:query => { :msg => @msg }
)
)
end
end
end
**NOTE: If the view was updated using AJAX calls, this mechanism may not work correctly as the view location will not change from one AJAX call to another. Therefore, you might need to specify the `:controller` option in WebView.navigate.**
### Sync Object Notifications
The `SyncEngine` can also send a notification when a specific object on the current page has been modified. This is useful if you have frequently-changing data like feeds or timelines in your application and want them to update without the user taking any action.
To use object notifications, first set the notification callback in `application.rb#initialize`:
:::ruby
class AppApplication < Rho::RhoApplication
def initialize
super
SyncEngine.set_objectnotify_url(
url_for(
:controller => "Product",
:action => :sync_object_notify
)
)
end
end
Next, in your controller action that displays the object(s), add the object notification by passing in a record or collection of records:
:::ruby
class ProductController < Rho::RhoController
# GET /Product
def index
@products = Product.find(:all)
add_objectnotify(@products)
render
end
# ...
def sync_object_notify
#... do something with notification data ...
# refresh the current page
WebView.refresh
# or call System.execute_js to call javascript function which will update list
end
end
#### Object Notification Parameters
The object notification callback receives three arrays of hashes: "deleted", "updated" and "created". Each hash contains values for the keys "object" and "source_id" so you can display which records were changed.
## Binary Data and Blob Sync
Synchronizing images or binary objects between RhoConnect and the `SyncEngine` is declared by having a 'blob attribute' on the [Rhom model](/rhodes/rhom). Please see the [blob sync section](/rhoconnect/blob-sync) for more information.
## Filtering Datasets with Search
If you have a large dataset in your backend service, you don't have to synchronize everything with the `SyncEngine`. Instead you can filter the synchronized dataset using the `SyncEngine`'s `search` function.
Like everything else with the `SyncEngine`, `search` requires a defined callback which is executed when the `search` results are retrieved from RhoConnect.
### Using Search
First, call `search` from your controller action:
:::ruby
def search
page = @params['page'] || 0
page_size = @params['page_size'] || 10
Contact.search(
:from => 'search',
:search_params => {
:FirstName => @params['FirstName'],
:LastName => @params['LastName'],
:Company => @params['Company']
},
:offset => page * page_size,
:max_results => page_size,
:callback => url_for(:action => :search_callback),
:callback_param => ""
)
render :action => :search_wait
end
Your callback might look like:
:::ruby
def search_callback
status = @params["status"]
if (status and status == "ok")
WebView.navigate(
url_for(
:action => :show_page,
:query => @params['search_params']
)
)
else
render :action => :search_error
end
end
**NOTE: Typically you want to forward the original search query `@params['search_params']` to your view that displays the results so you can perform the same query locally.**
Next, the resulting action `:show_page` will be called. Here we demonstrate using Rhom's [advanced find query syntax](/rhodes/rhom#advanced-queries) since we are filtering a very large dataset:
:::ruby
def show_page
@contacts = Contact.find(
:all,
:conditions => {
{
:func => 'LOWER',
:name => 'FirstName',
:op => 'LIKE'
} => @params[:FirstName],
{
:func => 'LOWER',
:name=>'LastName',
:op=>'LIKE'
} => @params[:LastName],
{
:func=>'LOWER',
:name=>'Company',
:op=>'LIKE'
} => @params[:Company],
},
:op => 'OR',
:select => ['FirstName','LastName', 'Company'],
:per_page => page_size,
:offset => page * page_size
)
render :action => :show_page
end
If you want to stop or cancel the search, return "stop" in your callback:
:::ruby
def search_callback
if(status and status == 'ok')
WebView.navigate( url_for :action => :show_page )
else
'stop'
end
end
Finally, you will need to implement the `search` method in your source adapter. See the [RhoConnect search method](/rhoconnect/source-adapters#source-adapter-api) for more details.
## SyncEngine API
Below is the full list of methods available on the `SyncEngine`:
### `login(login, password, callback)`
Authenticates the user with RhoConnect. The callback will be executed when it is finished. See the [authentication section](/rhodes/synchronization#sync-authentication) for details.
:::ruby
SyncEngine.login(
@params['login'],
@params['password'],
url_for(:action => :login_callback)
)
### `logout`
Logout the user from the RhoConnect server. This removes the local user session. See the [authentication section](/rhodes/synchronization#sync-authentication) for details.
:::ruby
SyncEngine.logout
### `logged_in`
Returns 1 if the `SyncEngine` currently has a user session, 0 if not.
:::ruby
if SyncEngine::logged_in == 1
render :action => :index
else
render :action => :login
end
### `dosync(show_sync_status = true, query_params = "")`
Start the `SyncEngine` process and display an optional status popup (defaults to true).
query_params will pass to sync server
:::ruby
SyncEngine.dosync(false)
#=> no status popups are displayed
SyncEngine.dosync(false, "param1=12¶m2=abc")
#=> no status popups are displayed and parameters will pass to sync server
### `dosync_source(source_id_or_name, show_sync_status = true, query_params = "")`
Star the `SyncEngine` process for a given source id or source name and display an optional status popup (defaults to true).
query_params will pass to sync server
:::ruby
SyncEngine.dosync_source(Product.get_source_id.to_i, false) #sync by source id
SyncEngine.dosync_source(Product.get_source_name, false) #sync by source name
### `lock_sync_mutex`
Blocking call to wait for `SyncEngine` lock (useful for performing batch operations).
:::ruby
SyncEngine.lock_sync_mutex
#... perform blocking tasks...
SyncEngine.unlock_sync_mutex
### `unlock_sync_mutex`
Release the acquired `SyncEngine` lock (make sure you do this if you call `lock_sync_mutex`!).
### `stop_sync`
Stops any sync operations currently in progress.
:::ruby
SyncEngine.stop_sync
#=> no callback is called
### `set_notification(source_id, callback_url, params = nil)`
See the [sync notification section](/rhodes/synchronization#notifications).
### `set_notification(-1, callback_url, params = nil)`
Set notification callback for all models. This callback is not removed after the sync process completes. See the [sync notification section](/rhodes/synchronization#notifications).
### `clear_notification(source_id)`
Clears the sync notification for a given source id.
:::ruby
SyncEngine.clear_notification(Product.get_source_id)
### `on_sync_create_error( src_name, objects, action )`
"create-error" has to be handled in sync callback. Otherwise sync will stop on this model. To fix create errors you should call Model.on_sync_create_error or SyncEngine.on_sync_create_error.
:::ruby
SyncEngine.on_sync_create_error( @params['source_name'],
@params['server_errors']['create-error'], :delete)
* objects - One or more error objects
* action - May be :delete or :recreate. :delete just remove object from client, :recreate will push this object to server again at next sync.
### `on_sync_update_error( src_name, objects, action, rollback_objects = nil )`
:::ruby
SyncEngine.on_sync_update_error( @params['source_name'],
@params['server_errors']['update-error'], :retry)
SyncEngine.on_sync_update_error( @params['source_name'],
@params['server_errors']['update-error'], :rollback, @params['server_errors']['update-rollback'] )
* objects - One or more error objects
* action - May be :retry or :rollback. :retry will push update object operation to server again at next sync, :rollback will write rollback_objects to client database.
* rollback_objects - contains objects attributes before failed update and sends by server. should be specified for :rollback action.
### `on_sync_delete_error( src_name, objects, action )`
:::ruby
SyncEngine.on_sync_delete_error( @params['source_name'],
@params['server_errors']['delete-error'], :retry)
* objects - One or more error objects
* action - May be :retry - will push delete object operation to server again at next sync.
### `set_pollinterval(interval)`
Update the `SyncEngine` poll interval. Setting this to 0 will disable polling-based sync. However, you may still use [push-based-sync](/rhoconnect/push).
:::ruby
SyncEngine.set_pollinterval(20)'
#=> now polls every 20 seconds
### `set_syncserver(server_url)`
Sets the RhoConnect server address and stores it in [`rhoconfig.txt`](/rhodes/configuration).
:::ruby
SyncEngine.set_syncserver("http://myapp.com/application")
#=> don't forget the '/application' path
### `set_objectnotify_url(url)`
See the [sync notification section](/rhodes/synchronization#notifications).
### `set_pagesize(size)`
Set the sync page size for the `SyncEngine`. Default size is 2000. See [the `SyncEngine` workflow](/rhodes/synchronization#syncengine-workflow) for how this is used.
:::ruby
SyncEngine.set_pagesize(5000)
### `get_pagesize`
Get the current sync page size for the `SyncEngine`. See [the `SyncEngine` workflow](/rhodes/synchronization#syncengine-workflow) for how this is used.
:::ruby
SyncEngine.get_pagesize
#=> 2000
SyncEngine.set_pagesize(5000)
SyncEngine.get_pagesize
#=> 5000
### `enable_status_popup(false)`
Enable or disable show status popup. True by default for Blackberry, false for other platforms.
:::ruby
SyncEngine.enable_status_popup(true)
### `set_ssl_verify_peer(true)`
Enable or disable verification of RhoConnect ssl certificates, true by default.
:::ruby
# using a self-signed cert
SyncEngine.set_ssl_verify_peer(false)
### `get_user_name`
Returns current username of the `SyncEngine` session if `logged_in` is true, otherwise returns the last logged in username.
:::ruby
SyncEngine.get_user_name
#=> "testuser"
### `search(*args)`
Call search on the RhoConnect application with given parameters. See the [search section](#filtering-datasets-with-search) for more details.
:::ruby
# :from Sets the RhoConnect path that records
# will be fetched with (optional).
# Default is 'search'.
#
# :search_params Hash containing key/value search items.
#
# :offset Starting record to be returned.
#
# :max_results Max number of records to be returned.
#
# :callback Callback to be executed after search
# is completed.
#
# :callback_param (optional) Parameters passed to callback.
#
# :progress_step (optional) Define how often search callback
# will be executed with 'in_progress' state.
# :sync_changes (optional) - true or false(default). Define should client changes send to server before search.
Contact.search(
:from => 'search',
:search_params => {
:FirstName => @params['FirstName'],
:LastName => @params['LastName'],
:Company => @params['Company']
},
:offset => page * page_size,
:max_results => page_size,
:callback => url_for(:action => :search_callback),
:callback_param => "",
:sync_changes => false
)
### `search(*args) (multiple sources)`
Call search on the RhoConnect application with multiple source names. This is useful if your `search` spans across multiple models.
For example:
:::ruby
SyncEngine.search(
:source_names => ['Product', 'Customer'],
:from => 'search',
:search_params => {
:FirstName => @params['FirstName'],
:LastName => @params['LastName'],
:Company => @params['Company']
},
:offset => page * page_size,
:max_results => page_size,
:callback => url_for(:action => :search_callback),
:callback_param => "",
:sync_changes => false
)
Parameters are the same as for ModelName.search with an additional parameter:
* `:source_names` - Sends a list of source adapter names to RhoConnect to search across.
## SyncEngine AJAX API
[Sync engine AJAX API](syncengine-ajax-api) has been implemented to provide access to low-level control on
synchronization process right from plain HTML/javascript UI pages.
It isn't intended to be used in every application. It requires deep knowledge of SyncEngine functionality and operations.
It may broke your application if used improperly so use it with care please.