Comparing version 3.2.2 to 3.3.0
#!/usr/bin/env node | ||
var version = '3.2.2', | ||
var version = '3.3.0', | ||
shelljs = require('shelljs'), | ||
@@ -259,3 +259,2 @@ exec = require('child_process').exec, | ||
dependencyPackages.sdkcommon, | ||
dependencyPackages.openssl, | ||
dependencyPackages.sqlcipher, | ||
@@ -452,3 +451,2 @@ dependencyPackages.salesforceNetwork, | ||
packageMap.commonutils = makePackageObj(path.join(__dirname, 'Dependencies', 'ThirdParty', 'SalesforceCommonUtils'), outputDirMap.appDependenciesDir, dependencyType.DIR); | ||
packageMap.openssl = makePackageObj(path.join(__dirname, 'Dependencies', 'ThirdParty', 'openssl'), outputDirMap.appDependenciesDir, dependencyType.DIR); | ||
packageMap.sqlcipher = makePackageObj(path.join(__dirname, 'Dependencies', 'ThirdParty', 'sqlcipher'), outputDirMap.appDependenciesDir, dependencyType.DIR); | ||
@@ -455,0 +453,0 @@ return packageMap; |
@@ -50,5 +50,5 @@ cordova.define('cordova/plugin_list', function(require, exports, module) { | ||
{ | ||
"com.salesforce": "3.2.0" | ||
"com.salesforce": "3.3.0" | ||
} | ||
// BOTTOM OF METADATA | ||
}); |
cordova.define("com.salesforce.plugin.oauth", function(require, exports, module) { | ||
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -29,3 +29,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
var SERVICE = "com.salesforce.oauth"; | ||
@@ -32,0 +32,0 @@ |
cordova.define("com.salesforce.plugin.sdkinfo", function(require, exports, module) { | ||
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -29,3 +29,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
var SERVICE = "com.salesforce.sdkinfo"; | ||
@@ -32,0 +32,0 @@ |
cordova.define("com.salesforce.plugin.sfaccountmanager", function(require, exports, module) { | ||
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -29,3 +29,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
var SERVICE = "com.salesforce.sfaccountmanager"; | ||
@@ -32,0 +32,0 @@ |
cordova.define("com.salesforce.plugin.smartstore", function(require, exports, module) { | ||
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -29,3 +29,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
var SERVICE = "com.salesforce.smartstore"; | ||
@@ -54,3 +54,3 @@ | ||
//for queryType "exact" | ||
//for queryType "exact" and "match" | ||
this.matchKey = null; | ||
@@ -70,2 +70,5 @@ | ||
//path to sort by : optional | ||
this.orderPath = null | ||
//"ascending" or "descending" : optional | ||
@@ -122,2 +125,3 @@ this.order = "ascending"; | ||
inst.queryType = "range"; | ||
inst.orderPath = path; | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
@@ -129,6 +133,8 @@ if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
// Returns a query spec that will page all entries exactly matching the matchKey value for path | ||
var buildExactQuerySpec = function (path, matchKey, pageSize) { | ||
var buildExactQuerySpec = function (path, matchKey, pageSize, order, orderPath) { | ||
var inst = new QuerySpec(path); | ||
inst.matchKey = matchKey; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
@@ -138,3 +144,3 @@ }; | ||
// Returns a query spec that will page all entries in the range beginKey ...endKey for path | ||
var buildRangeQuerySpec = function (path, beginKey, endKey, order, pageSize) { | ||
var buildRangeQuerySpec = function (path, beginKey, endKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
@@ -146,2 +152,3 @@ inst.queryType = "range"; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
@@ -151,3 +158,3 @@ }; | ||
// Returns a query spec that will page all entries matching the given likeKey value for path | ||
var buildLikeQuerySpec = function (path, likeKey, order, pageSize) { | ||
var buildLikeQuerySpec = function (path, likeKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
@@ -158,5 +165,19 @@ inst.queryType = "like"; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
}; | ||
// Returns a query spec that will page all entries matching the given full-text search matchKey value for path | ||
// Pass null for path to match matchKey across all full-text indexed fields | ||
var buildMatchQuerySpec = function (path, matchKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
inst.queryType = "match"; | ||
inst.matchKey = matchKey; | ||
inst.orderPath = orderPath; | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
}; | ||
// Returns a query spec that will page all results returned by smartSql | ||
@@ -271,2 +292,3 @@ var buildSmartQuerySpec = function (smartSql, pageSize) { | ||
if (querySpec.queryType == "smart") throw new Error("Smart queries can only be run using runSmartQuery"); | ||
if (querySpec.order != null && querySpec.orderPath == null) querySpec.orderPath = querySpec.indexPath; // for backward compatibility with pre-3.3 code | ||
storeConsole.debug("SmartStore.querySoup:isGlobalStore=" +isGlobalStore+ ",soupName=" + soupName + ",indexPath=" + querySpec.indexPath); | ||
@@ -371,2 +393,3 @@ exec(SALESFORCE_MOBILE_SDK_VERSION, successCB, errorCB, SERVICE, | ||
buildSmartQuerySpec: buildSmartQuerySpec, | ||
buildMatchQuerySpec: buildMatchQuerySpec, | ||
clearSoup: clearSoup, | ||
@@ -373,0 +396,0 @@ closeCursor: closeCursor, |
cordova.define("com.salesforce.plugin.smartsync", function(require, exports, module) { | ||
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -29,3 +29,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
var SERVICE = "com.salesforce.smartsync"; | ||
@@ -32,0 +32,0 @@ |
cordova.define("com.salesforce.util.bootstrap", function(require, exports, module) { | ||
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -29,3 +29,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -32,0 +32,0 @@ var logger = require("com.salesforce.util.logger"); |
cordova.define("com.salesforce.util.event", function(require, exports, module) { | ||
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -29,3 +29,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -32,0 +32,0 @@ var logger = require("com.salesforce.util.logger"); |
cordova.define("com.salesforce.util.exec", function(require, exports, module) { | ||
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -29,3 +29,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
var exec = function(pluginVersion, successCB, errorCB, service, action, args) { | ||
@@ -32,0 +32,0 @@ var tag = "TIMING " + service + ":" + action; |
cordova.define("com.salesforce.util.logger", function(require, exports, module) { | ||
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -29,3 +29,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
var appStartTime = (new Date()).getTime(); // Used for debug timing measurements. | ||
@@ -32,0 +32,0 @@ |
cordova.define("com.salesforce.util.push", function(require, exports, module) { | ||
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -29,3 +29,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -32,0 +32,0 @@ /** |
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -28,3 +28,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
var SERVICE = "com.salesforce.oauth"; | ||
@@ -31,0 +31,0 @@ |
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -28,3 +28,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
var SERVICE = "com.salesforce.sdkinfo"; | ||
@@ -31,0 +31,0 @@ |
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -28,3 +28,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
var SERVICE = "com.salesforce.sfaccountmanager"; | ||
@@ -31,0 +31,0 @@ |
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -28,3 +28,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
var SERVICE = "com.salesforce.smartstore"; | ||
@@ -53,3 +53,3 @@ | ||
//for queryType "exact" | ||
//for queryType "exact" and "match" | ||
this.matchKey = null; | ||
@@ -69,2 +69,5 @@ | ||
//path to sort by : optional | ||
this.orderPath = null | ||
//"ascending" or "descending" : optional | ||
@@ -121,2 +124,3 @@ this.order = "ascending"; | ||
inst.queryType = "range"; | ||
inst.orderPath = path; | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
@@ -128,6 +132,8 @@ if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
// Returns a query spec that will page all entries exactly matching the matchKey value for path | ||
var buildExactQuerySpec = function (path, matchKey, pageSize) { | ||
var buildExactQuerySpec = function (path, matchKey, pageSize, order, orderPath) { | ||
var inst = new QuerySpec(path); | ||
inst.matchKey = matchKey; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
@@ -137,3 +143,3 @@ }; | ||
// Returns a query spec that will page all entries in the range beginKey ...endKey for path | ||
var buildRangeQuerySpec = function (path, beginKey, endKey, order, pageSize) { | ||
var buildRangeQuerySpec = function (path, beginKey, endKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
@@ -145,2 +151,3 @@ inst.queryType = "range"; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
@@ -150,3 +157,3 @@ }; | ||
// Returns a query spec that will page all entries matching the given likeKey value for path | ||
var buildLikeQuerySpec = function (path, likeKey, order, pageSize) { | ||
var buildLikeQuerySpec = function (path, likeKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
@@ -157,5 +164,19 @@ inst.queryType = "like"; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
}; | ||
// Returns a query spec that will page all entries matching the given full-text search matchKey value for path | ||
// Pass null for path to match matchKey across all full-text indexed fields | ||
var buildMatchQuerySpec = function (path, matchKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
inst.queryType = "match"; | ||
inst.matchKey = matchKey; | ||
inst.orderPath = orderPath; | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
}; | ||
// Returns a query spec that will page all results returned by smartSql | ||
@@ -270,2 +291,3 @@ var buildSmartQuerySpec = function (smartSql, pageSize) { | ||
if (querySpec.queryType == "smart") throw new Error("Smart queries can only be run using runSmartQuery"); | ||
if (querySpec.order != null && querySpec.orderPath == null) querySpec.orderPath = querySpec.indexPath; // for backward compatibility with pre-3.3 code | ||
storeConsole.debug("SmartStore.querySoup:isGlobalStore=" +isGlobalStore+ ",soupName=" + soupName + ",indexPath=" + querySpec.indexPath); | ||
@@ -370,2 +392,3 @@ exec(SALESFORCE_MOBILE_SDK_VERSION, successCB, errorCB, SERVICE, | ||
buildSmartQuerySpec: buildSmartQuerySpec, | ||
buildMatchQuerySpec: buildMatchQuerySpec, | ||
clearSoup: clearSoup, | ||
@@ -372,0 +395,0 @@ closeCursor: closeCursor, |
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -28,3 +28,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
var SERVICE = "com.salesforce.smartsync"; | ||
@@ -31,0 +31,0 @@ |
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -28,3 +28,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -31,0 +31,0 @@ var logger = require("com.salesforce.util.logger"); |
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -28,3 +28,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -31,0 +31,0 @@ var logger = require("com.salesforce.util.logger"); |
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -28,3 +28,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
var exec = function(pluginVersion, successCB, errorCB, service, action, args) { | ||
@@ -31,0 +31,0 @@ var tag = "TIMING " + service + ":" + action; |
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -28,3 +28,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
var appStartTime = (new Date()).getTime(); // Used for debug timing measurements. | ||
@@ -31,0 +31,0 @@ |
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -28,3 +28,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -31,0 +31,0 @@ /** |
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -28,3 +28,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -492,3 +492,3 @@ /** | ||
//for queryType "exact" | ||
//for queryType "exact" and "match" | ||
this.matchKey = null; | ||
@@ -508,2 +508,5 @@ | ||
//path to sort by : optional | ||
this.orderPath = null | ||
//"ascending" or "descending" : optional | ||
@@ -560,2 +563,3 @@ this.order = "ascending"; | ||
inst.queryType = "range"; | ||
inst.orderPath = path; | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
@@ -567,6 +571,8 @@ if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
// Returns a query spec that will page all entries exactly matching the matchKey value for path | ||
var buildExactQuerySpec = function (path, matchKey, pageSize) { | ||
var buildExactQuerySpec = function (path, matchKey, pageSize, order, orderPath) { | ||
var inst = new QuerySpec(path); | ||
inst.matchKey = matchKey; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
@@ -576,3 +582,3 @@ }; | ||
// Returns a query spec that will page all entries in the range beginKey ...endKey for path | ||
var buildRangeQuerySpec = function (path, beginKey, endKey, order, pageSize) { | ||
var buildRangeQuerySpec = function (path, beginKey, endKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
@@ -584,2 +590,3 @@ inst.queryType = "range"; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
@@ -589,3 +596,3 @@ }; | ||
// Returns a query spec that will page all entries matching the given likeKey value for path | ||
var buildLikeQuerySpec = function (path, likeKey, order, pageSize) { | ||
var buildLikeQuerySpec = function (path, likeKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
@@ -596,5 +603,19 @@ inst.queryType = "like"; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
}; | ||
// Returns a query spec that will page all entries matching the given full-text search matchKey value for path | ||
// Pass null for path to match matchKey across all full-text indexed fields | ||
var buildMatchQuerySpec = function (path, matchKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
inst.queryType = "match"; | ||
inst.matchKey = matchKey; | ||
inst.orderPath = orderPath; | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
}; | ||
// Returns a query spec that will page all results returned by smartSql | ||
@@ -709,2 +730,3 @@ var buildSmartQuerySpec = function (smartSql, pageSize) { | ||
if (querySpec.queryType == "smart") throw new Error("Smart queries can only be run using runSmartQuery"); | ||
if (querySpec.order != null && querySpec.orderPath == null) querySpec.orderPath = querySpec.indexPath; // for backward compatibility with pre-3.3 code | ||
storeConsole.debug("SmartStore.querySoup:isGlobalStore=" +isGlobalStore+ ",soupName=" + soupName + ",indexPath=" + querySpec.indexPath); | ||
@@ -809,2 +831,3 @@ exec(SALESFORCE_MOBILE_SDK_VERSION, successCB, errorCB, SERVICE, | ||
buildSmartQuerySpec: buildSmartQuerySpec, | ||
buildMatchQuerySpec: buildMatchQuerySpec, | ||
clearSoup: clearSoup, | ||
@@ -811,0 +834,0 @@ closeCursor: closeCursor, |
@@ -30,3 +30,3 @@ /* | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -269,3 +269,3 @@ /* | ||
// In PhoneGap OR outside | ||
if (location.protocol === 'file:' || this.proxyUrl != null) { | ||
if (location.protocol === 'ms-appx:' || location.protocol === 'ms-appx-web:' || location.protocol === 'file:' || this.proxyUrl != null) { | ||
this.instanceUrl = instanceUrl; | ||
@@ -272,0 +272,0 @@ } |
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -28,3 +28,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -492,3 +492,3 @@ /** | ||
//for queryType "exact" | ||
//for queryType "exact" and "match" | ||
this.matchKey = null; | ||
@@ -508,2 +508,5 @@ | ||
//path to sort by : optional | ||
this.orderPath = null | ||
//"ascending" or "descending" : optional | ||
@@ -560,2 +563,3 @@ this.order = "ascending"; | ||
inst.queryType = "range"; | ||
inst.orderPath = path; | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
@@ -567,6 +571,8 @@ if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
// Returns a query spec that will page all entries exactly matching the matchKey value for path | ||
var buildExactQuerySpec = function (path, matchKey, pageSize) { | ||
var buildExactQuerySpec = function (path, matchKey, pageSize, order, orderPath) { | ||
var inst = new QuerySpec(path); | ||
inst.matchKey = matchKey; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
@@ -576,3 +582,3 @@ }; | ||
// Returns a query spec that will page all entries in the range beginKey ...endKey for path | ||
var buildRangeQuerySpec = function (path, beginKey, endKey, order, pageSize) { | ||
var buildRangeQuerySpec = function (path, beginKey, endKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
@@ -584,2 +590,3 @@ inst.queryType = "range"; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
@@ -589,3 +596,3 @@ }; | ||
// Returns a query spec that will page all entries matching the given likeKey value for path | ||
var buildLikeQuerySpec = function (path, likeKey, order, pageSize) { | ||
var buildLikeQuerySpec = function (path, likeKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
@@ -596,5 +603,19 @@ inst.queryType = "like"; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
}; | ||
// Returns a query spec that will page all entries matching the given full-text search matchKey value for path | ||
// Pass null for path to match matchKey across all full-text indexed fields | ||
var buildMatchQuerySpec = function (path, matchKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
inst.queryType = "match"; | ||
inst.matchKey = matchKey; | ||
inst.orderPath = orderPath; | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
}; | ||
// Returns a query spec that will page all results returned by smartSql | ||
@@ -709,2 +730,3 @@ var buildSmartQuerySpec = function (smartSql, pageSize) { | ||
if (querySpec.queryType == "smart") throw new Error("Smart queries can only be run using runSmartQuery"); | ||
if (querySpec.order != null && querySpec.orderPath == null) querySpec.orderPath = querySpec.indexPath; // for backward compatibility with pre-3.3 code | ||
storeConsole.debug("SmartStore.querySoup:isGlobalStore=" +isGlobalStore+ ",soupName=" + soupName + ",indexPath=" + querySpec.indexPath); | ||
@@ -809,2 +831,3 @@ exec(SALESFORCE_MOBILE_SDK_VERSION, successCB, errorCB, SERVICE, | ||
buildSmartQuerySpec: buildSmartQuerySpec, | ||
buildMatchQuerySpec: buildMatchQuerySpec, | ||
clearSoup: clearSoup, | ||
@@ -811,0 +834,0 @@ closeCursor: closeCursor, |
@@ -30,3 +30,3 @@ /* | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -269,3 +269,3 @@ /* | ||
// In PhoneGap OR outside | ||
if (location.protocol === 'file:' || this.proxyUrl != null) { | ||
if (location.protocol === 'ms-appx:' || location.protocol === 'ms-appx-web:' || location.protocol === 'file:' || this.proxyUrl != null) { | ||
this.instanceUrl = instanceUrl; | ||
@@ -272,0 +272,0 @@ } |
@@ -294,3 +294,3 @@ /* | ||
_supportedQueries : function() { | ||
supportedQueries : function() { | ||
// NB we don't have full support evidently | ||
@@ -302,3 +302,3 @@ return [ | ||
pattern: /SELECT (.*) FROM {(.*)} WHERE {(.*):(.*)} IN \((.*)\)/i, | ||
processor: this._smartQuerySoupIn | ||
processor: this.smartQuerySoupIn | ||
}, | ||
@@ -309,3 +309,3 @@ { | ||
pattern: /SELECT {(.*):_soup} FROM {(.*)} WHERE {(.*):(.*)} LIKE '(.*)'(?: ORDER BY LOWER\({(.*):(.*)}\))?/i, | ||
processor: this._smartQuerySoupLikeOrdered | ||
processor: this.smartQuerySoupLikeOrdered | ||
}, | ||
@@ -316,3 +316,3 @@ { | ||
pattern: /SELECT count\(\*\) FROM {(.*)}/i, | ||
processor: this._smartQuerySoupCount | ||
processor: this.smartQuerySoupCount | ||
}, | ||
@@ -323,3 +323,3 @@ { | ||
pattern: /SELECT {(.*):_soup} FROM {(.*)} WHERE {(.*):(.*)} ([!=<>]+) ([0-9]+)(?: ORDER BY LOWER\({(.*):(.*)}\))?/i, | ||
processor: this._smartQuerySoupCompare | ||
processor: this.smartQuerySoupCompare | ||
} | ||
@@ -330,5 +330,5 @@ | ||
_smartQuerySoupIn : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupIn : function(queryDesc, matches, smartSql) { | ||
var soupName = matches[2]; | ||
var selectFields = this._getSelectFields(soupName, matches[1]); | ||
var selectFields = this.getSelectFields(soupName, matches[1]); | ||
var whereField = matches[4]; | ||
@@ -373,3 +373,3 @@ var values = matches[5].split(","); | ||
// Expect comma separated of {soupName:y}, return array with the values of y | ||
_getSelectFields: function(soupName, s) { | ||
getSelectFields: function(soupName, s) { | ||
var fields = []; | ||
@@ -391,3 +391,3 @@ var fieldPattern = /{(.*):(.*)}/; | ||
_smartQuerySoupLikeOrdered : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupLikeOrdered : function(queryDesc, matches, smartSql) { | ||
if (matches[1] === matches[2] && matches[1] === matches[3] && (!matches[6] || matches[1] === matches[6])) { | ||
@@ -428,3 +428,3 @@ var soupName = matches[1]; | ||
_smartQuerySoupCount : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupCount : function(queryDesc, matches, smartSql) { | ||
var soupName = matches[1]; | ||
@@ -440,3 +440,3 @@ this.checkSoup(soupName); | ||
_smartQuerySoupCompare : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupCompare : function(queryDesc, matches, smartSql) { | ||
if (matches[1] === matches[2] && matches[1] === matches[3] && (!matches[7] || matches[1] === matches[7])) { | ||
@@ -491,3 +491,3 @@ // Gather the parameters. | ||
var smartSql = querySpec.smartSql; | ||
var supportedQueries = this._supportedQueries(); | ||
var supportedQueries = this.supportedQueries(); | ||
@@ -512,2 +512,116 @@ for (var i = 0; i < supportedQueries.length; i++) { | ||
// Support some full-text queries (see doesFullTextMatch for details) | ||
querySoupFullTextSearch: function(soupName, querySpec) { | ||
this.checkSoup(soupName); | ||
var soup = this._soups[soupName]; | ||
var soupIndexedData = this._soupIndexedData[soupName]; | ||
var results = []; | ||
var paths = []; | ||
if (querySpec.indexPath) { | ||
paths.push(querySpec.indexPath); | ||
} | ||
else { | ||
// No indexPath provided, match against all full-text fields | ||
var indexSpecs = this._soupIndexSpecs[soupName]; | ||
for (var i=0; i<indexSpecs.length; i++) { | ||
var indexSpec = indexSpecs[i]; | ||
if (indexSpec.type === "full_text") { | ||
paths.push(indexSpec.path); | ||
} | ||
} | ||
} | ||
for (var soupEntryId in soup) { | ||
var soupElt = soup[soupEntryId]; | ||
var text = ""; | ||
if (querySpec.indexPath) { | ||
text = soupIndexedData[soupEntryId][querySpec.indexPath]; | ||
} | ||
else { | ||
// No indexPath provided, match against all full-text fields | ||
var indexSpecs = this._soupIndexSpecs[soupName]; | ||
for (var i=0; i<indexSpecs.length; i++) { | ||
var indexSpec = indexSpecs[i]; | ||
if (indexSpec.type === "full_text") { | ||
text += soupIndexedData[soupEntryId][indexSpec.path] + " "; | ||
} | ||
} | ||
} | ||
if (this.doesFullTextMatch(text, querySpec.matchKey)) { | ||
results.push(soupElt); | ||
} | ||
} | ||
return this.sortResults(results, querySpec); | ||
}, | ||
// query: space separated terms that all need to be in text | ||
// A term can be prefixed by - to indicate it should not be present. | ||
// A term can be suffixed by * to indicate to match any words starting with that term | ||
// | ||
// Example for the text: "the fox jumped over the dog" | ||
// query "fox dog" will return true | ||
// query "fox NOT dog" will return false | ||
// query "f* dog" will return true | ||
doesFullTextMatch: function(text, query) { | ||
var queryWithMinusForNots = query.replace(/ NOT /g, " -"); // code was originally written for standard syntax, turning "abc NOT def" into "abc -def" | ||
var wordsOfQuery = queryWithMinusForNots.split(/[^a-zA-Z0-9*-]/); | ||
wordsOfQuery.sort(); // to move the "-" words first | ||
var wordsOfElt = text.split(/\W/); | ||
wordsOfElt.sort(); // to speed up matches | ||
for (var j=0; j<wordsOfQuery.length; j++) { | ||
var wordOfQuery = wordsOfQuery[j].trim(); | ||
if (wordOfQuery == "") { | ||
continue; | ||
} | ||
// Negative keyword (keyword to exclude) | ||
if (wordOfQuery.indexOf("-") == 0) { | ||
wordOfQuery = wordOfQuery.substring(1); | ||
for (var i=0; i<wordsOfElt.length; i++) { | ||
var wordOfElt = wordsOfElt[i].trim(); | ||
if (wordOfElt == "") { | ||
continue; | ||
} | ||
if (wordOfElt.indexOf(wordOfQuery) == 0) { | ||
// A query word to exclude was found | ||
return false; | ||
} | ||
} | ||
} | ||
// Regular keyword | ||
else { | ||
var foundQueryWord = false; | ||
for (var i=0; i<wordsOfElt.length; i++) { | ||
var wordOfElt = wordsOfElt[i].trim(); | ||
if (wordOfElt == "") { | ||
continue; | ||
} | ||
if (wordOfQuery.endsWith("*")) { | ||
if (wordOfElt.indexOf(wordOfQuery.substring(0, wordOfQuery.length - 1)) == 0) { | ||
foundQueryWord = true; | ||
// all the "-" tests have already been conducted, we don't need to test further | ||
break; | ||
} | ||
} | ||
else if (wordOfQuery == wordOfElt) { | ||
foundQueryWord = true; | ||
// all the "-" tests have already been conducted, we don't need to test further | ||
break; | ||
} | ||
} | ||
// This query word was not found | ||
if (!foundQueryWord) { | ||
return false; | ||
} | ||
} | ||
} | ||
return true; | ||
}, | ||
querySoupFull: function(soupName, querySpec) { | ||
@@ -518,2 +632,6 @@ if (querySpec.queryType == "smart") { | ||
if (querySpec.queryType == "match") { | ||
return this.querySoupFullTextSearch(soupName, querySpec); | ||
} | ||
// other query type | ||
@@ -548,5 +666,9 @@ this.checkSoup(soupName); | ||
results = results.sort(function(soupElt1,soupElt2) { | ||
var p1 = soupElt1[querySpec.indexPath]; | ||
var p2 = soupElt2[querySpec.indexPath]; | ||
return this.sortResults(results, querySpec); | ||
}, | ||
sortResults: function(results, querySpec) { | ||
var resultsSorted = results.sort(function(soupElt1,soupElt2) { | ||
var p1 = soupElt1[querySpec.orderPath]; | ||
var p2 = soupElt2[querySpec.orderPath]; | ||
var compare = ( p1 > p2 ? 1 : (p1 == p2 ? 0 : -1)); | ||
@@ -556,6 +678,5 @@ return (querySpec.order == "ascending" ? compare : -compare); | ||
return results; | ||
return resultsSorted; | ||
}, | ||
querySoup: function(soupName, querySpec) { | ||
@@ -562,0 +683,0 @@ var results = this.querySoupFull(soupName, querySpec); |
@@ -7,3 +7,3 @@ ## To create an application for ios or android | ||
cordova plugin add org.apache.cordova.statusbar (contactexplorer only) | ||
cordova plugin add https://github.com/wmathurin/SalesforceMobileSDK-CordovaPlugin | ||
cordova plugin add https://github.com/forcedotcom/SalesforceMobileSDK-CordovaPlugin | ||
cordova platform add android (for android) | ||
@@ -10,0 +10,0 @@ node plugins/com.salesforce/tools/postinstall-android.js 19 true (for android) |
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -28,3 +28,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -492,3 +492,3 @@ /** | ||
//for queryType "exact" | ||
//for queryType "exact" and "match" | ||
this.matchKey = null; | ||
@@ -508,2 +508,5 @@ | ||
//path to sort by : optional | ||
this.orderPath = null | ||
//"ascending" or "descending" : optional | ||
@@ -560,2 +563,3 @@ this.order = "ascending"; | ||
inst.queryType = "range"; | ||
inst.orderPath = path; | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
@@ -567,6 +571,8 @@ if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
// Returns a query spec that will page all entries exactly matching the matchKey value for path | ||
var buildExactQuerySpec = function (path, matchKey, pageSize) { | ||
var buildExactQuerySpec = function (path, matchKey, pageSize, order, orderPath) { | ||
var inst = new QuerySpec(path); | ||
inst.matchKey = matchKey; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
@@ -576,3 +582,3 @@ }; | ||
// Returns a query spec that will page all entries in the range beginKey ...endKey for path | ||
var buildRangeQuerySpec = function (path, beginKey, endKey, order, pageSize) { | ||
var buildRangeQuerySpec = function (path, beginKey, endKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
@@ -584,2 +590,3 @@ inst.queryType = "range"; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
@@ -589,3 +596,3 @@ }; | ||
// Returns a query spec that will page all entries matching the given likeKey value for path | ||
var buildLikeQuerySpec = function (path, likeKey, order, pageSize) { | ||
var buildLikeQuerySpec = function (path, likeKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
@@ -596,5 +603,19 @@ inst.queryType = "like"; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
}; | ||
// Returns a query spec that will page all entries matching the given full-text search matchKey value for path | ||
// Pass null for path to match matchKey across all full-text indexed fields | ||
var buildMatchQuerySpec = function (path, matchKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
inst.queryType = "match"; | ||
inst.matchKey = matchKey; | ||
inst.orderPath = orderPath; | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
}; | ||
// Returns a query spec that will page all results returned by smartSql | ||
@@ -709,2 +730,3 @@ var buildSmartQuerySpec = function (smartSql, pageSize) { | ||
if (querySpec.queryType == "smart") throw new Error("Smart queries can only be run using runSmartQuery"); | ||
if (querySpec.order != null && querySpec.orderPath == null) querySpec.orderPath = querySpec.indexPath; // for backward compatibility with pre-3.3 code | ||
storeConsole.debug("SmartStore.querySoup:isGlobalStore=" +isGlobalStore+ ",soupName=" + soupName + ",indexPath=" + querySpec.indexPath); | ||
@@ -809,2 +831,3 @@ exec(SALESFORCE_MOBILE_SDK_VERSION, successCB, errorCB, SERVICE, | ||
buildSmartQuerySpec: buildSmartQuerySpec, | ||
buildMatchQuerySpec: buildMatchQuerySpec, | ||
clearSoup: clearSoup, | ||
@@ -811,0 +834,0 @@ closeCursor: closeCursor, |
@@ -30,3 +30,3 @@ /* | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -269,3 +269,3 @@ /* | ||
// In PhoneGap OR outside | ||
if (location.protocol === 'file:' || this.proxyUrl != null) { | ||
if (location.protocol === 'ms-appx:' || location.protocol === 'ms-appx-web:' || location.protocol === 'file:' || this.proxyUrl != null) { | ||
this.instanceUrl = instanceUrl; | ||
@@ -272,0 +272,0 @@ } |
@@ -294,3 +294,3 @@ /* | ||
_supportedQueries : function() { | ||
supportedQueries : function() { | ||
// NB we don't have full support evidently | ||
@@ -302,3 +302,3 @@ return [ | ||
pattern: /SELECT (.*) FROM {(.*)} WHERE {(.*):(.*)} IN \((.*)\)/i, | ||
processor: this._smartQuerySoupIn | ||
processor: this.smartQuerySoupIn | ||
}, | ||
@@ -309,3 +309,3 @@ { | ||
pattern: /SELECT {(.*):_soup} FROM {(.*)} WHERE {(.*):(.*)} LIKE '(.*)'(?: ORDER BY LOWER\({(.*):(.*)}\))?/i, | ||
processor: this._smartQuerySoupLikeOrdered | ||
processor: this.smartQuerySoupLikeOrdered | ||
}, | ||
@@ -316,3 +316,3 @@ { | ||
pattern: /SELECT count\(\*\) FROM {(.*)}/i, | ||
processor: this._smartQuerySoupCount | ||
processor: this.smartQuerySoupCount | ||
}, | ||
@@ -323,3 +323,3 @@ { | ||
pattern: /SELECT {(.*):_soup} FROM {(.*)} WHERE {(.*):(.*)} ([!=<>]+) ([0-9]+)(?: ORDER BY LOWER\({(.*):(.*)}\))?/i, | ||
processor: this._smartQuerySoupCompare | ||
processor: this.smartQuerySoupCompare | ||
} | ||
@@ -330,5 +330,5 @@ | ||
_smartQuerySoupIn : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupIn : function(queryDesc, matches, smartSql) { | ||
var soupName = matches[2]; | ||
var selectFields = this._getSelectFields(soupName, matches[1]); | ||
var selectFields = this.getSelectFields(soupName, matches[1]); | ||
var whereField = matches[4]; | ||
@@ -373,3 +373,3 @@ var values = matches[5].split(","); | ||
// Expect comma separated of {soupName:y}, return array with the values of y | ||
_getSelectFields: function(soupName, s) { | ||
getSelectFields: function(soupName, s) { | ||
var fields = []; | ||
@@ -391,3 +391,3 @@ var fieldPattern = /{(.*):(.*)}/; | ||
_smartQuerySoupLikeOrdered : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupLikeOrdered : function(queryDesc, matches, smartSql) { | ||
if (matches[1] === matches[2] && matches[1] === matches[3] && (!matches[6] || matches[1] === matches[6])) { | ||
@@ -428,3 +428,3 @@ var soupName = matches[1]; | ||
_smartQuerySoupCount : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupCount : function(queryDesc, matches, smartSql) { | ||
var soupName = matches[1]; | ||
@@ -440,3 +440,3 @@ this.checkSoup(soupName); | ||
_smartQuerySoupCompare : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupCompare : function(queryDesc, matches, smartSql) { | ||
if (matches[1] === matches[2] && matches[1] === matches[3] && (!matches[7] || matches[1] === matches[7])) { | ||
@@ -491,3 +491,3 @@ // Gather the parameters. | ||
var smartSql = querySpec.smartSql; | ||
var supportedQueries = this._supportedQueries(); | ||
var supportedQueries = this.supportedQueries(); | ||
@@ -512,2 +512,116 @@ for (var i = 0; i < supportedQueries.length; i++) { | ||
// Support some full-text queries (see doesFullTextMatch for details) | ||
querySoupFullTextSearch: function(soupName, querySpec) { | ||
this.checkSoup(soupName); | ||
var soup = this._soups[soupName]; | ||
var soupIndexedData = this._soupIndexedData[soupName]; | ||
var results = []; | ||
var paths = []; | ||
if (querySpec.indexPath) { | ||
paths.push(querySpec.indexPath); | ||
} | ||
else { | ||
// No indexPath provided, match against all full-text fields | ||
var indexSpecs = this._soupIndexSpecs[soupName]; | ||
for (var i=0; i<indexSpecs.length; i++) { | ||
var indexSpec = indexSpecs[i]; | ||
if (indexSpec.type === "full_text") { | ||
paths.push(indexSpec.path); | ||
} | ||
} | ||
} | ||
for (var soupEntryId in soup) { | ||
var soupElt = soup[soupEntryId]; | ||
var text = ""; | ||
if (querySpec.indexPath) { | ||
text = soupIndexedData[soupEntryId][querySpec.indexPath]; | ||
} | ||
else { | ||
// No indexPath provided, match against all full-text fields | ||
var indexSpecs = this._soupIndexSpecs[soupName]; | ||
for (var i=0; i<indexSpecs.length; i++) { | ||
var indexSpec = indexSpecs[i]; | ||
if (indexSpec.type === "full_text") { | ||
text += soupIndexedData[soupEntryId][indexSpec.path] + " "; | ||
} | ||
} | ||
} | ||
if (this.doesFullTextMatch(text, querySpec.matchKey)) { | ||
results.push(soupElt); | ||
} | ||
} | ||
return this.sortResults(results, querySpec); | ||
}, | ||
// query: space separated terms that all need to be in text | ||
// A term can be prefixed by - to indicate it should not be present. | ||
// A term can be suffixed by * to indicate to match any words starting with that term | ||
// | ||
// Example for the text: "the fox jumped over the dog" | ||
// query "fox dog" will return true | ||
// query "fox NOT dog" will return false | ||
// query "f* dog" will return true | ||
doesFullTextMatch: function(text, query) { | ||
var queryWithMinusForNots = query.replace(/ NOT /g, " -"); // code was originally written for standard syntax, turning "abc NOT def" into "abc -def" | ||
var wordsOfQuery = queryWithMinusForNots.split(/[^a-zA-Z0-9*-]/); | ||
wordsOfQuery.sort(); // to move the "-" words first | ||
var wordsOfElt = text.split(/\W/); | ||
wordsOfElt.sort(); // to speed up matches | ||
for (var j=0; j<wordsOfQuery.length; j++) { | ||
var wordOfQuery = wordsOfQuery[j].trim(); | ||
if (wordOfQuery == "") { | ||
continue; | ||
} | ||
// Negative keyword (keyword to exclude) | ||
if (wordOfQuery.indexOf("-") == 0) { | ||
wordOfQuery = wordOfQuery.substring(1); | ||
for (var i=0; i<wordsOfElt.length; i++) { | ||
var wordOfElt = wordsOfElt[i].trim(); | ||
if (wordOfElt == "") { | ||
continue; | ||
} | ||
if (wordOfElt.indexOf(wordOfQuery) == 0) { | ||
// A query word to exclude was found | ||
return false; | ||
} | ||
} | ||
} | ||
// Regular keyword | ||
else { | ||
var foundQueryWord = false; | ||
for (var i=0; i<wordsOfElt.length; i++) { | ||
var wordOfElt = wordsOfElt[i].trim(); | ||
if (wordOfElt == "") { | ||
continue; | ||
} | ||
if (wordOfQuery.endsWith("*")) { | ||
if (wordOfElt.indexOf(wordOfQuery.substring(0, wordOfQuery.length - 1)) == 0) { | ||
foundQueryWord = true; | ||
// all the "-" tests have already been conducted, we don't need to test further | ||
break; | ||
} | ||
} | ||
else if (wordOfQuery == wordOfElt) { | ||
foundQueryWord = true; | ||
// all the "-" tests have already been conducted, we don't need to test further | ||
break; | ||
} | ||
} | ||
// This query word was not found | ||
if (!foundQueryWord) { | ||
return false; | ||
} | ||
} | ||
} | ||
return true; | ||
}, | ||
querySoupFull: function(soupName, querySpec) { | ||
@@ -518,2 +632,6 @@ if (querySpec.queryType == "smart") { | ||
if (querySpec.queryType == "match") { | ||
return this.querySoupFullTextSearch(soupName, querySpec); | ||
} | ||
// other query type | ||
@@ -548,5 +666,9 @@ this.checkSoup(soupName); | ||
results = results.sort(function(soupElt1,soupElt2) { | ||
var p1 = soupElt1[querySpec.indexPath]; | ||
var p2 = soupElt2[querySpec.indexPath]; | ||
return this.sortResults(results, querySpec); | ||
}, | ||
sortResults: function(results, querySpec) { | ||
var resultsSorted = results.sort(function(soupElt1,soupElt2) { | ||
var p1 = soupElt1[querySpec.orderPath]; | ||
var p2 = soupElt2[querySpec.orderPath]; | ||
var compare = ( p1 > p2 ? 1 : (p1 == p2 ? 0 : -1)); | ||
@@ -556,6 +678,5 @@ return (querySpec.order == "ascending" ? compare : -compare); | ||
return results; | ||
return resultsSorted; | ||
}, | ||
querySoup: function(soupName, querySpec) { | ||
@@ -562,0 +683,0 @@ var results = this.querySoupFull(soupName, querySpec); |
/* | ||
* Copyright (c) 2012-14, salesforce.com, inc. | ||
* Copyright (c) 2012-15, salesforce.com, inc. | ||
* All rights reserved. | ||
@@ -28,3 +28,3 @@ * | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -492,3 +492,3 @@ /** | ||
//for queryType "exact" | ||
//for queryType "exact" and "match" | ||
this.matchKey = null; | ||
@@ -508,2 +508,5 @@ | ||
//path to sort by : optional | ||
this.orderPath = null | ||
//"ascending" or "descending" : optional | ||
@@ -560,2 +563,3 @@ this.order = "ascending"; | ||
inst.queryType = "range"; | ||
inst.orderPath = path; | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
@@ -567,6 +571,8 @@ if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
// Returns a query spec that will page all entries exactly matching the matchKey value for path | ||
var buildExactQuerySpec = function (path, matchKey, pageSize) { | ||
var buildExactQuerySpec = function (path, matchKey, pageSize, order, orderPath) { | ||
var inst = new QuerySpec(path); | ||
inst.matchKey = matchKey; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
@@ -576,3 +582,3 @@ }; | ||
// Returns a query spec that will page all entries in the range beginKey ...endKey for path | ||
var buildRangeQuerySpec = function (path, beginKey, endKey, order, pageSize) { | ||
var buildRangeQuerySpec = function (path, beginKey, endKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
@@ -584,2 +590,3 @@ inst.queryType = "range"; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
@@ -589,3 +596,3 @@ }; | ||
// Returns a query spec that will page all entries matching the given likeKey value for path | ||
var buildLikeQuerySpec = function (path, likeKey, order, pageSize) { | ||
var buildLikeQuerySpec = function (path, likeKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
@@ -596,5 +603,19 @@ inst.queryType = "like"; | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
}; | ||
// Returns a query spec that will page all entries matching the given full-text search matchKey value for path | ||
// Pass null for path to match matchKey across all full-text indexed fields | ||
var buildMatchQuerySpec = function (path, matchKey, order, pageSize, orderPath) { | ||
var inst = new QuerySpec(path); | ||
inst.queryType = "match"; | ||
inst.matchKey = matchKey; | ||
inst.orderPath = orderPath; | ||
if (order) { inst.order = order; } // override default only if a value was specified | ||
if (pageSize) { inst.pageSize = pageSize; } // override default only if a value was specified | ||
inst.orderPath = orderPath ? orderPath : path; | ||
return inst; | ||
}; | ||
// Returns a query spec that will page all results returned by smartSql | ||
@@ -709,2 +730,3 @@ var buildSmartQuerySpec = function (smartSql, pageSize) { | ||
if (querySpec.queryType == "smart") throw new Error("Smart queries can only be run using runSmartQuery"); | ||
if (querySpec.order != null && querySpec.orderPath == null) querySpec.orderPath = querySpec.indexPath; // for backward compatibility with pre-3.3 code | ||
storeConsole.debug("SmartStore.querySoup:isGlobalStore=" +isGlobalStore+ ",soupName=" + soupName + ",indexPath=" + querySpec.indexPath); | ||
@@ -809,2 +831,3 @@ exec(SALESFORCE_MOBILE_SDK_VERSION, successCB, errorCB, SERVICE, | ||
buildSmartQuerySpec: buildSmartQuerySpec, | ||
buildMatchQuerySpec: buildMatchQuerySpec, | ||
clearSoup: clearSoup, | ||
@@ -811,0 +834,0 @@ closeCursor: closeCursor, |
@@ -30,3 +30,3 @@ /* | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -269,3 +269,3 @@ /* | ||
// In PhoneGap OR outside | ||
if (location.protocol === 'file:' || this.proxyUrl != null) { | ||
if (location.protocol === 'ms-appx:' || location.protocol === 'ms-appx-web:' || location.protocol === 'file:' || this.proxyUrl != null) { | ||
this.instanceUrl = instanceUrl; | ||
@@ -272,0 +272,0 @@ } |
@@ -294,3 +294,3 @@ /* | ||
_supportedQueries : function() { | ||
supportedQueries : function() { | ||
// NB we don't have full support evidently | ||
@@ -302,3 +302,3 @@ return [ | ||
pattern: /SELECT (.*) FROM {(.*)} WHERE {(.*):(.*)} IN \((.*)\)/i, | ||
processor: this._smartQuerySoupIn | ||
processor: this.smartQuerySoupIn | ||
}, | ||
@@ -309,3 +309,3 @@ { | ||
pattern: /SELECT {(.*):_soup} FROM {(.*)} WHERE {(.*):(.*)} LIKE '(.*)'(?: ORDER BY LOWER\({(.*):(.*)}\))?/i, | ||
processor: this._smartQuerySoupLikeOrdered | ||
processor: this.smartQuerySoupLikeOrdered | ||
}, | ||
@@ -316,3 +316,3 @@ { | ||
pattern: /SELECT count\(\*\) FROM {(.*)}/i, | ||
processor: this._smartQuerySoupCount | ||
processor: this.smartQuerySoupCount | ||
}, | ||
@@ -323,3 +323,3 @@ { | ||
pattern: /SELECT {(.*):_soup} FROM {(.*)} WHERE {(.*):(.*)} ([!=<>]+) ([0-9]+)(?: ORDER BY LOWER\({(.*):(.*)}\))?/i, | ||
processor: this._smartQuerySoupCompare | ||
processor: this.smartQuerySoupCompare | ||
} | ||
@@ -330,5 +330,5 @@ | ||
_smartQuerySoupIn : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupIn : function(queryDesc, matches, smartSql) { | ||
var soupName = matches[2]; | ||
var selectFields = this._getSelectFields(soupName, matches[1]); | ||
var selectFields = this.getSelectFields(soupName, matches[1]); | ||
var whereField = matches[4]; | ||
@@ -373,3 +373,3 @@ var values = matches[5].split(","); | ||
// Expect comma separated of {soupName:y}, return array with the values of y | ||
_getSelectFields: function(soupName, s) { | ||
getSelectFields: function(soupName, s) { | ||
var fields = []; | ||
@@ -391,3 +391,3 @@ var fieldPattern = /{(.*):(.*)}/; | ||
_smartQuerySoupLikeOrdered : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupLikeOrdered : function(queryDesc, matches, smartSql) { | ||
if (matches[1] === matches[2] && matches[1] === matches[3] && (!matches[6] || matches[1] === matches[6])) { | ||
@@ -428,3 +428,3 @@ var soupName = matches[1]; | ||
_smartQuerySoupCount : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupCount : function(queryDesc, matches, smartSql) { | ||
var soupName = matches[1]; | ||
@@ -440,3 +440,3 @@ this.checkSoup(soupName); | ||
_smartQuerySoupCompare : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupCompare : function(queryDesc, matches, smartSql) { | ||
if (matches[1] === matches[2] && matches[1] === matches[3] && (!matches[7] || matches[1] === matches[7])) { | ||
@@ -491,3 +491,3 @@ // Gather the parameters. | ||
var smartSql = querySpec.smartSql; | ||
var supportedQueries = this._supportedQueries(); | ||
var supportedQueries = this.supportedQueries(); | ||
@@ -512,2 +512,116 @@ for (var i = 0; i < supportedQueries.length; i++) { | ||
// Support some full-text queries (see doesFullTextMatch for details) | ||
querySoupFullTextSearch: function(soupName, querySpec) { | ||
this.checkSoup(soupName); | ||
var soup = this._soups[soupName]; | ||
var soupIndexedData = this._soupIndexedData[soupName]; | ||
var results = []; | ||
var paths = []; | ||
if (querySpec.indexPath) { | ||
paths.push(querySpec.indexPath); | ||
} | ||
else { | ||
// No indexPath provided, match against all full-text fields | ||
var indexSpecs = this._soupIndexSpecs[soupName]; | ||
for (var i=0; i<indexSpecs.length; i++) { | ||
var indexSpec = indexSpecs[i]; | ||
if (indexSpec.type === "full_text") { | ||
paths.push(indexSpec.path); | ||
} | ||
} | ||
} | ||
for (var soupEntryId in soup) { | ||
var soupElt = soup[soupEntryId]; | ||
var text = ""; | ||
if (querySpec.indexPath) { | ||
text = soupIndexedData[soupEntryId][querySpec.indexPath]; | ||
} | ||
else { | ||
// No indexPath provided, match against all full-text fields | ||
var indexSpecs = this._soupIndexSpecs[soupName]; | ||
for (var i=0; i<indexSpecs.length; i++) { | ||
var indexSpec = indexSpecs[i]; | ||
if (indexSpec.type === "full_text") { | ||
text += soupIndexedData[soupEntryId][indexSpec.path] + " "; | ||
} | ||
} | ||
} | ||
if (this.doesFullTextMatch(text, querySpec.matchKey)) { | ||
results.push(soupElt); | ||
} | ||
} | ||
return this.sortResults(results, querySpec); | ||
}, | ||
// query: space separated terms that all need to be in text | ||
// A term can be prefixed by - to indicate it should not be present. | ||
// A term can be suffixed by * to indicate to match any words starting with that term | ||
// | ||
// Example for the text: "the fox jumped over the dog" | ||
// query "fox dog" will return true | ||
// query "fox NOT dog" will return false | ||
// query "f* dog" will return true | ||
doesFullTextMatch: function(text, query) { | ||
var queryWithMinusForNots = query.replace(/ NOT /g, " -"); // code was originally written for standard syntax, turning "abc NOT def" into "abc -def" | ||
var wordsOfQuery = queryWithMinusForNots.split(/[^a-zA-Z0-9*-]/); | ||
wordsOfQuery.sort(); // to move the "-" words first | ||
var wordsOfElt = text.split(/\W/); | ||
wordsOfElt.sort(); // to speed up matches | ||
for (var j=0; j<wordsOfQuery.length; j++) { | ||
var wordOfQuery = wordsOfQuery[j].trim(); | ||
if (wordOfQuery == "") { | ||
continue; | ||
} | ||
// Negative keyword (keyword to exclude) | ||
if (wordOfQuery.indexOf("-") == 0) { | ||
wordOfQuery = wordOfQuery.substring(1); | ||
for (var i=0; i<wordsOfElt.length; i++) { | ||
var wordOfElt = wordsOfElt[i].trim(); | ||
if (wordOfElt == "") { | ||
continue; | ||
} | ||
if (wordOfElt.indexOf(wordOfQuery) == 0) { | ||
// A query word to exclude was found | ||
return false; | ||
} | ||
} | ||
} | ||
// Regular keyword | ||
else { | ||
var foundQueryWord = false; | ||
for (var i=0; i<wordsOfElt.length; i++) { | ||
var wordOfElt = wordsOfElt[i].trim(); | ||
if (wordOfElt == "") { | ||
continue; | ||
} | ||
if (wordOfQuery.endsWith("*")) { | ||
if (wordOfElt.indexOf(wordOfQuery.substring(0, wordOfQuery.length - 1)) == 0) { | ||
foundQueryWord = true; | ||
// all the "-" tests have already been conducted, we don't need to test further | ||
break; | ||
} | ||
} | ||
else if (wordOfQuery == wordOfElt) { | ||
foundQueryWord = true; | ||
// all the "-" tests have already been conducted, we don't need to test further | ||
break; | ||
} | ||
} | ||
// This query word was not found | ||
if (!foundQueryWord) { | ||
return false; | ||
} | ||
} | ||
} | ||
return true; | ||
}, | ||
querySoupFull: function(soupName, querySpec) { | ||
@@ -518,2 +632,6 @@ if (querySpec.queryType == "smart") { | ||
if (querySpec.queryType == "match") { | ||
return this.querySoupFullTextSearch(soupName, querySpec); | ||
} | ||
// other query type | ||
@@ -548,5 +666,9 @@ this.checkSoup(soupName); | ||
results = results.sort(function(soupElt1,soupElt2) { | ||
var p1 = soupElt1[querySpec.indexPath]; | ||
var p2 = soupElt2[querySpec.indexPath]; | ||
return this.sortResults(results, querySpec); | ||
}, | ||
sortResults: function(results, querySpec) { | ||
var resultsSorted = results.sort(function(soupElt1,soupElt2) { | ||
var p1 = soupElt1[querySpec.orderPath]; | ||
var p2 = soupElt2[querySpec.orderPath]; | ||
var compare = ( p1 > p2 ? 1 : (p1 == p2 ? 0 : -1)); | ||
@@ -556,6 +678,5 @@ return (querySpec.order == "ascending" ? compare : -compare); | ||
return results; | ||
return resultsSorted; | ||
}, | ||
querySoup: function(soupName, querySpec) { | ||
@@ -562,0 +683,0 @@ var results = this.querySoupFull(soupName, querySpec); |
@@ -30,3 +30,3 @@ /* | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -269,3 +269,3 @@ /* | ||
// In PhoneGap OR outside | ||
if (location.protocol === 'file:' || this.proxyUrl != null) { | ||
if (location.protocol === 'ms-appx:' || location.protocol === 'ms-appx-web:' || location.protocol === 'file:' || this.proxyUrl != null) { | ||
this.instanceUrl = instanceUrl; | ||
@@ -272,0 +272,0 @@ } |
@@ -48,3 +48,3 @@ /* | ||
cordova.interceptExec(SDKINFO_SERVICE, "getInfo", function (successCB, errorCB, args) { | ||
successCB(new SDKInfo("3.2.0", | ||
successCB(new SDKInfo("3.3.0", | ||
["com.salesforce.oauth", "com.salesforce.sdkinfo", "com.salesforce.sfaccountmanager", "com.salesforce.testrunner", "com.salesforce.smartstore", "com.salesforce.smartsync"], | ||
@@ -51,0 +51,0 @@ "ForcePluginsTest", "1.0", |
@@ -294,3 +294,3 @@ /* | ||
_supportedQueries : function() { | ||
supportedQueries : function() { | ||
// NB we don't have full support evidently | ||
@@ -302,3 +302,3 @@ return [ | ||
pattern: /SELECT (.*) FROM {(.*)} WHERE {(.*):(.*)} IN \((.*)\)/i, | ||
processor: this._smartQuerySoupIn | ||
processor: this.smartQuerySoupIn | ||
}, | ||
@@ -309,3 +309,3 @@ { | ||
pattern: /SELECT {(.*):_soup} FROM {(.*)} WHERE {(.*):(.*)} LIKE '(.*)'(?: ORDER BY LOWER\({(.*):(.*)}\))?/i, | ||
processor: this._smartQuerySoupLikeOrdered | ||
processor: this.smartQuerySoupLikeOrdered | ||
}, | ||
@@ -316,3 +316,3 @@ { | ||
pattern: /SELECT count\(\*\) FROM {(.*)}/i, | ||
processor: this._smartQuerySoupCount | ||
processor: this.smartQuerySoupCount | ||
}, | ||
@@ -323,3 +323,3 @@ { | ||
pattern: /SELECT {(.*):_soup} FROM {(.*)} WHERE {(.*):(.*)} ([!=<>]+) ([0-9]+)(?: ORDER BY LOWER\({(.*):(.*)}\))?/i, | ||
processor: this._smartQuerySoupCompare | ||
processor: this.smartQuerySoupCompare | ||
} | ||
@@ -330,5 +330,5 @@ | ||
_smartQuerySoupIn : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupIn : function(queryDesc, matches, smartSql) { | ||
var soupName = matches[2]; | ||
var selectFields = this._getSelectFields(soupName, matches[1]); | ||
var selectFields = this.getSelectFields(soupName, matches[1]); | ||
var whereField = matches[4]; | ||
@@ -373,3 +373,3 @@ var values = matches[5].split(","); | ||
// Expect comma separated of {soupName:y}, return array with the values of y | ||
_getSelectFields: function(soupName, s) { | ||
getSelectFields: function(soupName, s) { | ||
var fields = []; | ||
@@ -391,3 +391,3 @@ var fieldPattern = /{(.*):(.*)}/; | ||
_smartQuerySoupLikeOrdered : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupLikeOrdered : function(queryDesc, matches, smartSql) { | ||
if (matches[1] === matches[2] && matches[1] === matches[3] && (!matches[6] || matches[1] === matches[6])) { | ||
@@ -428,3 +428,3 @@ var soupName = matches[1]; | ||
_smartQuerySoupCount : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupCount : function(queryDesc, matches, smartSql) { | ||
var soupName = matches[1]; | ||
@@ -440,3 +440,3 @@ this.checkSoup(soupName); | ||
_smartQuerySoupCompare : function(queryDesc, matches, smartSql) { | ||
smartQuerySoupCompare : function(queryDesc, matches, smartSql) { | ||
if (matches[1] === matches[2] && matches[1] === matches[3] && (!matches[7] || matches[1] === matches[7])) { | ||
@@ -491,3 +491,3 @@ // Gather the parameters. | ||
var smartSql = querySpec.smartSql; | ||
var supportedQueries = this._supportedQueries(); | ||
var supportedQueries = this.supportedQueries(); | ||
@@ -512,2 +512,116 @@ for (var i = 0; i < supportedQueries.length; i++) { | ||
// Support some full-text queries (see doesFullTextMatch for details) | ||
querySoupFullTextSearch: function(soupName, querySpec) { | ||
this.checkSoup(soupName); | ||
var soup = this._soups[soupName]; | ||
var soupIndexedData = this._soupIndexedData[soupName]; | ||
var results = []; | ||
var paths = []; | ||
if (querySpec.indexPath) { | ||
paths.push(querySpec.indexPath); | ||
} | ||
else { | ||
// No indexPath provided, match against all full-text fields | ||
var indexSpecs = this._soupIndexSpecs[soupName]; | ||
for (var i=0; i<indexSpecs.length; i++) { | ||
var indexSpec = indexSpecs[i]; | ||
if (indexSpec.type === "full_text") { | ||
paths.push(indexSpec.path); | ||
} | ||
} | ||
} | ||
for (var soupEntryId in soup) { | ||
var soupElt = soup[soupEntryId]; | ||
var text = ""; | ||
if (querySpec.indexPath) { | ||
text = soupIndexedData[soupEntryId][querySpec.indexPath]; | ||
} | ||
else { | ||
// No indexPath provided, match against all full-text fields | ||
var indexSpecs = this._soupIndexSpecs[soupName]; | ||
for (var i=0; i<indexSpecs.length; i++) { | ||
var indexSpec = indexSpecs[i]; | ||
if (indexSpec.type === "full_text") { | ||
text += soupIndexedData[soupEntryId][indexSpec.path] + " "; | ||
} | ||
} | ||
} | ||
if (this.doesFullTextMatch(text, querySpec.matchKey)) { | ||
results.push(soupElt); | ||
} | ||
} | ||
return this.sortResults(results, querySpec); | ||
}, | ||
// query: space separated terms that all need to be in text | ||
// A term can be prefixed by - to indicate it should not be present. | ||
// A term can be suffixed by * to indicate to match any words starting with that term | ||
// | ||
// Example for the text: "the fox jumped over the dog" | ||
// query "fox dog" will return true | ||
// query "fox NOT dog" will return false | ||
// query "f* dog" will return true | ||
doesFullTextMatch: function(text, query) { | ||
var queryWithMinusForNots = query.replace(/ NOT /g, " -"); // code was originally written for standard syntax, turning "abc NOT def" into "abc -def" | ||
var wordsOfQuery = queryWithMinusForNots.split(/[^a-zA-Z0-9*-]/); | ||
wordsOfQuery.sort(); // to move the "-" words first | ||
var wordsOfElt = text.split(/\W/); | ||
wordsOfElt.sort(); // to speed up matches | ||
for (var j=0; j<wordsOfQuery.length; j++) { | ||
var wordOfQuery = wordsOfQuery[j].trim(); | ||
if (wordOfQuery == "") { | ||
continue; | ||
} | ||
// Negative keyword (keyword to exclude) | ||
if (wordOfQuery.indexOf("-") == 0) { | ||
wordOfQuery = wordOfQuery.substring(1); | ||
for (var i=0; i<wordsOfElt.length; i++) { | ||
var wordOfElt = wordsOfElt[i].trim(); | ||
if (wordOfElt == "") { | ||
continue; | ||
} | ||
if (wordOfElt.indexOf(wordOfQuery) == 0) { | ||
// A query word to exclude was found | ||
return false; | ||
} | ||
} | ||
} | ||
// Regular keyword | ||
else { | ||
var foundQueryWord = false; | ||
for (var i=0; i<wordsOfElt.length; i++) { | ||
var wordOfElt = wordsOfElt[i].trim(); | ||
if (wordOfElt == "") { | ||
continue; | ||
} | ||
if (wordOfQuery.endsWith("*")) { | ||
if (wordOfElt.indexOf(wordOfQuery.substring(0, wordOfQuery.length - 1)) == 0) { | ||
foundQueryWord = true; | ||
// all the "-" tests have already been conducted, we don't need to test further | ||
break; | ||
} | ||
} | ||
else if (wordOfQuery == wordOfElt) { | ||
foundQueryWord = true; | ||
// all the "-" tests have already been conducted, we don't need to test further | ||
break; | ||
} | ||
} | ||
// This query word was not found | ||
if (!foundQueryWord) { | ||
return false; | ||
} | ||
} | ||
} | ||
return true; | ||
}, | ||
querySoupFull: function(soupName, querySpec) { | ||
@@ -518,2 +632,6 @@ if (querySpec.queryType == "smart") { | ||
if (querySpec.queryType == "match") { | ||
return this.querySoupFullTextSearch(soupName, querySpec); | ||
} | ||
// other query type | ||
@@ -548,5 +666,9 @@ this.checkSoup(soupName); | ||
results = results.sort(function(soupElt1,soupElt2) { | ||
var p1 = soupElt1[querySpec.indexPath]; | ||
var p2 = soupElt2[querySpec.indexPath]; | ||
return this.sortResults(results, querySpec); | ||
}, | ||
sortResults: function(results, querySpec) { | ||
var resultsSorted = results.sort(function(soupElt1,soupElt2) { | ||
var p1 = soupElt1[querySpec.orderPath]; | ||
var p2 = soupElt2[querySpec.orderPath]; | ||
var compare = ( p1 > p2 ? 1 : (p1 == p2 ? 0 : -1)); | ||
@@ -556,6 +678,5 @@ return (querySpec.order == "ascending" ? compare : -compare); | ||
return results; | ||
return resultsSorted; | ||
}, | ||
querySoup: function(soupName, querySpec) { | ||
@@ -562,0 +683,0 @@ var results = this.querySoupFull(soupName, querySpec); |
@@ -308,3 +308,3 @@ /* | ||
var webAppSdkAgent = forcetkClient.computeWebAppSdkAgent(userAgent); | ||
var match = /SalesforceMobileSDK\/3.2.0 ([^\/]*)\/([^\ ]*) \(([^\)]*)\) ([^\/]*)\/1.0 Web (.*)/.exec(webAppSdkAgent); | ||
var match = /SalesforceMobileSDK\/3.3.0 ([^\/]*)\/([^\ ]*) \(([^\)]*)\) ([^\/]*)\/1.0 Web (.*)/.exec(webAppSdkAgent); | ||
if (match != null && match.length == 6) { | ||
@@ -311,0 +311,0 @@ QUnit.equals(match[1], expectedPlatform, "Wrong platform for user agent [" + userAgent + "]"); |
@@ -61,3 +61,3 @@ /* | ||
// sdkVersion | ||
QUnit.ok(sdkInfo.sdkVersion.indexOf("3.2") == 0, "expected different sdk version"); | ||
QUnit.ok(sdkInfo.sdkVersion.indexOf("3.3") == 0, "expected different sdk version"); | ||
// appName | ||
@@ -64,0 +64,0 @@ QUnit.ok(sdkInfo.appName == "HybridPluginTestApp" || sdkInfo.appName == "ForcePluginsTest", "expected different app name"); |
@@ -60,3 +60,3 @@ /* | ||
console.log("In SFSmartStoreTestSuite.stuffTestSoup"); | ||
var myEntry1 = { Name: "Todd Stellanova", Id: "00300A", attributes:{type:"Contact"} }; | ||
var myEntry1 = { Name: "Todd Stellanova", Id: "00300A", attributes:{type:"Contact"} }; | ||
var myEntry2 = { Name: "Pro Bono Bonobo", Id: "00300B", attributes:{type:"Contact"} }; | ||
@@ -213,3 +213,3 @@ var myEntry3 = { Name: "Robot", Id: "00300C", attributes:{type:"Contact"} }; | ||
/** | ||
* TEST registerSoup | ||
* TEST registerSoup with bogus soup | ||
*/ | ||
@@ -233,3 +233,3 @@ SmartStoreTestSuite.prototype.testRegisterBogusSoup = function() { | ||
/** | ||
* TEST registerSoup | ||
* TEST registerSoup with no indices | ||
*/ | ||
@@ -263,3 +263,3 @@ SmartStoreTestSuite.prototype.testRegisterSoupNoIndices = function() { | ||
/** | ||
* TEST upsertSoupEntries | ||
* TEST upsertSoupEntries | ||
*/ | ||
@@ -343,3 +343,3 @@ SmartStoreTestSuite.prototype.testUpsertSoupEntries = function() { | ||
/** | ||
* TEST upsertSoupEntries | ||
* TEST upsertSoupEntries to non existent soup | ||
*/ | ||
@@ -363,3 +363,3 @@ SmartStoreTestSuite.prototype.testUpsertToNonexistentSoup = function() { | ||
/** | ||
* TEST retrieveSoupEntries | ||
* TEST retrieveSoupEntries | ||
*/ | ||
@@ -432,6 +432,6 @@ SmartStoreTestSuite.prototype.testRetrieveSoupEntries = function() { | ||
/** | ||
* TEST querySoup | ||
* TEST querySoup with exact query | ||
*/ | ||
SmartStoreTestSuite.prototype.testQuerySoup = function() { | ||
console.log("In SFSmartStoreTestSuite.testQuerySoup"); | ||
SmartStoreTestSuite.prototype.testQuerySoupWithExactQuery = function() { | ||
console.log("In SFSmartStoreTestSuite.testQuerySoupWithExactQuery"); | ||
@@ -461,6 +461,6 @@ var self = this; | ||
/** | ||
* TEST querySoup | ||
* TEST querySoup with all query with descending sort order | ||
*/ | ||
SmartStoreTestSuite.prototype.testQuerySoupDescending = function() { | ||
console.log("In SFSmartStoreTestSuite.testQuerySoupDescending"); | ||
SmartStoreTestSuite.prototype.testQuerySoupWithAllQueryDescending = function() { | ||
console.log("In SFSmartStoreTestSuite.testQuerySoupWithAllQueryDescending"); | ||
@@ -490,4 +490,35 @@ var self = this; | ||
/** | ||
* TEST querySoup | ||
* TEST querySoup with range query using order path | ||
*/ | ||
SmartStoreTestSuite.prototype.testQuerySoupWithRangeQueryWithOrderPath = function() { | ||
console.log("In SFSmartStoreTestSuite.testQuerySoupWithRangeQueryWithOrderPath"); | ||
var self = this; | ||
self.stuffTestSoup(). | ||
pipe(function(entries) { | ||
QUnit.equal(entries.length, 3); | ||
var querySpec = navigator.smartstore.buildRangeQuerySpec("Id", null, "00300B", "ascending", 3, "Name"); | ||
// should match 00300A and 00300B but sort by name | ||
return self.querySoup(self.defaultSoupName, querySpec); | ||
}) | ||
.pipe(function(cursor) { | ||
QUnit.equal(cursor.totalEntries, 2, "totalEntries correct"); | ||
QUnit.equal(cursor.totalPages, 1, "totalPages correct"); | ||
QUnit.equal(cursor.currentPageOrderedEntries.length, 2, "check currentPageOrderedEntries"); | ||
QUnit.equal(cursor.currentPageOrderedEntries[0].Name,"Pro Bono Bonobo","verify first entry"); | ||
QUnit.equal(cursor.currentPageOrderedEntries[0].Id,"00300B","verify first entry"); | ||
QUnit.equal(cursor.currentPageOrderedEntries[1].Name,"Todd Stellanova","verify last entry"); | ||
QUnit.equal(cursor.currentPageOrderedEntries[1].Id,"00300A","verify last entry"); | ||
return self.closeCursor(cursor); | ||
}) | ||
.done(function(param) { | ||
QUnit.ok(true,"closeCursor ok"); | ||
self.finalizeTest(); | ||
}); | ||
}; | ||
/** | ||
* TEST querySoup with bad query spec | ||
*/ | ||
SmartStoreTestSuite.prototype.testQuerySoupBadQuerySpec = function() { | ||
@@ -728,2 +759,3 @@ console.log("In SFSmartStoreTestSuite.testQuerySoupBadQuerySpec"); | ||
QUnit.equal(query.indexPath,path,"check indexPath"); | ||
QUnit.equal(query.orderPath,path,"check orderPath"); | ||
QUnit.equal(query.matchKey,beginKey,"check matchKey"); | ||
@@ -735,2 +767,3 @@ QUnit.equal(query.pageSize,pageSize,"check pageSize"); | ||
QUnit.equal(query.indexPath,path,"check indexPath"); | ||
QUnit.equal(query.orderPath,path,"check orderPath"); | ||
QUnit.equal(query.beginKey,beginKey,"check beginKey"); | ||
@@ -744,2 +777,3 @@ QUnit.equal(query.endKey,endKey,"check endKey"); | ||
QUnit.equal(query.indexPath,path,"check indexPath"); | ||
QUnit.equal(query.orderPath,path,"check orderPath"); | ||
QUnit.equal(query.likeKey,beginKey,"check likeKey"); | ||
@@ -752,2 +786,3 @@ QUnit.equal(query.order,order,"check order"); | ||
QUnit.equal(query.indexPath,path,"check indexPath"); | ||
QUnit.equal(query.orderPath,path,"check orderPath"); | ||
QUnit.equal(query.beginKey,null,"check beginKey"); | ||
@@ -777,2 +812,3 @@ QUnit.equal(query.endKey,null,"check endKey"); | ||
QUnit.equal(nEntries, 1, "currentPageOrderedEntries correct"); | ||
QUnit.equal(cursor.currentPageOrderedEntries[0].Name,"Todd Stellanova","verify entry"); | ||
return self.closeCursor(cursor); | ||
@@ -803,2 +839,3 @@ }) | ||
QUnit.equal(nEntries, 1, "currentPageOrderedEntries correct"); | ||
QUnit.equal(cursor.currentPageOrderedEntries[0].Name,"Todd Stellanova","verify entry"); | ||
return self.closeCursor(cursor); | ||
@@ -828,2 +865,3 @@ }) | ||
QUnit.equal(nEntries, 1, "currentPageOrderedEntries correct"); | ||
QUnit.equal(cursor.currentPageOrderedEntries[0].Name,"Pro Bono Bonobo","verify entry"); | ||
return self.closeCursor(cursor); | ||
@@ -838,2 +876,89 @@ }) | ||
/** | ||
* TEST full-text search | ||
*/ | ||
SmartStoreTestSuite.prototype.testFullTextSearch = function() { | ||
console.log("In SFSmartStoreTestSuite.testFullTextSearch"); | ||
var self = this; | ||
var myEntry1 = { name: "elephant", description:"large mammals", colors:"grey"}; | ||
var myEntry2 = { name: "cat", description:"small mammals", colors:"black tabby white"}; | ||
var myEntry3 = { name: "dog", description:"medium mammals", colors:"grey black"}; | ||
var myEntry4 = { name: "lizard", description:"small reptilian", colors:"black green white"}; | ||
var rawEntries = [myEntry1, myEntry2, myEntry3, myEntry4]; | ||
var soupName = "animals"; | ||
self.removeAndRecreateSoup(soupName, [{path:"name", type:"string"}, {path:"description", type:"full_text"}, {path:"colors", type:"full_text"}]) | ||
.pipe(function() { | ||
return self.upsertSoupEntries(soupName,rawEntries); | ||
}) | ||
.pipe(function(entries) { | ||
// Searching across fields with one term | ||
var querySpec = navigator.smartstore.buildMatchQuerySpec(null, "grey", "ascending", 10, "name"); | ||
return self.tryFullTextSearch(soupName, querySpec, ["dog", "elephant"]); | ||
}) | ||
.pipe(function() { | ||
// Searching across fields with multiple terms | ||
var querySpec = navigator.smartstore.buildMatchQuerySpec(null, "small black", "descending", 10, "name"); | ||
return self.tryFullTextSearch(soupName, querySpec, ["lizard", "cat"]); | ||
}) | ||
.pipe(function() { | ||
// Searching across fields with one term starred | ||
var querySpec = navigator.smartstore.buildMatchQuerySpec(null, "gr*", "ascending", 10, "name"); | ||
return self.tryFullTextSearch(soupName, querySpec, ["dog", "elephant", "lizard"]); | ||
}) | ||
.pipe(function() { | ||
// Searching across fields with multiple terms one being negated | ||
var querySpec = navigator.smartstore.buildMatchQuerySpec(null, "black NOT tabby", "descending", 10, "name"); | ||
return self.tryFullTextSearch(soupName, querySpec, ["lizard", "dog"]); | ||
}) | ||
.pipe(function() { | ||
// Searching across fields with multiple terms (one starred, one negated) | ||
var querySpec = navigator.smartstore.buildMatchQuerySpec(null, "gr* NOT small", "ascending", 10, "name"); | ||
return self.tryFullTextSearch(soupName, querySpec, ["dog", "elephant"]); | ||
}) | ||
.pipe(function(entries) { | ||
// Searching one field with one term | ||
return self.run | ||
var querySpec = navigator.smartstore.buildMatchQuerySpec("colors", "grey"); | ||
return self.tryFullTextSearch(soupName, querySpec, ["elephant", "dog"]); | ||
}) | ||
.pipe(function() { | ||
// Searching one field with multiple terms | ||
var querySpec = navigator.smartstore.buildMatchQuerySpec("colors", "white black", "ascending", 10, "name"); | ||
return self.tryFullTextSearch(soupName, querySpec, ["cat", "lizard"]); | ||
}) | ||
.pipe(function() { | ||
// Searching one field with one term starred | ||
var querySpec = navigator.smartstore.buildMatchQuerySpec("colors", "gr*", "ascending", 10, "name"); | ||
return self.tryFullTextSearch(soupName, querySpec, ["dog", "elephant", "lizard"]); | ||
}) | ||
.pipe(function() { | ||
// Searching one field with multiple terms one being negated | ||
var querySpec = navigator.smartstore.buildMatchQuerySpec("colors", "black NOT tabby", "descending", 10, "name"); | ||
return self.tryFullTextSearch(soupName, querySpec, ["lizard", "dog"]); | ||
}) | ||
.pipe(function() { | ||
// Searching one with multiple terms (one starred, one negated) | ||
var querySpec = navigator.smartstore.buildMatchQuerySpec("description", "m* NOT small", "ascending", 10, "name"); | ||
return self.tryFullTextSearch(soupName, querySpec, ["dog", "elephant"]); | ||
}) | ||
.done(function(param) { | ||
QUnit.ok(true,"closeCursor ok"); | ||
self.finalizeTest(); | ||
}); | ||
}; | ||
SmartStoreTestSuite.prototype.tryFullTextSearch = function(soupName, querySpec, expectedNames) { | ||
var self = this; | ||
return self.querySoup(soupName, querySpec) | ||
.pipe(function(cursor) { | ||
QUnit.equal(cursor.currentPageOrderedEntries.length, expectedNames.length, "check currentPageOrderedEntries when trying match '" + querySpec.matchKey + "'"); | ||
for (var i=0; i<cursor.currentPageOrderedEntries.length; i++) { | ||
QUnit.equal(cursor.currentPageOrderedEntries[i].name,expectedNames[i],"verify that entry " + i + " is " + expectedNames[i] + " when trying match '" + querySpec.matchKey + "'"); | ||
} | ||
return self.closeCursor(cursor); | ||
}) | ||
}; | ||
/** | ||
* TEST query with compound path | ||
@@ -840,0 +965,0 @@ */ |
@@ -28,3 +28,3 @@ /* | ||
// Version this js was shipped with | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.2.0"; | ||
var SALESFORCE_MOBILE_SDK_VERSION = "3.3.0"; | ||
@@ -31,0 +31,0 @@ cordova.define("com.salesforce.plugin.testrunner", function(require, exports, module) { |
{ | ||
"name": "salesforcemobilesdk-shared", | ||
"version": "3.2.0", | ||
"version": "3.3.0", | ||
"dependencies": { | ||
@@ -5,0 +5,0 @@ "jquery": "2.0.3", |
{ | ||
"name": "salesforcemobilesdk-shared", | ||
"version": "3.2.0", | ||
"version": "3.3.0", | ||
"dependencies": {}, | ||
@@ -5,0 +5,0 @@ "devDependencies": { |
{ | ||
"name": "forceios", | ||
"version": "3.2.2", | ||
"version": "3.3.0", | ||
"description": "Utilities for creating mobile apps based on the Salesforce Mobile SDK for iOS", | ||
@@ -5,0 +5,0 @@ "keywords": [ "mobilesdk", "ios", "salesforce", "mobile", "sdk" ], |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 2 instances in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
0
206630
7
44886779
294