diff --git a/services/sync/modules/constants.js b/services/sync/modules/constants.js index 7160fd57e04b..5ee630e287c6 100644 --- a/services/sync/modules/constants.js +++ b/services/sync/modules/constants.js @@ -92,6 +92,7 @@ MOBILE_BATCH_SIZE: 50, // Default batch size for applying incoming records. DEFAULT_STORE_BATCH_SIZE: 1, HISTORY_STORE_BATCH_SIZE: 50, // same as MOBILE_BATCH_SIZE +FORMS_STORE_BATCH_SIZE: 50, // same as MOBILE_BATCH_SIZE // score thresholds for early syncs SINGLE_USER_THRESHOLD: 1000, diff --git a/services/sync/modules/engines/forms.js b/services/sync/modules/engines/forms.js index 8bb5ebd5cf96..0a086e4b7f82 100644 --- a/services/sync/modules/engines/forms.js +++ b/services/sync/modules/engines/forms.js @@ -44,6 +44,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://services-sync/engines.js"); Cu.import("resource://services-sync/record.js"); Cu.import("resource://services-sync/util.js"); +Cu.import("resource://services-sync/constants.js"); Cu.import("resource://services-sync/log4moz.js"); const FORMS_TTL = 5184000; // 60 days @@ -159,6 +160,8 @@ FormEngine.prototype = { _storeObj: FormStore, _trackerObj: FormTracker, _recordObj: FormRec, + applyIncomingBatchSize: FORMS_STORE_BATCH_SIZE, + get prefName() "history", _findDupe: function _findDupe(item) { @@ -173,6 +176,12 @@ function FormStore(name) { FormStore.prototype = { __proto__: Store.prototype, + applyIncomingBatch: function applyIncomingBatch(records) { + return Utils.runInTransaction(Svc.Form.DBConnection, function() { + return Store.prototype.applyIncomingBatch.call(this, records); + }, this); + }, + getAllIDs: function FormStore_getAllIDs() { let guids = {}; for each (let {name, value} in FormWrapper.getAllEntries()) diff --git a/services/sync/modules/util.js b/services/sync/modules/util.js index ab26ff688759..c367e819059b 100644 --- a/services/sync/modules/util.js +++ b/services/sync/modules/util.js @@ -198,7 +198,23 @@ let Utils = { throw batchEx; }; }, - + + runInTransaction: function(db, callback, thisObj) { + let hasTransaction = false; + try { + db.beginTransaction(); + hasTransaction = true; + } catch(e) { /* om nom nom exceptions */ } + + try { + return callback.call(thisObj); + } finally { + if (hasTransaction) { + db.commitTransaction(); + } + } + }, + createStatement: function createStatement(db, query) { // Gecko 2.0 if (db.createAsyncStatement) diff --git a/services/sync/tests/unit/test_forms_store.js b/services/sync/tests/unit/test_forms_store.js index 45447bc771ba..5f572efc5f4a 100644 --- a/services/sync/tests/unit/test_forms_store.js +++ b/services/sync/tests/unit/test_forms_store.js @@ -1,10 +1,15 @@ _("Make sure the form store follows the Store api and correctly accesses the backend form storage"); Cu.import("resource://services-sync/engines/forms.js"); +Cu.import("resource://services-sync/util.js"); function run_test() { let baseuri = "http://fake/uri/"; let store = new FormEngine()._store; + function applyEnsureNoFailures(records) { + do_check_eq(store.applyIncomingBatch(records).length, 0); + } + _("Remove any existing entries"); store.wipe(); for (let id in store.getAllIDs()) { @@ -12,10 +17,11 @@ function run_test() { } _("Add a form entry"); - store.create({ + applyEnsureNoFailures([{ + id: Utils.makeGUID(), name: "name!!", value: "value??" - }); + }]); _("Should have 1 entry now"); let id = ""; @@ -45,10 +51,11 @@ function run_test() { } _("Add another entry"); - store.create({ + applyEnsureNoFailures([{ + id: Utils.makeGUID(), name: "another", value: "entry" - }); + }]); id = ""; for (let _id in store.getAllIDs()) { if (id == "")