rhoconnect 3.4.5 → 4.0.0.beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +57 -3
- data/Gemfile +9 -7
- data/Gemfile.lock +37 -37
- data/Rakefile +18 -7
- data/bench/benchapp/Gemfile +1 -1
- data/bench/benchapp/config.ru +0 -3
- data/bench/benchapp/controllers/ruby/application.rb +17 -0
- data/bench/benchapp/controllers/ruby/application_controller.rb +17 -0
- data/bench/benchapp/controllers/ruby/mock_adapter_controller.rb +8 -0
- data/bench/benchapp/controllers/ruby/queue_mock_adapter_controller.rb +8 -0
- data/bench/benchapp/{sources → models/ruby}/mock_adapter.rb +1 -1
- data/bench/benchapp/{sources → models/ruby}/queue_mock_adapter.rb +0 -0
- data/bench/benchapp/spec/{sources → models/ruby}/mock_adapter_spec.rb +1 -1
- data/bench/benchapp/spec/{sources → models/ruby}/queue_mock_adapter_spec.rb +1 -1
- data/bench/benchapp/spec/spec_helper.rb +2 -2
- data/bench/blobapp/Gemfile +1 -1
- data/bench/blobapp/config.ru +0 -3
- data/bench/blobapp/controllers/ruby/application_controller.rb +17 -0
- data/bench/blobapp/controllers/ruby/blob_adapter_controller.rb +8 -0
- data/bench/blobapp/{sources → models/ruby}/blob_adapter.rb +9 -2
- data/bench/blobapp/spec/{sources → models/ruby}/blob_adapter_spec.rb +1 -1
- data/bench/blobapp/spec/spec_helper.rb +1 -1
- data/bench/lib/bench/cli.rb +1 -1
- data/bench/scripts/blob_cud_script.rb +1 -1
- data/bench/scripts/query_md_script.rb +1 -1
- data/bench/scripts/query_only_script.rb +1 -1
- data/bench/scripts/query_script.rb +1 -1
- data/bench/scripts/test_query_script.rb +7 -1
- data/bench/spec/mock_adapter_spec.rb +1 -1
- data/bench/spec/result_spec.rb +3 -3
- data/bin/rhoconnect +5 -3
- data/commands/dtach/dtach_install.rb +2 -2
- data/commands/execute.rb +8 -3
- data/commands/generators/app.rb +3 -3
- data/commands/generators/controller.rb +6 -0
- data/commands/generators/model.rb +6 -0
- data/commands/generators/source.rb +3 -3
- data/commands/generators/update.rb +1 -1
- data/commands/redis/redis_about.rb +2 -2
- data/commands/redis/redis_download.rb +1 -1
- data/commands/redis/redis_install.rb +4 -3
- data/commands/redis/redis_restart.rb +4 -4
- data/commands/redis/redis_start.rb +5 -4
- data/commands/redis/redis_startbg.rb +5 -4
- data/commands/redis/redis_status.rb +13 -0
- data/commands/redis/redis_stop.rb +3 -3
- data/commands/rhoconnect/config.rb +28 -16
- data/commands/rhoconnect/flushdb.rb +1 -2
- data/commands/rhoconnect/get_token.rb +15 -11
- data/commands/rhoconnect/restart.rb +13 -5
- data/commands/rhoconnect/set_admin_password.rb +8 -8
- data/commands/rhoconnect/start.rb +74 -16
- data/commands/rhoconnect/startbg.rb +1 -1
- data/commands/rhoconnect/startdebug.rb +1 -1
- data/commands/rhoconnect/stop.rb +13 -1
- data/commands/rhoconnect/web.rb +5 -5
- data/commands/rhoconnect_console/console.rb +7 -5
- data/commands/{rhoconnect → rhoconnect_spec}/spec.rb +0 -0
- data/commands/rhoconnect_war/war.rb +9 -9
- data/commands/utilities/blank_app.ru +56 -0
- data/commands/utilities/redis_runner.rb +54 -19
- data/doc/authentication.txt +80 -6
- data/doc/blob-sync.txt +104 -97
- data/doc/bulk-sync.txt +1 -1
- data/doc/client-java.txt +3 -3
- data/doc/client-objc.txt +2 -2
- data/doc/client.txt +4 -4
- data/doc/command-line.txt +105 -200
- data/doc/data-partitioning.txt +40 -0
- data/doc/deploying.txt +249 -77
- data/doc/extending-rhoconnect-server.txt +40 -57
- data/doc/heroku-addon.txt +2 -0
- data/doc/install.txt +45 -95
- data/doc/introduction.txt +1 -1
- data/doc/java-plugin.txt +365 -190
- data/doc/metadata.txt +1 -1
- data/doc/migration.txt +108 -142
- data/doc/preparing-production.txt +1 -1
- data/doc/push-backend-setup.txt +2 -0
- data/doc/push-client-setup-android.txt +78 -0
- data/doc/push-client-setup-bb.txt +81 -0
- data/doc/push-client-setup-ios.txt +70 -0
- data/doc/push-client-setup-rps.txt +200 -0
- data/doc/push-client-setup.txt +63 -66
- data/doc/push-server-setup.txt +67 -40
- data/doc/push-testing.txt +29 -0
- data/doc/push.txt +21 -6
- data/doc/rest-api.txt +128 -55
- data/doc/rhoconnect-redis-stack.txt +120 -0
- data/doc/settings.txt +4 -12
- data/doc/source-adapters-intro.txt +28 -0
- data/doc/source-adapters.txt +235 -272
- data/doc/stats-middleware.txt +9 -29
- data/doc/supported-platforms.txt +21 -30
- data/doc/testing.txt +40 -42
- data/doc/tutorial.txt +72 -57
- data/examples/simple/Gemfile +1 -1
- data/examples/simple/application.rb +4 -5
- data/examples/simple/my_server.rb +2 -2
- data/examples/simple/settings/settings.yml +1 -1
- data/generators/rhoconnect.rb +151 -50
- data/generators/templates/application/Gemfile +1 -1
- data/generators/templates/application/Rakefile +3 -3
- data/generators/templates/application/config.ru +1 -4
- data/generators/templates/application/controllers/application_controller.rb +17 -0
- data/generators/templates/application/controllers/js/application_controller.js +14 -0
- data/generators/templates/application/controllers/ruby/application_controller.rb +17 -0
- data/generators/templates/application/package.json +8 -0
- data/generators/templates/application/rcgemfile +2 -5
- data/generators/templates/application/settings/settings.yml +3 -3
- data/generators/templates/application/spec/application_controller_spec.rb +23 -0
- data/generators/templates/application/spec/js_spec.rb +25 -0
- data/generators/templates/application/spec/spec_helper.rb +21 -7
- data/generators/templates/source/controllers/js/controller.js +7 -0
- data/generators/templates/source/controllers/ruby/controller.rb +8 -0
- data/generators/templates/source/controllers/ruby/controller_spec.rb +27 -0
- data/generators/templates/source/models/js/model.js +46 -0
- data/generators/templates/source/{source_adapter.rb → models/ruby/model.rb} +15 -10
- data/generators/templates/source/{source_spec.rb → models/ruby/model_spec.rb} +1 -1
- data/install.sh +5 -5
- data/installer/unix-like/create_texts.rb +2 -2
- data/installer/unix-like/rho_connect_install_constants.rb +2 -2
- data/installer/unix-like/rho_connect_install_utilities.rb +1 -1
- data/installer/utils/constants.rb +4 -4
- data/js-adapters/ballroom.js +216 -0
- data/js-adapters/node.rb +52 -0
- data/js-adapters/node_channel.rb +181 -0
- data/js-adapters/request.js +27 -0
- data/js-adapters/response.js +57 -0
- data/js-adapters/rhoconnect_helpers.js +60 -0
- data/js-adapters/router.js +60 -0
- data/js-adapters/server.js +5 -0
- data/lib/rhoconnect/api/app/ans_login.rb +3 -3
- data/lib/rhoconnect/api/app/bulk_data.rb +10 -10
- data/lib/rhoconnect/api/app/fast_delete.rb +11 -10
- data/lib/rhoconnect/api/app/fast_insert.rb +11 -10
- data/lib/rhoconnect/api/app/fast_update.rb +11 -10
- data/lib/rhoconnect/api/app/login.rb +5 -5
- data/lib/rhoconnect/api/app/push_deletes.rb +12 -11
- data/lib/rhoconnect/api/app/push_objects.rb +12 -11
- data/lib/rhoconnect/api/app/query.rb +8 -7
- data/lib/rhoconnect/api/app/queue_updates.rb +98 -94
- data/lib/rhoconnect/api/app/search.rb +8 -7
- data/lib/rhoconnect/api/client/client_get_db_doc.rb +5 -5
- data/lib/rhoconnect/api/client/client_set_db_doc.rb +8 -8
- data/lib/rhoconnect/api/client/create.rb +7 -7
- data/lib/rhoconnect/api/client/get_client_params.rb +4 -4
- data/lib/rhoconnect/api/client/list_client_docs.rb +17 -17
- data/lib/rhoconnect/api/client/register.rb +12 -12
- data/lib/rhoconnect/api/client/reset.rb +5 -5
- data/lib/rhoconnect/api/readstate/set_refresh_time.rb +9 -9
- data/lib/rhoconnect/api/source/get_source_params.rb +4 -4
- data/lib/rhoconnect/api/source/list_sources.rb +16 -16
- data/lib/rhoconnect/api/source/update_source_params.rb +6 -6
- data/lib/rhoconnect/api/store/get_db_doc.rb +4 -4
- data/lib/rhoconnect/api/store/set_db_doc.rb +7 -7
- data/lib/rhoconnect/api/system/get_adapter.rb +4 -4
- data/lib/rhoconnect/api/system/get_license_info.rb +8 -8
- data/lib/rhoconnect/api/system/login.rb +15 -15
- data/lib/rhoconnect/api/system/reset.rb +11 -11
- data/lib/rhoconnect/api/system/save_adapter.rb +4 -4
- data/lib/rhoconnect/api/system/stats.rb +22 -22
- data/lib/rhoconnect/api/user/create_user.rb +7 -7
- data/lib/rhoconnect/api/user/delete_client.rb +6 -6
- data/lib/rhoconnect/api/user/delete_user.rb +11 -10
- data/lib/rhoconnect/api/user/list_clients.rb +4 -4
- data/lib/rhoconnect/api/user/list_source_docs.rb +10 -10
- data/lib/rhoconnect/api/user/list_users.rb +3 -3
- data/lib/rhoconnect/api/user/ping.rb +3 -3
- data/lib/rhoconnect/api/user/show_user.rb +3 -3
- data/lib/rhoconnect/api/user/update_user.rb +5 -5
- data/lib/rhoconnect/api/user/user_get_db_doc.rb +5 -5
- data/lib/rhoconnect/api/user/user_set_db_doc.rb +10 -10
- data/lib/rhoconnect/api_token.rb +5 -6
- data/lib/rhoconnect/app.rb +6 -46
- data/lib/rhoconnect/application/init.rb +5 -2
- data/lib/rhoconnect/async.rb +76 -39
- data/lib/rhoconnect/bulk_data/bulk_data.rb +6 -4
- data/lib/rhoconnect/client.rb +59 -9
- data/lib/rhoconnect/condition/admin_required.rb +27 -0
- data/lib/rhoconnect/condition/client_required.rb +50 -0
- data/lib/rhoconnect/condition/login_required.rb +22 -0
- data/lib/rhoconnect/condition/source_required.rb +49 -0
- data/lib/rhoconnect/condition/verbs.rb +17 -0
- data/lib/rhoconnect/condition/verify_success.rb +19 -0
- data/lib/rhoconnect/controller/app_base.rb +74 -0
- data/lib/rhoconnect/controller/base.rb +68 -0
- data/lib/rhoconnect/controller/clients_controller.rb +79 -0
- data/lib/rhoconnect/controller/dynamic_adapter_controller.rb +93 -0
- data/lib/rhoconnect/controller/js_base.rb +124 -0
- data/lib/rhoconnect/controller/read_state_controller.rb +22 -0
- data/lib/rhoconnect/controller/source_adapter_base.rb +14 -0
- data/lib/rhoconnect/controller/sources_controller.rb +44 -0
- data/lib/rhoconnect/controller/store_controller.rb +25 -0
- data/lib/rhoconnect/controller/system_controller.rb +67 -0
- data/lib/rhoconnect/controller/users_controller.rb +99 -0
- data/lib/rhoconnect/db_adapter.rb +1 -3
- data/lib/rhoconnect/document.rb +159 -50
- data/lib/rhoconnect/handler/authenticate/execute_methods.rb +77 -0
- data/lib/rhoconnect/handler/authenticate/runner.rb +49 -0
- data/lib/rhoconnect/handler/authenticate.rb +3 -0
- data/lib/rhoconnect/handler/bulk_data.rb +28 -0
- data/lib/rhoconnect/handler/changes/engine.rb +271 -0
- data/lib/rhoconnect/handler/changes/execute_methods.rb +88 -0
- data/lib/rhoconnect/handler/changes/pass_through_runner.rb +11 -0
- data/lib/rhoconnect/handler/changes/runner.rb +53 -0
- data/lib/rhoconnect/handler/changes.rb +31 -0
- data/lib/rhoconnect/handler/helpers/auth_method.rb +29 -0
- data/lib/rhoconnect/handler/helpers/binding.rb +18 -0
- data/lib/rhoconnect/handler/helpers/bulk_data.rb +53 -0
- data/lib/rhoconnect/handler/helpers/source_job.rb +14 -0
- data/lib/rhoconnect/handler/helpers.rb +4 -0
- data/lib/rhoconnect/handler/plugin_callbacks/execute_methods.rb +99 -0
- data/lib/rhoconnect/handler/plugin_callbacks/runner.rb +28 -0
- data/lib/rhoconnect/handler/plugin_callbacks.rb +67 -0
- data/lib/rhoconnect/handler/query/engine.rb +93 -0
- data/lib/rhoconnect/handler/query/execute_methods.rb +21 -0
- data/lib/rhoconnect/handler/query/pass_through_runner.rb +35 -0
- data/lib/rhoconnect/handler/query/runner.rb +270 -0
- data/lib/rhoconnect/handler/query.rb +19 -0
- data/lib/rhoconnect/handler/search/engine.rb +60 -0
- data/lib/rhoconnect/handler/search/execute_methods.rb +32 -0
- data/lib/rhoconnect/handler/search/pass_through_runner.rb +18 -0
- data/lib/rhoconnect/handler/search/runner.rb +104 -0
- data/lib/rhoconnect/handler/search.rb +26 -0
- data/lib/rhoconnect/handler/sync.rb +29 -0
- data/lib/rhoconnect/jobs/source_job.rb +13 -4
- data/lib/rhoconnect/js_adapter.rb +79 -0
- data/lib/rhoconnect/license.rb +10 -2
- data/lib/rhoconnect/middleware/current_user.rb +14 -1
- data/lib/rhoconnect/middleware/helpers.rb +10 -93
- data/lib/rhoconnect/middleware/x_domain_session_wrapper.rb +1 -1
- data/lib/rhoconnect/model/base.rb +229 -0
- data/lib/rhoconnect/model/dynamic_adapter_model.rb +90 -0
- data/lib/rhoconnect/model/js_base.rb +121 -0
- data/lib/rhoconnect/ping/android.rb +1 -1
- data/lib/rhoconnect/predefined_adapters/bench_adapter.rb +7 -4
- data/lib/rhoconnect/read_state.rb +3 -3
- data/lib/rhoconnect/server.rb +159 -190
- data/lib/rhoconnect/source.rb +100 -11
- data/lib/rhoconnect/stats/record.rb +10 -10
- data/lib/rhoconnect/store.rb +905 -591
- data/lib/rhoconnect/{model.rb → store_orm.rb} +53 -115
- data/lib/rhoconnect/tasks.rb +18 -4
- data/lib/rhoconnect/test_methods.rb +30 -17
- data/lib/rhoconnect/user.rb +35 -17
- data/lib/rhoconnect/utilities.rb +1 -1
- data/lib/rhoconnect/version.rb +2 -2
- data/lib/rhoconnect/web-console/server.rb +29 -14
- data/lib/rhoconnect/web-console/views/home.js +10 -10
- data/lib/rhoconnect/web-console/views/new_ping.js +1 -1
- data/lib/rhoconnect.rb +120 -51
- data/rhoconnect.gemspec +4 -3
- data/spec/api/api_helper.rb +1 -6
- data/spec/api/app/fast_delete_spec.rb +4 -4
- data/spec/api/app/fast_insert_spec.rb +4 -4
- data/spec/api/app/fast_update_spec.rb +8 -8
- data/spec/api/app/push_deletes_spec.rb +2 -2
- data/spec/api/app/push_objects_spec.rb +5 -5
- data/spec/api/client/client_get_db_doc_spec.rb +6 -4
- data/spec/api/client/client_set_db_doc_spec.rb +3 -2
- data/spec/api/client/get_client_params_spec.rb +14 -0
- data/spec/api/client/list_client_docs_spec.rb +30 -20
- data/spec/api/client/reset_spec.rb +36 -0
- data/spec/api/source/get_source_params_spec.rb +23 -17
- data/spec/api/system/get_license_info_spec.rb +0 -20
- data/spec/api/system/login_spec.rb +8 -0
- data/spec/api/system/reset_spec.rb +0 -1
- data/spec/api/system/stats_spec.rb +5 -5
- data/spec/api/user/create_user_spec.rb +14 -6
- data/spec/api/user/delete_user_spec.rb +20 -18
- data/spec/api/user/list_users_spec.rb +5 -6
- data/spec/api/user/update_user_spec.rb +5 -4
- data/spec/apps/rhotestapp/config.ru +16 -1
- data/spec/apps/rhotestapp/controllers/js/js_sample_controller.js +23 -0
- data/spec/apps/rhotestapp/controllers/js/sample2_controller.js +32 -0
- data/spec/apps/rhotestapp/controllers/ruby/application_controller.rb +21 -0
- data/spec/apps/rhotestapp/controllers/ruby/sample_adapter_controller.rb +8 -0
- data/spec/apps/rhotestapp/models/js/js_sample.js +55 -0
- data/spec/apps/rhotestapp/models/js/sample2.js +25 -0
- data/spec/apps/rhotestapp/{sources → models/ruby}/base_adapter.rb +0 -0
- data/spec/apps/rhotestapp/{sources → models/ruby}/fixed_schema_adapter.rb +0 -0
- data/spec/apps/rhotestapp/{sources → models/ruby}/other_adapter.rb +0 -0
- data/spec/apps/rhotestapp/{sources → models/ruby}/sample_adapter.rb +0 -0
- data/spec/apps/rhotestapp/{sources → models/ruby}/simple_adapter.rb +2 -2
- data/spec/apps/rhotestapp/{sources → models/ruby}/sub_adapter.rb +0 -0
- data/spec/apps/rhotestapp/settings/settings.yml +0 -1
- data/spec/bulk_data/bulk_data_spec.rb +20 -5
- data/spec/cli/cli_spec.rb +83 -0
- data/spec/client_spec.rb +20 -17
- data/spec/client_sync_spec.rb +244 -406
- data/spec/controllers/js_base_spec.rb +89 -0
- data/spec/doc/doc_spec.rb +18 -18
- data/spec/document_spec.rb +29 -13
- data/spec/dynamic_adapter_spec.rb +6 -6
- data/spec/generator/generator_spec.rb +7 -4
- data/spec/jobs/bulk_data_job_spec.rb +14 -10
- data/spec/jobs/source_job_spec.rb +8 -8
- data/spec/license_spec.rb +5 -2
- data/spec/models/js_model_spec.rb +39 -0
- data/spec/node_spec.rb +42 -0
- data/spec/perf/store_perf_spec.rb +67 -12
- data/spec/ping/android_spec.rb +1 -1
- data/spec/read_state_spec.rb +1 -1
- data/spec/rhoconnect_spec.rb +1 -1
- data/spec/server/cors_spec.rb +14 -18
- data/spec/server/server_spec.rb +265 -88
- data/spec/server/stats_spec.rb +1 -1
- data/spec/source_adapter_spec.rb +54 -27
- data/spec/source_spec.rb +8 -3
- data/spec/source_sync_spec.rb +538 -468
- data/spec/spec_helper.rb +35 -4
- data/spec/stats/record_spec.rb +10 -10
- data/spec/{model_spec.rb → store_orm_spec.rb} +56 -54
- data/spec/store_spec.rb +159 -179
- data/spec/support/shared_examples.rb +36 -27
- data/spec/sync_states_spec.rb +40 -33
- data/spec/test_methods_spec.rb +18 -14
- data/spec/user_spec.rb +17 -30
- metadata +156 -52
- data/bench/benchapp/application.rb +0 -39
- data/bench/blobapp/application.rb +0 -44
- data/commands/rhoconnect/clean_start.rb +0 -9
- data/commands/rhoconnect/create_user.rb +0 -18
- data/commands/rhoconnect/delete_device.rb +0 -9
- data/commands/rhoconnect/delete_user.rb +0 -8
- data/commands/rhoconnect/reset.rb +0 -16
- data/commands/rhoconnect/reset_refresh.rb +0 -11
- data/generators/templates/application/application.rb +0 -43
- data/lib/rhoconnect/client_sync.rb +0 -434
- data/lib/rhoconnect/dynamic_adapter.rb +0 -91
- data/lib/rhoconnect/middleware/admin_user.rb +0 -23
- data/lib/rhoconnect/middleware/current_request.rb +0 -16
- data/lib/rhoconnect/middleware/login_required.rb +0 -22
- data/lib/rhoconnect/source_adapter.rb +0 -132
- data/lib/rhoconnect/source_sync.rb +0 -464
- data/spec/apps/rhotestapp/application.rb +0 -23
data/lib/rhoconnect/document.rb
CHANGED
|
@@ -1,87 +1,196 @@
|
|
|
1
1
|
module Document
|
|
2
|
-
|
|
2
|
+
class << self
|
|
3
|
+
def included(base)
|
|
4
|
+
base.extend ClassMethods
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module ClassMethods
|
|
9
|
+
def define_valid_doctypes(doctypes = [])
|
|
10
|
+
@valid_doctypes ||= Set.new
|
|
11
|
+
doctypes.each do |doctype|
|
|
12
|
+
@valid_doctypes.add(doctype.to_sym)
|
|
13
|
+
end
|
|
14
|
+
@enforce_valid_doctypes ||= true
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def valid_doctypes
|
|
18
|
+
@valid_doctypes ||= Set.new
|
|
19
|
+
@valid_doctypes
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def enforce_valid_doctypes
|
|
23
|
+
@enforce_valid_doctypes ||= false
|
|
24
|
+
end
|
|
25
|
+
def enforce_valid_doctypes=(enforce_flag)
|
|
26
|
+
@enforce_valid_doctypes = enforce_flag
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def set_db_doc(doctype, data, append=false)
|
|
31
|
+
verify_doctype(doctype)
|
|
32
|
+
Store.get_store(store_index(doctype)).set_db_doc(docname(doctype), data, append)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def get_db_doc(doctype)
|
|
36
|
+
verify_doctype(doctype)
|
|
37
|
+
Store.get_store(store_index(doctype)).get_db_doc(docname(doctype))
|
|
38
|
+
end
|
|
39
|
+
|
|
3
40
|
# Store wrapper methods for document
|
|
4
41
|
def get_data(doctype,type=Hash)
|
|
5
|
-
|
|
42
|
+
verify_doctype(doctype)
|
|
43
|
+
Store.get_store(store_index(doctype)).get_data(docname(doctype), type)
|
|
6
44
|
end
|
|
7
|
-
|
|
45
|
+
|
|
8
46
|
def get_object(doctype, key)
|
|
9
|
-
|
|
47
|
+
verify_doctype(doctype)
|
|
48
|
+
Store.get_store(store_index(doctype)).get_object(docname(doctype), key)
|
|
10
49
|
end
|
|
11
|
-
|
|
50
|
+
|
|
12
51
|
def get_objects(doctype, keys)
|
|
13
|
-
|
|
52
|
+
verify_doctype(doctype)
|
|
53
|
+
Store.get_store(store_index(doctype)).get_objects(docname(doctype), keys)
|
|
14
54
|
end
|
|
15
|
-
|
|
55
|
+
|
|
16
56
|
def get_list(doctype)
|
|
17
|
-
|
|
57
|
+
verify_doctype(doctype)
|
|
58
|
+
Store.get_store(store_index(doctype)).get_list(docname(doctype))
|
|
18
59
|
end
|
|
19
|
-
|
|
60
|
+
|
|
20
61
|
def get_value(doctype)
|
|
21
|
-
|
|
62
|
+
verify_doctype(doctype)
|
|
63
|
+
Store.get_store(store_index(doctype)).get_value(docname(doctype))
|
|
22
64
|
end
|
|
23
|
-
|
|
65
|
+
|
|
24
66
|
def put_object(doctype, key, data={})
|
|
25
|
-
|
|
67
|
+
verify_doctype(doctype)
|
|
68
|
+
Store.get_store(store_index(doctype)).put_object(docname(doctype), key, data)
|
|
26
69
|
end
|
|
27
|
-
|
|
70
|
+
|
|
28
71
|
def put_data(doctype,data,append=false)
|
|
29
|
-
|
|
72
|
+
verify_doctype(doctype)
|
|
73
|
+
Store.get_store(store_index(doctype)).put_data(docname(doctype),data,append)
|
|
30
74
|
end
|
|
31
|
-
|
|
75
|
+
|
|
76
|
+
def put_tmp_data(doctype, data, append=false)
|
|
77
|
+
Store.get_store(store_index(doctype)).put_tmp_data(docname(doctype),data,append)
|
|
78
|
+
end
|
|
79
|
+
|
|
32
80
|
def put_list(doctype,data,append=false)
|
|
33
|
-
|
|
81
|
+
verify_doctype(doctype)
|
|
82
|
+
Store.get_store(store_index(doctype)).put_list(docname(doctype),data,append)
|
|
34
83
|
end
|
|
35
|
-
|
|
84
|
+
|
|
36
85
|
def update_objects(doctype,updates)
|
|
37
|
-
|
|
86
|
+
verify_doctype(doctype)
|
|
87
|
+
Store.get_store(store_index(doctype)).update_objects(docname(doctype),updates)
|
|
38
88
|
end
|
|
39
|
-
|
|
89
|
+
|
|
40
90
|
def remove_objects(doctype,deletes)
|
|
41
|
-
|
|
91
|
+
verify_doctype(doctype)
|
|
92
|
+
Store.get_store(store_index(doctype)).delete_objects(docname(doctype),deletes)
|
|
42
93
|
end
|
|
43
|
-
|
|
94
|
+
|
|
44
95
|
def put_value(doctype,data)
|
|
45
|
-
|
|
96
|
+
verify_doctype(doctype)
|
|
97
|
+
Store.get_store(store_index(doctype)).put_value(docname(doctype),data)
|
|
46
98
|
end
|
|
47
|
-
|
|
99
|
+
|
|
48
100
|
def delete_data(doctype,data)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def flash_data(doctype)
|
|
53
|
-
Store.flash_data(docname(doctype))
|
|
101
|
+
verify_doctype(doctype)
|
|
102
|
+
Store.get_store(store_index(doctype)).delete_data(docname(doctype),data)
|
|
54
103
|
end
|
|
55
|
-
|
|
56
|
-
def
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
Store.flash_data(docnamestr)
|
|
104
|
+
|
|
105
|
+
def flush_data(doctype)
|
|
106
|
+
verify_doctype(doctype)
|
|
107
|
+
Store.flush_data(docname(doctype))
|
|
60
108
|
end
|
|
61
|
-
|
|
109
|
+
|
|
62
110
|
def rename(srcdoctype,dstdoctype)
|
|
63
|
-
|
|
111
|
+
verify_doctype(srcdoctype)
|
|
112
|
+
verify_doctype(dstdoctype)
|
|
113
|
+
Store.get_store(store_index(srcdoctype)).rename(docname(srcdoctype),docname(dstdoctype))
|
|
64
114
|
end
|
|
65
|
-
|
|
66
|
-
def
|
|
67
|
-
|
|
115
|
+
|
|
116
|
+
def rename_tmp_data(srcdoctype,dstdoctype)
|
|
117
|
+
verify_doctype(dstdoctype)
|
|
118
|
+
Store.get_store(store_index(srcdoctype)).rename_tmp_data(docname(srcdoctype),docname(dstdoctype))
|
|
68
119
|
end
|
|
69
|
-
|
|
70
|
-
def
|
|
71
|
-
|
|
120
|
+
|
|
121
|
+
def clone(srcdoctype, dstdocname)
|
|
122
|
+
verify_doctype(srcdoctype)
|
|
123
|
+
Store.get_store(store_index(srcdoctype)).clone(docname(srcdoctype), dstdocname)
|
|
72
124
|
end
|
|
73
|
-
|
|
74
|
-
def put_zdata(doctype,assoc_key, data={},append=false)
|
|
75
|
-
Store.put_zdata(docname(doctype),assoc_key, data,append)
|
|
76
|
-
end
|
|
77
|
-
|
|
125
|
+
|
|
78
126
|
# Generate the fully-qualified docname
|
|
79
127
|
def docname(doctype)
|
|
80
128
|
"#{self.class.class_prefix(self.class)}:#{self.app_id}:#{self.doc_suffix(doctype)}"
|
|
81
129
|
end
|
|
82
|
-
|
|
130
|
+
|
|
131
|
+
# default data sharding
|
|
132
|
+
def store_index(doctype)
|
|
133
|
+
0
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def compute_store_index(doctype, source, user_id)
|
|
137
|
+
index = 0
|
|
138
|
+
# app-partitioned sources go to 0
|
|
139
|
+
# everything else if sharded
|
|
140
|
+
if(source.partition == :user)
|
|
141
|
+
index_char = Digest::SHA1.hexdigest("#{user_id}:#{source.name}")[0]
|
|
142
|
+
# designate Store 0 only for system data
|
|
143
|
+
num_user_stores = Store.num_stores - 1
|
|
144
|
+
if num_user_stores > 0
|
|
145
|
+
index = index_char.hex/(16/num_user_stores)
|
|
146
|
+
if index >= num_user_stores
|
|
147
|
+
index = num_user_stores - 1
|
|
148
|
+
end
|
|
149
|
+
# make up for fact that user store index starts from 1
|
|
150
|
+
index += 1
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
index
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def exists?(dockey)
|
|
157
|
+
verify_doctype(dockey)
|
|
158
|
+
Store.get_store(store_index(dockey)).exists?(docname(dockey))
|
|
159
|
+
end
|
|
160
|
+
|
|
83
161
|
# Update count for a given document
|
|
84
162
|
def update_count(doctype,count)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
end
|
|
163
|
+
verify_doctype(doctype)
|
|
164
|
+
Store.get_store(store_index(doctype)).update_count(docname(doctype), count)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def verify_doctype(doctype)
|
|
168
|
+
# doctype must be in the list (or list must be empty - which is default for 'all documents are valid')
|
|
169
|
+
return true if !self.class.enforce_valid_doctypes or self.class.valid_doctypes.member?(doctype.to_sym) or (self.class.valid_doctypes.size == 0)
|
|
170
|
+
raise Rhoconnect::InvalidDocumentException.new("Invalid document type #{doctype} for #{self.class.name}")
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# interface for doc diffs
|
|
174
|
+
def get_diff_data(srcdoctype, dstdocname, p_size = nil)
|
|
175
|
+
verify_doctype(srcdoctype)
|
|
176
|
+
Store.get_store(store_index(srcdoctype)).get_diff_data(docname(srcdoctype), dstdocname, p_size)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def get_diff_data_bruteforce(srcdoctype, dstdocname, p_size = nil)
|
|
180
|
+
verify_doctype(srcdoctype)
|
|
181
|
+
Store.get_store(store_index(srcdoctype)).get_diff_data_bruteforce(docname(srcdoctype), dstdocname, p_size)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def update_elements(doctype, inserts_elements_map, deletes_elements_map)
|
|
185
|
+
verify_doctype(doctype)
|
|
186
|
+
Store.get_store(store_index(doctype)).update_elements(docname(doctype), inserts_elements_map, deletes_elements_map)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Computes token for a single client request
|
|
190
|
+
def compute_token(doc_key)
|
|
191
|
+
verify_doctype(doc_key)
|
|
192
|
+
token = get_token
|
|
193
|
+
Store.get_store(store_index(doc_key)).put_value(docname(doc_key),token)
|
|
194
|
+
token.to_s
|
|
195
|
+
end
|
|
196
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
module Rhoconnect
|
|
2
|
+
module Handler
|
|
3
|
+
module Authenticate
|
|
4
|
+
module ExecuteMethods
|
|
5
|
+
def execute_authenticate_handler(route_handler)
|
|
6
|
+
_logout
|
|
7
|
+
_login(route_handler)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def execute_admin_authenticate_handler(route_handler)
|
|
11
|
+
token = ''
|
|
12
|
+
_logout
|
|
13
|
+
_login(route_handler)
|
|
14
|
+
u = User.load(params[:login])
|
|
15
|
+
token = _do_get_api_token(params, u)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def execute_rps_authenticate_handler(route_handler)
|
|
19
|
+
_check_login do
|
|
20
|
+
_rps_login(route_handler) ? status(204) : status(401)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# helper methods
|
|
25
|
+
private
|
|
26
|
+
def _logout
|
|
27
|
+
session[:login] = nil
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def _login(route_handler)
|
|
31
|
+
_check_login do
|
|
32
|
+
@handler = Rhoconnect::Handler::Authenticate::Runner.new(current_app, route_handler, params)
|
|
33
|
+
user = @handler.run
|
|
34
|
+
if user
|
|
35
|
+
session[:login] = user.login
|
|
36
|
+
session[:app_name] = APP_NAME
|
|
37
|
+
status(200)
|
|
38
|
+
else
|
|
39
|
+
raise LoginException.new("Unable to authenticate '#{params[:login]}'")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def _rps_login(route_handler)
|
|
45
|
+
res = false
|
|
46
|
+
if current_app
|
|
47
|
+
auth = Rack::Auth::Basic::Request.new(request.env)
|
|
48
|
+
if auth.provided? and auth.basic? and auth.credentials
|
|
49
|
+
params[:login] = auth.credentials.first
|
|
50
|
+
params[:password] = auth.credentials.last
|
|
51
|
+
res = route_handler.call
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
res
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def _check_login
|
|
58
|
+
begin
|
|
59
|
+
yield
|
|
60
|
+
rescue LoginException => le
|
|
61
|
+
throw :halt, [401, le.message]
|
|
62
|
+
rescue Exception => e
|
|
63
|
+
throw :halt, [500, e.message]
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def _do_get_api_token(params,user)
|
|
68
|
+
if user and user.admin == 1 and user.token
|
|
69
|
+
user.token.value
|
|
70
|
+
else
|
|
71
|
+
raise ApiException.new(422, "Invalid/missing API user")
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Rhoconnect
|
|
2
|
+
module Handler
|
|
3
|
+
module Authenticate
|
|
4
|
+
class Runner
|
|
5
|
+
attr_accessor :app, :route_handler, :params
|
|
6
|
+
|
|
7
|
+
include Rhoconnect::Handler::Helpers::Binding
|
|
8
|
+
|
|
9
|
+
def initialize(app, route_handler, params = {})
|
|
10
|
+
raise ArgumentError.new('Invalid app') unless app
|
|
11
|
+
raise ArgumentError.new('Invalid authenticate handler') unless route_handler
|
|
12
|
+
@app = app
|
|
13
|
+
@route_handler = bind_handler(:authenricate_handler_method, route_handler)
|
|
14
|
+
@params = params
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def run
|
|
18
|
+
if params[:login].nil? or params[:login].empty?
|
|
19
|
+
return false
|
|
20
|
+
end
|
|
21
|
+
user = _do_authenticate
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
def _do_authenticate
|
|
26
|
+
user = nil
|
|
27
|
+
if params[:login] == 'rhoadmin'
|
|
28
|
+
user = @route_handler.call
|
|
29
|
+
else
|
|
30
|
+
if Rhoconnect.appserver
|
|
31
|
+
auth_result = Rhoconnect::Model::DynamicAdapterModel.authenticate(params[:login],params[:password])
|
|
32
|
+
else
|
|
33
|
+
auth_result = @route_handler.call
|
|
34
|
+
end
|
|
35
|
+
if auth_result
|
|
36
|
+
params[:login] = auth_result if auth_result.is_a? String
|
|
37
|
+
user = User.load(params[:login]) if User.is_exist?(params[:login])
|
|
38
|
+
if not user
|
|
39
|
+
user = User.create(:login => params[:login])
|
|
40
|
+
app.users << user.id
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
user
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'rhoconnect/handler/helpers'
|
|
2
|
+
|
|
3
|
+
# Bulk Data extenstion
|
|
4
|
+
module Rhoconnect
|
|
5
|
+
module Handler
|
|
6
|
+
module BulkData
|
|
7
|
+
def self.registered(app)
|
|
8
|
+
app.helpers Rhoconnect::Handler::Helpers::BulkData
|
|
9
|
+
# bulk sync request
|
|
10
|
+
app.post "/bulk_data", \
|
|
11
|
+
{ :login_required => true,
|
|
12
|
+
:client_required => true,
|
|
13
|
+
:source_required => false,
|
|
14
|
+
:admin_required => false,
|
|
15
|
+
:deprecated_route => {:verb => :get, :url => ['/application/bulk_data', '/api/application/bulk_data']}
|
|
16
|
+
} do
|
|
17
|
+
content_type :json
|
|
18
|
+
sources_param = params[:sources]
|
|
19
|
+
if sources_param.is_a?String
|
|
20
|
+
sources_param = sources_param.split(',')
|
|
21
|
+
end
|
|
22
|
+
data = do_bulk_data(params[:partition].to_sym,current_client, sources_param)
|
|
23
|
+
data.to_json
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
module Rhoconnect
|
|
2
|
+
module Handler
|
|
3
|
+
module Changes
|
|
4
|
+
class Engine
|
|
5
|
+
attr_accessor :source, :model, :route_handler, :params, :operations
|
|
6
|
+
|
|
7
|
+
include Rhoconnect::Handler::Helpers::SourceJob
|
|
8
|
+
include Rhoconnect::Handler::Helpers::Binding
|
|
9
|
+
include Rhoconnect::Handler::Helpers::AuthMethod
|
|
10
|
+
|
|
11
|
+
def initialize(operations, model, route_handler, params = {})
|
|
12
|
+
raise ArgumentError.new(UNKNOWN_SOURCE) unless (model and model.source)
|
|
13
|
+
raise ArgumentError.new('Invalid app for source') unless model.source.app
|
|
14
|
+
raise ArgumentError.new('Invalid CUD handler') unless route_handler
|
|
15
|
+
|
|
16
|
+
@source = model.source
|
|
17
|
+
# if handler is not bound - bind it to self
|
|
18
|
+
# normally it should be bound to a Controller's instance
|
|
19
|
+
@route_handler = bind_handler(:cud_handler_method, route_handler)
|
|
20
|
+
@params = params
|
|
21
|
+
@model = model
|
|
22
|
+
@operations = operations
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def do_cud
|
|
26
|
+
if source.cud_queue or source.queue
|
|
27
|
+
async(:cud,source.cud_queue || source.queue)
|
|
28
|
+
else
|
|
29
|
+
run_cud
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Pass through CUD to adapter, no data stored
|
|
34
|
+
def do_pass_through_cud
|
|
35
|
+
return if auth_method('login') == false
|
|
36
|
+
res,processed_objects = {},[]
|
|
37
|
+
begin
|
|
38
|
+
operations.each do |op|
|
|
39
|
+
objects = params[op]
|
|
40
|
+
params[:operation] = op if objects
|
|
41
|
+
objects.each do |key,value|
|
|
42
|
+
case op
|
|
43
|
+
when 'create'
|
|
44
|
+
params[:create_object] = value
|
|
45
|
+
@route_handler.call
|
|
46
|
+
when 'update'
|
|
47
|
+
value['id'] = key
|
|
48
|
+
params[:update_object] = value
|
|
49
|
+
@route_handler.call
|
|
50
|
+
when 'delete'
|
|
51
|
+
value['id'] = key
|
|
52
|
+
params[:delete_object] = value
|
|
53
|
+
@route_handler.call
|
|
54
|
+
end
|
|
55
|
+
processed_objects << key
|
|
56
|
+
end if objects
|
|
57
|
+
end
|
|
58
|
+
rescue Exception => e
|
|
59
|
+
log "Error in pass through method: #{e.message}"
|
|
60
|
+
res['error'] = {'message' => e.message }
|
|
61
|
+
end
|
|
62
|
+
auth_method('logoff')
|
|
63
|
+
res['processed'] = processed_objects
|
|
64
|
+
res.to_json
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def run_cud
|
|
68
|
+
return if auth_method('login') == false
|
|
69
|
+
operations.each do |op|
|
|
70
|
+
send op.to_sym
|
|
71
|
+
end
|
|
72
|
+
auth_method('logoff')
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# CUD Operations
|
|
76
|
+
def create
|
|
77
|
+
_measure_and_process_cud('create')
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def update
|
|
81
|
+
_measure_and_process_cud('update')
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def delete
|
|
85
|
+
_measure_and_process_cud('delete')
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
def _measure_and_process_cud(operation)
|
|
90
|
+
Rhoconnect::Stats::Record.update("source:#{operation}:#{@source.name}") do
|
|
91
|
+
params[:operation] = operation
|
|
92
|
+
_process_cud(operation)
|
|
93
|
+
params.delete(:operation)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def _process_create(modified_recs,key,value)
|
|
98
|
+
params[:create_object] = value
|
|
99
|
+
link = route_handler.call
|
|
100
|
+
# Store object-id link for the client
|
|
101
|
+
# If we have a link, store object in client document
|
|
102
|
+
# Otherwise, store object for delete on client
|
|
103
|
+
modified_recs.each do |modified_rec|
|
|
104
|
+
if link
|
|
105
|
+
modified_rec[:links] ||= {}
|
|
106
|
+
modified_rec[:links][modified_rec[:key]] = { 'l' => link.to_s }
|
|
107
|
+
modified_rec[:creates] ||= {}
|
|
108
|
+
modified_rec[:creates][link.to_s] = value
|
|
109
|
+
else
|
|
110
|
+
modified_rec[:deletes] ||= {}
|
|
111
|
+
modified_rec[:deletes][modified_rec[:key]] = value
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def _process_update(modified_recs,key,value)
|
|
117
|
+
# Add id to object hash to forward to backend call
|
|
118
|
+
value['id'] = key
|
|
119
|
+
params[:update_object] = value
|
|
120
|
+
# Perform operation
|
|
121
|
+
route_handler.call
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def _process_delete(modified_recs,key,value)
|
|
125
|
+
value['id'] = key
|
|
126
|
+
params[:delete_object] = value
|
|
127
|
+
route_handler.call
|
|
128
|
+
# Perform operation
|
|
129
|
+
modified_recs.each do |modified_rec|
|
|
130
|
+
modified_rec[:dels] ||= {}
|
|
131
|
+
modified_rec[:dels][modified_rec[:key]] = value
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def _process_cud(operation)
|
|
136
|
+
# take everything from the queue and erase it
|
|
137
|
+
# so that no other process will be able to process it again
|
|
138
|
+
operation_hashes = []
|
|
139
|
+
client_ids = []
|
|
140
|
+
operation_hashes,client_ids = @source.process_queue(operation)
|
|
141
|
+
invalid_meta = @model.validate(operation,operation_hashes,client_ids)
|
|
142
|
+
|
|
143
|
+
errors,links,deletes,creates,dels = {},{},{},{},{}
|
|
144
|
+
operation_hashes.each_with_index do |client_operation_data,index|
|
|
145
|
+
client_id = client_ids[index]
|
|
146
|
+
|
|
147
|
+
current_invalid_meta = invalid_meta[index] || {}
|
|
148
|
+
client_operation_data.each do |key, value|
|
|
149
|
+
begin
|
|
150
|
+
continue_loop = true
|
|
151
|
+
modified_recs = [{:client_id => client_id, :key => key, :value => value }]
|
|
152
|
+
record_invalid_meta = current_invalid_meta[key] || {}
|
|
153
|
+
# Remove object from queue
|
|
154
|
+
client_operation_data.delete(key)
|
|
155
|
+
|
|
156
|
+
# skip the rec - if it is a duplicate of some other record
|
|
157
|
+
next if record_invalid_meta[:duplicate_of]
|
|
158
|
+
|
|
159
|
+
# prepare duplicate docs
|
|
160
|
+
duplicates = record_invalid_meta[:duplicates] || {}
|
|
161
|
+
duplicates.each do |duplicate|
|
|
162
|
+
modified_recs << duplicate
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# raise conflict error if record is marked with one
|
|
166
|
+
raise Rhoconnect::Model::ObjectConflictErrorException.new(record_invalid_meta[:error]) if record_invalid_meta[:error]
|
|
167
|
+
|
|
168
|
+
# Call on source adapter to process individual object
|
|
169
|
+
case operation
|
|
170
|
+
when 'create'
|
|
171
|
+
_process_create(modified_recs,key,value)
|
|
172
|
+
when 'update'
|
|
173
|
+
_process_update(modified_recs,key,value)
|
|
174
|
+
when 'delete'
|
|
175
|
+
_process_delete(modified_recs,key,value)
|
|
176
|
+
end
|
|
177
|
+
rescue Exception => e
|
|
178
|
+
log "Model raised #{operation} exception: #{e}"
|
|
179
|
+
log e.backtrace.join("\n")
|
|
180
|
+
continue_loop = false
|
|
181
|
+
modified_recs.each do |modified_rec|
|
|
182
|
+
modified_rec[:errors] ||= {}
|
|
183
|
+
modified_rec[:errors][modified_rec[:key]] = modified_rec[:value]
|
|
184
|
+
modified_rec[:errors]["#{modified_rec[:key]}-error"] = {'message'=>e.message}
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
{ :errors => errors,
|
|
189
|
+
:links => links,
|
|
190
|
+
:deletes => deletes,
|
|
191
|
+
:creates => creates,
|
|
192
|
+
:dels => dels }.each do |doc_name, doc|
|
|
193
|
+
modified_recs.each do |modified_rec|
|
|
194
|
+
doc[modified_rec[:client_id]] ||= {}
|
|
195
|
+
next unless modified_rec[doc_name]
|
|
196
|
+
doc[modified_rec[:client_id]].merge!(modified_rec[doc_name])
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
break unless continue_loop
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Record rest of queue (if something in the middle failed)
|
|
203
|
+
if not client_operation_data.empty?
|
|
204
|
+
@source.push_queue(operation,client_id,client_operation_data,true)
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# now, process all the modified docs
|
|
209
|
+
processed_clients = {}
|
|
210
|
+
client_ids.each do |client_id|
|
|
211
|
+
processed_clients[client_id] = Client.load(client_id,{:source_name => @source.name}) unless processed_clients[client_id]
|
|
212
|
+
end
|
|
213
|
+
{ "delete_page" => deletes,
|
|
214
|
+
"#{operation}_links" => links,
|
|
215
|
+
"#{operation}_errors" => errors }.each do |doctype,client_docs|
|
|
216
|
+
client_docs.each do |client_id,data|
|
|
217
|
+
client = processed_clients[client_id]
|
|
218
|
+
client.put_data(doctype,data,true) unless data.empty?
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
if operation == 'create'
|
|
223
|
+
total_creates = {}
|
|
224
|
+
creates.each do |client_id,client_doc|
|
|
225
|
+
next if client_doc.empty?
|
|
226
|
+
client = processed_clients[client_id]
|
|
227
|
+
client.put_data(:cd,client_doc,true)
|
|
228
|
+
client.update_count(:cd_size,client_doc.size)
|
|
229
|
+
total_creates.merge!(client_doc)
|
|
230
|
+
end
|
|
231
|
+
unless total_creates.empty?
|
|
232
|
+
@source.lock(:md) do |s|
|
|
233
|
+
s.put_data(:md,total_creates,true)
|
|
234
|
+
s.update_count(:md_size,total_creates.size)
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
if operation == 'delete'
|
|
240
|
+
# Clean up deleted objects from master document and corresponding client document
|
|
241
|
+
total_dels = {}
|
|
242
|
+
objs = {}
|
|
243
|
+
dels.each do |client_id,client_doc|
|
|
244
|
+
next if client_doc.empty?
|
|
245
|
+
client = processed_clients[client_id]
|
|
246
|
+
client.delete_data(:cd,client_doc)
|
|
247
|
+
client.update_count(:cd_size,-client_doc.size)
|
|
248
|
+
total_dels.merge!(client_doc)
|
|
249
|
+
end
|
|
250
|
+
unless total_dels.empty?
|
|
251
|
+
@source.lock(:md) do |s|
|
|
252
|
+
s.delete_data(:md,total_dels)
|
|
253
|
+
s.update_count(:md_size,-total_dels.size)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
if operation == 'update'
|
|
258
|
+
errors.each do |client_id, error_doc|
|
|
259
|
+
next if error_doc.empty?
|
|
260
|
+
client = processed_clients[client_id]
|
|
261
|
+
cd = client.get_data(:cd)
|
|
262
|
+
error_doc.each do |key, value|
|
|
263
|
+
client.put_data(:update_rollback,{key => cd[key]},true) if cd[key]
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|